Есть такая штука.. tn_switch_context
Там такой код
Код
tn_sw_restore
ldmfd sp!, {r0}
ldmfd sp!, {r1}
msr CPSR_cxsf, r1; с этой точки прерывания разрешены ! Комментарий мой
msr SPSR_cxsf, r0
mrs r4, CPSR
bic r4, r4, #NOINT
msr CPSR_c, r4
ldmfd sp!, {r0-r12,lr,pc}
ldmfd sp!, {r0}
ldmfd sp!, {r1}
msr CPSR_cxsf, r1; с этой точки прерывания разрешены ! Комментарий мой
msr SPSR_cxsf, r0
mrs r4, CPSR
bic r4, r4, #NOINT
msr CPSR_c, r4
ldmfd sp!, {r0-r12,lr,pc}
То есть стек задачи еще не развернут, прерывания разрешены. Наступление прерывания, требующего переключения контекста в нем затребует у этой задачи еще 15*4=60 байт стека. (вернее надо будет 68 байт, но 8 мы уже отыграли назад) Вот дальше у меня сомнения - сколько раз такое может произойти...
В реалии раза 3-4 я точно наблюдаю - хорошо видно по использованию стека. Как уменьшить тоже понятно - перенести восстановление CPSR после развертывания большей части стека через ldmfd sp!, {r0-r12,lr,pc}.
Но вот по идее то все равно, сколько раз такое может произойти - вобщем-то определить невозможно, а значит и минимальный требуемый стек для потока должен стремиться к бесконечности ?
Замена вышепреведенного кода на вот такой (жутко наивный, но все же)
Код
ldmfd sp!, {r0}
ldr r1, =t_spsr
str r0, [r1]
ldmfd sp!, {r0}
ldr r1, =t_cpsr
str r0, [r1]
ldmfd sp!, {r0-r12,lr}
push {r1}
ldr r1, =t_spsr
ldr r1,[r1]
msr SPSR_cxsf, r1
ldr r1, =t_cpsr
ldr r1,[r1]
msr CPSR_cxsf, r1
pop {r1}
ldmfd sp!, {pc}
ldr r1, =t_spsr
str r0, [r1]
ldmfd sp!, {r0}
ldr r1, =t_cpsr
str r0, [r1]
ldmfd sp!, {r0-r12,lr}
push {r1}
ldr r1, =t_spsr
ldr r1,[r1]
msr SPSR_cxsf, r1
ldr r1, =t_cpsr
ldr r1,[r1]
msr CPSR_cxsf, r1
pop {r1}
ldmfd sp!, {pc}
уменьшила требуемый стек очень прилично.
Вопрос возник не праздно, прокачивю через USB большой поток.. и в результате например банальная tn_idle_task благополучно через перваливала за 96 слов требуемого стека, при том что по умолчанию он 48. Но все равно как я понимаю не застрахован и в этом случае. Какие будут соображения ?