MSP430F5438A支持基于COAP协议的通讯方案验证
[复制链接]
Demo的整体目标:支持基于COAP协议的通讯方案验证;
经过多种比对及现有资源的考虑,最终选定为如下方案,都已存在开源代码,只要做简单的适配应该就可以进行上板调试。
硬件方案:MSP430F5438A + 操作系统:ucos + 物联网套件:阿里IoT-SDK_V2.0 + IDE:IAR
由于阿里IoT-SDK_V2.0基于linux系统进行编程(尚未支持其他平台),编译器为GCC,所以在移植的过程中遇到了许多问题:
1、 配置头文件目录:IAR的环境中不使用makefile,因此头文件目录需要在IAR中进行单独配置,具体的配置方法如下:
a) 右键工程名称,选中Options...
b) 找到C/C++ compiler -> Preprocessor ;在Additional include directories:(one per line),其中$PROJ_DIR$为工程的根目录,基于该根目录配置相关的内容目录即可;
可以先单独compile每个文件,解决完编译问题后,再make进行符号表链接;
2、关键字冲突:IAR的编译器没有GCC的丰富,下面把我在编译的过程中遇到的几个问题记录如下:
a) typeof:尽管之前也做过几年C预言的嵌入式开发,但typeof的关键字还是头一次接触。由于阿里的Iot SDK中用到了linux的list库,用来支持链表操作
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
在使用到该宏的地方出现如下的编译错误,经初步判断,应该是typeof关键字不识别,typeof关键字用于获取参数的类型;经过多轮百度,未找到IAR编译环境可识别该关键字的方案;
Warning[Pe223]: function "typeof" declared implicitly D:\SVN\02 智能化解决方案\软件工程\ucos-msp430\ucos-msp430\ali-IoT\src\packages\iot-coap-c\CoAPExport.c 219
Warning[Pe549]: variable "cur" is used before its value is set D:\SVN\02 智能化解决方案\软件工程\ucos-msp430\ucos-msp430\ali-IoT\src\packages\iot-coap-c\CoAPExport.c 219
Error[Pe029]: expected an expression D:\SVN\02 智能化解决方案\软件工程\ucos-msp430\ucos-msp430\ali-IoT\src\packages\iot-coap-c\CoAPExport.c 219
Error[Pe059]: function call is not allowed in a constant expression D:\SVN\02 智能化解决方案\软件工程\ucos-msp430\ucos-msp430\ali-IoT\src\packages\iot-coap-c\CoAPExport.c 219
仔细阅读list库后,发现list库中包含两种类型的实现方案:
第1种.上述类似iterate模版的实现方案,结构体的设置较为灵活,可支持各种类型的结构体,因此typeof的关键字不可或缺;
第2种.较为传统,是基于链表结构体的实现方案,直接操作链表,因此不需要使用typeof的关键字,实现如下:
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
经分析,可采用接口list_for_each_safe替代list_for_each_entry_safe;高亮部分既为解决该问题的核心之处, list_entry 的定义可自行百度
/*解决前*/
void LITE_json_keys_release(list_head_t *keylist)
{
json_key_t *pos, *tmp;
list_for_each_entry_safe(pos, tmp, keylist,list)
{
if (pos->key) {
LITE_free(pos->key);
}
list_del(&pos->list);
LITE_free(pos);
}
}
/*解决后*/
void LITE_json_keys_release(list_head_t *keylist)
{
json_key_t *pos, *tmp;
list_head_t *list_pos, *list_tmp;
list_for_each_safe(list_pos, list_tmp, keylist)
{
pos = list_entry(pos, json_key_t, list);
if (pos->key) {
LITE_free(pos->key);
}
list_del(&pos->list);
LITE_free(pos);
}
}
b) __restrict__: C99标准中引入了restricted指针,用以缓解C语言中指针二义性的问题。缓解指针二义性问题可用于编译器的代码优化。
LITE_sprintf((char *__restrict__)ascii + i % 16, "%c", ((buf[i] >= ' ' && buf[i] <= '~') ? buf[i] : '.'));
IAR种出现如下编译错误,这个解决方案比较简单,直接去除__restrict__关键字,但是会牺牲部分性能;待未来再考虑这部分的优化
Error[Pe018]: expected a ")" D:\SVN\02 智能化解决方案\软件工程\ucos-msp430\ucos-msp430\ali-IoT\src\packages\LITE-log\lite-log.c 60
先写到这里,后续如果遇到新增问题,再进行补充;
|