这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » C30编译器与Protothreads

共1条 1/1 1 跳转至

C30编译器与Protothreads

工程师
2014-10-13 19:55:11     打赏

   最近一个项目选用了dspic30f4013做为主处理器,正好可以利用这个项目运用下Protothreads协作式嵌入式系统,编译器选用C30,这两天主要功能都做完了,想测试下程序的稳定性,因有CAN及RS232接口,就利用这两个端口不断的输入输出数据,从CAN接口数据中的一个连续序列数中判断程序是否发生过复位现象,并记录复位发生的原因,经过1个小时的连续运行,发现出现了多次随机复位现象,且复位时间间隔不固定,发生复位的原因居然是使用了复位指令导致的,可我的程序没有用复位指令啊。后多次测试,发现在RS232不收发数据时,程序居然没有再发生过复位现象,或者关闭程序中的AD采样部分程序,也不会发生复位,测到后来都不知道到底是哪出了问题。


        一开始怀疑自己程序中哪个功能模块初始化不正确导致相互冲突,可找了很长时间,没有发现有什么大的问题,一直没解决这个随机复位现象,后来怀疑Protothreads系统与C30编译器有冲突,导致程序编译不正确。为了找到原因,我用前后台的方式重新写了一遍程序,程序居然运行正常了,连续2小时没发生后任何复位现象,真是晕。


        第一次用Protothreads就出现这种莫名其妙的问题,实在是不死心,还是利用Protothreads将程序整个重新编排了下,暂时屏蔽不用的功能模块,仅留下RS232与CAN接口,连续运行监测后,发现还是有随机复位现象,可能是这个问题测试时间长了,到处怀疑,因程序中RS232接收用了接收中断,特意看了下C30中关于中断的定义,发现4013头文件中定义的是


#define _ISR __attribute__((interrupt))
#define _ISRFAST __attribute__((interrupt, shadow))


我因为以前写过PIC24的程序,没用此定义,自己写的如下,是一个定时器中断


void __attribute__((__interrupt__, __shadow__,__auto_psv__)) _T1Interrupt(void)


我写的参数中多了一个auto_psv,查找用户手册,发现这个参数对中断影响不大,但shadow这个参数在编译器用户指南中说明如下


shadow 属性使编译器使用影子寄存器而不是软件堆栈来保存寄存器。该属性通常与interrupt 属性同时使用


        为了找到随机复位的原因,我可是什么可能都试了,发现中断定义的问题后,直接将中断函数中不用的参数都删除了,改成如下方式


void __attribute__((__interrupt__)) _T1Interrupt(void)


        把所有的中断定义都改成了上面的样式后,编译后提示auto_psv警告,暂时不理,将程序下载后运行,居然没有再发生过复位,哈哈找到原因的感觉真好,居然是这个原因导致Protothreads编写的程序长时间运行无故复位,上网找了下auto_psv警告发生的原因,最终将中断函数定义改为如下方式


void __attribute__((__interrupt__, __no_auto_psv__)) _T1Interrupt(void)


        编译后没有再发生警告,程序长时间运行正常。


        因项目时间及水平有限等原因,也没有继续深入查找原因,可能是C30编译器为了配合dspic的特性加入的这个参数,导致进入中断后,相关变量进行了一个非法保存,使Protothreads调度发生了错误,程序跑飞后触发了空程序段中的复位指令,使单片机复位,通过这个问题可以看出,虽然Protothreads是纯C语言写的协作式系统,应该与单片机平台无关,但相应的编译器为了体现某些单片机的特殊功能,加入了相应的参数,与标准C编译器GCC之间有了些区别,最终导致程序的运行结果异常。呵,最终还是将Protothreads利用起来了,程序结构比以前明晰了很多。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]