新博客:http://sparkandshine.net/
分类: 嵌入式
2012-04-10 17:37:10
摘要:
本文详细记录了Contiki动态加载模块Loader在IAR下移植遇到的问题,分析及解决。
一、编译错误
1.1 could not open source file
Contiki是在Linux平台下开发的,其源码引用了Linux库头文件(仅仅引用库文件,自己实现,比如dlfcn.h的dlopen函数),当在IAR编译时提示could not open source file错误,解决方法是将这些头文件从Linux找出来并加到IAR的工程目录,Linux库头文件可能又包含其他库头文件,不过不用担心,会很快收敛的:-)涉及到文件如下:
为了尽量少改动代码,根据源码,用文件目录core/linux_lib组织这些被引用库头文件,记得将相应路径加到IAR的预处理路径中,linux_lib文件压缩包文件 linux_lib.rar 。
1.2 FILE未定义
编译提示FILE未定义,在malloc.h文件,如下,在Contiki并没有用到这些函数,注释掉。
1.3 expression must be a pointer to a complete object type
编译时,提示错误"expression must be a pointer to a complete object type ",定位于Contiki\core\loader\cmod.c 94,如下:
h类型是cle_info结构体,bss、data、datasize类型分别为void *、void *、cle_word(实质是u16_t)。理论上是没有错的,但这跟编译器有关(GCC可以,IAR不行),主要问题在于类似的隐式转换,这里将类型转换显式化(假设是32位的处理器),如下:
1.4 类型不匹配
编译时,在文件core\loader\cmod.c提示错误a value of type "void *" cannot be assigned to an entity of type "void (*)(void)" ,提示错误的源代码如下:
.init和.fini是程序初始化与终结代码段,这两个段的代码会最终拼成两个函数_init()和_fini()。cle_lookup函数返回void类型的指针,但cmod_module[imod].fini是函数指针。
问题转化为将指针转换为函数指针(也许在GCC无须修改),修改后代码如下:
同理,init = cle_lookup(&h, pread, off, "_init")改成:
在elfloader_compat.c也有类似的问题,修改后代码如下:
关于如何将指针转换为函数指针可参考博文《如何将一个指针强制转换为一个函数指针》。
1.5 off_t和intptr_t重定义
off_t分别在platform/stm32test/contiki-conf.h、core/linux_lib/sys/unistd.h定义,前者实质是unsigned long,后者实质是long int,这里注释后者的定义。
intptr_t分别在IAR Systems\Embedded Workbench 5.4\arm\INC\stdint.h、core/linux_lib/sys/unistd.h定义,前者实质是__INTPTR_T_TYPE__,后者实质是int,这里注释后者的定义。
1.6 _etext、_edata、__data_start未定义
编译时,在elfloader_compat.c提示_etext、_edata、__data_start未定义错误,这些符号(通常称特殊符号)被定义在链接脚本中(ld链接器是这样,IAR也是吗?),程序使用需先声明,链接器会在链接成可执行文件时解析成正确的值。在elfloader_compat.c加入如下代码:
1.7 ROM_ERASE_UNIT_SIZE未定义
编译时,在elfloader_compat.c报ROM_ERASE_UNIT_SIZE未定义错误,Contiki是按sector擦除的,这里将ROM_ERASE_UNIT_SIZE定义为COFFEE_SECTOR_SIZE,在elfloader_compat.c加入如下代码:
三、链接错误
3.1 elfloader_arch_allocate_ram等重定义
链接时,提示elfloader_arch_allocate_ram、elfloader_arch_allocate_ram、elfloader_arch_relocate、elfloader_arch_write_rom重定义,如下:
图1 重定义错误
elfloader_arch_allocate_ram、elfloader_arch_allocate_ram、elfloader_arch_relocate、elfloader_arch_write_rom分别在文件core/loader/elfloader-stub.c、cpu/arm/stm32f103/elfloader-stm32f10x.c实现。elfloader-stub.c可以理解为elfloader-stub.h实现的模板,我本以为还要自己实现呢(我的MCU是stm32f103),原来Contiki已经有了,这里将elfloader-stub.c从工程目录移除,并添加elfloader-stm32f10x.c。
3.2 elfloader_load、elfloader_unknow重定义
链接时,提示elfloader_load、elfloader_unknow重定义,其分别在文件core/loader/elfloader.c、core/loader/elfloader_compat.c实现。这里将elfloader_compat.c从工程目录移除。
至此,编译链接成功,接下来就是写些测试例子测试下:-)