no zuo no die, why you try?
你的QQ名称就很好的诠释了这一切!
…..一次偶然机会,本来是在中断外延时的,但因为程序处理的问题改了一下代码,然后发现这个问题,就一直想不懂,所以想看看到底怎么回事。
发布于8年前
no zuo no die, why you try?
你的QQ名称就很好的诠释了这一切!
…..一次偶然机会,本来是在中断外延时的,但因为程序处理的问题改了一下代码,然后发现这个问题,就一直想不懂,所以想看看到底怎么回事。
发布于8年前
这几天一直纠结,再把自己理解加一下,不知正确与否?
1、正常情况下,即在线程中调用rt_thread_delay,会把当前PC if (thread->error == -RT_ETIMEOUT)等其他寄存器压到应用层的栈(这里针对comtex-M系列)
2、如果在中断里面调用rt_thread_delay,系统会直接在MSP(主栈)里面,同时中断退出时,相当恢复到进中断之前的PC(因为systick的中断优先级最低,一定要等所有中断ISR全部执行完,再执行pendsv中断),这样造成的结果就是当thread->thread_timer超时,本来是希望恢复到 if (thread->error == -RT_ETIMEOUT),结果恢复到进中断前的PC,这与设计应该不符。
3、根据上面理解,然后有人会提出来为什么在中断可以调用信号量发送等呢?
我的理解,应该是一样的,因为发送信号量函数后面没有需要调度回来再继续执行。
4、查了网上资料,大部分是关于linux,给出的解释大概是说进行内核态后,无法获取current_thread信息,这个应该设计上的的原因,但cortex-M系列没有存在这样的情况,因为current_thread作为全局变量是可以获取的,所以给出上面我的理解,不知正确与否?
发布于8年前
老大,稍加解释一下。呵呵!
发布于9年前
啥问题?请指教,哈!
发布于9年前
需求:ADC 采样频率 1S/12800个,即78us采样一次,并且要求4个通道采到,CPU频率需要工作在4MHZ或者8MHZ,以便保证功耗,采用rtthread 系统,CPU采用cortex-M0+,freescale KL series,此芯片有个限制:4个ADC通道不能同时采样。
一、 需要解决的问题:
1、 ADC轮流采样。
2、 78us采样一次。
3、 低功耗问题。
4、 在cpu工作在4MHZ或者8MHZ情况下,rtthread系统在78us能及时的响应。
二:对策及思考:
1、 根据一、条件4,采用中断方式基本行不通,大概评估了一下在4MHZ情况,rtthread系统响应时间大约要150us.
2、 采用DMA方式来采样ADC的值。
3、 采用DMA方式来改变ADC的采样通道从而触发ADC采样,DMA的触发源为:周期性硬件定时器 78us触发一次。
二、 方案:
三、 实现:
五、上述方案及实现存在的问题:
1、如上图2: 当4个通道值传送完成以后,DMA0的BCR如何及时进行填充?因为TPM的触发频率78us/次,如果DMA0传送结束以后没有及时填充BCR,会导致DMA0出错。
2、同样上图3:DMA1的BCR如何及时填充?虽然它的触发间隔是78us+DMA0传送时间+ADC采样完成时间。 试了一下这个是可以用DMA中断来进行BCR填充,但它仍然有一定的风险,导致DMA1出错。
六、接下去的方案及实现:
就是解决 五 中的2个问题,由于芯片有一个link功能:当一个DMA结束以后可以启动另一个DMA,即采用另一个DMA(设DMA2)中对DMA0的BCR进行赋值。
这里DMA2需要传送清除DMA0完成标志+DMA0的BCR等2个数据到DMA0的寄存器来实现,而DMA2本身的BCR可以采用DMA2中断来实现,因为DMA2中断只要在有大约64478us时间里面完成对BCR的填充就OK。
同时道理可以在DMA1 link 到DMA3,让DMA3来完成DMA1的BCR和清除标志的工作。当DMA3中断来时发信号量到任务,然后进行数据copy,为了防止采样BUF溢出,采用循环2倍BUF,同时在DMA3中断到来时,cpu根据标志读取相应的BUF段。
如下图:
注:相当于采用4个DMA来规避。
注: 不知道怎么上传图片。。。。
发布于9年前
问题二:是对临界区的保护,无法开启中断。
发布于9年前
补充:rtthread下采样AD,是采用DMA方式,当DMA数据传送结束以后,需要及时在DMA的中断服务程序中重新写入DMA搬运的长度,DMA的中断服务程序大概是80微秒中断一次。
发布于9年前
能不能把VBUS机制也讲讲,只是一个建议,如果跟整个思路不合,就当没提,呵呵
发布于9年前
2天看完,看得还算过隐啊,什么时候出版,先预定一本哈。
发布于9年前
哦,有点忘记了,就是第一条是获取向量表地址__vector_table
,第二条是获取 CSTACK
值
多谢哈!
发布于9年前
恩,谢了,懂了
发布于9年前
把 “那会不会导致无法实现中断嵌套和中断优先级的区分”
改成“ 那会不会导致无法实现中断嵌套和中断优先级”
发布于9年前
恩,放在线程里初始化,是不会出现混乱。谢了。
发布于9年前
恩,OK,谢谢!
发布于9年前
谢谢,aozima,后来单步调试了一下,发现在rt_compenet_init()调用各种init函数时,调用自己应用程序中rt_pin_mode();时候,出现了上述错误,先去掉自己的应用程序,系统可以运行,看来这个rt_pin_mode()还不是很理解。
问 中断里面能用rt_thread_delay?