移植Conkiti内核到LPC11U14上

来源:互联网 发布:淘宝冻结资金 编辑:程序博客网 时间:2024/06/05 07:30

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

0 0
原创粉丝点击