MCU -- Stm32F100CB cotex-M3架构,128KB ROM,8KB SRAM。
Ethernet Controller –ENC28J60 10Mb 以太网控制器,使用SPI总线与MCU交互。
802.15.4 Controller –cc2500 802.15.4 网络控制芯片,使用SPI总线与MCU交互。
准备编译调试工具集
这里我们使用GNU编译工具集,最少要包括编译器(GCC),链接器(LD),调试器(GDB),实用工具集(ReadELF,ObjCopy)。
编译器的选择:能编译出thumb2指令集的编译器即可,这里选用gcc版本号4.5.2。也可以使用第三方提供的编译好的GNU编译工具链,其中Mentor提供的就不错,可以到如下网站下载:
http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/platforms/arm-eabi
准备下载调试环境
硬件:JLink调试器,version 8.
与硬件连接软件: SEGGERJLINK或者使用OpenOCD都行,我们这里使用的是SEGGERJLINK,以后会试试OpenOCD。
准备相关代码
Contiki2.5源码:http://sourceforge.net/projects/contiki/?source=directory
Enc28J60示例代码,可以从Microchip网站上下载,这里不列出。
CC2500示例代码,还没写CC2500的Contiki驱动但这不是重点,示例可以从TI网站上获得。
首先我们的目标是让Contiki操作系统运行起来,关键部分就是启动系统时钟,对应到Contiki进程就是启动Etimer进程。但只启动一个etimer进程没有意思,我们加上一个LED闪烁进程,使用etimer来定时亮灭。所以综上,我们最原始的Contiki系统包含一个系统进程(只是比喻,Contiki中进程不分系统与用户)etimer_process,与一个用户进程led_twinkling_process。而etimer_process由Contiki系统提供,我们这里只需对系统时钟进行初始化并定时更新系统时钟(用户自定义current_clock),并判断etimer的下一个定时时刻是否已到(通过比较current_clock与etimer的定时时刻来判定)如果时钟等待序列中有等待时钟的进程那么就调度etimer进程执行,通过其来唤醒相关进程。相关代码如下:
#include <stm32f10x_map.h> #include <nvic.h> #include <sys/clock.h> #include <sys/cc.h> #include <sys/etimer.h> #include <debug-uart.h> static volatile clock_time_t current_clock= 0; static volatile unsigned longcurrent_seconds = 0; static unsigned int second_countdown =CLOCK_SECOND; void SysTick_handler(void) __attribute__((interrupt)); void SysTick_handler(void) { (void)SysTick->CTRL; SCB->ICSR= SCB_ICSR_PENDSTCLR; current_clock++; if(etimer_pending()&& etimer_next_expiration_time() <= current_clock) { etimer_request_poll(); } if(--second_countdown == 0) { current_seconds++; second_countdown= CLOCK_SECOND; } } void clock_init() { NVIC_SET_SYSTICK_PRI(8); SysTick->LOAD= ((unsigned int)24000000) / 8 / CLOCK_SECOND; SysTick->CTRL= SysTick_CTRL_ENABLE | SysTick_CTRL_TICKINT; } clock_time_t clock_time(void) { returncurrent_clock; } unsigned long clock_seconds(void) { returncurrent_seconds; }
接下来就是针对Contiki编写准备以太网卡enc28j60的驱动,包含spi驱动,照着芯片厂商提供的示例代码编写就差不多了。
驱动有了,还要实现驱动与Contiki之间的接口,这一步还是比较容易的可以参照Contiki提供的文档中的例子“example-packet-drv.c”来编写,值得注意就是ethernet链路层头有14个字节大小,要在“contiki-conf.h”中指出来,具体来说就是定义宏“#defineUIP_CONF_LLH_LEN 14”。当然因为ethernet的MTU为1500所以我们定义uip buffer的大小就为1500.
再来,最主要的一个与移植相关的文件就是contiki-conf.h了,其位于platform/my_platform/文件夹下,用于定制Contiki的功能。
最后就是编写相应platform的Makefile了,将“CONTIKI_TARGET_DIRS”,“CONTIKI_TARGET_SOURCEFILES”附上相应的值,并包含相应cpu的Makefile即可。
最后的最后LD使用连接脚本也需要自己编写,指明各段的位置(位于ROM还是SRAM)。
OK,编译下载。