ARM cortex如何处理PendSV处理程序

f2uvfpb9  于 2023-03-22  发布在  其他
关注(0)|答案(2)|浏览(258)

我正在创建一个RTOS内核,需要使用PendSV处理程序进行上下文切换。我通过执行以下操作来触发PendSV处理程序:0xE000ED04 =(0x1〈〈28);这将PendSVset寄存器设置为1,因此理论上,处理程序应该触发。我在触发前禁用中断,在触发后启用。启用后PendSV应该触发。优先级是最低的0xFF,系统处理程序优先级是0x 00。我不确定发生了什么,为什么pendsv处理程序没有运行。我使用TI-MSP 432控制器,我想也许是控制器处理中断的方式?
它在vectpending中设置,vectpending是001110,对于pendsv是14。
如果有人能帮忙,我会非常感激。

4nkexdtk

4nkexdtk1#

我假设你在Systick定时器处理程序中设置了PENDSVSET位(根据你在评论中给出的信息)。由于你设置的PendSV优先级低于Systick的优先级,所以PendSV将挂起,直到Systick中断返回。PendSV不能中断Systick,因为它的优先级较低。从Systick中断返回时,PendSV将通过尾链中断保持。
所以,PendSV中断不会像你期望的那样在Systick定时器处理程序中设置PENDSVSET位时立即生成。它只会在从Systick中断返回时中断。

1yjd4xko

1yjd4xko2#

你有没有尝试过这样简单的东西(一次性代码实验对于裸机开发是至关重要的,试着不要项目的其余部分和所有过度复杂的东西)

.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word pendsv_handler
.word hang

.thumb_func
reset:
    bl notmain
    b hang
    
.thumb_func
hang:   b .
.align

...

.thumb_func
pendsv_handler:
    mov r4,#1
    bx lr
    
.thumb_func
.globl pendsv_test
pendsv_test:
    push {r4,lr}
    mov r4,#0
    str r1,[r0]
pendsv_loop:
    cmp r4,#0
    bne pendsv_loop
    mov r0,r4
    pop {r4,pc}

拜访

#define ICSR 0xE000ED04

hexstring(0x12345678);
hexstring(pendsv_test(ICSR,1<<28));
hexstring(0x11111111);

在我的例子中,它有一些uart输出:

12345678 
00000001 
11111111

然后可以继续这个:

.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word pendsv_handler
.word hang


// ************** EXCEPTION HANDLER ***************
void pendsv_handler ( void )
{
    hexstring(GET32(ICSR));
}
// ************** EXCEPTION HANDLER ***************

int notmain ( void )
{
    clock_init();
    uart2_init();
    hexstring(0x12345678);
    PUT32(ICSR,1<<28);
    hexstring(0x11111111);
    return(0);
}

并看到

12345678 
0000080E 
11111111

这告诉我PendSV在到达处理程序时被清除。
就优先级而言,文档说pendsv和svc是相等的,所以

stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word svc_handler
.word hang
.word hang
.word pendsv_handler
.word hang

以及

// ************** EXCEPTION HANDLER ***************
void pendsv_handler ( void )
{
    hexstring(0x22222222);
    hexstring(GET32(ICSR));
    hexstring(0x22222222);
}
// ************** EXCEPTION HANDLER ***************

// ************** EXCEPTION HANDLER ***************
void svc_handler ( void )
{
    unsigned int ra;
    
    hexstring(GET32(ICSR));
    PUT32(ICSR,1<<28);
    for(ra=0;ra<20;ra++)
    {
        hexstring(GET32(ICSR));
    }
}
// ************** EXCEPTION HANDLER ***************

int notmain ( void )
{
    clock_init();
    uart2_init();
    hexstring(0x12345678);
    SVC();
    hexstring(0x11111111);
    return(0);
}

注:

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

然后我们得到

12345678 
0000080B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
1000E80B 
22222222 
0000080E 
22222222 
11111111

pendsv触发的时间是永恒的,但是因为svc调用在文档中是相等的,所以它不能,直到svc调用返回。你也可以用中断来做这个,但是异常应该高于中断吗?检查文档。
没有理由你的体验应该和我在你的cortex-m上的体验不一样。如果pendsv没有发生,那就分而治之。把问题分成两半。拿着当前的代码,开始删除东西,朝着什么都没有的方向努力。这样做一点。从几乎什么都没有开始,让pendsv启动,然后开始添加东西,朝着中间的地方努力,找到似乎导致它的原因,理解即使你找到了它,那可能不是它。那是它的内脏代码,你可能已经创造了另一种情况。
在裸机环境下,阅读和丢弃代码的实验时间超过99%,而编写最终程序的时间只占很小一部分。
你是否做了这些事情来查看中断处理程序或你正在做的其他事情是如何影响pendsv成功的?在你设置pendsv之后,ICSR寄存器显示了什么?
相对于留给pendsv的时钟周期,systick或其他同等级别的处理程序中有多少时间,您是否在系统级设计中确保有空闲时钟供处理程序使用。
如果你想在systick处理程序中进行线程交换,那么要么直接执行,要么使用svc而不是pendsv。

相关问题