ucos在s3c2410上的移植-u球体育app下载

单片机 > 单片机程序设计 > 详情

ucos在s3c2410上的移植

发布时间:2025-07-18 发布时间:
|

反反复复弄了一个多星期,参考了不少资料,终于让ucos在自己的板子上跑起来了。期间遇到了不少问题,还好坚持下来,挺 了过去.....复习一下,记录下来,以当后用:

      1.在ads中建产工程,进入工程界面后,先建立两个组,一个为命名为ucosii,另一个为s3c2410。

ucosii,下再建两个组,一个为arm,添加移植要修改的三个文件,另一个sourc则添加与处理器无关的 ucos源文件。

s3c2410下主要存放一些与开发板初始化等有关的文件。

ucos在s3c2410上的移植 -  tianwaike1 - 开拓-进取        

2.移植的重点主要在三个有处理器有关的文件os_cpu.h,os_cpu_a.s 和os_cpu_c.c三个文件的编写。

(1)根据书上的移植说明及相关的参考文件,os_cpu.h的编写最简单,主要是定义一些数据类型以及开关中断的 方法等;

(2) os_cpu_c.c这个文件中,有不少钩子函数,都默认为空函数即可,无需编写.只有一个很重要的函数需要动手编写,即任务堆栈初始化函数 ostaskstkinit,它在任务创建时用来对任务堆栈的初始化工作,可以采用软中断或函数调用的方式来完成.

os_stk *ostaskstkinit (void (*task)(void *pd), void *p_arg, os_stk *ptos, int16u opt)
{
    os_stk *stk;

    opt      = opt;                 /* 'opt' is not used, prevent warning                      */
    
    stk      = ptos;                /* load stack pointer                                      */
    
    *(stk)   = (os_stk)task;        /* entry point                                             */
    *(--stk) = (int32u)0;         /* lr                                                      */
    *(--stk) = (int32u)0;         /* r12                                                     */
    *(--stk) = (int32u)0;         /* r11                                                     */
    *(--stk) = (int32u)0;         /* r10                                                      */
    *(--stk) = (int32u)0;         /* r9                                                      */
    *(--stk) = (int32u)0;         /* r8                                                      */
    *(--stk) = (int32u)0;         /* r7                                                      */
    *(--stk) = (int32u)0;         /* r6                                                      */
    *(--stk) = (int32u)0;         /* r5                                                      */
    *(--stk) = (int32u)0;         /* r4                                                      */
    *(--stk) = (int32u)0;         /* r3                                                      */
    *(--stk) = (int32u)0;         /* r2                                                      */
    *(--stk) = (int32u)0;         /* r1                                                      */
    *(--stk) = (int32u)p_arg;   /* r0 : argument arm的第一个参数存放在r0中                                         */
    *(--stk) = (int32u)0x00000013l;   /* cpsr (svc mode, enable both irq and fiq interrupts)    */                  
    return (stk);
}

(3).os_cpu_a.s文件中需要编写四个汇编函数: osstarthighrdy, osctxsw, ostickisr , osintctxsw

;*********************************************************************************************************/
import osrunning        //在本文件中要用到别的文件中定义的变量,要import导入
import ostcbcur       
import ostcbhighrdy
import ospriocur
import ospriohighrdy
import osintnesting

   
import osintenter
import osintexit
import ostaskswhook
import ostimetick

import handleeint0

export osstarthighrdy    //在本汇编文件中定义实现的函数或变量用export导出,在别的文件中只要用时,
export osctxsw              //用extern(.c文件)或import(.s文件)声明
export ostickisr 
export osintctxsw

export oscpusavesr
export oscpurestoresr

export os_cpu_irq_isr


area ucos_arm, code, readonly

;*********************************************************************************************************
;                                          start multitasking
;                                       void osstarthighrdy(void)
;
; the stack frame is assumed to look as follows:
;
;           entry point(task name)     (high memory)
;                               lr(r14)
;                               r12
;                               r11
;                               r10
;                               r9
;                               r8
;                               r7
;                               r6
;                               r5
;                               r4
;                               r3
;                               r2
;                               r1
;                               r0 : argument
; ostcbhighrdy->ostcbstkptr --> cpsr         (low memory)
;
; note : osstarthighrdy() must:
;           a) call ostaskswhook() then,
;           b) set osrunning to true,
;           c) switch to the highest priority task.
;********************************************************************************************************** */
osstarthighrdy 
;---------------------------------------------------------------------------------- 
; 下面的代码功能:osrunning = true;
;---------------------------------------------------------------------------------- 

msr     cpsr_cxsf,#svcmode|noint     ;switch to svc mode with irq&fiq disable

bl   ostaskswhook            ;call user define task switch hook

ldr   r0, =osrunning          ; osrunning =true
mov   r1, #1
strb r1, [r0]

;----------------------------------------------------------------------------------  
;    sp = ostcbhighrdy->ostcbstkptr;得到将要恢复运行任务的堆栈指针
;---------------------------------------------------------------------------------- 
ldr r0, =ostcbhighrdy   ;堆栈指针在任务控制块偏移量为0的地方
ldr r0, [r0]         
ldr sp, [r0]        

;----------------------------------------------------------------------------------  
; prepare to return to proper mode 从新任务堆栈中恢复处理器的所有寄存器
;---------------------------------------------------------------------------------- 
ldmfd sp!, {r0} 
msr spsr_cxsf, r0
ldmfd sp!, {r0-r12, lr, pc}^


;**********************************************************************************************************
;                                perform a context switch (from task level)任务级任务切换
;                                           void osctxsw(void)
;
; note(s):     1) upon entry: 
;                 ostcbcur      points to the os_tcb of the task to suspend
;                 ostcbhighrdy points to the os_tcb of the task to resume
;
;              2) the stack frame of the task to suspend looks as follows:
;                                                   
;                                                   pc                    (high memory)
;                lr(r14)     
;                                    r12
;                                     r11
;                                    r10
;                                    r9
;                                     r8
;                                     r7
;                                     r6
;                                     r5
;                                     r4
;                                     r3
;                                     r2
;                                     r1
;                                     r0
;        ostcbcur->ostcbstkptr ----> cpsr      (low memory)
;
;
;              3) the stack frame of the task to resume looks as follows:
;
;                  pc     (high memory)
;                                                   lr(r14) 
;                                     r12
;                                    r11
;                                    r10
;                                    r9
;                                     r8
;                                     r7
;                                      r6
;                                     r5
;                                     r4
;                                     r3
;                                     r2
;                                     r1
;                                      r0
;       ostcbhighrdy->ostcbstkptr ----> cpsr      (low memory)
;*********************************************************************************************************/
osctxsw

stmfd sp!, {lr}           ;pc
stmfd sp!, {r0-r12, lr}   ;r0-r12 lr
mrs   r0, cpsr       ;push cpsr
stmfd sp!, {r0} 
  
;----------------------------------------------------------------------------------
;    ostcbcur->ostcbstkptr = sp 在当前任务控制块中保存当前任务的堆栈指针
;----------------------------------------------------------------------------------  
ldr   r0, =ostcbcur
ldr   r0, [r0]
str   sp, [r0]

;----------------------------------------------------------------------------------  
; ostaskswhook();
;--------------------------------------------------------------------------------- 
bl    ostaskswhook

;----------------------------------------------------------------------------------   
; ostcbcur = ostcbhighrdy; 将指向当前任务的指针指向要恢复的任务//ostcbcur:pointer to highest priority tcb r-to-r   
;----------------------------------------------------------------------------------  
ldr   r0, =ostcbhighrdy
ldr   r1, =ostcbcur
ldr   r0, [r0]
str   r0, [r1]

;----------------------------------------------------------------------------------  
; ospriocur = ospriohighrdy; 将新任务的优先级赋给当前任务的优先级//ospriohighrdy: priority of highest priority task
;----------------------------------------------------------------------------------  
ldr   r0, =ospriohighrdy
ldr   r1, =ospriocur
ldrb r0, [r0]
strb r0, [r1]

;----------------------------------------------------------------------------------  
; ostcbhighrdy->ostcbstkptr;得到将要运行的任务的堆栈指针
;----------------------------------------------------------------------------------  
ldr   r0, =ostcbhighrdy
ldr   r0, [r0]
ldr   sp, [r0]

;---------------------------------------------------------------------------------- 
;restore new task context 从新任务中恢复处理器的寄存器
;---------------------------------------------------------------------------------- 
ldmfd sp!, {r0}   ;pop cpsr
msr spsr_cxsf, r0
ldmfd sp!, {r0-r12, lr, pc}^ 

*********************************************************************************************************
;                                            tick handler
; description: 此处为时钟节拍中断处理函数

;过程简介:当初始化时钟源(采用timer0),开始中断后。定时时间到,产生中断,cpu进入 irq模式,pc跳转到0x18处,经过中断源查询后,调用os_cpu_irq_isr   ,在os_cpu_irq_isr 中切换为管理模后保存处理器寄存器后,再经查询跳转到些正式进行中断服务程序处理,然后返回(中断处理及切换最难:后详解)
;     this handles all the timer0(int_timer0) interrupt which is used to generate the uc/os-ii tick.
;*********************************************************************************************************/

ostickisr
;---------------------------------------------------------------------------------- 
;;保存处理器的值;
;----------------------------------------------------------------------------------

mov     r5,lr 
;---------------------------------------------------------------------------------- 
;调用osintenter or 将osiintnesting加1
;---------------------------------------------------------------------------------- 

mov r1, #1                     ;清除中断标志
mov r1, r1, lsl #10      ; timer0 source pending reg.timer0为位10
ldr r0, =srcpnd         ;源未决寄存器中有中断时,相应位置1,
ldr     r2, [r0]
orr     r1, r1,r2
str r1, [r0]

ldr   r0, =intpnd         ;中断未决寄存器中只保存未屏蔽的具有最高优先级的一位中断标志
ldr   r1, [r0]
str   r1, [r0]  

;----------------------------------------------------------------------------------  
; ostimetick();
;---------------------------------------------------------------------------------- 
bl   ostimetick 
mov    pc, r5           ; return 

;*********************************************************************************************************
;                                perform a context switch (from an isr)
;                                        void osintctxsw(void)
;
; description: 1) this code performs a context switch if a higher priority task has been made ready-to-run
;               during an isr.
;
;              2) the stack frame of the task to suspend looks as follows:
;
;                pc      (high memory)
;                                                   lr(r14)
;                                    r12
;                                     r11
;                                    r10
;                                    r9
;                                     r8
;                                     r7
;                                     r6
;                                     r5
;                                     r4
;                                     r3
;                                     r2
;                                     r1
;                                     r0
;                                    
;        ostcbcur->ostcbstkptr ----> cpsr      (low memory)
;
;
;              3) the stack frame of the task to resume looks as follows:
;
;                  pc      (high memory)
;                                                   lr(r14) 
;                                     r12
;                                    r11
;                                    r10
;                                    r9
;                                     r8
;                                     r7
;                                      r6
;                                     r5
;                                     r4
;                                     r3
;                                     r2
;                                     r1
;                                      r0
;       ostcbhighrdy->ostcbstkptr ----> cpsr      (low memory)
;*********************************************************************************************************/
osintctxsw
;----------------------------------------------------------------------------------  
; call ostaskswhook();
;---------------------------------------------------------------------------------- 
bl    ostaskswhook

;----------------------------------------------------------------------------------   
; ostcbcur = ostcbhighrdy;
;----------------------------------------------------------------------------------  
ldr   r0, =ostcbhighrdy
ldr   r1, =ostcbcur
ldr   r0, [r0]
str   r0, [r1]

;----------------------------------------------------------------------------------  
; ospriocur = ospriohighrdy;
;----------------------------------------------------------------------------------  
ldr   r0, =ospriohighrdy
ldr   r1, =ospriocur
ldrb r0, [r0]
strb r0, [r1]

;----------------------------------------------------------------------------------  
;    sp = ostcbhighrdy->ostcbstkptr;
;----------------------------------------------------------------------------------  
ldr   r0, =ostcbhighrdy
ldr   r0, [r0]
ldr   sp, [r0]

;---------------------------------------------------------------------------------- 
; restore new task context
;---------------------------------------------------------------------------------- 
ldmfd sp!, {r0}              ;pop cpsr
msr spsr_cxsf, r0
ldmfd sp!, {r0-r12, lr, pc}^ 


os_cpu_irq_isr

stmfd   sp!, {r1-r3}    ; use r1-r3 as temporary registers,push r1-r3 to irq stack
;----------------------------------------------------------------------------
;   r1--sp
; r2--pc 
;   r3--spsr
;------------------------------------------------------------------------
mov     r1, sp
add     sp, sp, #12             ;adjust irq stack pointer,因为保存了r1-r3,,sp_irq往下移了,为了以后中断使用

                                              ;要用到中断堆栈,故此处需要调整回去到其开始定义的地方
sub     r2, lr, #4              ;adjust pc for return address to task

mrs     r3, spsr                 ; copy spsr (task cpsr)

  

msr     cpsr_cxsf, #svcmode|noint   ;change to svc mode

                                                                   ; save task''s context onto old task''s stack
         
stmfd   sp!, {r2}               ; push task''s pc 
stmfd   sp!, {r4-r12, lr}   ; push task''s lr,r12-r4

ldmfd   r1!, {r4-r6}    ; load task''s r1-r3 from irq stack 
stmfd   sp!, {r4-r6}    ; push task''s r1-r3 to svc stack
stmfd   sp!, {r0}       ; push task''s r0 to svc stack

stmfd   sp!, {r3}     ; push task''s cpsr

ldr     r0,=osintnesting        ;osintnesting ,将中断嵌套层数加1
ldrb    r1,[r0]
add     r1,r1,#1
strb    r1,[r0] 
//下面几句此处为2.5以上实现中断嵌套 与编译器无关的精彩改进之处。可以中断嵌套后无需调整堆栈指针sp

;其原理就是在最外层中断时,把sp保存到任务控制块的堆栈中:ostcbcur->ostcbstkptr=sp,把sp所指堆栈赋给ostcbstkptr即ostcbcur->ostcbstkptr指向的刚发生中断时的堆栈,以后不管是否发生中断嵌套,使得sp发 生变化。都只需要任务恢复时从此恢复任务的sp,使用有用的堆栈,而不用去理后面中断嵌套发生的堆栈变化(对任务来说无用)

cmp     r1,#1              ;{if(osintnesting==1){; 则将被中断任务的堆栈指针保存在被中断任务的任务任务控制块中 
bne     �

ldr     r4,=ostcbcur            ;ostcbcur->ostcbstkptr=sp;以免中断退出调用高优先级任务后破坏堆栈指针,

                                                   ;避免调整堆栈指针的麻烦
ldr     r5,[r4]
str     sp,[r5]                 ;}

1
msr    cpsr_c,#irqmode|noint    ;change to irq mode to use irq stack to handle interrupt
ldr     r0, =intoffset          ;根据中断偏移寄存器中的值为查到中断源号,再跳转到相应的中断服务中程序中去;

   ldr     r0, [r0]     
   ldr     r1, irqisrvect
    mov     lr, pc                                 ; save lr befor jump to the c function we need return back
    ldr     pc, [r1, r0, lsl #2]            ; call os_cpu_irq_isr_handler();   
    
    msr   cpsr_c,#svcmode|noint   ;change to svc mode
    bl    osintexit                                   ;call osintexit
    
    ldmfd   sp!,{r4}                          ;pop the task''s cpsr 
    msr   spsr_cxsf,r4
    ldmfd   sp!,{r0-r12,lr,pc}^      ;pop new task''s context

irqisrvect dcd handleeint0

;*********************************************************************************************************

;采用第三种方法处理开关中断
oscpusavesr
mrs     r0, cpsr     ; set irq and fiq bits in cpsr to disable all interrupts
orr     r1, r0, #0xc0
msr     cpsr_c, r1
mrs     r1, cpsr     ; confirm that cpsr contains the proper interrupt disable flags
and     r1, r1, #0xc0
cmp     r1, #0xc0
bne     oscpusavesr     ; not properly disabled (try again)
mov     pc, lr      ; disabled, return the original cpsr contents in r0

oscpurestoresr
msr     cpsr_c, r0
mov     pc, lr
         
end

上述为编写与处理器有关的三个文件,要使ocos在板上运行起来,还得做一些板子初始化方面的工作。如2410的启动加载文件就是必需的,还有 mmu初始等....后继续





『本文转载自网络,u球体育app下载的版权归原作者所有,如有侵权请联系删除』

热门文章 更多
stm32cubemx新建工程 基本io配置过程
网站地图