├── README.md ├── Makefile ├── gpio.c ├── gpio.h ├── eatmem.c ├── main.c └── no_rt_motor.c /README.md: -------------------------------------------------------------------------------- 1 | # Xenomai-3-example-demo 2 | Add some Xenomai3 API example for beginner learning. 3 | 4 | # USAGE 5 | ## Real time program 6 | `make` 7 | 8 | `sudo ./rt_task` 9 | 10 | ## Non real time program 11 | `make no_rt` 12 | 13 | `sudo ./no_rt_motor` 14 | ## Memory load 15 | `make load` 16 | 17 | `sudo ./eatmem` 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | SKIN = native 3 | CFLAGS = -std=gnu99 $(shell xeno-config --skin=$(SKIN) --cflags) 4 | LDFLAGS = $(shell xeno-config --skin=$(SKIN) --ldflags) 5 | 6 | EXE = rt_motor 7 | LOAD = eatmem 8 | 9 | all: main.c gpio.c 10 | $(CC) $^ $(CFLAGS) $(LDFLAGS) -o $(EXE) 11 | 12 | no_rt: 13 | $(CC) no_rt_motor.c -o no_rt_motor 14 | 15 | load: 16 | $(CC) eatmem.c -o $(LOAD) 17 | 18 | clean: 19 | rm $(EXE) $(LOAD) no_rt_motor 20 | -------------------------------------------------------------------------------- /gpio.c: -------------------------------------------------------------------------------- 1 | // How to access GPIO registers from C-code on the Raspberry-Pi 2 | // Example program 3 | // 15-January-2012 4 | // Dom and Gert 5 | // Revised: 15-Feb-2013 6 | 7 | // Access from ARM Running Linux 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "gpio.h" 15 | 16 | // Set up a memory regions to access GPIO 17 | void setup_io() { 18 | 19 | /* open /dev/mem */ 20 | if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 21 | printf("can't open /dev/mem \n"); 22 | exit(-1); 23 | } 24 | /* mmap GPIO */ 25 | gpio_map = mmap( NULL, //Any adddress in our space will do 26 | BLOCK_SIZE, //Map length 27 | PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory 28 | MAP_SHARED, //Shared with other processes 29 | mem_fd, //File to map 30 | GPIO_BASE //Offset to GPIO peripheral 31 | ); 32 | 33 | close(mem_fd); //No need to keep mem_fd open after mmap 34 | 35 | if (gpio_map == MAP_FAILED) { 36 | printf("mmap error %d\n", (int)gpio_map);//errno also set! 37 | exit(-1); 38 | } 39 | 40 | // Always use volatile pointer! 41 | gpio = (volatile unsigned *)gpio_map; 42 | } 43 | -------------------------------------------------------------------------------- /gpio.h: -------------------------------------------------------------------------------- 1 | // How to access GPIO registers from C-code on the Raspberry-Pi 2 | // Example program 3 | // 15-January-2012 4 | // Dom and Gert 5 | // Revised: 15-Feb-2013 6 | 7 | // Access from ARM Running Linux 8 | 9 | #ifndef GPIO_H 10 | #define GPIO_H 11 | 12 | #define BCM2708_PERI_BASE 0x3F000000 13 | #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ 14 | #define PAGE_SIZE (4*1024) 15 | #define BLOCK_SIZE (4*1024) 16 | 17 | int mem_fd; 18 | void *gpio_map; 19 | 20 | // I/O access 21 | volatile unsigned *gpio; 22 | 23 | // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) 24 | #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) 25 | #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) 26 | #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) 27 | 28 | #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 29 | #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 30 | 31 | #define GET_GPIO(g) (*(gpio+13)&(1< 34 | #include 35 | #include 36 | int main(int argc, char **argv) 37 | { 38 | int i; 39 | for(i=0; i < 500; i++){ 40 | char *tmp; 41 | int j; 42 | tmp = malloc(1024*1024); 43 | if(!tmp){ 44 | printf("Cannot allocate memory\n"); 45 | exit(0); 46 | } 47 | 48 | // Ensure the pages are actually allocated! 49 | for(j=0; j < 1024*1024; j+=1024){ 50 | tmp[j] = 1; 51 | } 52 | printf("Allocated memory (%d MiB)\n",i); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "gpio.h" 8 | 9 | #define TASK_STKSZ 0 //default stack size 10 | #define TASK_PRIO 20 //0-99 11 | #define TASK_MODE 0 //no flags 12 | 13 | #define A_PHASE_PIN 20 14 | #define B_PHASE_PIN 21 15 | #define STEP_PIN 5 16 | #define DIR_PIN 6 17 | 18 | void motor_control(void *arg); 19 | 20 | int main(int argc, char** argv) { 21 | 22 | setup_io(); 23 | 24 | INP_GPIO(A_PHASE_PIN); 25 | INP_GPIO(B_PHASE_PIN); 26 | INP_GPIO(STEP_PIN); 27 | OUT_GPIO(STEP_PIN); 28 | INP_GPIO(DIR_PIN); 29 | OUT_GPIO(DIR_PIN); 30 | 31 | int i; 32 | int err; 33 | 34 | mlockall(MCL_CURRENT | MCL_FUTURE); 35 | RT_TASK rt_task; 36 | 37 | err = rt_task_spawn( &rt_task, "rt_motor_control", TASK_STKSZ, TASK_PRIO, TASK_MODE, &motor_control, NULL); 38 | 39 | if(err) { 40 | rt_task_delete(&rt_task); 41 | exit(1); 42 | } 43 | 44 | getchar(); 45 | return 0; 46 | } 47 | 48 | void motor_control(void *arg) { 49 | 50 | int A_curr = 0; 51 | int B_curr = 0; 52 | int A_pre = 0; 53 | int B_pre = 0; 54 | 55 | if( GET_GPIO(20) ){ 56 | if( GET_GPIO(21) ){ 57 | A_pre = 1; 58 | B_pre = 1; 59 | }else{ 60 | A_pre = 1; 61 | B_pre = 0; 62 | } 63 | }else{ 64 | if( GET_GPIO(21) ){ 65 | A_pre = 0; 66 | B_pre = 1; 67 | }else{ 68 | A_pre = 0; 69 | B_pre = 0; 70 | } 71 | } 72 | 73 | while(1){ 74 | if( GET_GPIO(20) ){ 75 | if( GET_GPIO(21) ){ 76 | A_curr = 1; 77 | B_curr = 1; 78 | }else{ 79 | A_curr = 1; 80 | B_curr = 0; 81 | } 82 | }else{ 83 | if( GET_GPIO(21) ){ 84 | A_curr = 0; 85 | B_curr = 1; 86 | }else{ 87 | A_curr = 0; 88 | B_curr = 0; 89 | } 90 | } 91 | 92 | if( A_curr != A_pre || B_curr != B_pre) { 93 | if( A_pre == 1 && B_pre == 0 ) { 94 | if( A_curr == 1 ){ 95 | GPIO_SET = 1 << 6; 96 | }else{ 97 | GPIO_CLR = 1 << 6; 98 | } 99 | }else if( A_pre == 1 && B_pre == 1 ){ 100 | if( A_curr == 0 ){ 101 | GPIO_SET = 1 << 6; 102 | }else{ 103 | GPIO_CLR = 1 << 6; 104 | } 105 | }else if( A_pre == 0 && B_pre == 1 ){ 106 | if( A_curr == 0 ){ 107 | GPIO_SET = 1 << 6; 108 | }else{ 109 | GPIO_CLR = 1 << 6; 110 | } 111 | }else if( A_pre == 0 && B_pre == 0 ){ 112 | if( A_curr == 1 ){ 113 | GPIO_SET = 1 << 6; 114 | }else{ 115 | GPIO_CLR = 1 << 6; 116 | } 117 | } 118 | 119 | GPIO_SET = 1 << 5; 120 | usleep(1); 121 | GPIO_CLR = 1 << 5; 122 | 123 | A_pre = A_curr; 124 | B_pre = B_curr; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /no_rt_motor.c: -------------------------------------------------------------------------------- 1 | 2 | // How to access GPIO registers from C-code on the Raspberry-Pi 3 | // Example program 4 | // 15-January-2012 5 | // Dom and Gert 6 | // Revised: 15-Feb-2013 7 | 8 | // Access from ARM Running Linux 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #define BCM2708_PERI_BASE 0x3F000000 20 | #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ 21 | #define PAGE_SIZE (4*1024) 22 | #define BLOCK_SIZE (4*1024) 23 | 24 | int mem_fd; 25 | void *gpio_map; 26 | int time_interval = 1000; 27 | 28 | // I/O access 29 | volatile unsigned *gpio; 30 | 31 | // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) 32 | #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) 33 | #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) 34 | #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) 35 | 36 | #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 37 | #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 38 | 39 | #define GET_GPIO(g) (*(gpio+13)&(1<