uCOSII移植ARM的笔记_第1页
uCOSII移植ARM的笔记_第2页
uCOSII移植ARM的笔记_第3页
uCOSII移植ARM的笔记_第4页
uCOSII移植ARM的笔记_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、uCOS-II移植ARM的笔记UCOS-II的移植需要提供2,3个文件分别介绍如下:一:OS_CPU.H1 与编译器有关的数据类型经典的全局变量定义,可以套用,简洁明了实用性好。#ifdef  OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT  extern#endif   只是按照不同的编译器编写对应的数据类型的typedef   对应于ARM7的数据类型的编写如下typedef unsigned char  B

2、OOLEAN;                 /* 布尔变量                              

3、0;  */typedef unsigned char  INT8U;                   /* 无符号8位整型变量                     

4、60;  */typedef signed   char  INT8S;                   /* 有符号8位整型变量                   

5、0;    */typedef unsigned short INT16U;                  /* 无符号16位整型变量                     

6、  */typedef signed   short INT16S;                  /* 有符号16位整型变量                     

7、0; */typedef unsigned int   INT32U;                  /* 无符号32位整型变量                       *

8、/typedef signed   int   INT32S;                  /* 有符号32位整型变量                     &#

9、160; */typedef float          FP32;                    /* 单精度浮点数(32位长度)              

10、   */typedef double         FP64;                    /* 双精度浮点数(64位长度)             

11、60;   */    在上面定义的各种数据类型中按照ARM7的堆栈宽度选择INT32Utypedef INT32U         OS_STK;                  /* 堆栈是32位宽度      &

12、#160;                    */    2 与处理器相关的代码    先定义中断的实现方式,预先设定的中断方式有三种,在ARM7中设置为方式2#define     OS_CRITICAL_METHOD     2&#

13、160;           /* 选择开、关中断的方式 */ _swi(0x00) void OS_TASK_SW(void);              /*  任务级任务切换函数          */_

14、swi(0x01) void _OSStartHighRdy(void);         /*  运行优先级最高的任务        */_swi(0x02) void OS_ENTER_CRITICAL(void);       /*  关中断      

15、                */_swi(0x03) void OS_EXIT_CRITICAL(void);        /*  开中断                &#

16、160;     */ _swi(0x40) void *GetOSFunctionAddr(int Index); /*  获取系统服务函数入口        */_swi(0x41) void *GetUsrFunctionAddr(int Index);/*  获取自定义服务函数入口      */_swi(0x42) void OSISRBegin(

17、void);              /*  中断开始处理                */_swi(0x43) int  OSISRNeedSwap(void);       

18、0;   /*  判断中断是否需要切换        */ _swi(0x80) void ChangeToSYSMode(void);         /*  任务切换到系统模式          */_swi(0x81) void ChangeT

19、oUSRMode(void);         /*  任务切换到用户模式          */_swi(0x82) void TaskIsARM(INT8U prio);         /*  任务代码是ARM代码     

20、      */_swi(0x83) void TaskIsTHUMB(INT8U prio);       /*  任务代码是THUMB             */       定义堆栈的生长方式,ARM7内核支持两种生长方式,但是ADS的C语言

21、编译器只支持从上往下的生长方式,因此:#define OS_STK_GROWTH    1                      /*  堆栈是从上往下长的,0从下往上的生长方式         */ 最后几行分别定义了用户模式01和系统模式1f

22、以及IRQ中断禁止的指令80三个立即数,方便调用。#define     USR32Mode       0x10                /*  用户模式           

23、60;        */#define     SYS32Mode       0x1f                /*  系统模式       

24、;             */#define     NoInt           0x80    还有两个预定义往后看应该知道作用,暂不考虑,不是很重要。 #ifndef USER_USING_MODE#define USER_USING_MO

25、DE       USR32Mode               /*  任务缺省模式                 */#endif #ifndef OS_SELF_EN#de

26、fine OS_SELF_EN     0                        /*  允许返回OS与任务分别编译、固化*/   #endifOS_CPU_EXT INT32U OsEnterSum;   &#

27、160;               /*  关中断计数器(开关中断的信号量)    */ 二OS_CPU.C文件头文件的引用:#define  OS_CPU_GLOBALS#include "config.h" /* 函数名称: OSTaskStkInit* 功能描述: 任务堆栈初始化代码,本函数

28、调用失败会使系统崩溃* 输入: task  : 任务开始执行的地址*         pdata :传递给任务的参数*         ptos  :任务的堆栈开始位置*         opt   :附加参数,当前版本对于本函数

29、无用,具体意义参见OSTaskCreateExt()的opt参数* 输出: 栈顶指针位置* 全局变量:* 调用模块:* 作者: 陈明计* 日期: 2003年6月5日*-* 修改人: 陈明计* 日期: 2003年6月13日*-*/         OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos

30、, INT16U opt)    OS_STK *stk;     opt    = opt;                           /* 'opt' 

31、0;没有使用。作用是避免编译器警告    */    stk    = ptos;                          /* 获取堆栈指针     

32、;                                  */               

33、60;                             /* 建立任务环境,ADS1.2使用满递减堆栈       */    *stk = (OS_STK) task; 

34、                  /*  pc  */    *-stk = (OS_STK) task;                 /*  

35、lr  */     *-stk = 0;                             /*  r12  */    *-stk = 0; 

36、;                            /*  r11  */    *-stk = 0;           

37、                  /*  r10  */    *-stk = 0;                     &

38、#160;       /*  r9   */    *-stk = 0;                             /* &

39、#160;r8   */    *-stk = 0;                             /*  r7   */    *-stk

40、 = 0;                             /*  r6   */    *-stk = 0;        

41、60;                    /*  r5   */    *-stk = 0;                  

42、;           /*  r4   */    *-stk = 0;                           &

43、#160; /*  r3   */    *-stk = 0;                             /*  r2   */ 

44、60;  *-stk = 0;                             /*  r1   */    *-stk = (unsigned int) pdata;  

45、        /*  r0,第一个参数使用R0传递   */    *-stk = (USER_USING_MODE|0x00);           /*  spsr,允许 IRQ, FIQ 中断   */   &#

46、160;*-stk = 0;                             /*  关中断计数器OsEnterSum;    */     return (stk);OSTaskStkIni

47、t()函数的功能是初始化任务的栈结构,任务的堆栈结构与CPU的体系结构、编译器有密切的关联。从ARM的结构可以写出如下的栈结构:程序计数器PC,程序链接器LR,R12R1,R0用于传递第一个参数pdata,CPSR/SPSR,关中断计数器(用于计算关中断的次数,这样就实现了中断的嵌套),返回的地址指针是指向的最后一个存入的数据,而不是一个空地址。/* 函数名称: SWI_Exception* 功能描述: 软中断异常处理程序,提供一些系统服务*          *&

48、#160;输入:  SWI_Num:功能号*          Regs0 为第一个参数,也是返回值*          Regs1 为第二个参数*          Regs2 为第三个参数*    

49、0;     Regs3 为第四个参数* 输出: 根据功能而定*        * 全局变量: 无* 调用模块: 无* 作者: 陈明计* 日期: 2003年6月5日*-* 修改人: 陈明计* 日期: 2003年6月19日*-* 修改人: 陈明计* 日期: 2003年6月24日*-

50、*/#if OS_SELF_EN > 0extern int const _OSFunctionAddr;extern int const _UsrFunctionAddr;#endif        void SWI_Exception(int SWI_Num, int *Regs)    OS_TCB   *ptcb;       switch(SWI_Num)

51、60;           /case 0x00:                    /* 任务切换函数OS_TASK_SW,参考os_cpu_s.s文件     */     

52、;   /    break;        /case 0x01:                    /* 启动任务函数OSStartHighRdy,参考os_cpu_s.s文件 */   &#

53、160;    /    break;        case 0x02:                      /* 关中断函数OS_ENTER_CRITICAL(),参考os_cpu.h文件 

54、*/            _asm                            MRS     R0, SPSR  &

55、#160;             ORR     R0, R0, #NoInt                MSR     SPSR_c, R0     &

56、#160;                  OsEnterSum+;            break;        case 0x03:      

57、60;               /* 开中断函数OS_EXIT_CRITICAL(),参考os_cpu.h文件 */            if (-OsEnterSum = 0)          

58、60;                 _asm                                

59、;    MRS     R0, SPSR                    BIC     R0, R0, #NoInt           &

60、#160;        MSR     SPSR_c, R0                                  

61、      break;#if OS_SELF_EN > 0        case 0x40:                              

62、;          /* 返回指定系统服务函数的地址       */                             

63、           /* 函数地址存于数组_OSFunctionAddr中*/                                 &#

64、160;      /* 数组_OSFunctionAddr需要另外定义  */                                    

65、;    /* Regs0 为第一个参数,也是返回值 */                                        /

66、* Regs1 为第二个参数             */                                 

67、60;      /* Regs2 为第三个参数             */                           

68、;             /* Regs3 为第四个参数             */                    &

69、#160;                   /* 仅有一个参数为系统服务函数的索引 */            Regs0 =  _OSFunctionAddrRegs0;      &

70、#160;     break;        case 0x41:                                 

71、60;      /* 返回指定用户的服务函数的地址     */                                  

72、60;     /* 函数地址存于数组_UsrFunctionAddr中*/                                      

73、0; /* 数组_UsrFunctionAddr需要另外定义 */                                        /* Regs0

74、0;为第一个参数,也是返回值 */                                        /* Regs1 为第二个参数   

75、          */                                       

76、0;/* Regs2 为第三个参数             */                                 

77、       /* Regs3 为第四个参数             */                          &#

78、160;             /* 仅有一个参数为用户服务函数的索引 */            Regs0 =  _UsrFunctionAddrRegs0;            b

79、reak;        case 0x42:                      /* 中断开始处理 */            OSIntNestin

80、g+;            break;        case 0x43:                      /*  判断中断是否需要切换 

81、;            */            if (OSTCBHighRdy = OSTCBCur)                     

82、;       Regs0 = 0;                        else                

83、60;           Regs0 = 1;                        break;#endif        case 0x80: &

84、#160;                    /* 任务切换到系统模式 */            _asm            &#

85、160;               MRS     R0, SPSR                BIC     R0, R0, #0x1f    

86、;            ORR     R0, R0, #SYS32Mode                   MSR     SPSR_c, R0   &

87、#160;                    break;        case 0x81:                  

88、60;   /* 任务切换到用户模式 */            _asm                            MRS &

89、#160;   R0, SPSR                BIC     R0, R0, #0x1f                ORR    

90、0;R0, R0, #USR32Mode                   MSR     SPSR_c, R0                    

91、60;   break;        case 0x82:                      /* 任务是ARM代码 */          

92、;  if (Regs0 <= OS_LOWEST_PRIO)                            ptcb = OSTCBPrioTblRegs0;          

93、60;     if (ptcb != NULL)                                    ptcb -> OSTCBStkPtr1 &= (1

94、<< 5);                                        break;       

95、 case 0x83:                      /* 任务是THUMB代码 */            if (Regs0 <= OS_LOWEST_PRIO)    

96、;                        ptcb = OSTCBPrioTblRegs0;                if (ptcb != NULL)   

97、;                                 ptcb -> OSTCBStkPtr1 |= (1 << 5);          

98、;                              break;        default:         

99、60;  break;    软件中断异常SWI服务程序C语言部分    void SWI_Exception(int SWI_Num, int *Regs):参数SWI_Num对应前面文件中定义的功能号,其中0、1号的功能在后面的文件中定义,这里只定义了其他10个功能。    2、3分别对应关中断和开中断    关中断:MRS     R0, SPSR   

100、0;     /在软件中断的时候直接对程序状态保存寄存器SPSR操作也就是对CPSR的操作                   ORR     R0, R0, #NoInt    /在汇编语言中对寄存器的对应位置位用ORR,清零用BIC    

101、60;              MSR     SPSR_c, R0        /SPSR_c表示的是只改变SPSR的控制段的8位代码,其他三段_f,_s,_x中标志位在_f段,其他为保留位    开中断:MRS     R0, SPSR  &

102、#160;    /在开中断中基本与上面相同,只是ORR改成BIC清零                   BIC     R0, R0, #NoInt               

103、;    MSR     SPSR_c, R    由于需要实现中断嵌套,所以只有当关中断的计数器减为0的时候才能够开中断,而且每次关中断的时候该计数器都应该加1。另外,插入汇编语言时用_asm指令。     80、81、82、83分别对应系统模式、用户模式、ARM指令集、THUMB指令集    系统模式:MRS     R0, SPSR 

104、;                       BIC     R0, R0, #0x1f     /先将控制模式的低5位清零             

105、0;          ORR     R0, R0, #SYS32Mode       /设置成系统模式的1F                        MSR &

106、#160;   SPSR_c, R0    用户模式:MRS     R0, SPSR                        BIC     R0, R0, #0x1f    

107、60;                   ORR     R0, R0, #USR32Mode     /设置成用户模式的10                 

108、0;      MSR     SPSR_c, R0_OSStartHighRdy        MSR     CPSR_c, #(NoInt | SYS32Mode)  MSR:在ARM中只有MSR能够直接设置状态寄存器CPSR或SPSR,可以是立即数或者源寄存器,NoInt是禁止中断,SYS32Mode是系统模式     

109、                                           ;告诉uC/OS-II自身已经运行     

110、   LDR     R4, =OSRunning  ;OSRunning正在运行多任务的标志,OSRunning是把OSRunning的地址加载到R4,R4里存的是一个地址。        MOV     R5, #1          STRB    R5, R4   ;将R

111、5存储到R4存的地址的变量即OSRunning中,也就是将OSRunning置1        BL      OSTaskSwHook                    ;调用钩子函数,OSTaskSwHook 是用于扩展的,在任务切换的时候执行用户自己定义的功能。

112、0;       LDR     R6, =OSTCBHighRdy    ;OSTCBHighRdy指向最高优先级任务的控制块TCB的指针!将放指针的地址放到R6中。        LDR     R6, R6  ;将R6地址处的数据读出即OSTCBHighRdy的地址放到R6中     

113、0;  B       OSIntCtxSw_1   ;跳转到OSIntCtxSw_1         AREA    SWIStacks, DATA, NOINIT,ALIGN=2SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间 继续昨天没有

114、看完的代码OSIntCtxSw                                               

115、60;    ;下面为保存任务环境        LDR     R2, SP, #20                       ;获取PC,放入R2       

116、LDR     R12, SP, #16                      ;获取R12,/R12存的什么东西啊?        MRS     R0, CPSR      

117、;  MSR     CPSR_c, #(NoInt | SYS32Mode)   进入系统模式并禁止中断        MOV     R1, LR    R1放LR值        STMFD   SP!, R1-R2     

118、;                   ;保存LR,PC,将R1,R2存入SP        STMFD   SP!, R4-R12                

119、60;      ;保存R4-R12,将R4-12存入SP        MSR     CPSR_c, R0   ;再回到之前的模式        LDMFD   SP!, R4-R7            

120、            ;获取R0-R3        ADD     SP, SP, #8                        

121、  ;出栈R12,PC                MSR     CPSR_c, #(NoInt | SYS32Mode)        STMFD   SP!, R4-R7           

122、             ;保存R0-R3                LDR     R1, =OsEnterSum              &

123、#160;      ;获取OsEnterSum        LDR     R2, R1        STMFD   SP!, R2, R3                 

124、      ;保存CPSR,OsEnterSum                                          

125、;          ;保存当前任务堆栈指针到当前任务的TCB        LDR     R1, =OSTCBCur        LDR     R1, R1        STR   

126、;  SP, R1        BL      OSTaskSwHook                        ;调用钩子函数        

127、0;                                           ;OSPrioCur <= OSPrioHighRdy  

128、60;     LDR     R4, =OSPrioCur        LDR     R5, =OSPrioHighRdy        LDRB    R6, R5        STRB    R6,

129、 R4                                                 

130、60;  ;OSTCBCur <= OSTCBHighRdy        LDR     R6, =OSTCBHighRdy        LDR     R6, R6        LDR     R4, =OSTCBCur  &

131、#160;     STR     R6, R4OSIntCtxSw_1                                     &#

132、160;              ;获取新任务堆栈指针        LDR     R4, R6      ;把OSTCBHighRdy指向最高优先级任务的控制块TCB的指针给R4        ADD   

133、;  SP, R4, #68                         ;17寄存器:CPSR,OsEnterSum,R0-R12,LR,SP        LDR     LR, SP, #-8   ;取出LR放

134、到LR        MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式并且保持禁止中断        MOV     SP, R4          

135、60;                   ;设置堆栈指针        LDMFD   SP!, R4, R5                  &

136、#160;    ;CPSR,OsEnterSum。LDMFD数据出栈,放入R4,R5                                        &#

137、160;           ;恢复新任务的OsEnterSum        LDR     R3, =OsEnterSum   ;OsEnterSum的地址存入R3        STR     R4, R3   ;把R4的值赋给OsE

138、nterSum            MSR     SPSR_cxsf, R5                       ;恢复CPSR;在管理模式里是修改SPSR     &

139、#160;  LDMFD   SP!, R0-R12, LR, PC              ;运行新任务  ,恢复现场,异常处理返回 实时系统概念1 前后台系统   不复杂的小系统通常选择前后台系统,应用程序是一个无限循环。在循环中调用相应的函数完成相应的操作,这部分可以看成后台行为。中断服务程序处理异步事件,可以看成前台行为。2 代码的临界段 

140、0;  需要在前后关开中断的代码,不能被打断的代码 3 资源   输入输出设备,各种变量,结构,数组 4 共享资源   可以被多个任务使用的资源 5多任务   通过CPU在许多任务之间转换和调度 6任务  每个任务都是一个无限循环,都可能处于五种状态之一:休眠,就绪,运行,挂起,被中断。UCOS中提供各种函数使任务能从一个状态变为另一个状态  每个任务都有自己的CPU寄存器和栈空间以及T

141、CB任务控制块 7任务切换  任务切换过程是将正在运行任务的CPU寄存器全部内容保存到任务自己的栈区中,再将下一个要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行 8内核  负责管理各个任务,为每个任务分配CPU时间,并负责任务间的通信 9调度决定该轮到哪个任务运行。主要是通过优先级来决定。总是让处于就绪态的优先级最高的任务先运行。 10不可剥夺型内核  每个任务主动放弃CPU的使用权,放弃的方法可以使用多种函数定时或者定事件的放弃。异步事件还是由中断服务来处理

142、。中断处理结束之后还是回到被中断的那个任务直到该任务主动放弃CPU的使用权。在任务级,不可剥夺型内核允许使用不可重入函数函数不必担心被重复调用,因为每个时刻都只有一个任务在运行。当然,该函数不能具有放弃CPU使用权的功能。 11可剥夺型内核  当系统响应时间很重要,就需要使用可剥夺型内核。最高优先级任务一旦就绪,总能得到CPU的使用权。当运行的任务使一个更高优先级的任务进入就绪态,当前任务的CPU使用权就被剥夺或挂起,更高优先级的任务获得CPU的使用权。如果是中断服务子程序造成的,中断完成后被中断的任务被挂起,执行更高优先级的任务。  在可剥夺型内核中,要谨慎使用不可重入函数。因为低优先级的和高优先级的任务有可能都调用该函数。  总是让就绪态的高优先级的任务先运行,中断服务程序可以抢占CPU 12可重入函数  可重入函数或者只使用局部变量,要么就是使用全局变量并且对全局变量予以保护。 13时间片轮番调度法  UCOS中各个任务的优先级都是不同的。不支持时间片轮番调度 14任务优先级  从0开始,越小的优先级越高 15静态优先级  在执行过程中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论