OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5042|回复: 4

FreeRTOS源码阅读,关于SVC中断的疑问。请大佬帮我解答

[复制链接]

28

主题

104

帖子

0

精华

初级会员

Rank: 2

积分
150
金钱
150
注册时间
2018-1-11
在线时间
64 小时
发表于 2021-9-2 11:45:41 | 显示全部楼层 |阅读模式
20金钱
疑问1:
之所以要在切到异常模式,主要是为了SP指针的切换。复位之后使用MSP,但是要使用OS,必然会用到独立的任务栈,在异常处理中就可以从MSP切到PSP,这样切到任务执行时就使用任务的栈。当然,这里面有将任务栈数据出到CPU寄存器组。问题来了,理论上(我的认知),SVC中断中做的事我也可以使用一个我系统不会用的外部中断,然后软件写中断标志来触发,然后在中断处理来完成SVC中的事情,如果理论正确,为什么就一定要用SVC呢?
疑问2:
M4的FreeRTOS,任务创建的时候,会初始化栈区,如下
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
    /* Simulate the stack frame as it would be created by a context switchinterrupt. */
    /* Offset added to account for the way the MCU uses the stack on entry/exit
    of interrupts, and to ensure alignment. */
    /* 异常发生时,自动加载到CPU寄存器的内容 */
    pxTopOfStack--;
    *pxTopOfStack = portINITIAL_XPSR;    /* xPSR  xPSR的bit24必须置1*/
    pxTopOfStack--;
    *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK;    /* PC 即任务入口函数*/
    pxTopOfStack--;
    *pxTopOfStack = ( StackType_t ) prvTaskExitError;    /* LR 函数返回地址*/

    /* Save code space by skipping register initialisation. */
    pxTopOfStack -= 5;    /* R12, R3, R2 and R1. */
    *pxTopOfStack = ( StackType_t ) pvParameters;    /* R0 任务形参*/
    /* A save method is being used that requires each task to maintain its own exec return value. */
    pxTopOfStack--;
    *pxTopOfStack = portINITIAL_EXEC_RETURN;       //0xFFFF_FFF1 返回handler模式
                                                                                            //0xFFFF_FFF9 返回线程模式,并使用主堆栈(SP=MSP)
                                                                                            //0xFFFF_FFFD 返回线程模式,并使用线程堆栈(SP=PSP)
    /* 异常发生时,手动加载到CPU寄存器的内容 */
    pxTopOfStack -= 8;    /* R11, R10, R9, R8, R7, R6, R5 and R4. 默认初始化为0*/

    return pxTopOfStack;
}

然后SVC中断中会将栈区的寄存器数据出栈到CPU寄存器组,如下
__asm void vPortSVCHandler( void )
{
    PRESERVE8

    /* Get the location of the current TCB. */
    ldr    r3, =pxCurrentTCB    /* pxCurrentTCB指向处于最高优先级的就绪任务TCB */
    ldr r1, [r3]          /* 获取任务TCB地址 */
    ldr r0, [r1]          /* 获取任务TCB的第一个成员,即当前堆栈栈顶pxTopOfStack */
    /* Pop the core registers. */
    ldmia r0!, {r4-r11, r14} /*  1.以R0寄存器值(也就是当前任务的栈顶指针)为基准,将任务栈的R4-R11
                                                            (其实都是0,有必要出栈吗,此处不理解为什么要出,难道仅仅是为了让指针动?
                                                                那完全没必要出栈啊,直接移动栈指针不就可以了)出栈到 CPU 寄存器R4-R11
                                                             2.当出完R4-R11,指针指向的是地址处的值是  portINITIAL_EXEC_RETURN
                                                                将这个值给到寄存器R14。主要为了从SVC退出时使得硬件在退出时使用
                                                                进程栈指针 PSP 完成出栈操作并返回后进入任务模式、返回Thumb 状态*/
                                                                                       
    msr psp, r0                                     /* 最新的栈顶指针赋给线程堆栈指针PSP */
    isb
    mov r0, #0                                /*将R0 寄存器清0*/
    msr    basepri, r0                        /*设置 basepri 寄存器的值为 0,即打开所有中断*/
    bx r14                                    /*异常返回,这个时候出栈使用的是 PSP 指针,自动将栈中的剩下内容加载到 CPU 寄存器:
                                                        xPSR, PC(任务入口地址), R14, R12, R3, R2, R1, R0(任务的形参)同时 PSP
                                                        的值也将更新,即指向任务栈的栈顶     */        
}

这里出栈R4-R11,真的有这个必要吗?初始化任务的时候栈区保存的R4-R11并没有实际意义啊。

一个大专狗,理论知识实在欠缺,希望大佬帮忙解惑。



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

14

主题

821

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2034
金钱
2034
注册时间
2021-7-17
在线时间
635 小时
发表于 2021-9-2 15:43:59 | 显示全部楼层
回复

使用道具 举报

79

主题

395

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1765
金钱
1765
注册时间
2015-9-21
在线时间
544 小时
发表于 2021-9-2 16:50:12 | 显示全部楼层
研究的这么细致么
回复

使用道具 举报

28

主题

104

帖子

0

精华

初级会员

Rank: 2

积分
150
金钱
150
注册时间
2018-1-11
在线时间
64 小时
 楼主| 发表于 2021-9-3 09:10:44 | 显示全部楼层
硕果累累 发表于 2021-9-2 16:50
研究的这么细致么

这不是间歇性的兴致来了吗,准备周末自己改一下来验证。
回复

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-9-6 10:22:21 | 显示全部楼层
帮顶   
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 18:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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