移植Conkiti内核到LPC11U14上

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按键做反应。

你可能感兴趣的:(移植Conkiti内核到LPC11U14上)