1

I am creating a RTOS kernel and need to use the PendSV handler for context switching. I trigger the PendSV handler by doing : 0xE000ED04 = (0x1 << 28);. This sets the PendSVset register to 1, so theoretically, the handler should trigger. I do disable interrupts before triggering and enable after triggering. After the enabling PendSV should trigger. The priority is the lowest 0xFF and the systick handler priority is 0x00. I am not sure what is going on and why the pendsv handler is not running. I am using an TI-MSP432 controller and I figure maybe its the way the controller is handling the interrupt?

It is set in vectpending, vectpending is 001110 which is 14 for pendsv.

If anybody can help, I'd greatly appreciate it.

4

2 回答 2

0

我假设您PENDSVSET在 Systick 计时器处理程序中设置了位(根据您在评论中提供的信息)。由于您将 PendSV 的优先级设置为低于 Systick 的优先级,因此 PendSV 将一直挂起,直到 Systick 中断返回。PendSV 无法中断 Systick,因为它的优先级较低。在从 Systick 中断返回时,PendSV 将通过尾链中断保持。

于 2021-06-08T17:37:21.070 回答
0

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

.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 调用返回。您也可以使用中断来执行此操作,但是异常应该高于中断吗?检查文档。

没有理由为什么您的皮质-m 体验与我的不同。如果没有发生pendsv,则分而治之。把问题分成两半。获取当前代码并开始删除无用的东西。这样做一会儿。从几乎没有触发 pendsv 开始,然后开始添加东西,向中间工作,在那里你找到似乎导致它的原因,理解即使你找到它,也可能不是 IT。那是 IT 的内脏代码,你可能创造了另一种情况。

阅读和一次性代码实验的时间远远超过您使用裸机的 99%。编写最终程序只占您时间的一小部分。

您是否做过这些事情来查看中断处理程序或您正在做的其他事情如何影响pendsv 成功?设置 pendsv 后 ICSR 寄存器向您显示什么?

相对于为 pendsv 留下的时钟周期,systick 或其他同等级别的处理程序中有多少时间,您是否在系统级设计中确保有空闲时钟供处理程序所有时间使用。

如果你想在 systick 处理程序中进行线程交换,那么要么就这样做,要么使用 svc 而不是 pendsv。

于 2021-02-28T17:12:29.660 回答