它被设置在vectpending中,vectpending为001110,即14表示pendsv。 如果有人能帮忙,我将非常感激。
我假设您在Systick定时器处理程序中设置了位(根据您在评论中提供的信息)。由于您将PendSV优先级设置为低于Systick的优先级,因此PendSV将挂起,直到Systick中断返回。 PendSV无法中断Systick,因为它的优先级较低。从Systick中断返回后,PendSV将通过尾链接中断进行控制。
因此,当您在Systick定时器处理程序中设置位时,PendSV中断不会立即生成,就像您所期望的那样。只有在从Systick中断返回时才会中断。
你尝试过像这样简单的东西吗(随意编写代码实验对于裸机开发至关重要,请尝试不依赖项目其他部分和所有过度复杂的东西)
.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调用返回之前它才能被触发。你也可以使用中断来实现这一点,但异常应该比中断更高?请查看文档。
如果pendsv没有发生,那么你的经验与我不应该有什么不同。将问题分成两半。拿出当前的代码并开始逐步删除一些东西,朝着没有任何东西的方向努力。坚持一段时间。从几乎没有东西开始,让pendsv触发,然后开始添加东西,朝着中间的方向努力,找到似乎引起问题的东西,即使你找到了它,那也可能不是最终答案。这是裁剪代码的IT,你可能会创造出另一种情况。
阅读和丢弃代码实验在裸机编程中占据了超过99%的时间。编写最终程序只占很小一部分时间。
你是否做过这些事情来查看中断处理程序或其他你正在执行的操作如何影响pendsv的成功?设置pendsv后,ICSR寄存器显示给你多少时间?
在systick或其他相等级别的处理程序中,剩余的时钟周期相对于pendsv有多少时间?在系统级设计中,你是否确保有空闲时钟供所有处理程序使用?
如果你想在systick处理程序中进行线程交换,那么要么直接执行它,要么使用svc,而不是pendsv。