Contiki开发要点
来源:互联网 发布:java代码如何添加log4j 编辑:程序博客网 时间:2024/05/16 12:43
Contiki开发要点
一.Protothread变量定义
Adam Dunkels的论文中提到,基于Contiki的protothread开发时要特别注意变量的生存周期,分配在栈中的自动变量,随着函数被多次返回与调用,它很容易带来错误。现在,通过分析几个实例程序来总结protothread中定义变量的规律。
1. 一个出错的程序
如图1所示的程序用于打印当前的时钟值,可得到的结果总是一些错误值,用理解传统函数的眼光来看很难发现错误的原因,查看下图2的程序清单就可以得到更清晰的答案。
图1自动变量使用出错
从图2可以看到,第一次调用函数时,tClock已经赋值正确的时钟值,随着函数返回tClock这种栈变量的空间被回收(本质是该空间被别的变量覆盖占用);后续调用函数时tClock再次被分配空间,它包含的垃圾值被打印出来,然后被赋值正确的时钟值,再随着函数返回而回收空间,如此反复,错误就这样诞生了。
小结:一旦函数退出,自动变量的生存周期结束,它的值将是错误的。
图2绿色是首次调用,红色是后续调用,蓝色是共同调用
2. 使用静态变量避免错误
在上述的分析中发现protothread的自动变量容易产生错误,那么定义成static的静态变量就可以解决该问题。确实,因为static变量的生存周期不受函数返回的影响,因此不会出错。
小结:static变量在protothread的整个执行周期内都是安全的。
3. 自动变量的安全区域
虽然static变量在protothread是安全的,但它会占用过多内存。举例,如果N个protothread都要分配M大小临时变量,如果都定义成static类型,那么这些变量将占用N*M大小的内存;如果定义成自动变量,那么只需要M大小的内存。
图3的代码是对图1出错代码的更改,结合图4可以看出是正确的。为什么这次自动变量tClock使用正确呢?因为它的使用范围在一个执行流之内(函数没有返回)。
小结:protothread中自动变量的安全区域是在一个执行流内,即函数不能返回。
图3自动变量使用正确
总结:在protothread中定义变量,如果该变量的使用范围需要跨越任何“阻塞进程”的函数(API包括:PROCESS_YIELD()、PROCESS_WAIT_EVENT()等),那么只能定义为static类型;否则可以使用自动变量,但仍需仔细辨别。
图4绿色是首次调用,红色是后续调用,蓝色是共同调用
二.不要使用switch()语句
这个道理是很明显的,看看图2和图4的代码就知道:一个protothread程序会预编译成带switch()的函数结构,如果用户再使用switch()结构,那将是一个多么混乱的世界!不仅编译器会报警,可能出错;开发者也很难把握程序的执行流了。替代的办法是使用if()语句,毕竟它能实现和switch()一样的功能。
作者简介:
蒋俊,男,硕士研究生,现任长沙市锐米通信科技有限公司CEO。
从事通信研究与嵌入式开发10年,主攻微功率无线网络。
精通LoRa无线扩频通信,无线星型/树型/MESH网络设计;
通晓Contiki,Linux,uC/OS-II,OSAL等操作系统;
熟悉ARM,DSP,STM8,PIC,PC104等处理器;
擅长AD,RF等集成IC开发。
Web: www.rimelink.com
EMail: jiangjunjie_2005@126.com
QQ群:35212129
- Contiki开发要点
- Contiki开发要点
- Contiki开发5:Hello,Contiki
- Contiki开发4:基于DEMO移植Contiki
- Contiki开发6:shell系统
- Contiki开发8:进程协作
- Contiki开发9: 下载源代码
- LoRa开发4:移植Contiki
- Contiki
- Contiki开发1:Contiki与8位MCU
- Contiki开发2:工具和环境
- Contiki开发7:中断与进程
- Eclipse+WIN7+CC2538移植开发Contiki
- contiki移植开发板实验框架
- 2、使用instantcontiki2.7进行contiki开发-获取contiki-sensinode分支
- 1、contiki系统开发-instantcontiki2.7 开发环境安装
- 4、contiki系统开发-UDP-IPV6数据传输功能测试
- Contiki开发3:调试平台与Debug系统
- Contiki内核原理
- bzoj-1845 三角形面积并
- Android ContentObserver ---拦截短信并删除
- LeetCode_binary-tree-zigzag-level-order-traversal
- 数据存储(sharedPreferences,内部存储,外部存储,SQLite数据库,网络存储)
- Contiki开发要点
- 设计一个多终端日志打印的接口,使得它可以动态支持不同终端的日志打印
- VC++ EDIT控件重绘
- 1140 鸡蛋栈【模拟栈】
- Linux下搭建tomcat集群全记录
- Contiki rtimer原理与移
- 控制自定义Dialog的大小和位置(计算器对话框的制作)
- Contiki协议栈
- CentOS下如何挂载NTFS分区