搜索
bottom↓
回复: 0

uC/OS在高速响应事件使用标志组时的异常求解?

[复制链接]

出0入0汤圆

发表于 2014-8-29 17:26:05 | 显示全部楼层 |阅读模式
本帖最后由 styleno1 于 2014-8-29 17:24 编辑

硬件接口:STM32 SPI2 <--> SPI Flash,@18M。
工作逻辑:使用DMA1的CH4与CH5,用于获得最佳的读写SPI Flash速度。由于SPI的工作逻辑,两通道必须同时开启,然后由中断发送各自标志组对应位。


任务级代码:
  1.             OSFlagPost(pSPI_Flash_Flags, FLAGS_SPI_RW_DONE, OS_FLAG_CLR, &Err);
  2.             OS_ENTER_CRITICAL();
  3.             DMA_Cmd(DMA1_Channel4, ENABLE);
  4.             DMA_Cmd(DMA1_Channel5, ENABLE);
  5.             OS_EXIT_CRITICAL();
  6.             OSFlagPend(pSPI_Flash_Flags, FLAGS_SPI_RW_DONE, OS_FLAG_WAIT_SET_ALL | OS_FLAG_CONSUME, 0, &Err);
复制代码


其中:
  1. /* 标志组标志位 */
  2. #define FLAGS_SPI_RX_DONE   0x10
  3. #define FLAGS_SPI_TX_DONE   0x20
  4. #define FLAGS_SPI_RW_DONE   0x30
复制代码


异常现象描述:
当传输数据长度短于24字节时,任务切换出现错乱。
现象虽然是任务在空闲任务中运行,但任务堆栈已被破坏。
全程DMA表现正常,标志组状态位值正常。

常规分析:
在此通信速度下,事件在阻塞前开始发生,有可能在OSFlagPend()尚未完成任务调度前,事件标志位置位,引起的问题。

仿真时的异常关键点:
OSFlagPend()OS_Sched()临界段内、DMA中断设置断点,全速运行,率先到达OS_Sched()的临界段:


意味着先置位了软中断,然而此时DMA中断标志已经置位:


执行出临界段,先响应DMA的中断,这时中断退出的系统调用触发OSIntCtxSw(),此次会导致PSV标志位溢出。
随后第二个DMA中断发生,2个标志组置位使任务就绪,此时判定最高优先级等于该任务,不会触发调度。
由前文可知,此时一次软件中断已经等待多时,发生了一次自己跟自己的调度。。。呜呼!
  1.     OS_CPU_PendSVHandler
  2.     CPSID   I                                                   ; Prevent interruption during context switch
  3.     MRS     R0, PSP                                             ; PSP is process stack pointer
  4.     CBZ     R0, OS_CPU_PendSVHandler_nosave                     ; Skip register save the first time

  5.     SUBS    R0, R0, #0x20                                       ; Save remaining regs r4-11 on process stack
  6.     STM     R0, {R4-R11}

  7.     LDR     R1, =OSTCBCur                                       ; OSTCBCur->OSTCBStkPtr = SP;
  8.     LDR     R1, [R1]
  9.     STR     R0, [R1]                                            ; R0 is SP of process being switched out

  10.                                                                 ; At this point, entire context of process has been saved
  11. OS_CPU_PendSVHandler_nosave
  12.     PUSH    {R14}                                               ; Save LR exc_return value
  13.     LDR     R0, =OSTaskSwHook                                   ; OSTaskSwHook();
  14.     BLX     R0
  15.     POP     {R14}

  16.     LDR     R0, =OSPrioCur                                      ; OSPrioCur = OSPrioHighRdy;
  17.     LDR     R1, =OSPrioHighRdy
  18.     LDRB    R2, [R1]
  19.     STRB    R2, [R0]

  20.     LDR     R0, =OSTCBCur                                       ; OSTCBCur  = OSTCBHighRdy;
  21.     LDR     R1, =OSTCBHighRdy
  22.     LDR     R2, [R1]
  23.     STR     R2, [R0]

  24.     LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
  25.     LDM     R0, {R4-R11}                                        ; Restore r4-11 from new process stack
  26.     ADDS    R0, R0, #0x20
  27.     MSR     PSP, R0                                             ; Load PSP with new process SP
  28.     ORR     LR, LR, #0x04                                       ; Ensure exception return uses process stack
  29.     CPSIE   I
  30.     BX      LR                                                  ; Exception return will restore remaining context

  31.     END
复制代码

问题:该推理是否正确?如何解决此类问题?(如果从我的假设出发,加入优先级比较即可)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

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

本版积分规则

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

GMT+8, 2024-5-10 10:10

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

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