繁体   English   中英

ARM皮质如何处理 PendSV Handler

[英]How does ARM cortex handle PendSV Handler

我正在创建一个 RTOS kernel 并且需要使用 PendSV 处理程序进行上下文切换。 我通过执行以下操作触发 PendSV 处理程序:0xE000ED04 = (0x1 << 28);。 这会将 PendSVset 寄存器设置为 1,因此理论上,处理程序应该触发。 我确实在触发前禁用中断并在触发后启用。 启用 PendSV 后应该会触发。 优先级是最低的 0xFF,systick 处理程序优先级是 0x00。 我不确定发生了什么以及为什么 pendsv 处理程序没有运行。 我正在使用 TI-MSP432 controller,我认为它可能是 controller 处理中断的方式?

它在 vectpending 中设置,vectpending 为 001110,对于 pendsv 为 14。

如果有人可以提供帮助,我将不胜感激。

你有没有尝试过这样简单的事情(一次性代码实验对于裸机开发至关重要,尝试不使用项目的 rest 和所有过度复杂的东西)

.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 output:

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。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM