嵌入式技术论坛
直播中

万物死

8年用户 1280经验值
擅长:MEMS/传感技术
私信 关注
[问答]

启动线程转到system_call出现故障如何解决

启动线程scheduler.c转到rt_hw_context_switch_to函数,触发system_call()故障。求帮助!rt_hw_context_switch_to函数如下,使用PowerPC芯片PPC460,谢谢!

/* void rt_hw_context_switch_to(to); */
.globl rt_hw_context_switch_to

rt_hw_context_switch_to:
/* set rt_thread_switch_interrput_flag = 1 /
lis r5,rt_thread_switch_interrput_flag@h
ori r5,r5,rt_thread_switch_interrput_flag@l
li r6, 0x01
stw r6,0(r5)
/
set rt_interrupt_from_thread = 0 /
lis r5,rt_interrupt_from_thread@h
ori r5,r5,rt_interrupt_from_thread@l
li r6, 0x00
stw r6,0(r5)
/
set rt_interrupt_from_thread = to /
lis r5,rt_interrupt_to_thread@h
ori r5,r5,rt_interrupt_to_thread@l
stw r3,0(r5)
/
trigger a system call */
sc
blr

回帖(10)

李鑫

2022-9-13 14:37:21
然后呢,进哪儿了? sc 这里是必经之路
举报

万物死

2022-9-13 14:37:37
去了static void System_Call(void),此函数原本是{COND_TRAP(31,0,0);}
我改成:{rt_hw_systemcall_entry();},然后进了Unalign_Access(),死了。
rt_hw_systemcall_entry:
mtspr SPRG0,r3 / save r3 to SPRG0 /
mtspr SPRG1,r4 / save r4 to SPRG1 /

lis     r3,rt_thread_switch_interrput_flag@h
ori     r3,r3,rt_thread_switch_interrput_flag@l
lwz     r4,0(r3)
cmpi    cr0,0,r4,0x0                        /* whether is 0     */
beq     _no_switch                          /* no switch, exit  */
li      r4,0x0                              /* set rt_thread_switch_interrput_flag to 0 */
stw     r4,0(r3)
/* load from thread to r3 */
lis     r3,rt_interrupt_from_thread@h       /* set rt_interrupt_from_thread */
ori     r3,r3,rt_interrupt_from_thread@l
lwz     r3,0(r3)
cmpi    cr0,0,r3,0x0                        /* whether is 0 */
beq     _restore                            /* it's first switch, goto _restore */
/* save r1:sp to thread[from] stack pointer */
subi    r1, r1, STACK_FRAME_SIZE
stw     r1, 0(r3)
/* restore r3, r4 from SPRG */
mfspr   r3,SPRG0
mfspr   r4,SPRG0
/* save registers   */
stw     r0,GPR0(r1)                         /* save general purpose registers 0    */
stmw    r2,GPR2(r1)                         /* save general purpose registers 2-31 */
mfusprg0 r0                                 /* save usprg0  */
stw     r0,USPRG0(r1)
mfcr    r0,                                 /* save cr      */
stw     r0,CR(r1)
mfxer   r0                                  /* save xer     */
stw     r0,XER(r1)
mfctr   r0                                  /* save ctr     */
stw     r0,CTR(r1)
mflr    r0                                  /* save lr      */
stw     r0, LR(r1)
mfsrr0  r0                                  /* save SRR0 and SRR1   */
stw     r0,SRR0(r1)
mfsrr1  r0
stw     r0,SRR1(r1)
_restore:
/ get thread[to] stack pointer /
lis r4,rt_interrupt_to_thread@h
ori r4,r4,rt_interrupt_to_thread@l
lwz r1,0(r4)
lwz r1,0(r1)

lwz     r0,SRR1(r1)                         /* restore SRR1 and SRR0   */
mtsrr1  r0
lwz     r0,SRR0(r1)
mtsrr0  r0
lwz     r0,LR(r1)                           /* restore lr       */
mtlr    r0
lwz     r0,CTR(r1)                          /* restore ctr     */
mtctr   r0
lwz     r0,XER(r1)                          /* restore xer     */
mtxer   r0
lwz     r0,CR(r1)                           /* restore cr      */
mtcr    r0
lwz     r0,USPRG0(r1)                       /* restore usprg0  */
// mtusprg0 r0
lmw     r2, GPR2(r1)                        /* restore general register */
lwz     r0,GPR0(r1)
addi    r1, r1, STACK_FRAME_SIZE
/* RFI will restore status register and thus the correct priority*/
rfi
_no_switch:
/ restore r3, r4 from SPRG /
mfspr r3,SPRG0
mfspr r4,SPRG0
rfi
举报

李鑫

2022-9-13 14:37:53
Unalign_Access 是因为你的目标线程栈地址没对齐还是 pc 指针没对齐。这俩寄存器的值是你的目地线程的初始入口和线程栈地址吗?
举报

万物死

2022-9-13 14:38:01
这个怎么检查呢?是跟STACK_FRAME_SIZE有关吗?线程建立的参数吗?
举报

李鑫

2022-9-13 14:38:11
调用 rt_hw_context_switch_to 前,断点查看俩线程控制块。rt_thread_t 里面不是有入口地址和栈地址吗,还有保存的栈顶指针。
举报

万物死

2022-9-13 14:38:21
这有什么问题吗?
to_thread 0x0001000c
name 0x0001000c
type 0x1
flags 0x0
list {…}
tlist {…}
sp 0x000107f8
entry 0xfffe2134
parameter 0x00000000
stack_addr 0x00010098
stack_size 0x800
error 0x0
stat 0x3
current_priority 0x2
init_priority 0x2
number_mask 0x4
event_set 0x0
event_info 0x0
init_tick 0x14
remaining_tick 0x14
thread_timer {…}
cleanup 0x00000000
user_data 0x0
highest_ready_priority 0x2
举报

万物死

2022-9-13 14:38:28
逐条确认是restore里面第7条语句引起的异常:
lwz r0,SRR1(r1) / restore SRR1 and SRR0 /
举报

李鑫

2022-9-13 14:38:43
看前边的 to_thread 几个指针挺好的。从流程上讲,这么走也是对的,from thread 是0 第一次进 restore 是对的。

sc指令调用操作系统去运行服务程序。当控制返回到一个运行系统调用的程序时,寄存器的内容依赖于程序提供的系统所使用的寄存器的约定。
跟在sc指令后面的有效指令地址被放在SRR0中。MSR中的位0、5~9和16~31被放在SRR1中相应的位置,SRR1中位1~4和10~15被设置为没有定义值。当sc异常产生,异常处理程序更改MSR寄存器。

lwz r0,SRR1(r1) 这里的 r1 指针能错了?
举报

万物死

2022-9-13 14:38:53
这是PPC405原来调试过的呀,用在PPC460有问题嘛
举报

李鑫

2022-9-13 14:39:01
问题根源可能不在这儿,但是得找到异常的地方,然后反向找引起异常的原因。
要是说,所有的变量,寄存器值都是正常的,但是走到这里就是出错了,这是不可能的。总有一些值意外变了。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分