430也能玩嵌入式:Contiki内核在IAR+MSP430下移植(转发)

2019-08-07 19:39发布

摘要:本文详细记录了Contiki内核在IAR+MSP430下移植步骤,遇到的问题,分析解决,最后附上工程源码。
前言分析了Contiki有一段时间了,但本人还没真正移植过。之前是我们项目组一哥们移植好了(IAR+ARM),我在调试Contiki文件系统Coffee遇到了难题,于是就想在MSP430平台上调试,理由是MSP430硬件比较简单。最近,CU网友kangerbiao45d已经把Contiki移到IAR+Telosb,给了我莫大鼓舞(感谢他)。我手头有MSP430-169LCD,于是下决心移植Contiki到IAR+MSP430-169LCD。终于跑通了,遂将过程详细记录,以供分享。
官方的Contiki源码是在Linux开发环境进行的,移植到IAR,首要解决的就是GCC与IAR之间的差异,包括:    (1)GCC是用Makefile来管理工程编译,而IAR是IDE,通过工程文件目录来反映文件间的关系,所以必要时需要将路径加到preprocesses;(2)嵌入式汇编,GCC内嵌汇编与IAR内嵌汇编格式差异甚大,需要全面修改Contiki出现内嵌汇编的地方;(3)文件差异,Linux平台下的Contiki会调用Linux的头文件或者文件名不同(比如io.h与io430.h)。再者需要解决版子间的差异,如果节点恰是Contiki支持的,那最好(比如Telosb),否则选择一个相近的节点进行修改,比如我的板子MSP430-169LCD,其MCU是MSP430F169,与Telosb的MSP430F1161属于同一序列。
一、下载源码及创建工程文件1.1 下载源代码Contiki最新版本是2.5,可以从SourceForge下载源码,猛击这里下载。1.2 创建工程文件移植的指导思想是先把内核跑起来,而后根据需求再把文件系统、动态加载、网络模块加上去。所以这里只需把Contiki内核相关的源文件加到工程目录,不过加多了也没关系,还有后续的调试嘛:-)取一个Contiki支持的节点来修改,这里选择Tosek(因其MCU是MSP430F1611),将platform/sky/下文件拷贝到新建文件夹platform/MSP430-169LCD。我的工程目录如下(期间删了若干文件):图1 Contiki_msp430工程目录示意图接下来,就一步步修改吧。值得一提的是,考虑到后续还要移植文件系统、动态加载、网络模块,本次遇到错误是尽可能的修改,实在不行,才从工程目录将该文件删除。所以,实际移植Contiki内核要比以下描述的要简单得多。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
houjiakai
1楼-- · 2019-08-08 17:09
修改的部分源码如下:
  • //filename:msp430.c
  • //asmv("mov r1, %0" : "=r" (stack_pointer)); //sbrk(int incr)函数
  • *stack_pointer = (unsigned short)__get_SP_register();
  • //asmv("mov r2, %0" : "=r" (sr)); //splhigh_(void)函数
  • //asmv("bic %0, r2" : : "i" (GIE));
  • asmv("EINT");
  • //asmv("bis %0, r2" : : "r" (sr)); //splx_(int sr)函数
  • asmv(" bis &sr,r2"); //改成这样不行!!!直接注释了


2.6 板子相关的未定义变量编译会出现很多未定义错误,诸如ADC12MCTL_NO(sky-sensors.c,显然板子相关)、UCB0CTL1等(cpu/msp430/spix.c)、UCA0STAT等(cpu/msp430/dev/uart0x.c及uart1x.c),这里简单地把这些相关文件从工程目录移除。

houjiakai
2楼-- · 2019-08-08 18:21
 精彩回答 2  元偷偷看……
houjiakai
3楼-- · 2019-08-08 18:35
3.3 重复段Error[e24]链接时提示如下错误:图6 IAR Error[e24]示意图造成这个问题的原因是有些文件包含了msp430.h,而有些文件包含了io430.h。以MSP430F1611为例,前者通过宏定位到msp430f1600.h,通过则是定位到iox16x.h,而这两个文件有很多重叠的地方(如本例的IE1)。cpu/msp430/rom.c包含了io430.h,flash.c包含了msp430.h,在这里,将flash.c包含的msp430.h改成io430.h。同样的问题也发生在cpu/msp430/watchdog.c、core/dev/sht11.c、platform/MSP430-169LCD/dev/button-sensor.c(这个还得从包含的头文件追溯,在cpu/msp430/dev/hwconf.h文件)、cpu/msp430/leds-arch.c、cpu/msp430/clock.c、cpu/msp430/cc2420-arch-sfd.c等,可以通过Find in Files寻找msp430.h来替换。
houjiakai
4楼-- · 2019-08-08 22:49
3.4 外部符号未定义(1) BV在cpu/msp430/button.c提示外部符号BV未定义,通过Find in Files查找,可知该宏通常是定义在contiki-conf.h或者platform-conf.h文件,如下:图7 BV宏定义位置这里,模仿其他例程,在platform/MSP430-169LCD/contiki-conf.h文件加入如下代码:
  • #ifndef BV
  •   #define BV(x) (1<<(x))
  • #endif



houjiakai
5楼-- · 2019-08-08 22:59
(2)cc2420_sfd_counter、cc2420_sfd_start_time和cc2420_sfd_end_time在cpu/msp430/cc2420-arch-sfd.c提示外部符号cc2420_sfd_counter.c、cc2420_sfd_start_time和cc2420_sfd_end_time未定义,该文件将这三个变量声明为外部变量,源码如下:
  • extern volatile uint8_t cc2420_sfd_counter;
  • extern volatile uint16_t cc2420_sfd_start_time;
  • extern volatile uint16_t cc2420_sfd_end_time;


事实上,这三个变量已经在contiki-2.5/core/dev/cc2420.c文件定义了, 而这个文件已经被我工程目录删除了,因为编译cc2420.c会引发一系列端口未定义(如TXEPT、UTXIFG0),而这些端口大概是跟cc2420芯片有关吧。这里,我们简单将cpu/msp430/目录下的cc2420*.c文件从工程移除。
houjiakai
6楼-- · 2019-08-09 03:30
(3) dint与eint在cpu/msp430/clock.c提示外部符号dint和eint未定义,这是因为Linux开发环境用eint()和dint()分别开、关中断,但IAR则是使用__enable_interrupt()和__disable_interrupt()。可以直接替换eint()和dint(),这里采用更具移植性的方法,在platform/MSP430-169LCD/platform-conf.h加下如下代码:
  • #ifdef __IAR_SYSTEMS_ICC__
  •   #define dint() __disable_interrupt()
  •   #define eint() __enable_interrupt()
  • #endif


(4)autostart_processes未定义在测试例子main文件提示外部符号autostart_processes未定义,原因是autostart_processes指针数组是由宏AUTOSTART_PROCESSES定义,而该宏又取决于条件编译,直接看源码吧(在core/sys/autostart.h):

一周热门 更多>