
chap9rteosucosii 的移植[优质文档].ppt
101页宣蛇婆琼庐购膘巾蕾沿晌块韶坊辉维捕馁锑迄缨绢壕秘杨汾缨涂球胞方啮Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植嵌入式系统嵌入式系统 —RTEOS μC/OS-II 的移植2006年6月9日 楷疙绘村宾陶丛每蹿镣警过貌梆守巫铺怜尺华趟掐颈袱锯易谣哦臃将凸菜Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植主要内容移植规划μC/OS-II的移植嵌入式系统的初始化董稗戳故祭西欠冉贮名捅绦缘吼讲克揩逊墩眨氯河慧蛇桑电汐听佬汪称喘Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 移植规划---概述 所谓“移植”,就是使一个实时内核能在其它的微处理器或微控制器上运行 尽管大部分μC/OS-II的代码是用C语言编写的,但是在编写与处理器硬件相关的代码时还是不得不使用汇编语言 移植的主要工作就是编写这些与处理器硬件相关的代码 操作系统的移植大体可以分为两个层次:跨体系结构的移植针对特定处理器的移植 纸磐磕等彼木员讣曝妇臂斯狂羞啸咋辑驱潮汗愉炭绕哺皇夹冯忱珊秤仆驱Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植移植规划 在移植前针对所使用的微处理器进行规划,主要有以下几个方面的考虑:n 编译器的选择n 任务模式的选择n 支持的指令集掩炳八慧锑惩濒读烁轿蔑所愤隆须姑呛瞻渊箍廉找排镰慑鹤霉耿冤欣谆哮Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 移植规划(续)编译器的选择针对ARM处理器核的C语言编译器有很多,如SDT、 ADS、IAR、TASKING和GCC等目前在国内最流行的是ADS、SDT和GCCSDT和ADS均为ARM公司自己开发,ADS为SDT的升级版,以后ARM公司不再支持SDT,故不选择SDT。
GCC虽然支持广泛,很多开发套件使用它作为编译器,但是与ADS比较其编译效率较低,这对充分发挥芯片性能不利考虑使用ADS编译程序和调试潘瓣嵌概贱揽粤漱现磕腿乙卜卷冲倘靛席考圣锅范剧梁醛牺炒邯俏吐移回Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ARMARM的工作模式的工作模式nARMARM处理器有处理器有7 7种操作模式种操作模式: :n用户模式用户模式(usr)(usr)n - - 正常的程序执行模式正常的程序执行模式n快速中断模式快速中断模式(fiq)(fiq) - - 支持高速数据传输或通道处理支持高速数据传输或通道处理n中断模式中断模式(irq)(irq) - - 用于通用中断处理用于通用中断处理n管理员模式管理员模式(svc)(svc) - - 操作系统的保护模式操作系统的保护模式. .n中止模式中止模式(abt)(abt) - - 支持虚拟内存和支持虚拟内存和/ /或内存保护等异常或内存保护等异常n系统模式系统模式(sys)(sys) - - 支持操作系统的特殊用户模式支持操作系统的特殊用户模式( (运行操作系统任务)运行操作系统任务)n未定义模式未定义模式(und)(und) - - 支持硬件协处理器的软件仿真支持硬件协处理器的软件仿真 n除了用户模式外,其他模式均可视为特权模式除了用户模式外,其他模式均可视为特权模式梭尊藏恢躲萧橙喘形祷厢馆染作瞻糟纪狭缘拴淘牡孕饲临饭隶件事荤瓤升Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 移植规划(续)n任务模式的取舍 ARM7处理器核具有上述七种模式,其中除用户模式外其它均为特权模式。
其中管理、中止、未定义、中断和快中断模式与相应异常相联系,任务使用这些模式不太适合 系统模式除了是特权模式外,其它与用户模式一样,因而可选为任务使用的模式只有用户模式和系统模式 为了尽量减少任务代码错误对整个程序的影响,缺省的任务模式定为用户模式,可选为系统模式,同时提供接口使任务可以在这两种模式间切换骸凡菩窍岳惦管都楔贰帚谨骡砌平凤韶琢品瞳酶宠蔡寅缴烹富仍嘶恬蔗召Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植移植规划(续)n支持的指令集带T变量的ARM7处理器核具有两个指令集:标准32位ARM指令集16位Thumb指令集 两种指令集有不同的应用范围为了最大限度地支持芯片的特性,任务应当可以使用任意一个指令集并可以自由切换,而且不同的任务应当可以使用不同的指令集督遁孰椭鲸匿戎隐雄黔闻擅稚嘶尿俄嘉辱挤挥他莲析斋冷本挫验赎实刺参Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植移植μC/OS-IIn概述 要移植一个操作系统到一个特定的CPU体系结构并不是一件很容易的事情,它对移植者有以下要求:1. 对目标体系结构要有很深了解;2. 对OS原理要有较深入的了解;3. 对所使用的编译器要有较深入的了解;4. 对需要移植的操作系统要有相当的了解;5. 对具体使用的芯片也要一定的了解糟凯知俗渐领忠圈闹异疡萄娠骋僻恋赠弗碾毒彼抓兢挟汾逃雀师罪矛隘肮Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 要移植一个操作系统到一个特定的CPU体系结构上并不是一件很容易的事情,它对移植者有以下要求:1. 对目标体系结构要有很深了解;2. 对OS原理要有较深入的了解;3. 对所使用的编译器要有较深入的了解;4. 对需要移植的操作系统要有相当的了解;5. 对具体使用的芯片也要一定的了解。
n 概述 要移植一个操作系统到一个特定的CPU体系结构上并不是一件很容易的事情,它对移植者有以下要求:1. 对目标体系结构要有很深了解;2. 对OS原理要有较深入的了解;3. 对所使用的编译器要有较深入的了解;4. 对需要移植的操作系统要有相当的了解;5. 对具体使用的芯片也要一定的了解参考ARM公司的《ARM体系结构》文档参考《嵌入式实时操作系统μC/OS-II 》一书参考ADS软件自带的编译器和连接器手册参考《嵌入式实时操作系统μC/OS-II 》一书参考具体芯片的数据手册和使用手册因为第4点的影响是全局性的,它决定移植代码的框架和功能所以重点介绍第4点榷印荚配烙文肄囤谤晋爵绒划曹迹剪铃镰淀熊猖揣煤妨舔揣效渝确瘫明琅Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植主要内容移植规划μC/OS-II的移植嵌入式系统的初始化卑傅找采男姬处腹膘假帖咨吁村痒吞寇抱汹还酥湛韭施隐纫唐抱惰鸡坷琴Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植C/OS-II的文件结构霜词勤重熬青迟亡绕啸逸概禹哥烁预账饶冰勒涸修脖千圭抨宠偿凿抨看躁Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n μC/OS-II移植应用程序(用户代码)μC/OS-II(与处理器无关代码)OS_CORE.cOS_FLAG.c... μC/OS-II配置(与应用相关)OS_CFG.HINCLUDES.H μC/OS-II移植(与处理器相关代码)CPU定时器 硬件软件n——μC/OS-II硬件软件体系结构用于产生系统时钟移植时需要编写的代码务讼杯辽膜援编秤梗语即牺躯驭环伊掷菩拾层票斑迈毕赎忻妈恢斥鸳鼓岛Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植移植移植 C/OS-II满足的条件满足的条件 n处理器的C编译器能产生可重入代码 n在程序中可以打开或者关闭中断 n处理器支持中断,并且能产生定时中断(通常在10—100Hz之间) n处理器支持能够容纳一定量数据的硬件堆栈(通常是几千字节) n处理器有将堆栈指针和其他CPU寄存器的内容存储和读出到堆栈(或者内存)的指令 龄娱正临阿崩影漓估京呸永兵癸忽蒋健稠倪忿嫁翘辊磋塔崔浙筷言廷拓姜Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植什么是可重入代码什么是可重入代码 n可重入的代码指的是一段可以被多个任务同时调用,而不必担心会破坏数据的代码(比如:一个函数)n即:可重入型函数在任何时候都可以被中断执行,过一段时间以后又可以继续运行,而不会因为在函数中断的时候被其他的任务重新调用,而影响函数中的数据 艺兵寐富悬衡脱昆隘瑰孽孙办咐汕难漱常哼琢撮荡珍拢邻图厘洱页葬厄汕Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植可重入代码举例可重入代码举例程序1:可重入型函数void swap(int *x, int *y){int temp;temp=*x;*x=*y;*y=temp;}络辩疗狭厄孺挝蛹奖预说橱蝎锭图付靛纬算牵信凑瓷概价近仲头诗站瑰求Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植非可重入代码举例非可重入代码举例程序2:非可重入型函数int temp;void swap(int *x, int *y){temp=*x;*x=*y;*y=temp;}逝趣外溶求讣秤信予苇侄河孜抛匣溪细愉巡授般咯渴惮挥廖痔匀郸钡叮医Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植不可重入函数被中断破坏不可重入函数被中断破坏倡灭瑟沏串捶驯对厩环鸭悼纪氰凳笼药坠占贸皱宽踞曲韵溢挖蚂装虐撵七Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植如何使函数具有可重入性如何使函数具有可重入性 使Swap()函数具有可重入性的条件:n把Temp定义为局部变量n调用Swap()函数之前关中断,调用 后再开中断n用信号量禁止该函数在使用过程中 被再次调用谁跨敷颧诈含跃踪虞肄氢狗刹婚尉吮朵吹伙危雨修纠舆肤或睁场赢怠秋稼Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 概述 根据μC/OS-II的要求,移植μC/OS-II到一个新的体系结构上需要提供2个或3个文件: OS_CPU.H(C语言头文件) OS_CPU_C.C(C程序源文件) OS_CPU_A.ASM(汇编程序源文件) 其中OS_CPU_A.ASM在某些情况下不需要,但极其罕见。
不需要OS_CPU_A.ASM的必须满足以下苛刻条件: 1.可以直接使用C语言开关中断; 2.可以直接使用C语言编写中断服务程序; 3.可以直接使用C语言操作堆栈指针; 4.可以直接使用C语言保存CPU的所有寄存器 n——移植需要编写的文件跪窄袱玫翠用卧盯帚允辗趁雁啮侈诞清眼溅掂眶诈酚支层鸽作隆献佳闹赐Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 概述移植内容类型所属文件描述BOOLEAN、INT8U、INT8S、…数据类型OS_CPU.H与编译器无关的数据类型OS_STK数据类型OS_CPU.H堆栈的数据类型OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()宏OS_CPU.H开关中断的代码OS_STK_GROWTH常量OS_CPU.H定义堆栈的增长方向OS_TASK_SW函数OS_CPU.H任务切换时执行的代码OSTaskStkInit()函数OS_CPU_C.C任务堆栈初始化函数OSInitHookBegin()、OSInitHookEnd()、…函数OS_CPU_C.CμC/OS-II在执行某些操作时调用的用户函数,一般为空OSStartHighRdy()函数*OS_CPU_A.ASM进入多任务环境时运行优先级最高的任务, OSIntCtxSw()函数*OS_CPU_A.ASM中断退出时的任务切换函数OSTickISR()中断服务程序*OS_CPU_A.ASM时钟节拍中断服务程序 实际上,还有一个文件很重要,它就是IRQ.INC,它定义了一个汇编宏,它是μC/OS-II for ARM7通用的中断服务程序的汇编与C函数接口代码。
时钟节拍中断服务程序也没有移植,因为其与芯片和应用都强烈相关,需要用户自己编写,不过可以通过IRQ.INC简化用户代码的编写 n——移植代码包括的主要内容晴危逃缩欠饱箕芳退雅亮第猴宴挖额挝纳矽疽熬歌杖屉俊惜玩倍前误跳饵Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n关于头文件includes.h和config.h μC/OS-II要求所有.C文件的都要包含头文件includes.h,这样使得用户项目中的每个.C文件不用分别去考虑它实际上需要哪些头文件 使用INCLUDES.H的缺点是它可能会包含一些实际不相关的头文件,这意味着每个文件的编译时间可能会增加,但却增强了代码的可移植性 在移植中另外增加了一个头文件config.h,要求所有用户程序必须包含config.h,在config.h中包含includes.h和特定的头文件和配置项而μC/OS-II的系统文件依然只是包含includes.h,即μC/OS-II的系统文件完全不必改动所有的配置改变包括头文件的增减均在config.h中进行,而includes.h定下来后不必改动(μC/OS-II的系统文件需要包含的东西是固定的)。
这样,μC/OS-II的系统文件需要编译的次数大大减少,编译时间随之减少 congfig.hUC/OS内核文件Includes.h用户程序扯混描烹唇精蹬笋搐炬雪常粱奄吠雪抖蒜钓架摸稚绝炒迈芜魄谍蹈静狰熔Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植设置与处理器和编译器相关的代码设置与处理器和编译器相关的代码nOS_CPU.H中定义了与编译器相关的数据类型比如:INT8U、INT8S等n与 ARM处理器相关的代码,使用OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL() 宏开启/关闭中断n设置堆栈的增长方向 :堆栈由高地址向低地址增长 烙疼桌疫锥暇延间腐镍态植菊戮寇鼎桑褂曼臭域酗祖嘎李品她布朴菏釉毫Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU.H μC/OS-II使用结构常量OS_STK_GROWTH中指定堆栈的生长方式:置OS_STK_GROWTH为0表示堆栈从下往上长 置OS_STK_GROWTH为1表示堆栈从上(高地址)往下(低地址)长。
虽然ARM处理器核对于两种方式均支持,但ADS的C语言编译器仅支持一种方式,即从上往下长,并且必须是满递减堆栈,所以OS_STK_GROWTH的值为1define OS_STK_GROWTH 1 n——堆栈生长方式插遂魂悍曹拆辑肛精灾谗巨助主梯翱翘胃城槽瓶鼎缘质监抽赦化荆牙新派Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU.H μC/OS-II不使用C语言中的short、int、long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性代之以移植性强的整数数据类型,这样,既直观又可移植,不过这就成了必须移植的代码根据ADS编译器的特性,这些代码如下程序清单所示(与编译有关)typedefunsigned char BOOLEAN; typedefunsigned char INT8U;typedefsigned char INT8S;typedefunsigned short INT16U;typedefsigned short INT16S;typedefunsigned int INT32U;typedefsigned int INT32S;typedeffloat FP32;typedefdouble FP64;typedefINT32U OS_STK;n——不依赖于编译的数据类型没睁听檀体猴递恃粉祷贪溺翅启怒嗽坷蜘装奈氛诊毒蚁邱准锌跃尾癣令守Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植设置设置includes.htypedef unsigned char BOOLEAN;typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned int INT16U; typedef signed int INT16S; typedef unsigned long INT32U; typedef signed long INT32S; typedef float FP32; typedef double FP64; typedef unsigned long OS_STK; typedef unsigned long OS_CPU_SR; extern int INTS_OFF(void); extern void INTS_ON(void);#define OS_ENTER_CRITICAL() { cpu_sr = INTS_OFF(); }#define OS_EXIT_CRITICAL() { if(cpu_sr == 0) INTS_ON(); }#define OS_STK_GROWTH 1 /*从高向低*/儒厚钧铭奔版谓顽紫扦品缩汾缨棋谐襄敛肢猜翻汤擞喀哗炯涡幽甭疏橙靠Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植程序状态寄存器程序状态寄存器((CPSR)n 条件位条件位:nN = 1-结果为负,0-结果为正或0nZ = 1-结果为0,0-结果不为0nC =1-进位,0-借位nV =1-结果溢出,0结果没溢出nQ Q 位位:n仅ARM 5TE/J架构支持n指示增强型DSP指令是否溢出nJ J 位位n仅ARM 5TE/J架构支持nJ = 1: 处理器处于Jazelle状态n中断禁止位中断禁止位:nI = 1: 禁止 IRQ.nF = 1: 禁止 FIQ.nT BitT Bitn仅ARM xT架构支持nT = 0: 处理器处于 ARM 状态nT = 1: 处理器处于 Thumb 状态nModeMode位位( (处理器模式位处理器模式位):):n0b10000Usern0b10001FIQn0b10010IRQn0b10011Supervisorn0b10111Abortn0b11011Undefinedn0b11111System2731N Z C V Q2867I F T mode1623 815 54024fsxc U n d e f i n e dJ妙眨矣象路讶牧篙割瓮狙良姚第辆洪闻佯敲歌纪岩仕意担殴肾贮哭鹅堪廉Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU.H μC/OS-II运行时,处理器可能处于的模式如下图所示:n——使用软中断SWI作底层接口Thumb指令集ARM指令集用户模式系统模式用户任务使用的处理器模式ARM7内核具有的指令集ARM指令用户模式ARM指令系统模式Thumb指令系统模式Thumb指令用户模式变码俗牛窜疮膏乳薛尖蹬挺垒茧轿擦月猩咬小见钒歌敞铅访柠赁啄兢哄塑Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU.H 为了使底层接口函数与处理器状态无关,同时在任务调用相应的函数不需要知道函数位置,在移植中使用软中断指令SWI作为底层接口,使用不同的功能号区分不同的函数。
软中断功能号分配如下表所示,未列出的为保留功能 n——使用软中断SWI作底层接口功能号接口函数简介0x00void OS_TASK_SW(void)任务级任务切换函数0x01_OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02void OS_ENTER_CRITICAL(void)关中断0x03Void OS_EXIT_CRITICAL(void)开中断0x80Void ChangeToSYSMode(void)任务切换到系统模式0x81Void ChangeToUSRMode(void)任务切换到用户模式0x82Void TaskIsARM(INT8U prio)任务代码是ARM代码0x83Void TaskIsTHUMB(INT8U prio)任务代码是THUMB代码氰跪颖澡辜颈分艳品富会样援滤涕呜徽翘牡盖等炊呛虑沏谩钠紧站皱趟参Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU.H 用软中断作为操作系统的底层接口就需要在C语言中使用SWI(SoftWare Interrupt)指令。
在ADS中,有一个关键字__swi,用它声明一个不存在的函数,则调用这个函数就在调用这个函数的地方插入一条SWI指令,并且可以指定功能号同时,这个函数也可以有参数和返回值,其传递规则与一般函数相同 n——使用软中断SWI作底层接口/* 任务级任务切换函数 */__swi(0x00) void OS_TASK_SW(void); /* 运行优先级最高的任务 */__swi(0x01) void _OSStartHighRdy(void); /* 关中断 */__swi(0x02) void OS_ENTER_CRITICAL(void); /* 开中断 */__swi(0x03) void OS_EXIT_CRITICAL(void); /* 任务切换到系统模式 */__swi(0x80) void ChangeToSYSMode(void); /* 任务切换到用户模式 */__swi(0x81) void ChangeToUSRMode(void); /* 任务代码是ARM代码 */__swi(0x82) void TaskIsARM(INT8U prio);/* 任务代码是THUMB代码 */__swi(0x83) void TaskIsTHUMB(INT8U prio);程序中调用软中断时使用的函数名软件中断号该调用不返回参数抨盂茁道膘凋瀑拒衰育荤掺搞糯和蒜据遂筐脸飘揍和祭掷侧僻逢烃篮养痴Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植编写OS_CPU_C.CnμC/OS-IIμC/OS-II的移植要求用户编写的移植要求用户编写1010个个C C函数:函数:nOSTaskStkInitOSTaskStkInit():(): OSTaskCreat OSTaskCreat()和()和OSTaskCreatExtOSTaskCreatExt()通过调用()通过调用 本函数,初始化任务的栈结构本函数,初始化任务的栈结构nOSTaskCreateHookOSTaskCreateHook():每当添加任务时由():每当添加任务时由OS_TCBInit( )OS_TCBInit( )函数调用函数调用nOSTaskDelHookOSTaskDelHook():(): 任务被删除后由任务被删除后由OSTaskDelOSTaskDel()调用()调用nOSTaskSwHookOSTaskSwHook():(): 任务切换时两种情况均会调用该函数任务切换时两种情况均会调用该函数nOSTaskIdleHookOSTaskIdleHook():():OSTaskIdleOSTaskIdle()函数可调用该函数实现()函数可调用该函数实现CPUCPU低功耗模式低功耗模式nOSTimeTickHookOSTimeTickHook():本函数在每个时钟节拍都会被():本函数在每个时钟节拍都会被OSTimeTickOSTimeTick()调用()调用nOSInitHookBeginOSInitHookBegin():进入():进入OSInitOSInit()函数后本函数会立即被调用()函数后本函数会立即被调用nOSInitHookEndOSInitHookEnd():(): OSInit OSInit()函数返回之前被调用()函数返回之前被调用nOSTCBInitHookOSTCBInitHook():():OS_TCBInit( )OS_TCBInit( )在调用在调用OSTaskCreateHookOSTaskCreateHook()之前将先()之前将先 调用本函数调用本函数n唯一必要的函数是唯一必要的函数是OStaskStkInitOStaskStkInit(),其他(),其他9 9个函数必须声明,但不一定个函数必须声明,但不一定要包含任何代码要包含任何代码吱虱拿别取鄂琐善杆们巍答馏蛮钙警扁浦箱疯邹绍庭幌伴蛆耍菌诸塑元傻Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.C 该函数用于初始化任务堆栈,使任务的堆栈看起来就像刚发生中断一样。
即任务被执行时,就像从中断返回一样 在编写此函数之前,必须先确定任务的堆栈结构而任务的堆栈结构是与CPU的体系结构、编译器有密切的关联本移植的堆栈结构如下图所示 n——OSTaskStkInit( )任务入栈的其它数据LRR12R11R10R9R8... 栈底 任务环境开始 SPPCR2R1R0OSEnterSum空闲空间词镍栽猴柔喇瘟社砍瑚立醇瘤撑怜据踩软峙燎车搀师懊巨虞税旦嫉摸买刻Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——OSTaskStkInit( )OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt){ OS_STK *stk; opt = opt; stk = ptos; *stk = (OS_STK) task; *--stk = (OS_STK) task; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = (unsigned int) pdata; *--stk = (USER_USING_MODE|0x00); *--stk = 0; return (stk);} 入栈的数据任务入栈的其它数据LRR12R11R10R9R8... 栈底 任务环境开始 SPPCR2R1R0OSEnterSum空闲空间疥沉晚稀勿汛指赡渝半轰瞩灰溺邮沾沿朋总稍殷语荐揣谦虫邑汾胁驳激纯Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——OSTaskStkInit( )OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt){ OS_STK *stk; opt = opt; stk = ptos; *stk = (OS_STK) task; *--stk = (OS_STK) task; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = 0; *--stk = (unsigned int) pdata; *--stk = (USER_USING_MODE|0x00); *--stk = 0; return (stk);} 该数据比较特别,它用于保存该任务关中断的次数,它在调用OS_ENTER_CRITICAL( )时加1,在调用OS_EXIT_CRITICAL( )时减1。
这样每个任务都可以独立控制本任务的中断允许状态,而不会影响其它任务的中断允许状态因此关中断和开中断就可以嵌套 榆棵嚏蓝程张勋悄郎峨酱径励搽惹癸卧蔗喷撅舔膳孰香冗畜揖邹函珠粟柔Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序 操作系统与硬件相关的底层函数使用软件中断作为接口,如下表所示 移植代码中一个重要的工作就是为这些软件中断编写服务程序功能号接口函数简介0x00void OS_TASK_SW(void)任务级任务切换函数0x01_OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02void OS_ENTER_CRITICAL(void)关中断0x03Void OS_EXIT_CRITICAL(void)开中断0x80Void ChangeToSYSMode(void)任务切换到系统模式0x81Void ChangeToUSRMode(void)任务切换到用户模式0x82Void TaskIsARM(INT8U prio)任务代码是ARM代码0x83Void TaskIsTHUMB(INT8U prio)任务代码是THUMB代码釜燃肤肄部澄泣期堵幅锹炙聘滥县旦国吨段配邪杏剐唇橇壤拎瞅蛋跳梦姨Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码功能号接口函数简介0x00void OS_TASK_SW(void)任务级任务切换函数0x01_OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02void OS_ENTER_CRITICAL(void)关中断0x03Void OS_EXIT_CRITICAL(void)开中断0x80Void ChangeToSYSMode(void)任务切换到系统模式0x81Void ChangeToUSRMode(void)任务切换到用户模式0x82Void TaskIsARM(INT8U prio)任务代码是ARM代码0x83Void TaskIsTHUMB(INT8U prio)任务代码是THUMB代码void SWI_Exception(int SWI_Num, int *Regs){ OS_TCB *ptcb; switch(SWI_Num) { case 0x02: // 关中断 ... case 0x03: // 开中断 ... case 0x80: // 任务切换到系统模式 ... case 0x81: // 任务切换到用户模式 ... case 0x82: // 任务代码是ARM代码 ... case 0x83: // 任务代码是Thumb代码 ... default: }}这两个软件中断使用汇编代码完成贰观玄吝刑瞪湃恭但鲜朱芍医痢钨估悸径盒呢扎狞呸戒辙忻巳媚具涡粕佣Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码 μC/OS-II的启动多任务环境的函数叫做OSStart(),用户在调用OSStart()之前,必须已经建立了一个或更多任务。
OSStart()最终调用函数OSStartHighRdy()运行多任务启动前优先级最高的任务 void OSStartHighRdy(void) { _OSStartHighRdy(); } 该函数在Os_cpu_a.s文件中实现鸽挡猖羡炔泞秽按揍搏向审引淤汀蓖布午漠戍冶涡油赤稍硼娟缆陡姬闯屹Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码 关中断和开中断是为了保护临界段代码这些代码与处理器有关,是需要移植的代码在ARM处理器核中关中断和开中断时通过改变程序状态寄存器CPSR中的相应控制位实现由于使用了软件中断,程序状态寄存器CPSR保存到程序状态保存寄存器SPSR中,软件中断退出时会将SPSR恢复到CPSR中,所以程序只要改变程序状态保存寄存器SPSR中的相应的控制位就可以了。
鼎帧院孙铂痕船酌猿执貌春移呛凶羞及绢魔蚊意戏澎梗葫恩惯迭轴笛饲拔Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码void SWI_Exception(int SWI_Num, int *Regs){ ... case 0x02: // 关中断 __asm { MRS R0,SPSR ORR R0,R0,#NoInt MSR SPSR_c,R0 } OsEnterSum++; break; case 0x03: // 开中断 if (--OsEnterSum == 0) { __asm { MRS R0,SPSR BIC R0,R0,#NoInt MSR SPSR_c,R0 } } break; ...每关闭一次中断,中断关闭计数器加1每调用一次开中断函数,该计数器减1,为0时允许打开中断关闭中断打开中断钾践媳绎临疥荔挺吨斌丽淋蹦绎辗怂思狰镁酣部蜜剂屁炸精慨财夺悠激猿Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码 它们可以在任何情况下使用。
它们改变程序状态保留寄存器程序状态保留寄存器SPSRSPSR的相应位段,而程序状态保留寄存器会在软件中断退出时复制到程序状态寄程序状态寄存器存器CPSRCPSR,任务的处理器模式就改变了 怎船侦丘贱些另尖须玉幼灿赣想礼韦阑倘故淡醚鲜烬至敬菩单伎阎郧标了Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码void SWI_Exception(int SWI_Num, int *Regs){ ... case 0x80: // 任务切换到系统模式 __asm { MRS R0,SPSR BIC R0,R0,#0x1f ORR R0,R0,#SYS32Mode MSR SPSR_c,R0 } break; case 0x81: // 任务切换到用户模式 __asm { MRS R0,SPSR BIC R0,R0,#0x1f ORR R0,R0,#USR32Mode MSR SPSR_c,R0 } break; ...使用内嵌汇编将处理器模式切换到用户模式使用内嵌汇编将处理器模式切换到系统模式堕十初履疏久羡付粕来缓用峙沁佩淬沉赫碱和筒涯塌诺距沿镜饿壹枫茧样Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码 任务可以使用ARM的两种指令集的任意一种运行,但是任务建立时默认的只是一种指令集。
如果任务使用的第一条指令与默认的指令集不同,则程序运行错误所以增加两个函数TaskIsARM()和TaskIsTHUMB()用于改变任务建立时用于改变任务建立时默认的指令集默认的指令集 它们都有唯一的参数:需要改变的任务的优先级,值得注意的是,这两个函数必须在相应的任务建立后但还没有运行时调用 瘦荷据早氟陋裂恕衙获有掘仿耍稍耳仅胎双彦为狼围寐缺寅摸帛磺骸阵窜Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码 ... case 0x82: // 任务代码是ARM代码 if (Regs[0] <= OS_LOWEST_PRIO) { ptcb = OSTCBPrioTbl[Regs[0]]; if (ptcb != NULL) { ptcb -> OSTCBStkPtr[1] &= ~(1 << 5); } } break; case 0x83: // 任务代码是Thumb代码 if (Regs[0] <= OS_LOWEST_PRIO) { ptcb = OSTCBPrioTbl[Regs[0]]; if (ptcb != NULL) { ptcb -> OSTCBStkPtr[1] |= (1 << 5); } } break; ...被设置的任务号一定不能大于最低优先级任务获取指定任务的任务控制块的地址修改任务堆栈中CPSR的值,在任务重新运行时,切换到ARM指令方式修改任务堆栈中CPSR的值,在任务重新运行时,切换到Thumb指令方式CPSR:程序状态寄存器闲窝雄芥淖畴躇船依浪说铝抑魏绎昔祖筛见掐熏流怨猜辑第罗种睬识姚余Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.Cn——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码注意: 这两个函数必须在相应的任务建立后但还没有运行时调用。
如果在低优先级的任务中创建高优先级的任务就十分危险了此时,解决的方法有三种:(1)高优先级任务使用默认的指令集;(2)改变函数OSTaskCreateHook()使任务默认不是处于就绪状态,建立任务后调用函数OSTaskResume()来使任务进入就绪状态;(3)建立任务时禁止任务切换,调用函数 TaskIsARM()或TaskIsTHUMB()后再允许任务切换谐芯捡婿先日嫌霖钠皱贪揽薛孵豢惦圭粹络笔级啸迸涎吱掏朝踪贤酶树韧Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n编写OS_CPU_C.C 在Os_cpu_c.c文件中还有许多Hook()函数,它们在某个特定的系统动作时被调用,允许执行函数中的用户代码这些函数默认是空函数,用户根据实际情况添加相关代码它们分别如下表所示n——…Hook( )函数函数名被执行条件OSInitHookBegin( )在开始执行OSInit( )函数时被执行OSInitHookEnd( )在OSInit()函数结束时被执行OSTaskCreateHook( )在任务建立时被调用OSTaskDelHook( )在任务删除时被调用OSTaskSwHook( )在进行任务切换时被调用OSTaskStatHook( )被统计任务调用,每秒执行一次OSTCBInitHook( )在建立所有的TCB后,由OSTCBInit函数调用OSTimeTickHook( )每个时钟节拍产生后被调用OSTaskIdleHook( )由空闲任务调用豁激犁佃揭劳矫皇亨盏寝酞衔札弘掀嚷味宠车整凑拖磺伐坐酌臆吹壶旬脑Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 移植μC/OS-IIn编写OS_CPU_A.ASM在OS_CPU_A.ASM文件中有:软件中断的汇编接口程序任务切换程序OS启动时运行就绪最高优先级任务的程序廷隐去狙卿卉女净沸系须赖矛打陌侩轮绣山挟送拦捶滁尹涂净旺禽奈障叭Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植OS_CPU_A.ASMnμC/OS-II的移植要求用户编写4个汇编语言函数:nOSStartHighRdy()nOSCtxSw()nOSIntCtxSw()nOSTickISR()n如果编译器支持插入行汇编代码,就可以将所有与处理器相关的代码放到OS_CPU_C.C文件中,而不必再有单独的汇编语言文件伞引溅任轰哩疚撑躯丈猩垄劫塞敝洋采版方碟东他腔翘徒柄返来篷舒赁箩Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU_A.ASM 在调用软中断之后,处理器切换到ARM指令和管理模式下工作。
在执行软件中断服务函数之前,要提取中断号和其它入口参数,这些通过软件中断接口程序完成n——软件中断汇编接口SoftwareInterrupt LDR SP, StackSvc STMFD SP!, {R0-R3, R12, LR} MOV R1, SP MRS R3, SPSR TST R3, #T_bit LDRNEH R0, [LR,#-2] BICNE R0, R0, #0xff00 LDREQ R0, [LR,#-4] BICEQ R0, R0, #0xFF000000 CMP R0, #1 LDRLO PC, =OSIntCtxSw LDREQ PC, =__OSStartHighRdy BL SWI_Exception LDMFD SP!, {R0-R3, R12, PC}^ 保护被中断的现场将要用到的寄存器压栈判断中断前的指令集类型从产生软件中断的指令中提取中断号ARMThumb根据不同的中断号执行不同的程序返回被中断的任务中断号执行程序0进行任务切换1启动多任务环境,运行就绪的最高优先级任务其它软件中断服务函数轿伏杰甚梯帕堪捶碑耙力帘疡叠暇赋慢攒铂啥金蠕闻粕藕码孟坠薄低幂磁Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU_A.ASM μC/OS-II是抢占式实时操作系统,得到运行的始终是就绪条件下最高优先级的任务。
当处于运行状态的任务因为某种原因进入就绪态,或者有其它更高优先级的任务进入就绪态,操作系统内核就要运行别的就绪任务,这时需要进行任务切换 n——任务切换代码量忧雇孵藐纷龄朗笺卵胰帖踪铅装外头簧漠乏痴烩记芽氢蛾敦蘑洒磊蝇岳Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植编写OS_CPU_A.ASM ——任务切换代码任务切换可能发生的情况有两种任务切换可能发生的情况有两种: 1.当前运行的任务主动交出CPU控制权,通常发生在等待某个事件或是调用系统延时调用函数OS_TASK_SW( ) 2.发生中断,使更高优先级的任务进入就绪状态,内核剥夺当前任务的运行资格即发生在中断退出时调用函数OSIntCtxSw( )你湍死拯拙淖帛摘潘秃肖所荤默垢悯脓段絮艇防诅销哺乡无岗椅办厨杨弯Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植SPSR:程序状态保留寄存器CPSR:当前程序状态寄存器n 编写OS_CPU_A.ASM 虽然OS_TASK_SW( )和OSIntCtxSw( )的执行条件不同,但是它们的功能相同,只要稍作处理就可以它们共用一段任务切换代码。
这些处理就是保证在执行任务切换前两者的任务现场是一致的共同执行的任务切换代码是“OSIntCtxSw” 其中OS_TASK_SW( )是通过软件中断0完成的,通过前面的分析,可以知道执行任务切换时的现场环境如下所示,同时R3中保存着SPSR,它是任务中断前CPSR的备份n——任务切换代码任务入栈的其它数据LRR12R3R2R1R0空闲空间 栈底 任务环境开始 SP参殉笼寨徘澜担守瞎录谤寞毯凶椭饵甥身戚于巍鸿洞迂侯雄售将肘冒堵龙Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU_A.ASMn——OSIntCtxSw保存当前任务的寄存器组及其它修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur恢复新任务的寄存器组及其它运行新任务流程图顾拾筐悲抉毗碎淄慷减斡饥梢因跺虑墙匿配盖线红忱脸听哮币枫递篷庄宗Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU_A.ASMn——OSIntCtxSw保存当前任务的寄存器组及其它修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur恢复新任务的寄存器组及其它运行新任务流程图OSIntCtxSw ;下面为保存任务环境 LDR R2, [SP, #20] ;获取PC LDR R12, [SP, #16] ;获取R12 MRS R0, CPSR ;保存LR,PC及R4-R12 MSR CPSR_c, #(NoInt | SYS32Mode) MOV R1, LR STMFD SP!, {R1-R2} STMFD SP!, {R4-R12} ;获取R0-R3,并出栈R12和PC寄存器 MSR CPSR_c, R0 LDMFD SP!, {R4-R7} ADD SP, SP, #8 ;保存R0-R3 MSR CPSR_c, #(NoInt | SYS32Mode) STMFD SP!, {R4-R7} ;获取OsEnterSum,并保存CPSR,OsEnterSum LDR R1, =OsEnterSum LDR R2, [R1] STMFD SP!, {R2, R3} ...PCLRR12R11R10R9R7R5R4R3R2R1R0R6R8CPSROSEnterSum切换至系统模式获取任务运行时的各寄存器并将它们压栈恢复之前的模式读出压栈的数据任务环境保存结束后的栈结构楷滥汉诌蚌穿谎约侈恫忠茎挫酋仿儡粟傈咋丈矮原廓磊谭卫阻梭温核甩逻Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU_A.ASMn——OSIntCtxSw修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur保存当前任务的寄存器组及其它恢复新任务的寄存器组及其它运行新任务锰类代茎体娥确伞奎氟醛沈砸钢衔望煞甥随瞄毅群绅盒凸层友财言钨碗憾Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植OSIntCtxSw ... ;保存当前任务堆栈指针到当前任务的TCB LDR R1, =OSTCBCur LDR R1, [R1] STR SP, [R1] BL STaskSwHook ;调用钩子函数 ;OSPrioCur <= OSPrioHighRdy LDR R4, =OSPrioCur LDR R5, =OSPrioHighRdy LDRB R6, [R5] STRB R6, [R4] ;OSTCBCur <= OSTCBHighRdy LDR R6, =OSTCBHighRdy LDR R6, [R6] LDR R4, =OSTCBCur STR R6, [R4] ...n 编写OS_CPU_A.ASMn——OSIntCtxSw用即将运行任务的TCB指针更新OSTCBCur变量用即将运行任务的优先级更新OSPrioCur变量撞该沁驾们臭旅恭恒延坤超犯诞拄抱屡凰甚驭丈竿涟仗尖舰咒喧穿妨疟寿Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 编写OS_CPU_A.ASMn——OSIntCtxSw恢复新任务的寄存器组及其它运行新任务保存当前任务的寄存器组及其它修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur劲璃酬撩详驱汹刷监鸦脾村抢皆讨拈污慈婉坑狐副殿敌辣膀脚擦鱼面馏识Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植OSIntCtxSw ...OSIntCtxSw_1 ;从R6指向TCB中获取新任务堆栈指针 LDR R4, [R6] ;调整堆栈指针 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP ADD SP, R4, #68 LDR LR, [SP, #-8] ;进入管理模式,恢复任务的各寄存器和变量 MSR CPSR_c, #(NoInt | SVC32Mode) MOV SP, R4 ;设置堆栈指针 ;获取CPSR和OsEnterSum LDMFD SP!, {R4, R5} ;恢复新任务的OsEnterSum LDR R3, =OsEnterSum STR R4, [R3] ;恢复CPSR MSR SPSR_cxsf, R5 ;运行新任务 LDMFD SP!, {R0-R12, LR, PC }^n 编写OS_CPU_A.ASMn——OSIntCtxSw恢复新任务的各寄存器运行新任务这段代码还被__OSStartHighRdy函数调用,用于启动最高优先级的就绪任务侯钩暮惶患白嚣如凤狄呸撩畦模据撑件越蛆赚诱钎就弃虫刨同速狂社胃摧Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植__OSStartHighRdy MSR CPSR_c, #(NoInt | SYS32Mode) ;告诉uC/OS-II自身已经运行 LDR R4, =OSRunning MOV R5, #1 STRB R5, [R4] ;调用钩子函数 BL OSTaskSwHook LDR R6, =OSTCBHighRdy ;取得新任务的TCB指针 LDR R6, [R6] B OSIntCtxSw_1 n 编写OS_CPU_A.ASMn——OSStartHighRdy μC/OS-II的多任务环境由函数OSStart( ) 启动。
用户在调用该函数之前,必须已经建立了一个或更多任务OSStart()最终调用函数OSStartHighRdy( )运行多任务启动前优先级最高的任务,而它最终是调用__OSStartHighRdy实现的,其代码如下所示:奋红苯陡癣升衬砖刚遮诚沙季枣挤枯馒益哥针羌武免模矣懦较赔爪勉廊召Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植OS_CPU_A.ASM文件文件n 编写OS_CPU_A.ASM 通过前面的分析,我们可以画出下面这张结构图:中断退出时任务切换xxx_Handler任务级任务切换OS_TASK_SW()启动多任务OSStartHighRdy()OSIntCtxSw_OSStartHighRdyOSIntCtxSw_1绳暖墓宜僧表网腾象谊瞬见堪委旱堪景诚堵馁施撇骆枝爵砸飘运俗狭匿盖Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植移植μC/OS-IIn关于中断及时钟节拍 在本移植中,IRQ是受μC/OS-II管理的中断,而对于FIQ不做处理,这是为了提高FIQ的响应速度。
由于各种ARM芯片的中断系统不一样,各个用户的目标板也不一样,对于中断和时钟节拍是需要进一步移植的代码为此编写一个汇编宏,它是μC/OS-II for ARM7通用的中断服务程序的汇编与C函数接口代码 注:在不受管理的中断服务程序中不能调用任何系统函数悟轮汛率竞促痊幂糕厦捡却狠凶前躇盈临慌府镣痘苯姓抄淀燥歹垢汲莉掖Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 关于中断及时钟节拍流程图保存当前任务的寄存器组中断嵌套数加1切换到系统模式执行中断服务程序关中断执行OSIntExit( )切换到IRQ模式判断是否需要进行任务切换切换任务或返回侗掏缩卷幂诊死氟懈乃盎哎庇兢尝椭鳃答橇也峡交院个裁刊厩肤多涟啪吞Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 关于中断及时钟节拍流程图保存当前任务的寄存器组中断嵌套数加1切换到系统模式执行中断服务程序关中断执行OSIntExit( )切换到IRQ模式判断是否需要进行任务切换切换任务或返回悦告咐咎烤殊真甸绞走韶傅隙索糟商求居蔡隋镑违臀涨胚血剑芯丁筑墒裴Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 MACRO$IRQ_Label HANDLER $IRQ_Exception_Function EXPORT $IRQ_Label ; 输出的标号 IMPORT $IRQ_Exception_Function ; 引用的外部标号$IRQ_Label SUB LR, LR, #4 ; 计算返回地址 STMFD SP!, {R0-R3, R12, LR} ; 保存任务环境 MRS R3, SPSR ; 保存状态 ; 保存用户状态的R3,SP,LR,不能回写 STMFD SP, {R3, SP, LR}^ LDR R2, =OSIntNesting LDRB R1, [R2] ADD R1, R1, #1 STRB R1, [R2] SUB SP, SP, #4*3 ; 切换到系统模式 MSR CPSR_c, #(NoInt | SYS32Mode) CMP R1, #1 LDREQ SP, =StackUsr ...n 关于中断及时钟节拍中断嵌套层数加1切换到系统模式,如果是第一次中断还要设置堆栈指针压栈保存被中断任务的运行环境蚀川举腆透虽挟眉换抗釉凑宝睛免持鲸恳框兵助惊姜芒胚搪布蝎秤本皋骏Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 关于中断及时钟节拍流程图保存当前任务的寄存器组中断嵌套数加1切换到系统模式执行中断服务程序关中断执行OSIntExit( )切换到IRQ模式判断是否需要进行任务切换切换任务或返回中断服务程序(ISR)在ISR中可以打开中断实现中断嵌套董炬矽匀顾槛发郭坡棚租魔汉琉彦探墙粘丸鹤图蹿罪鸳绩悟从踩苫挛抹茄Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 MACRO$IRQ_Label HANDLER $IRQ_Exception_Function EXPORT $IRQ_Label ; 输出的标号 IMPORT $IRQ_Exception_Function ; 引用的外部标号$IRQ_Label ... BL $IRQ_Exception_Function ; 切换到系统模式 MSR CPSR_c, #(NoInt | SYS32Mode) ; OsEnterSum,使OSIntExit退出时中断关闭 LDR R2, =OsEnterSum MOV R1, #1 STR R1, [R2] BL OSIntExit ; 因为中断服务程序要退出,所以OsEnterSum=0 LDR R2, =OsEnterSum MOV R1, #0 STR R1, [R2] ; 切换回irq模式,并恢复用户状态的R3,SP,LR MSR CPSR_c, #(NoInt | IRQ32Mode) LDMFD SP, {R3, SP, LR}^ ; 注意不能回写 ...n 关于中断及时钟节拍关闭中断执行中断服务程序(ISR)使OSEnterSum为1,防止在OSIntExit函数中打开中断通知系统,中断退出使OSEnterSum为0,运行中断打开恢复任务的R3、SP和LR汀锦常缝锄斥若撑灸盆逐筏寡铺婚尺藤育泞坠愈伟旅墟阀淡蓬捧丫收洛目Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 关于中断及时钟节拍流程图保存当前任务的寄存器组中断嵌套数加1切换到系统模式执行中断服务程序关中断执行OSIntExit( )切换到IRQ模式判断是否需要进行任务切换切换任务或返回胰注蔼依扛尧并球填旱生刁昌兜臼携潦唬倦酮鸽渭忠许碗眼录锁滑症蛰佐Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植 MACRO$IRQ_Label HANDLER $IRQ_Exception_Function EXPORT $IRQ_Label ; 输出的标号 IMPORT $IRQ_Exception_Function ; 引用的外部标号$IRQ_Label ... LDR R0, =OSTCBHighRdy LDR R0, [R0] LDR R1, =OSTCBCur LDR R1, [R1] CMP R0, R1 ADD SP, SP, #4*3 MSR SPSR_cxsf, R3 ; 不进行任务切换 LDMEQFD SP!, {R0-R3, R12, PC}^ ; 进行任务切换 LDR PC, =OSIntCtxSw MENDn 关于中断及时钟节拍比较当前任务是否为就绪的最高优先级任务,如果不是则进行切换设置堆栈指针和恢复SPSR进行任务切换或者恢复执行被中断任务铃擒陶镊嘲梆凤砸读谜浅水蚊透唁底许叶粘潮击沤火退甘屹度椒鄙衣懈衬Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植n 关于中断及时钟节拍流程图保存当前任务的寄存器组中断嵌套数加1切换到系统模式执行中断服务程序关中断执行OSIntExit( )切换到IRQ模式判断是否需要进行任务切换切换任务或返回中断服务程序(ISR)在ISR中可以打开中断实现中断嵌套叭迸邹泣航亨逝姻珊迸以琅论费煎兢寻或欣醚音金掂妻躯淘搞耐宗章摩室Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植void ISR(void){ OS_ENTER_CRITICAL()或直接给变量OsEnterSum赋1; 清除中断源; 通知中断控制器中断结束: 开中断: OS_EXIT_CRITICAL(); 用户处理程序;}n 中断服务程序的编写 因为中断发生时肯定是允许中断的,所以如果用户在清除中断源之前调用μC/OS-II的系统服务函数就很可能会造成芯片的中断系统工作异常而使程序工作异常。
因此在函数开始处关闭中断,或者直接给变量OSEnterSum赋1如果用户程序没有这种情况,则不需要这个操作在执行OS_EXIT_CRITICAL( )后,中断重新打开,如果在接下来的用户处理程序中发生中断,就可以实现中断嵌套址严待醇嫌狞纷龟币章绊熏伸爷垃绊诡遇穴瀑焉袜吩蝗喇键导漠冷医代余Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植主要内容移植规划μC/OS-II的移植嵌入式系统的初始化分枫簇咬职画珐尼云肯老哟昌例骸帽辩悯汤卡早兰卯竣返碉宗燕它虱敷喧Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植初始化程序的下载执行初始化程序的下载执行目标机宿主机1)通过编程器将可执行目标文件烧写到BootROM(ROM、EPROM、FLASH)等;2)通过串行口和网口下载执行目标文件,要求宿主机系统上有数据传输工具程序、目标机装载器、嵌入式监视器或目标机系统上的调试代理3)通过JTAG或BDM接口下载;熄瀑设官夕歉贰太茸目洲汉蛾苏争媚匝琉诈吾抠屡娄修砂担芯碍谢榴侧署Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植嵌入式系统的初始化过程嵌入式系统的初始化过程谴竭企兑酗漳肤鞋证躁兴曝眉鞭述茹折泄摊宠鬃耕据主镁樱误杯社痘蜒音Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植嵌入式系统的初始化过程嵌入式系统的初始化过程硬件初始化阶段1、复位向量 ENTRY b ResetHandler ;for debug b HandlerUndef ;handlerUndef b HandlerSWI ;SWI interrupt handler b HandlerPabort ;handlerPAbort b HandlerDabort ;handlerDAbort b . ;handlerReserved b HandlerIRQ b HandlerFIQ阜琳吃理职铣冠格将堵百枝青塞阻酝屠铜钙养渊藏仇裕啪珍叫役荒智允寻Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植嵌入式系统的初始化过程(嵌入式系统的初始化过程(2 2))硬件初始化阶段2、最小硬件初始化1)设置适当的寄存器,使嵌入式处理器处于一个已知的状态:获得CPU的类型;获得或设置CPU的时钟频率。
2)禁止中断和高速缓存3)初始化内存控制器、内存芯片和高速缓存单元,包括:得到内存的开始地址;得到内存的大小;如果有要求,则还需要进行主存测试;咕刘药戍悍六琶宙钨吝页捣卢杨辽疤辊疥俊妒漱联缠橱蓝煽庄互反伶诡酿Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植嵌入式系统的初始化过程(嵌入式系统的初始化过程(3 3))硬件初始化阶段3、其余硬件初始化1)引导代码调用合适的函数对目标机系统上的全部硬件部件进行初始化,包括:建立执行处理程序初始化中断处理程序初始化总线接口初始化板级外设得到内存的开始地址;过溯北借痢最停芬兵来厢篓羌遣迫凤泌舀故臃域誉渡及宾叹辆痹内辨前发Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植嵌入式系统的初始化过程(嵌入式系统的初始化过程(4 4))RTOS初始化阶段4、RTOS初始化1)RTOS初始化2)RTOS对象和服务初始化任务信号量定时器中断内存管理3)RTOS任务堆栈初始化4)RTOS扩展部件初始化5)启动RTOS邪慨氮毁卑进贤员灼缔腆腊瓶欺慨抒鼠贰卑谤泉汗撰亭蓑伟坝圾头穷胚铬Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ARM7TDMIARM7TDMI系统初始化的一般过程系统初始化的一般过程启动(系统上电/复位)从程序入口点关闭中断初始化时钟等硬件相关寄存器初始化存储器系统初始化C所需要的存储器空间调用C入口函数嫩瑚祸殿来臂犬匪且找课谁枪弘浅利用蚊翌侮网雾泥假铂哈歪模斋剑柿沟Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植一、设置程序入口指针一、设置程序入口指针n上电复位后直接到程序入口点执行,入口点一般为一个跳转表,跳转到复位处理程序处开始执行ARM7TDMI系统的初始化;n启动程序首先必须定义入中指针,而且整个应用程序只有一个入口指针例:AREA Boot,CODE,READONLY ENTRY /*设置程序入口指针*/熄头宽晴袭咸万肾辙吞智勾义伶缅的擞叭炸父盼肛鹰户蒙场汝号已窟筐亥Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植二、设置中断向量二、设置中断向量nARM要求中断向量必须设置在从OX00000000地址开始,连续8*4字节的地址空间;n向量表包含一系列跳转指令,跳转到相应的中断服务程序;n对各未用中断,使其指向一个含返回指令的哑函数,以防止错误中断引起系统的混乱;扒纬掖烛廖胀份柬撩骇森析卉粕淘裔贡仆华负碌骗谊反分涪浅眶沈缘梢鄂Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植中断向量表中断向量表FIQ0x1C外部快速中断IRQ0x18一般外部中断(Reserved)0x14保留Data Abort0x10数据异常Frefetch Abort0x0C预取指异常Software int0x08软件中断Undef0x04未定义指令中断Reset0x00复位中断确埂拆帕二巧栖蚕谅巩今搐厢亚服渗厕内挪德斌邑屈肌星匣虎畦荡古艾动Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植中断向量表的程序中断向量表的程序AREA Boot,CODE,READONLYENTRYB Reset_handlerB Undef_HandlerB SWI_HandlerB PreAbort_HandlerB . ;for reserved interrupt,stop hereB IRQ_handlerB FIQ_handler具决词指阁此孜另绢顷噶丧宠吕昼仅蹄锅绕用乱踩袁诬先俺拍闸熬衙舟惶Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植三、初始化时钟和设置相关的寄存器三、初始化时钟和设置相关的寄存器n通过设置时钟控制器来确定CPU的工作频率,设置中断控制寄存器屏蔽中断懦图恍耕斩结坏蝶纂圃彤坷蔚约蒲款官鱼客胶甫航卜挽夫经叉推衅魔泅咳Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植四、初始化存储器系统四、初始化存储器系统存储器类型和时序配置(参考芯片手册,设置与内存映射相关的寄存器)n一个复杂的系统可能存在多种存储器类型的接口,需要根据实际的系统设计对此加以正确配置。
对同一种存储器类型来说,也因为访问速度的差异,需要不同的时序设置n通常Flash 和SRAM 同属于静态存储器类型,可以合用同一个存储器端口;n而DRAM 因为动态刷新和地址线复用等特性,通常配有专用的存储器端口n存储器端口的接口时序优化是非常重要的,影响到整个系统的性能因为一般系统运行的速度瓶颈都存在于存储器访问,所以存储器访问时序应尽可能地快;但同时又要考虑由此带来的稳定性问题只有根据具体选定的芯片,进行多次的测试之后,才能确定最佳的时序配置研玲缴埔没竭莹灰锚淬倒涡椅育栈私曙略悉骆火呻困腻逮俏厢褐矽疡谱谴Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植存储器地址分布存储器地址分布n有些系统具有非常灵活的存储器地址分配特性,进行存储器初始化设计的时候一定要根据应用程序的具体要求来完成地址分配n一种典型的情况是启动ROM 的地址重映射(remap)当一个系统上电后程序将自动从0 地址处开始执行,因此在系统的初始状态,必须保证在0 地址处存在正确的代码,即要求0 地址开始处的存储器是非易性的ROM 或Flash 等但是因为ROM 或Flash 的访问速度相对较慢,每次中断发生后都要从读取ROM 或Flash 上面的向量表开始,影响了中断响应速度。
因此有的系统便提供一种灵活的地址重映射方法,可以把0 地址重新指向到RAM 中去在这种地址映射的变化过程当中,程序员需要仔细考虑的是程序的执行流程不能被这种变化所打断牵抓孺退赡澜塞畴织愈坛凝启像纲蜂菏放蔡茨涵讶稽蛛窑悠疼钠摹缅阵工Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ROMROM地址的重映射地址的重映射(remap)0x0200(boot code)0x0100(Reset_handler)……B Reset_Handler0x0000Flash(remap)0x0204(boot code)0x0200(Reset_handler)B Reset_Handler0x0000RAM封卑毋绦毙酥鲸藤铡氨屉拜侦咬酌僚禹关侦爱寄敬狰笔惑哮咬寂似耕演泡Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ROM地址重映射的实现mov r8,#RAM_BASE_BOOT//RAM_BASE_BOOT是重映射前内部RAM区地址 add r9, pc,#-(8+.-VectorTable) //VectorTale是异常向量表入口ldmia r9!, {r0-r7} //读8个异常向量 stmia r8!, {r0-r7} //保存8个异常向量到RAM区ldmia r9!, {r0-r4} //读5个异常处理程序绝对地址stmia r8!, {r0-r4} //保存5个异常处理程序绝对地址到RAM区 为保证重映射之后提供正确的中断入口地址,在重映射之前就必须把中断和异常向量表拷贝到内部RAM中。
其程序实现如下:步擞熏虱醉依领獭稳溪窍念灭砸铅监忆弟盒劝高闸更拄舜干胰仓像饼府砒Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植五、初始化堆栈五、初始化堆栈nARM处理器有好几种运行状态(模式),各种状态都需要有自己的堆栈,所以需要分别为这些堆栈分配空间并设置好各自的堆栈指针n每一种状态的堆栈指针寄存器(SP)都是独立的(System 和User 模式使用相同的SP 寄存器)因此对程序中需要用到的每一种模式都要给SP 寄存器定义一个堆栈地址方法是改变状态寄存器CPSR内的状态位,使处理器切换到不同的状态,然后给SP 赋值意不要切换到User模式进行User 模式的堆栈设置,因为进入User 模式后就不能再操作CPSR 回到别的模式了可能会对接下去的程序执行造成影响n一般堆栈的大小要根据需要而定,但是要尽可能给堆栈分配快速和高带宽的存储器堆栈性能的提高对系统整体性能的影响是非常明显的票娩失胃汹峪菩纫英衙羊先手雅论乍储陇酶港蔓群努盎貉炒疾翅喀暴姑尾Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植堆栈初始化代码示例堆栈初始化代码示例MRS R0, CPSR ; CPSR -> R0BIC R0, R0, #MODEMASK ; 安全起见,屏蔽模式位以外的其它位ORR R1, R0, #IRQMODE ; 把设置模式位设置成需要的模式(IRQ)MSR CPSR_cxsf, R1 ; 转到IRQ 模式LDR SP, =UndefStack ; 设置SP_irqORR R1,R0,#FIQMODEMSR CPSR_cxsf, R1 ; FIQModeLDR SP, =FIQStackORR R1, R0, #SVCMODEMSR CPSR_cxsf, R1 ; SVCModeLDR SP, =SVCStack暑杏敝陛系泽褂佑普蝶沛矽蚤噬翻卡肥茹纪光盟括旱琉缎胚鬼束豺群再吝Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植六、初始化应用程序执行环境六、初始化应用程序执行环境映像一开始总是存储在ROM/Flash 里面的,其RO 部分既可以在ROM/Flash里面执行,也可以转移到速度更快的RAM 中去;而RW 和ZI 这两部分必须是需要转移到可写的RAM 里去的。
所谓应用程序执行环境的初始化,就是完成必要的从ROM 到RAM 的数据传输和内容清零扬隧詹辅忌猫坚抒届横卿雅相伤尹象扮荷跑札惶眷阶饶孵摘借倡谆案砰噶Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植六、初始化六、初始化C C环境环境n在目标文件中,代码、数据放在不同的段中源文件编译链接生成含.data、.text段的目标文件,且链接器生成的.data段是以系统RAM为参考地址n故在系统启动时需要拷贝ROM或FLASH中的.data段到RAM,以完成对RAM的初始化在初始化期间应将系统需要读写的数据和变量从ROM拷贝到RAM里运行少沧练枫踊凯兢贝埠蝴贬鸥十练冗裂埂舵模助投抚均望鬼泛母见差曰轩吹Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植链接器产生的符号表链接器产生的符号表n符号由链接器自动产生,只读段(read-only RO)就是代码段,读写段(read-write RW)是已经初始化的全局变量,而零初始化段(zero-initialized section ZI)中存放未初始化的全局变量;阳勇泳摔冀轨峦渝客祖冒座滩梳催惦叠竿才厨串值靶觅詹永站歪郁梳伞暂Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植初始化初始化C C环境(环境(2 2))nC环境初始化,就是利用上述符号初始化RW和ZI段以使后面使用的全局变量的C程序正常运行;n这里有两个循环,第一个循环把预初始化的数据段RW(位于代码段的后面)复制到RAM中,另一个循环把未初始化的数据段ZI初始化为0,也就是实现把从ROM中的.data段拷贝到RAM,对ZI段内的数据初始化为0,以完成对C环境的实始化;妒释谷省喀世烽撞帅矽享秧河遣团猾咕仓眩拘捏蒸善毛蕴自裹依锐搞淹弧Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植初始化初始化C C环境(环境(3 3))险呆糖具谈丽愈恶餐缓裤腋铃贮修衰区穿回老纯隐弃罗嗣擅贰颧笋咙僚咬Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植改变处理器模式改变处理器模式除用户模式以外,其他6 种模式都是特权模式。
因为在初始化过程中许多操作需要在特权模式下才能进行(比如CPSR 的修改),所以要特别注意不能过早地进入用户模式一般地,在初始化过程中会经历以下一些模式变化:敲贱学铺搽定因讼壕皇熬屹讥郎渡变玛啦尚雄斜计延割儿汰慈补匿呻虱架Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植七、七、调用调用C C程序程序n对main函数的调用进入uc/OS的入口,通过这个入口就进入uC/OS的主函数,启动对uC/OS的初始化n例 IMPORT Main b Main ;C Entry退权裂诣霓娠八坞炎旱迢去摊束摇粥亦誓原枯躇伤味害震蜘药燥阎炯痒酉Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植uC/OSuC/OS系统的初始化系统的初始化n完成了前面的硬件初始化和运行环境的相关设置后,进入Main(), Main()是uC/OS的入口函数,启动对uC/OS的初始化厅掷夏毅粉店化合于祝柴嘘晤帕熄邪箔戊壶褐指佣汁裴捡慷镇琉恫泣蜒斋Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ARMARM的硬件抽象层的硬件抽象层——uHALuC/OS——uHALuC/OSnARM公司为操作系统的开发提供了一个硬件抽象层HAL,称为uHAL;n从结构上看,uHAL是一组库程序,需要说明的是,uHAL并不是专门为uC/OS准备的,甚至也不是专为操作系统内核准备的;nuHAL只是个针对ARM核的函数库;nuC/OS是建立在uHAL的基础之上的;宣童捞果角察重休厚摈酥共琐扫窘趟缄馈颗伙缮右休又诀她垄粮陀孟携扦Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植uC/OSuC/OS系统的初始化(系统的初始化(2 2))速帽缝贵堑桓蒜郡暴淌孺准景厚躁拔疡汛垛恐隧拦捅疲渡洛炉龙缺癣排蛛Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ARMTargetInit()ARMTargetInit()函数结构函数结构ARMTargetInit()调uHAL打印接口打印系统信息调用uHAL函数禁止所有中断调用uHAL函数对中断初始化uHAL函数对ARM计数器初始化结束缝理冶永汰坞藉潜欠宋技编馏驱颐奔掩谗舞洱骗本寇婶寝良宋闽湘魁酋吕Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植uHALuHAL的功能的功能nuHAL的作用之一是在操作系统本身进入正常运行之前,为系统提供基本的输入输出手段,例如uHALr_printf()等;nuHAL还要为操作系统的运行准备一个基本的运行环境,具体包括下列各种初始化:n通过uHAL_ResetMMU(),将MMU设置在一个确定的初始状态;n通过ARMDisable()关闭中断;n通过uHAL_InitInterrupts()设置中断向量处理程序;n通过uHAL_InitTimer()对系统使用的计数器进行初始化赐珍蔬里炽詹轰浑恒慷甄嚷弹耽静垒蒜个索给关庚萍搔霖腕亩柯邑切钠卖Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植ARMTargetStart()ARMTargetStart()的分析的分析n创建了任务之后,ARMTargetStart()调用uHALr_InstallSystemTimer()创建一个系统时钟,为时钟中断做好准备;蓟恼哪蠢盟桌袍叙抹齐乱凳捡暴戒李悼嘶熄僻门困攻蟹湘兹燕陵鼎狠舰族Chap9_RTEOS_uCOS-II 的移植Chap9_RTEOS_uCOS-II 的移植。












