的移植优质文档_第1页
的移植优质文档_第2页
的移植优质文档_第3页
的移植优质文档_第4页
的移植优质文档_第5页
已阅读5页,还剩96页未读 继续免费阅读

下载本文档

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

文档简介

会计学1的移植优质文档主要内容移植规划μC/OS-II的移植嵌入式系统的初始化董稗戳故祭西欠冉贮名捅绦缘吼讲克揩逊墩眨氯河慧蛇桑电汐听佬汪称喘Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第1页/共101页

移植规划---概述

所谓“移植”,就是使一个实时内核能在其它的微处理器或微控制器上运行。尽管大部分μC/OS-II的代码是用C语言编写的,但是在编写与处理器硬件相关的代码时还是不得不使用汇编语言。移植的主要工作就是编写这些与处理器硬件相关的代码。操作系统的移植大体可以分为两个层次:跨体系结构的移植针对特定处理器的移植

纸磐磕等彼木员讣曝妇臂斯狂羞啸咋辑驱潮汗愉炭绕哺皇夹冯忱珊秤仆驱Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第2页/共101页移植规划

在移植前针对所使用的微处理器进行规划,主要有以下几个方面的考虑:编译器的选择任务模式的选择支持的指令集掩炳八慧锑惩濒读烁轿蔑所愤隆须姑呛瞻渊箍廉找排镰慑鹤霉耿冤欣谆哮Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第3页/共101页

移植规划(续)编译器的选择针对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的移植第4页/共101页ARM的工作模式ARM处理器有7种操作模式:用户模式(usr)-正常的程序执行模式快速中断模式(fiq)

-支持高速数据传输或通道处理中断模式(irq)

-用于通用中断处理管理员模式(svc)

-操作系统的保护模式.中止模式(abt)

-支持虚拟内存和/或内存保护等异常系统模式(sys)

-支持操作系统的特殊用户模式(运行操作系统任务)未定义模式(und)

-支持硬件协处理器的软件仿真除了用户模式外,其他模式均可视为特权模式梭尊藏恢躲萧橙喘形祷厢馆染作瞻糟纪狭缘拴淘牡孕饲临饭隶件事荤瓤升Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第5页/共101页

移植规划(续)任务模式的取舍ARM7处理器核具有上述七种模式,其中除用户模式外其它均为特权模式。其中管理、中止、未定义、中断和快中断模式与相应异常相联系,任务使用这些模式不太适合。系统模式除了是特权模式外,其它与用户模式一样,因而可选为任务使用的模式只有用户模式和系统模式。为了尽量减少任务代码错误对整个程序的影响,缺省的任务模式定为用户模式,可选为系统模式,同时提供接口使任务可以在这两种模式间切换。骸凡菩窍岳惦管都楔贰帚谨骡砌平凤韶琢品瞳酶宠蔡寅缴烹富仍嘶恬蔗召Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第6页/共101页移植规划(续)支持的指令集带T变量的ARM7处理器核具有两个指令集:标准32位ARM指令集16位Thumb指令集两种指令集有不同的应用范围。为了最大限度地支持芯片的特性,任务应当可以使用任意一个指令集并可以自由切换,而且不同的任务应当可以使用不同的指令集督遁孰椭鲸匿戎隐雄黔闻擅稚嘶尿俄嘉辱挤挥他莲析斋冷本挫验赎实刺参Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第7页/共101页移植μC/OS-II概述

要移植一个操作系统到一个特定的CPU体系结构并不是一件很容易的事情,它对移植者有以下要求:1.对目标体系结构要有很深了解;2.对OS原理要有较深入的了解;3.对所使用的编译器要有较深入的了解;4.对需要移植的操作系统要有相当的了解;5.对具体使用的芯片也要一定的了解糟凯知俗渐领忠圈闹异疡萄娠骋僻恋赠弗碾毒彼抓兢挟汾逃雀师罪矛隘肮Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第8页/共101页

要移植一个操作系统到一个特定的CPU体系结构上并不是一件很容易的事情,它对移植者有以下要求:1.对目标体系结构要有很深了解;2.对OS原理要有较深入的了解;3.对所使用的编译器要有较深入的了解;4.对需要移植的操作系统要有相当的了解;5.对具体使用的芯片也要一定的了解。

概述

要移植一个操作系统到一个特定的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的移植第9页/共101页主要内容移植规划μC/OS-II的移植嵌入式系统的初始化卑傅找采男姬处腹膘假帖咨吁村痒吞寇抱汹还酥湛韭施隐纫唐抱惰鸡坷琴Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第10页/共101页C/OS-II的文件结构霜词勤重熬青迟亡绕啸逸概禹哥烁预账饶冰勒涸修脖千圭抨宠偿凿抨看躁Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第11页/共101页μC/OS-II移植应用程序(用户代码)μC/OS-II(与处理器无关代码)OS_CORE.cOS_FLAG.c...μC/OS-II配置(与应用相关)OS_CFG.HINCLUDES.H

μC/OS-II移植(与处理器相关代码)CPU定时器硬件软件——μC/OS-II硬件软件体系结构用于产生系统时钟移植时需要编写的代码务讼杯辽膜援编秤梗语即牺躯驭环伊掷菩拾层票斑迈毕赎忻妈恢斥鸳鼓岛Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第12页/共101页移植C/OS-II满足的条件

处理器的C编译器能产生可重入代码在程序中可以打开或者关闭中断处理器支持中断,并且能产生定时中断(通常在10—100Hz之间)处理器支持能够容纳一定量数据的硬件堆栈(通常是几千字节)处理器有将堆栈指针和其他CPU寄存器的内容存储和读出到堆栈(或者内存)的指令

龄娱正临阿崩影漓估京呸永兵癸忽蒋健稠倪忿嫁翘辊磋塔崔浙筷言廷拓姜Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第13页/共101页什么是可重入代码

可重入的代码指的是一段可以被多个任务同时调用,而不必担心会破坏数据的代码(比如:一个函数)即:可重入型函数在任何时候都可以被中断执行,过一段时间以后又可以继续运行,而不会因为在函数中断的时候被其他的任务重新调用,而影响函数中的数据艺兵寐富悬衡脱昆隘瑰孽孙办咐汕难漱常哼琢撮荡珍拢邻图厘洱页葬厄汕Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第14页/共101页可重入代码举例

程序1:可重入型函数

voidswap(int*x,int*y) { inttemp; temp=*x; *x=*y; *y=temp; }络辩疗狭厄孺挝蛹奖预说橱蝎锭图付靛纬算牵信凑瓷概价近仲头诗站瑰求Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第15页/共101页非可重入代码举例程序2:非可重入型函数

inttemp; voidswap(int*x,int*y) { temp=*x; *x=*y; *y=temp; }逝趣外溶求讣秤信予苇侄河孜抛匣溪细愉巡授般咯渴惮挥廖痔匀郸钡叮医Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第16页/共101页不可重入函数被中断破坏倡灭瑟沏串捶驯对厩环鸭悼纪氰凳笼药坠占贸皱宽踞曲韵溢挖蚂装虐撵七Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第17页/共101页如何使函数具有可重入性

使Swap()函数具有可重入性的条件:把Temp定义为局部变量调用Swap()函数之前关中断,调用后再开中断用信号量禁止该函数在使用过程中被再次调用谁跨敷颧诈含跃踪虞肄氢狗刹婚尉吮朵吹伙危雨修纠舆肤或睁场赢怠秋稼Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第18页/共101页

概述

根据μ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的所有寄存器。——移植需要编写的文件跪窄袱玫翠用卧盯帚允辗趁雁啮侈诞清眼溅掂眶诈酚支层鸽作隆献佳闹赐Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第19页/共101页

概述移植内容类型所属文件描述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-IIforARM7通用的中断服务程序的汇编与C函数接口代码。时钟节拍中断服务程序也没有移植,因为其与芯片和应用都强烈相关,需要用户自己编写,不过可以通过IRQ.INC简化用户代码的编写。——移植代码包括的主要内容晴危逃缩欠饱箕芳退雅亮第猴宴挖额挝纳矽疽熬歌杖屉俊惜玩倍前误跳饵Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第20页/共101页关于头文件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的移植第21页/共101页设置与处理器和编译器相关的代码OS_CPU.H中定义了与编译器相关的数据类型。比如:INT8U、INT8S等。与ARM处理器相关的代码,使用OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()宏开启/关闭中断设置堆栈的增长方向:堆栈由高地址向低地址增长烙疼桌疫锥暇延间腐镍态植菊戮寇鼎桑褂曼臭域酗祖嘎李品她布朴菏釉毫Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第22页/共101页

编写OS_CPU.HμC/OS-II使用结构常量OS_STK_GROWTH中指定堆栈的生长方式:置OS_STK_GROWTH为0表示堆栈从下往上长。置OS_STK_GROWTH为1表示堆栈从上(高地址)往下(低地址)长。虽然ARM处理器核对于两种方式均支持,但ADS的C语言编译器仅支持一种方式,即从上往下长,并且必须是满递减堆栈,所以OS_STK_GROWTH的值为1。#defineOS_STK_GROWTH1——堆栈生长方式插遂魂悍曹拆辑肛精灾谗巨助主梯翱翘胃城槽瓶鼎缘质监抽赦化荆牙新派Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第23页/共101页

编写OS_CPU.HμC/OS-II不使用C语言中的short、int、long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性。代之以移植性强的整数数据类型,这样,既直观又可移植,不过这就成了必须移植的代码。根据ADS编译器的特性,这些代码如下程序清单所示(与编译有关)。typedef unsignedchar BOOLEAN;typedef unsignedchar INT8U;typedef signedchar INT8S;typedef unsignedshort INT16U;typedef signedshort INT16S;typedef unsignedint INT32U;typedef signedint INT32S;typedef float FP32;typedef double FP64;typedef INT32U OS_STK;——不依赖于编译的数据类型没睁听檀体猴递恃粉祷贪溺翅启怒嗽坷蜘装奈氛诊毒蚁邱准锌跃尾癣令守Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第24页/共101页设置includes.htypedefunsignedcharBOOLEAN;typedefunsignedcharINT8U;typedefsignedcharINT8S;typedefunsignedintINT16U;typedefsignedintINT16S;typedefunsignedlongINT32U;typedefsignedlongINT32S;typedeffloatFP32;typedefdoubleFP64;typedefunsignedlongOS_STK;typedefunsignedlongOS_CPU_SR;externintINTS_OFF(void);externvoidINTS_ON(void);#defineOS_ENTER_CRITICAL(){cpu_sr=INTS_OFF();}#defineOS_EXIT_CRITICAL(){if(cpu_sr==0)INTS_ON();}#defineOS_STK_GROWTH1 /*从高向低*/儒厚钧铭奔版谓顽紫扦品缩汾缨棋谐襄敛肢猜翻汤擞喀哗炯涡幽甭疏橙靠Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第25页/共101页程序状态寄存器(CPSR)

条件位:N=1-结果为负,0-结果为正或0Z=1-结果为0,0-结果不为0C=1-进位,0-借位V=1-结果溢出,0结果没溢出Q位:仅ARM5TE/J架构支持指示增强型DSP指令是否溢出J位仅ARM5TE/J架构支持J=1:处理器处于Jazelle状态中断禁止位:I=1:禁止IRQ.F=1:禁止FIQ.TBit仅ARMxT架构支持T=0:处理器处于ARM状态T=1:处理器处于Thumb状态Mode位(处理器模式位):0b10000 User0b10001 FIQ0b10010 IRQ0b10011 Supervisor0b10111 Abort0b11011 Undefined0b11111 System2731NZCVQ2867IFTmode1623

815

54024fsxc

UndefinedJ妙眨矣象路讶牧篙割瓮狙良姚第辆洪闻佯敲歌纪岩仕意担殴肾贮哭鹅堪廉Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第26页/共101页

编写OS_CPU.HμC/OS-II运行时,处理器可能处于的模式如下图所示:——使用软中断SWI作底层接口Thumb指令集ARM指令集用户模式系统模式用户任务使用的处理器模式ARM7内核具有的指令集ARM指令用户模式ARM指令系统模式Thumb指令系统模式Thumb指令用户模式变码俗牛窜疮膏乳薛尖蹬挺垒茧轿擦月猩咬小见钒歌敞铅访柠赁啄兢哄塑Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第27页/共101页

编写OS_CPU.H

为了使底层接口函数与处理器状态无关,同时在任务调用相应的函数不需要知道函数位置,在移植中使用软中断指令SWI作为底层接口,使用不同的功能号区分不同的函数。软中断功能号分配如下表所示,未列出的为保留功能。——使用软中断SWI作底层接口功能号接口函数简介0x00voidOS_TASK_SW(void)任务级任务切换函数0x01_OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02voidOS_ENTER_CRITICAL(void)关中断0x03VoidOS_EXIT_CRITICAL(void)开中断0x80VoidChangeToSYSMode(void)任务切换到系统模式0x81VoidChangeToUSRMode(void)任务切换到用户模式0x82VoidTaskIsARM(INT8Uprio)任务代码是ARM代码0x83VoidTaskIsTHUMB(INT8Uprio)任务代码是THUMB代码氰跪颖澡辜颈分艳品富会样援滤涕呜徽翘牡盖等炊呛虑沏谩钠紧站皱趟参Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第28页/共101页

编写OS_CPU.H

用软中断作为操作系统的底层接口就需要在C语言中使用SWI(SoftWareInterrupt)指令。在ADS中,有一个关键字__swi,用它声明一个不存在的函数,则调用这个函数就在调用这个函数的地方插入一条SWI指令,并且可以指定功能号。同时,这个函数也可以有参数和返回值,其传递规则与一般函数相同。——使用软中断SWI作底层接口 /*任务级任务切换函数 */__swi(0x00)voidOS_TASK_SW(void); /*运行优先级最高的任务 */__swi(0x01)void_OSStartHighRdy(void); /*关中断 */__swi(0x02)voidOS_ENTER_CRITICAL(void); /*开中断 */__swi(0x03)voidOS_EXIT_CRITICAL(void); /*任务切换到系统模式 */__swi(0x80)voidChangeToSYSMode(void); /*任务切换到用户模式 */__swi(0x81)voidChangeToUSRMode(void); /*任务代码是ARM代码 */__swi(0x82)voidTaskIsARM(INT8Uprio); /*任务代码是THUMB代码 */__swi(0x83)voidTaskIsTHUMB(INT8Uprio);程序中调用软中断时使用的函数名软件中断号该调用不返回参数抨盂茁道膘凋瀑拒衰育荤掺搞糯和蒜据遂筐脸飘揍和祭掷侧僻逢烃篮养痴Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第29页/共101页编写OS_CPU_C.CμC/OS-II的移植要求用户编写10个C函数:OSTaskStkInit():OSTaskCreat()和OSTaskCreatExt()通过调用本函数,初始化任务的栈结构OSTaskCreateHook():每当添加任务时由OS_TCBInit()函数调用OSTaskDelHook():任务被删除后由OSTaskDel()调用OSTaskSwHook():任务切换时两种情况均会调用该函数OSTaskIdleHook():OSTaskIdle()函数可调用该函数实现CPU低功耗模式OSTimeTickHook():本函数在每个时钟节拍都会被OSTimeTick()调用OSInitHookBegin():进入OSInit()函数后本函数会立即被调用OSInitHookEnd():OSInit()函数返回之前被调用OSTCBInitHook():OS_TCBInit()在调用OSTaskCreateHook()之前将先调用本函数唯一必要的函数是OStaskStkInit(),其他9个函数必须声明,但不一定要包含任何代码吱虱拿别取鄂琐善杆们巍答馏蛮钙警扁浦箱疯邹绍庭幌伴蛆耍菌诸塑元傻Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第30页/共101页编写OS_CPU_C.C

该函数用于初始化任务堆栈,使任务的堆栈看起来就像刚发生中断一样。即任务被执行时,就像从中断返回一样。在编写此函数之前,必须先确定任务的堆栈结构。而任务的堆栈结构是与CPU的体系结构、编译器有密切的关联。本移植的堆栈结构如下图所示。——OSTaskStkInit()任务入栈的其它数据LRR12R11R10R9R8...

栈底

任务环境开始SPPCR2R1R0OSEnterSum空闲空间词镍栽猴柔喇瘟社砍瑚立醇瘤撑怜据踩软峙燎车搀师懊巨虞税旦嫉摸买刻Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第31页/共101页编写OS_CPU_C.C——OSTaskStkInit()OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt){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=(unsignedint)pdata;*--stk=(USER_USING_MODE|0x00); *--stk=0;return(stk);}

入栈的数据任务入栈的其它数据LRR12R11R10R9R8...

栈底

任务环境开始SPPCR2R1R0OSEnterSum空闲空间疥沉晚稀勿汛指赡渝半轰瞩灰溺邮沾沿朋总稍殷语荐揣谦虫邑汾胁驳激纯Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第32页/共101页编写OS_CPU_C.C——OSTaskStkInit()OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt){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=(unsignedint)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的移植第33页/共101页编写OS_CPU_C.C——软件中断异常服务程序

操作系统与硬件相关的底层函数使用软件中断作为接口,如下表所示。移植代码中一个重要的工作就是为这些软件中断编写服务程序功能号接口函数简介0x00voidOS_TASK_SW(void)任务级任务切换函数0x01_OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02voidOS_ENTER_CRITICAL(void)关中断0x03VoidOS_EXIT_CRITICAL(void)开中断0x80VoidChangeToSYSMode(void)任务切换到系统模式0x81VoidChangeToUSRMode(void)任务切换到用户模式0x82VoidTaskIsARM(INT8Uprio)任务代码是ARM代码0x83VoidTaskIsTHUMB(INT8Uprio)任务代码是THUMB代码釜燃肤肄部澄泣期堵幅锹炙聘滥县旦国吨段配邪杏剐唇橇壤拎瞅蛋跳梦姨Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第34页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码功能号接口函数简介0x00voidOS_TASK_SW(void)任务级任务切换函数0x01_OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02voidOS_ENTER_CRITICAL(void)关中断0x03VoidOS_EXIT_CRITICAL(void)开中断0x80VoidChangeToSYSMode(void)任务切换到系统模式0x81VoidChangeToUSRMode(void)任务切换到用户模式0x82VoidTaskIsARM(INT8Uprio)任务代码是ARM代码0x83VoidTaskIsTHUMB(INT8Uprio)任务代码是THUMB代码voidSWI_Exception(intSWI_Num,int*Regs){OS_TCB*ptcb;switch(SWI_Num){case0x02://关中断

... case0x03://开中断

... case0x80://任务切换到系统模式

... case0x81://任务切换到用户模式

... case0x82://任务代码是ARM代码

... case0x83://任务代码是Thumb代码

... default: }}这两个软件中断使用汇编代码完成贰观玄吝刑瞪湃恭但鲜朱芍医痢钨估悸径盒呢扎狞呸戒辙忻巳媚具涡粕佣Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第35页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码μC/OS-II的启动多任务环境的函数叫做OSStart(),用户在调用OSStart()之前,必须已经建立了一个或更多任务。OSStart()最终调用函数OSStartHighRdy()运行多任务启动前优先级最高的任务。

voidOSStartHighRdy(void){_OSStartHighRdy();}

该函数在Os_cpu_a.s文件中实现。鸽挡猖羡炔泞秽按揍搏向审引淤汀蓖布午漠戍冶涡油赤稍硼娟缆陡姬闯屹Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第36页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介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的移植第37页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码voidSWI_Exception(intSWI_Num,int*Regs){...case0x02://关中断

__asm {MRSR0,SPSRORRR0,R0,#NoIntMSRSPSR_c,R0}OsEnterSum++;break;case0x03://开中断

if(--OsEnterSum==0){__asm{MRS R0,SPSRBIC R0,R0,#NoIntMSR SPSR_c,R0}}break;...每关闭一次中断,中断关闭计数器加1每调用一次开中断函数,该计数器减1,为0时允许打开中断关闭中断打开中断钾践媳绎临疥荔挺吨斌丽淋蹦绎辗怂思狰镁酣部蜜剂屁炸精慨财夺悠激猿Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第38页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码

它们可以在任何情况下使用。它们改变程序状态保留寄存器SPSR的相应位段,而程序状态保留寄存器会在软件中断退出时复制到程序状态寄存器CPSR,任务的处理器模式就改变了。

怎船侦丘贱些另尖须玉幼灿赣想礼韦阑倘故淡醚鲜烬至敬菩单伎阎郧标了Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第39页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码voidSWI_Exception(intSWI_Num,int*Regs){...case0x80://任务切换到系统模式

__asm {MRS R0,SPSRBIC R0,R0,#0x1fORR R0,R0,#SYS32ModeMSR SPSR_c,R0}break;case0x81://任务切换到用户模式

__asm {MRS R0,SPSRBIC R0,R0,#0x1fORR R0,R0,#USR32ModeMSR SPSR_c,R0}break;...使用内嵌汇编将处理器模式切换到用户模式使用内嵌汇编将处理器模式切换到系统模式堕十初履疏久羡付粕来缓用峙沁佩淬沉赫碱和筒涯塌诺距沿镜饿壹枫茧样Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第40页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码

任务可以使用ARM的两种指令集的任意一种运行,但是任务建立时默认的只是一种指令集。如果任务使用的第一条指令与默认的指令集不同,则程序运行错误。所以增加两个函数TaskIsARM()和TaskIsTHUMB()用于改变任务建立时默认的指令集。它们都有唯一的参数:需要改变的任务的优先级,值得注意的是,这两个函数必须在相应的任务建立后但还没有运行时调用。瘦荷据早氟陋裂恕衙获有掘仿耍稍耳仅胎双彦为狼围寐缺寅摸帛磺骸阵窜Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第41页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介0x00任务级任务切换函数0x01运行优先级最高的任务,由OSStartHighRdy产生0x02关中断0x03开中断0x80任务切换到系统模式0x81任务切换到用户模式0x82任务代码是ARM代码0x83任务代码是THUMB代码...case0x82://任务代码是ARM代码

if(Regs[0]<=OS_LOWEST_PRIO){ptcb=OSTCBPrioTbl[Regs[0]];if(ptcb!=NULL) {ptcb->OSTCBStkPtr[1]&=~(1<<5);}}break;case0x83://任务代码是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的移植第42页/共101页编写OS_CPU_C.C——软件中断异常服务程序功能号简介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的移植第43页/共101页编写OS_CPU_C.C

在Os_cpu_c.c文件中还有许多Hook()函数,它们在某个特定的系统动作时被调用,允许执行函数中的用户代码。这些函数默认是空函数,用户根据实际情况添加相关代码。它们分别如下表所示。——…Hook()函数函数名被执行条件OSInitHookBegin()在开始执行OSInit()函数时被执行OSInitHookEnd()在OSInit()函数结束时被执行OSTaskCreateHook()在任务建立时被调用OSTaskDelHook()在任务删除时被调用OSTaskSwHook()在进行任务切换时被调用OSTaskStatHook()被统计任务调用,每秒执行一次OSTCBInitHook()在建立所有的TCB后,由OSTCBInit函数调用OSTimeTickHook()每个时钟节拍产生后被调用OSTaskIdleHook()由空闲任务调用豁激犁佃揭劳矫皇亨盏寝酞衔札弘掀嚷味宠车整凑拖磺伐坐酌臆吹壶旬脑Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第44页/共101页

移植μC/OS-II编写OS_CPU_A.ASM在OS_CPU_A.ASM文件中有:软件中断的汇编接口程序任务切换程序OS启动时运行就绪最高优先级任务的程序廷隐去狙卿卉女净沸系须赖矛打陌侩轮绣山挟送拦捶滁尹涂净旺禽奈障叭Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第45页/共101页OS_CPU_A.ASMμC/OS-II的移植要求用户编写4个汇编语言函数:OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()如果编译器支持插入行汇编代码,就可以将所有与处理器相关的代码放到OS_CPU_C.C文件中,而不必再有单独的汇编语言文件伞引溅任轰哩疚撑躯丈猩垄劫塞敝洋采版方碟东他腔翘徒柄返来篷舒赁箩Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第46页/共101页

编写OS_CPU_A.ASM

在调用软中断之后,处理器切换到ARM指令和管理模式下工作。在执行软件中断服务函数之前,要提取中断号和其它入口参数,这些通过软件中断接口程序完成。——软件中断汇编接口SoftwareInterruptLDRSP,StackSvcSTMFDSP!,{R0-R3,R12,LR}MOVR1,SPMRSR3,SPSRTSTR3,#T_bitLDRNEHR0,[LR,#-2]BICNER0,R0,#0xff00LDREQR0,[LR,#-4]BICEQR0,R0,#0xFF000000

CMPR0,#1LDRLOPC,=OSIntCtxSwLDREQPC,=__OSStartHighRdyBLSWI_Exception

LDMFDSP!,{R0-R3,R12,PC}^保护被中断的现场将要用到的寄存器压栈判断中断前的指令集类型从产生软件中断的指令中提取中断号ARMThumb根据不同的中断号执行不同的程序返回被中断的任务中断号执行程序0进行任务切换1启动多任务环境,运行就绪的最高优先级任务其它软件中断服务函数轿伏杰甚梯帕堪捶碑耙力帘疡叠暇赋慢攒铂啥金蠕闻粕藕码孟坠薄低幂磁Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第47页/共101页

编写OS_CPU_A.ASMμC/OS-II是抢占式实时操作系统,得到运行的始终是就绪条件下最高优先级的任务。当处于运行状态的任务因为某种原因进入就绪态,或者有其它更高优先级的任务进入就绪态,操作系统内核就要运行别的就绪任务,这时需要进行任务切换。

——任务切换代码量忧雇孵藐纷龄朗笺卵胰帖踪铅装外头簧漠乏痴烩记芽氢蛾敦蘑洒磊蝇岳Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第48页/共101页编写OS_CPU_A.ASM——任务切换代码任务切换可能发生的情况有两种:

1.当前运行的任务主动交出CPU控制权,通常发生在等待某个事件或是调用系统延时。调用函数OS_TASK_SW()2.发生中断,使更高优先级的任务进入就绪状态,内核剥夺当前任务的运行资格。即发生在中断退出时。调用函数OSIntCtxSw()你湍死拯拙淖帛摘潘秃肖所荤默垢悯脓段絮艇防诅销哺乡无岗椅办厨杨弯Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第49页/共101页SPSR:程序状态保留寄存器CPSR:当前程序状态寄存器

编写OS_CPU_A.ASM

虽然OS_TASK_SW()和OSIntCtxSw()的执行条件不同,但是它们的功能相同,只要稍作处理就可以它们共用一段任务切换代码。这些处理就是保证在执行任务切换前两者的任务现场是一致的。共同执行的任务切换代码是“OSIntCtxSw”

其中OS_TASK_SW()是通过软件中断0完成的,通过前面的分析,可以知道执行任务切换时的现场环境如下所示,同时R3中保存着SPSR,它是任务中断前CPSR的备份。——任务切换代码任务入栈的其它数据LRR12R3R2R1R0空闲空间

栈底

任务环境开始SP参殉笼寨徘澜担守瞎录谤寞毯凶椭饵甥身戚于巍鸿洞迂侯雄售将肘冒堵龙Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第50页/共101页

编写OS_CPU_A.ASM——OSIntCtxSw保存当前任务的寄存器组及其它修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur恢复新任务的寄存器组及其它运行新任务流程图顾拾筐悲抉毗碎淄慷减斡饥梢因跺虑墙匿配盖线红忱脸听哮币枫递篷庄宗Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第51页/共101页

编写OS_CPU_A.ASM——OSIntCtxSw保存当前任务的寄存器组及其它修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur恢复新任务的寄存器组及其它运行新任务流程图OSIntCtxSw;下面为保存任务环境

LDRR2,[SP,#20];获取PCLDRR12,[SP,#16];获取R12MRSR0,CPSR;保存LR,PC及R4-R12MSRCPSR_c,#(NoInt|SYS32Mode)MOVR1,LRSTMFDSP!,{R1-R2}STMFDSP!,{R4-R12};获取R0-R3,并出栈R12和PC寄存器

MSRCPSR_c,R0LDMFDSP!,{R4-R7}ADDSP,SP,#8;保存R0-R3MSRCPSR_c,#(NoInt|SYS32Mode)STMFDSP!,{R4-R7};获取OsEnterSum,并保存CPSR,OsEnterSumLDRR1,=OsEnterSumLDRR2,[R1]STMFDSP!,{R2,R3}...PCLRR12R11R10R9R7R5R4R3R2R1R0R6R8CPSROSEnterSum切换至系统模式获取任务运行时的各寄存器并将它们压栈恢复之前的模式读出压栈的数据任务环境保存结束后的栈结构楷滥汉诌蚌穿谎约侈恫忠茎挫酋仿儡粟傈咋丈矮原廓磊谭卫阻梭温核甩逻Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第52页/共101页

编写OS_CPU_A.ASM——OSIntCtxSw修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur保存当前任务的寄存器组及其它恢复新任务的寄存器组及其它运行新任务锰类代茎体娥确伞奎氟醛沈砸钢衔望煞甥随瞄毅群绅盒凸层友财言钨碗憾Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第53页/共101页OSIntCtxSw...;保存当前任务堆栈指针到当前任务的TCBLDRR1,=OSTCBCurLDRR1,[R1]STRSP,[R1]BLSTaskSwHook;调用钩子函数

;OSPrioCur<=OSPrioHighRdyLDRR4,=OSPrioCurLDRR5,=OSPrioHighRdyLDRBR6,[R5]STRBR6,[R4]

;OSTCBCur<=OSTCBHighRdyLDRR6,=OSTCBHighRdyLDRR6,[R6]LDRR4,=OSTCBCurSTRR6,[R4]...

编写OS_CPU_A.ASM——OSIntCtxSw用即将运行任务的TCB指针更新OSTCBCur变量用即将运行任务的优先级更新OSPrioCur变量撞该沁驾们臭旅恭恒延坤超犯诞拄抱屡凰甚驭丈竿涟仗尖舰咒喧穿妨疟寿Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第54页/共101页

编写OS_CPU_A.ASM——OSIntCtxSw恢复新任务的寄存器组及其它运行新任务保存当前任务的寄存器组及其它修改当前任务的TCB堆栈指针用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur劲璃酬撩详驱汹刷监鸦脾村抢皆讨拈污慈婉坑狐副殿敌辣膀脚擦鱼面馏识Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第55页/共101页OSIntCtxSw...OSIntCtxSw_1;从R6指向TCB中获取新任务堆栈指针

LDRR4,[R6];调整堆栈指针

;17寄存器CPSR,OsEnterSum,R0-R12,LR,SPADDSP,R4,#68LDRLR,[SP,#-8];进入管理模式,恢复任务的各寄存器和变量

MSRCPSR_c,#(NoInt|SVC32Mode)MOVSP,R4;设置堆栈指针

;获取CPSR和OsEnterSumLDMFDSP!,{R4,R5};恢复新任务的OsEnterSumLDRR3,=OsEnterSumSTRR4,[R3];恢复CPSRMSRSPSR_cxsf,R5;运行新任务

LDMFDSP!,{R0-R12,LR,PC}^

编写OS_CPU_A.ASM——OSIntCtxSw恢复新任务的各寄存器运行新任务这段代码还被__OSStartHighRdy函数调用,用于启动最高优先级的就绪任务侯钩暮惶患白嚣如凤狄呸撩畦模据撑件越蛆赚诱钎就弃虫刨同速狂社胃摧Chap9_RTEOS_uCOS-II的移植Chap9_RTEOS_uCOS-II的移植第56页/共101页__OSStartHighRdyMSRCPSR_c,#(NoInt|SYS32Mode)

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

LDRR4,=OSRunningMOVR5,#1STRBR5,[R4];调用钩子函数

温馨提示

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

评论

0/150

提交评论