lgnq 发表于 2010-4-16 10:49:34

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

不知道问题出在哪了?

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

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

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

aozima 发表于 2010-4-16 10:59:26

应该是占用了大量的CPU,另外两个不跑了吧.
原因为printf()是很**的方式在输出,且输出多,于是,一直按住就忙不过来.

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

ffxz 发表于 2010-4-16 11:08:55

ARM Cortex-M3上是否有这个问题?

ffxz 发表于 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,你多看看线程切换的代码,是否在线程切换被中断抢占了,然后发生了中断嵌套。而中断嵌套时与线程切换间代码考虑得还不是很周到?

TBN1 发表于 2010-4-17 12:05:33

系统反映有这么慢么?

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

lgnq 发表于 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中断任务还没有退出呢。

ffxz 发表于 2010-4-19 08:57:49

你的移植代码还有问题呢,正常的应该是中断服务例程都执行完了后才切换到线程中执行的。你可以说说你中断处理部分移植的做法

lgnq 发表于 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,    
   
    MOV.W    rt_interrupt_to_thread, A0          ;将to_thread设置为新的堆栈指针
    LDC      , ISP
    POPM   R0,R1,R2,R3,A0,A1,SB,FB             ;利用to_thread堆栈恢复中断现场
    REIT                                       ;中断返回,切换到新任务to_thread

ffxz 发表于 2010-4-19 09:36:31

JEQ      rt_hw_context_switch_interrupt_do   ; 执行中断上下文切换

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

lgnq 发表于 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

现在测试下来,还没出现过问题。
页: [1]
查看完整版本: finsh shell中长按enter键,系统挂住了