搜索
bottom↓
回复: 9

finsh shell中长按enter键,系统挂住了

[复制链接]

出0入0汤圆

发表于 2010-4-16 10:49:34 | 显示全部楼层 |阅读模式
不知道问题出在哪了?

M16C平台,RTT 0.4.0
共有3个thread:
1,idle
2,finsh
3,led间隔1秒闪烁

不知道在其他移植平台上有没有类似的问题?

好像是中断嵌套中出了错误。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-4-16 10:59:26 | 显示全部楼层
应该是占用了大量的CPU,另外两个不跑了吧.
原因为printf()是很**的方式在输出,且输出多,于是,一直按住就忙不过来.

原来有发生在RADIO板上面,RX的上拉电阻没有,于是,一上电就收到乱码,系统也处于"挂"的状态.手一摸就好了.

出0入0汤圆

发表于 2010-4-16 11:08:55 | 显示全部楼层
ARM Cortex-M3上是否有这个问题?

出0入0汤圆

发表于 2010-4-16 12:18:11 | 显示全部楼层
STM32 Radio上的表现:(from aozima testing)
串口上面一直在打印,没有挂吧

不按后,还在打印....要N久才行恢复

----
从STM32上的串口设计来看(Cortex-M3上是支持中断嵌套的),它有一个64字节的循环buffer,但这个buffer是那种可丢弃的,即如果接收的数据来不及处理,新接收的数据会把最老的数据冲掉(下一个读指针也会往前推)。所以当长按enter时,这个接收buffer会全部都是enter键值,而因为其中还有打印的问题,所以数据的处理速度应该赶不上接收的速度(打印的字符多于接收的字符),所以有部分的enter键值会被覆盖。

当不按enter键时,当所有接收buffer中的数据都处理完时,系统应该恢复到空闲状态。

如果是中断嵌套的问题,lgnq,你多看看线程切换的代码,是否在线程切换被中断抢占了,然后发生了中断嵌套。而中断嵌套时与线程切换间代码考虑得还不是很周到?

出0入0汤圆

发表于 2010-4-17 12:05:33 | 显示全部楼层
系统反映有这么慢么?

就是个16M的386,常按ENTER也没有问题啊,何况72M的CM3

出0入0汤圆

 楼主| 发表于 2010-4-19 08:39:56 | 显示全部楼层
回复【4楼】TBN1
系统反映有这么慢么?  
就是个16M的386,常按ENTER也没有问题啊,何况72M的CM3
-----------------------------------------------------------------------
我用的是7MHz的 M16C,我说的挂住也不是反映慢的问题

问题出在中断嵌套中:

串口中断引起任务调度,从idle任务切换到finsh,串口中断程序退出时,才真正切换到finsh任务执行
如果在串口中断程序退出前,系统时钟中断发生,并且此时正好是led任务延时到了,那么又要引发任务切换,从finsh切换到led

此时系统就死掉了,to_thread指向了一个莫名的地址。

而且中断嵌套中执行任务切换有一个弊端,中断处理时间无法保证。
比如前一个例子,系统中断退出时,要先切换到led任务去执行,但是uart中断任务还没有退出呢。

出0入0汤圆

发表于 2010-4-19 08:57:49 | 显示全部楼层
你的移植代码还有问题呢,正常的应该是中断服务例程都执行完了后才切换到线程中执行的。你可以说说你中断处理部分移植的做法

出0入0汤圆

 楼主| 发表于 2010-4-19 09:33:01 | 显示全部楼层
所有中断服务程序都是一样的结构,下面以串口中断服务程序为例。

rt_hw_uart0_receive_handler:
    PUSHM    R0,R1,R2,R3,A0,A1,SB,FB             ; 保存现场
    JSR      rt_interrupt_enter                  ; 调用RTT函数,通知进入中断
    JSR      u0rec_handler                       ; 执行串口中断处理  
    JSR      rt_interrupt_leave                  ; 调用RTT函数,通知退出中断

    CMP.W    #1, rt_thread_switch_interrput_flag ; 如果中断切换上下文标志==1,则跳转到rt_hw_context_switch_interrupt_do
    JEQ      rt_hw_context_switch_interrupt_do   ; 执行中断上下文切换
                                                 ; 如果中断切换上下文标志!=1
    POPM     R0,R1,R2,R3,A0,A1,SB,FB             ; 恢复现场
    REIT                                         ; 串口中断服务程序正常退出

rt_hw_context_switch_interrupt_do
    MOV.W    #0, rt_thread_switch_interrput_flag ;清除中断切换上下文标志   
    MOV.W    rt_interrupt_from_thread, A0        ;保存堆栈指针到from_thread
    STC      ISP, [A0]   
   
    MOV.W    rt_interrupt_to_thread, A0          ;将to_thread设置为新的堆栈指针
    LDC      [A0], ISP
    POPM     R0,R1,R2,R3,A0,A1,SB,FB             ;利用to_thread堆栈恢复中断现场
    REIT                                         ;中断返回,切换到新任务to_thread

出0入0汤圆

发表于 2010-4-19 09:36:31 | 显示全部楼层
JEQ      rt_hw_context_switch_interrupt_do   ; 执行中断上下文切换

后面的做关中断处理,这个时候已经不能让中断再抢占了,否则就发生了上下文切换过程的混乱。

出0入0汤圆

 楼主| 发表于 2010-4-19 11:24:37 | 显示全部楼层
回复【8楼】ffxz
JEQ      rt_hw_context_switch_interrupt_do   ; 执行中断上下文切换  
后面的做关中断处理,这个时候已经不能让中断再抢占了,否则就发生了上下文切换过程的混乱。
-----------------------------------------------------------------------
试过了,还是不行。

最主要的问题原来是出在中断禁止和中断打开函数
原先我是直接关闭和打开中断
rt_hw_interrupt_disable
    FCLR    I
    RTS

rt_hw_interrupt_enable
    FSET    I
    RTS

后来读了RTT手册《异常与中断》那一章。
关闭中断要先保存中断前的中断状态,
打开中断时恢复中断前的中断状态。

rt_hw_interrupt_disable
    STC     FLG, R0
    FCLR    I
    RTS

rt_hw_interrupt_enable
    LDC     R0,FLG
    RTS

现在测试下来,还没出现过问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 12:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表