久芯网

请教大伙,如何实现SysTick中断的嵌套自身?

avatar 元元道人 提问时间: 2023-07-14 11:16:37 / 未解决
  1. AREA    CODE1, CODE, READONLY
  2. SysTick_Handler        PROC
  3.                                 EXPORT        SysTick_Handler
  4.                                 IMPORT  RTTaskSchedule       
  5.                                 POP                {R0-R7}
  6.                                 PUSH        {R0-R7}                                        ;这次压栈后,堆栈和刚进中断时一致,但是栈的内容已经被读到寄存器中       
  7.                                 LDR                R6,=RTTaskSchedule                ;伪造栈的内容,让异常返回到想要执行的函数
  8.                                 PUSH        {R0-R7}                                       
  9.                                 LDR R0,=0xFFFFFFF9
  10.                                 BX R0
  11.                                 ENDP
  12.                                        
  13. AREA    CODE2, CODE, READONLY                       
  14. IrqReturn                PROC
  15.                                 EXPORT        IrqReturn
  16.                                 POP                {R0,R1}                                        ;进入IrqReturn产生的压栈数据,直接丢弃
  17.                                 POP                {R0-R7}                                        ;下面恢复进入systick中断前的8个寄存器
  18.                                 MOV                R12,R4
  19. ;                                MOV                LR,R5                                        ;LR的值保持当前
  20.                                 MSR                XPSR,R7
  21.                                 MOV                PC, R6
  22. ;                                BX                 LR
  23.                                 ENDP
  24.                                
  25.                                 END
复制代码


我想通过SysTick的嵌套自身,实现任务的抢占式调度,请问有人知道要怎么弄吗?
上面的汇编是我直接伪造返回现场让中断直接退出到我想要执行的调度函数RTTaskSchedule ,执行完调度函数RTTaskSchedule 后再执行函数IrqReturn返回到main中。但是这段代码并不能实现我想要的功能,被嵌套的调度函数RTTaskSchedule 不能正常返回了。
14个回答
  • avatar xmshao
    回答时间: 2023-07-14 11:47:56

    据我所知,ARM中断并不支持自己嵌套自己,或许会因为标志清零延时问题导致刚退出去后发生重进。 当然,你这里说的嵌套,应该说只是模拟类似操作不是真的自己嵌套,这样原理上个人觉得没有大问题,但要求对压栈出栈操作及相关寄存器很清晰,否则比较难以玩转。 不过真心期待你能成功搞定。 另外,不同优先级任务本身不就支持抢占吗?为什么要如此费周章?

  • avatar CC4
    回答时间: 2023-07-14 12:19:26

    什么叫嵌套自身?难以理解

  • avatar 元元道人
    回答时间: 2023-07-14 12:43:03
    CC4 发表于 2022-10-20 13:23
    什么叫嵌套自身?难以理解

    就是第一个中断函数还没执行完,又来了中断,这时候又再一次执行中断函数。

  • avatar CC4
    回答时间: 2023-07-14 13:10:09

    第一次进中断,压栈。

  • avatar 元元道人
    回答时间: 2023-07-14 13:32:07
    CC4 发表于 2022-10-20 16:30
    第一次进中断,压栈。

    哥们,细说,多谢哈。

  • avatar butterflyspring
    回答时间: 2023-07-14 13:58:07
    元元道人 发表于 2022-10-20 13:50
    就是第一个中断函数还没执行完,又来了中断,这时候又再一次执行中断函数。 ...

    如果你说的是同一中断,那不是出不来了么?

  • avatar 废鱼
    回答时间: 2023-07-14 14:29:15

    freertos用的是中断抢占式,可以参考freertos的使用。407是修改中断组号来实现开启抢占式中断模式,具体的使用建议参考对应芯片手册中关于中断配置的部分。

  • avatar 元元道人
    回答时间: 2023-07-14 14:52:19
    废鱼 发表于 2022-10-21 10:53
    freertos用的是中断抢占式,可以参考freertos的使用。407是修改中断组号来实现开启抢占式中断模式,具体的 ...

    哥们仔细看,我要实现的是当前在执行的中断嵌套自身,不是其它的中断来抢占。

  • avatar yr
    回答时间: 2023-07-14 15:19:14

    楼主是不是想得到类似函数递归一样的效果,函数实现递归(自己调用自己)是完全没问题的,但是同一个中断调用同一个中断似乎无法实现,因为正在响应systick中断时,arm的nvic的active interrupt寄存器中该中断是置位的,此时再来的systick中断,抢占优先级并没有改变,应该不会挂起当前的systick中断,转而响应新来的systick中断。

  • avatar 废鱼
    回答时间: 2023-07-14 15:38:16
    元元道人 发表于 2022-10-21 11:58
    哥们仔细看,我要实现的是当前在执行的中断嵌套自身,不是其它的中断来抢占。 ...

    首先你要理解中断产生的原理,即便是正常程序操作,在使用各种rtos时,都会增加互斥。只有中断抢占可以打断其他中断而执行,但是中断自己不会抢占自己。除非是你用其他的中断调用的函数和你目前使用的函数是一个。比如你把.s中不同的中断,修改使用同一个函数。

  • avatar 废鱼
    回答时间: 2023-07-14 16:09:46
    元元道人 发表于 2022-10-21 11:58
    哥们仔细看,我要实现的是当前在执行的中断嵌套自身,不是其它的中断来抢占。 ...

    既然是想做到任务的抢占式调度,可以参考freertos的任务调用。

  • avatar 元元道人
    回答时间: 2023-07-14 16:39:48
    废鱼 发表于 2022-10-22 09:33
    既然是想做到任务的抢占式调度,可以参考freertos的任务调用。

    要是参考freeRTOS的内核来,那我直接用freeRTOS不就完事了吗。现在就是想减少调度器的复杂度,以前在51单片机上就是就用中断嵌套自身来调度的,任务调度函数代码贼少。

  • avatar 元元道人
    回答时间: 2023-07-14 17:07:05
    yr 发表于 2022-10-21 22:18
    楼主是不是想得到类似函数递归一样的效果,函数实现递归(自己调用自己)是完全没问题的,但是同一个中断调 ...

    是的,有点类似递归。这个调度方案就是通过进入中断硬件的压栈和出栈实现抢占式调度,我在m3内核上已经实现了;这个抢占式调度以前在51上用得贼多。

  • avatar 元元道人
    回答时间: 2023-07-14 17:38:24
    butterflyspring 发表于 2022-10-21 10:14
    如果你说的是同一中断,那不是出不来了么?

    是有无法返回堆栈溢出的风险,这就需要程序员自己去管理任务的执行时间了,比如有task_1ms、task_5ms两个周期执行的任务,task_1ms任务必须在1ms的时间内执行完,否则堆栈溢出;task_5ms任务必须在5ms内执行完(这5ms既要每1ms执行一次task_1ms,还要把task_5ms执行完,剩余的cpu时间去跑主函数main的循环。)

会员中心 微信客服
客服
回到顶部