分类: 嵌入式
2012-05-30 19:46:49
1、 ucos系统一般运行在svc模式下
2、 需要初始化两个栈,IRQ mode,SVCmode,一般先初始化IRQ模式的栈,在初始化SVC模式的栈,因为在初始化svc堆栈后,一般直接跳转到__main,这样我们所谓的用户态代码和ucos代码都运行在svc,这样的好处就是我们可以通过操作cpsr来disable 中断,没有了中断就没有了线程的切换,可以用于保护共享数据。
3、 Scat 文件,代码的组织是
RO(.text,.constdata) |
RW(.data) |
ZI (.bss) |
HEAP |
STACK(SVC) |
STACK(IRQ) |
相应的scat文件如下:
SRAM_LOAD 0x00000000
{
SRAM_EXEC 0x00000000
{
startup.o (RESET, +First)
* (+RO, +RW,+ZI)
}
}
4、 OSCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED.这个函数在时钟中断处理中被调用,在调用之前把处理器模式切换到SVC模式。
5、 使用scat文件,必须得重新书写__user_initial_stackheap函数,原来库中的不能用了。只要我们调用__main,就需要__user_initial_stackheap函数,反汇编一下就能看到__main会调用_rt_entry,在_rt_entry中调用__user_initial_stackheap和main函数。
6、 Arm11支持vector类型的中断,需要设置一下协处理器,代码如下:
mrc p15,0,r0,c1,c0,0
orr r0,r0,#(1<<24)
mcr p15,0,r0,c1,c0,0
7、 系统要切换必须要有始终中断,因此需要两方面:timer初始化和中断处理函数。
相应的中断处理函数代码如下:
TICKISR FUNCTION
STMFD sp!, {r0 - r2} ; Save working registers onto IRQ stack
SUB r2, lr, #4
MOV r0, sp
MRS r1, SPSR
ADD sp, sp, #12
MSR CPSR_c, #0xd3 ; Switch to SVC mode
STR r2, [sp, #-4]! ; Save task's context onto task's stack
STMFD sp!, {r3 - r12, lr}
LDMFD r0!, {r3 - r5} ; Move task's r0-r2 from IRQ stack to task's stack
STMFD sp!, {r3 - r5}
STR r1, [sp, #-4]! ; Save task's CPSR
BL OSIntEnter ; Notify uC/OS-II of ISR
LDR r0, =OSIntNesting ; if (OSIntNesting == 1)
LDRB r1,[r0]
CMP r1, #1
BNE %F0
LDR r0, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = sp
LDR r1, [r0]
STR sp, [r1]
0
LDR r0, =0x0a80000c ; Clear interrupt source
MOV r1, #0
STR r1, [r0]
BL OSTimeTick ; Process system tick
BL OSIntExit ; Notify uC/OS-II of end of ISR
LDR r0, [sp], #4 ; Load task's context
MSR SPSR_cxsf, r0
LDMFD sp!, {r0 - r12, lr, pc}^ ; Run task
ENDFUNC
8、scatter文件分为加载域和执行域,一个加载域包括多个执行域。