现在的位置: 首页 > 综合 > 正文

移植Conkiti内核到LPC11U14上

2018年04月11日 ⁄ 综合 ⁄ 共 7094字 ⁄ 字号 评论关闭

Conkiti的调度内核很简单:使用轻量级的proto-threads进程模型,可以在事件驱动内核上提供一种线性的、类似于线程的编程风格。

因此Conkiti的上下文保存不会使用到汇编而完全用C语言完成,proto-threads属于抢占式OS模型,需要进程主动释放CPU,进程的上下文通过当前文件的行号保存。因此上下文切换可以通过C完成。

1.调度内核涉及的文件:

conkiti/core/sys/

arg.c        ctimer.c    etimer.h         pt-sem.h  subprocess.h 

arg.h        ctimer.h    lc-addrlabels.h  pt.h      timer.c 

autostart.c  dsc.h       lc-switch.h      process.c   rtimer.c  timer.h 

autostart.h  energest.c  lc.h             process.h   rtimer.h 

cc.h         energest.h  loader.h         procinit.c  stimer.c 

clock.h      etimer.c    log.h            procinit.h  stimer.h

conkiti/core/lib/

crc16.c  ifft.c  makefile   me_tabs.h      ringbuf.c 

crc16.h  ifft.h  me.c       nouse          ringbuf.h 

gcr.c    list.c  me.h       petsciiconv.c  strncasecmp.c 

gcr.h    list.h  me_tabs.c  petsciiconv.h

 

2.移植需要实现的函数:

void clock_init(void)   初始化时钟

   安装clock tick中断到lpc11u14的cortex-m0内核定时器中断内

   目前系统设置的是一个tick 1ms

   clock tick中断为sec计时而设置,每1000个tick对sec做++处理

clock_time_t clock_time(void) 获取当前时钟tick数

   直接返回lpc11u14系统tick数Lpc11u_System_GetTick()

unsigned long clock_seconds(void) 获取当期时钟秒计数

   返回clock tick 中断内sec值

void clock_delay(unsigned int t) delay函数

   这个函数会在contiki的dev下面用,目前移植调度内核,因此该函数暂时为空

 

3.调度内核配置

/* CC configuration*/ 

#define CC_CONF_REGISTER_ARGS 1                                     //允许寄存器变量 

#define CC_CONF_FUNCTION_POINTER_ARGS 1                       //允许函数指针 

#define CC_CONF_FASTCALL    __attribute__((fastcall))            //支持fastcall,fastcall是在传递参数时通过寄存器完成,而不使用压栈 

//#define CC_CONF_CONST_FUNCTION_BUG 

//#define CC_CONF_UNSIGNED_CHAR_BUGS 

//#define CC_CONF_DOUBLE_HASH 

#define CC_CONF_INLINE    __attribute__((inline))                    //支持inline函数 

//#define CC_CONF_ASSIGN_AGGREGATE 

//#define CC_CONF_NO_VA_ARGS 0 

#define CC_BYTE_ALIGNED __attribute__ ((packed, aligned(1)))  //支持结构体字节对齐

/* Process configuration*/ 

#define AUTOSTART_ENABLE 1                                                  //开启process自动启动机制 

#define PROCESS_CONF_NO_PROCESS_NAMES 0                        //保存process name

 

按照如上配置和实现,已经在ds lpc11u14的板子上调度成功,测试代码如下:实现了一个灯周期性的闪烁,其它三个灯根据输入的数字点亮:

1   #include "driver/gpio.h" 
2   #include "driver/uart.h" 
3   
4   #include "lpc11u_system.h" 
5   
6   #include "contiki.h" 
7   
8   
9   static process_event_t event_data_ready; 
10  static u8 u8Data = 0; 
11  
12  
13  PROCESS(Led_Flash, "Led-flash"); 
14  PROCESS(Uart_PRC1, "Uart-Proc1"); 
15  PROCESS(Uart_PRC2, "Uart-Proc2"); 
16  
17  AUTOSTART_PROCESSES(&Led_Flash, &Uart_PRC1, &Uart_PRC2); 
18  
19  int main() 
20  { 
21      u8 u8Data; 
22  
23      u32 u32Time; 
24      u8 u8i = 0; 
25      
26      Lpc11u_System_Init(); 
27      GPIO_Init(); 
28      Uart_Init(); 
29      Shell_Init();    
30  
31      SPI_Flash_Init(); 
32  
33      u32Time = Lpc11u_System_GetTick(); 
34      
35      printf("Frank Test: Hello world!\r\n"); 
36  
37      while(u8i<10)  
38      { 
39          if(Uart_Read(0, &u8Data, 1, 0) == 1) 
40          { 
41              printf("Get char %c\r\n", u8Data); 
42          } 
43          
44          if(Lpc11u_SysTem_DiffTick(u32Time)>=1000) 
45          { 
46              u32Time = Lpc11u_System_GetTick(); 
47              
48              if(u8i%4 == 0) 
49              { 
50                  GPIO_SetLevel(0, 0); 
51                  GPIO_SetLevel(1, 1); 
52                  GPIO_SetLevel(2, 1); 
53                  GPIO_SetLevel(3, 1); 
54              } 
55              else if(u8i%4 == 1) 
56              { 
57                  GPIO_SetLevel(0, 1); 
58                  GPIO_SetLevel(1, 0); 
59                  GPIO_SetLevel(2, 1); 
60                  GPIO_SetLevel(3, 1); 
61              } 
62              else if(u8i%4 == 2) 
63              { 
64                  GPIO_SetLevel(0, 1); 
65                  GPIO_SetLevel(1, 1); 
66                  GPIO_SetLevel(2, 0); 
67                  GPIO_SetLevel(3, 1); 
68              }else if(u8i%4 == 3) 
69              { 
70                  GPIO_SetLevel(0, 1); 
71                  GPIO_SetLevel(1, 1); 
72                  GPIO_SetLevel(2, 1); 
73                  GPIO_SetLevel(3, 0); 
74              } 
75              u8i++; 
76          } 
77      } 
78  
79  
80      printf("Test OK, Start contiki....\r\n"); 
81      clock_init(); 
82      process_init(); 
83      ctimer_init(); 
84      
85      process_start(&etimer_process, NULL); 
86      autostart_start(autostart_processes); 
87  
88      while(1)  
89      { 
90           etimer_request_poll(); 
91          do  
92          { 
93              } while(process_run() > 0); 
94      } 
95      return 0; 
96  } 
97  
98  
99  PROCESS_THREAD(Led_Flash, ev, data)  
100 {  
101     static u8 u8i = 0; 
102     static u8 *pu8Data; 
103     
104     PROCESS_BEGIN(); 
105 
106     printf("%s process start!\r\n", PROCESS_NAME_STRING(&Led_Flash)); 
107 
108     while(1) 
109     { 
110         PROCESS_WAIT_EVENT_UNTIL(ev == event_data_ready); 
111         pu8Data = data; 
112         
113         if(*pu8Data == 8) 
114         { 
115             GPIO_SetLevel(0, (u8i++)&0x01); 
116         } 
117         else 
118         { 
119             //printf("%s-> Get event data %u\r\n", PROCESS_NAME_STRING(&Led_Flash), *pu8Data); 
120             GPIO_SetLevel(3, (*pu8Data & 0x1)); 
121             GPIO_SetLevel(2, (*pu8Data>>1) & 0x1); 
122             GPIO_SetLevel(1, (*pu8Data>>2) & 0x1); 
123         } 
124     } 
125     
126     PROCESS_END(); 
127 } 
128 
129 PROCESS_THREAD(Uart_PRC1, ev, data)  
130 {  
131     PROCESS_BEGIN(); 
132 
133     static struct etimer timer; 
134     etimer_set(&timer, 1000);        //etimer who seting ,whe used 
135     printf("%s process start!\r\n", PROCESS_NAME_STRING(&Uart_PRC1)); 
136 
137     event_data_ready = process_alloc_event(); 
138 
139     while(1) 
140     { 
141         PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); 
142         //printf("%s-> Time Get\r\n", PROCESS_NAME_STRING(&Uart_PRC1)); 
143         u8Data = 8; 
144         process_post(&Led_Flash, event_data_ready, &u8Data); 
145         etimer_reset(&timer); 
146     } 
147     
148     PROCESS_END(); 
149 } 
150 
151 PROCESS_THREAD(Uart_PRC2, ev, data)  
152 {  
153     PROCESS_BEGIN(); 
154     static struct etimer timer; 
155     static u8 u8Read; 
156     etimer_set(&timer, 20);        //etimer who seting ,whe used 
157     printf("%s process start!\r\n", PROCESS_NAME_STRING(&Uart_PRC2)); 
158 
159     while(1) 
160     { 
161         PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); 
162         if(1 == Uart_Read(0, &u8Read, 1, 0)) 
163         { 
164             //printf("%s Get Uart Data %c\r\n",  PROCESS_NAME_STRING(&Uart_PRC2), u8Read); 
165             u8Data = u8Read - 0x30; 
166             if(u8Data>=0 && u8Data<=7) 
167             { 
168                //printf("%s Send Uart Data %u to Led_Flash\r\n",  PROCESS_NAME_STRING(&Uart_PRC2), u8Data); 
169                 process_post(&Led_Flash, event_data_ready, &u8Data); 
170             } 
171             else 
172             { 
173                 //printf("%s No Send Uart Data\r\n",  PROCESS_NAME_STRING(&Uart_PRC2)); 
174             } 
175         } 
176         etimer_reset(&timer); 
177     } 
178     
179     PROCESS_END(); 
180 } 
181 
182 

以上

Led_Flash process接收event,根据event信息决定点亮那些LED

Uart_PRC1 process每1s发一次event到Led_Flash process, 改变LED 0的状态

Uart_PRC2 process每20 ms读一次串口,根据串口接收到的数据改变LED1~3的状态,只对0~7按键做反应。

抱歉!评论已关闭.