


下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、uc/os-ll 在 ARM7E的移植1、移植的要求要使卩C/OS-H正常运行于某处理器上,须满足以下要求:1)处理器的C编译器能产生可重入代码;2)可以在C语言代码中打开和关闭中断;3) 处理器支持中断,并且能产生定时中断(通常在10至100Hz之间);4)处理器支持能够容纳一定量数据(可能是几千字节)的硬件堆栈;5)处理器有将堆栈指针和其它 CPU寄存器读出和存储到堆栈或内存中的指令。2、移植过程基于卩c/os-h的硬/软件体系结构如下图。教材P165图5-8卩c/os-h的移植集中在 os_cpu.h,os_cpu_A.s,os_cpu这三个文件上,下面分别详细介绍三个文件中的函数和需要
2、修改或者编写的代码。2.1 OS_CPU.h 的移植该文件定义了和处理器及编译器相关的定义及一些全局函数声明。由于ARM7处理器字长为32位,半字长为16位,字节为8位,因此在OS_CPU.h文件修改与 编译器相关的定义如下:typedef unsigned char BOOLEAN;typedef un sig ned char INT8U;typedef signed char INT8S;typedef unsigned short INT16U; /*某些编译器中int是32位的,故统一用short 表示 */typedef sig ned short INT16S;typedef u
3、n sig ned long INT32U;typedef sig ned long INT32S;typedef float FP32;typedef double FP64;typedef unsigned longOS_STK/*堆栈宽度为 32位,即 ARM7中的字对齐方式*/*下面是与处理器相关的代码*/#define 0S_CRITICAL_METH0D*2使用方式2保护临界代码*/#define OS_ENTER_CRITICAL() ARMDisableInt() /* 临界段代码保护宏定义 */#defi ne OS_EXIT_CRITICAL() ARME nablel n
4、t()#defi ne OS_STK_GROWTHM定义堆栈生长方向为向下生长 */#defi ne OS_TASK_SW OSCtxSw宏定义,用于非中断级的任务切换 */*下面开始声明全局函数声明,均是 OS_CPU_A中需要编写的函数*/extern voidOSCtxSw(void); /*声明任务级任务切换函数*/extern voidOSIntCtxSw(void) ; /*声明中断级任务切换函数*/extern voidARMDisableInt(void) ; /* 声明中断禁止函数 */extern voidARMEnableInt(void); /* 声明中断恢复函数 */
5、extern voidOSTickISR(void); /*声明时钟中断服务函数*/2.2 OS_CPU_C.C 文件移植OS_CPU_C.文件时,需要编写的是任务堆栈初始化函数 OSTaskStklnit和 时钟节拍中断服务钩子函数 OSTimeTickHooh在卩C/OS-II中,每一个任务都有自己的任务堆栈,当发生任务切换或者中断 时,其CPU使用权被剥脱,为了任务能被再次运行,那么这个被打断的任务所 用到的处理器的寄存器内容均应得到保存,按照ARM7处理器的压栈和入栈指令 的特点,设计任务堆栈如下任务堆栈的结构:CPSRROR1R12LR (R14PC (R15根据任务堆栈结构示意图,
6、OS_STI函数编写如下:#define SVCMODE 0x13 /*定义svc模式的命令字,用户任务运行在svc模式下*/OS_STK* OSTaskStklnit (void (*task)(void *pd), void *pdata, OS_STKptos,INT16U opt)OS_STK *stk; /*定义堆栈指针*/opt = opt;stk = (OS_STK) ptos; /*保存任务堆栈栈顶指针*/*-stk = (OS_STK) task; /* 用来保存PC,初始化成任务入口地址在被保护存现场的则是该任务运行时被中断时的地址*/*-stk = (OS_STK) ta
7、sk; /* 用来保存 LR*/*-stk = 0; /* r12 */*-stk = 0; /* r11 */*-stk = 0; /* r10 */*-stk = 0; /* r9 */*-stk = 0; /* r8 */*-stk = 0; /* r7 */*-stk = 0; /* r6 */*-stk = 0; /* r5 */*-stk = 0; /* r4 */*-stk = 0; /* r3 */*-stk = 0; /* r2 */*-stk = 0; /* r1 */*-stk = (INT32U) pdata; /*在ARM勺编译建议中,r0用于参数传递*/*-stk
8、= (SVC32MODE|0x40); /* 用来保存CPSR并禁止FIQ,由于任务和操作 系统均运行在svc模式,被中断到其他模式再返回后仍然回到 svc模式,故SPSR 没有用到*/return (OS_STK *)stk); /*返回任务堆栈的指针*/说明:用户创建任务时,OSTaskCreat ()会调用OSTaskStk In it函数初始化该 任务的堆栈,并把返回的堆栈指针保存到该任务的TCB结构中的最前面的参数OSTCBStkPtr中,当该任务要被恢复时,任务切换函数从其TCB块中取得其任务 堆栈指针,依次将堆栈内容弹到处理器对应的CPSRrO, r1,r12,lr,pc的寄存器
9、中,完成现场的恢复和程序指针PC的返回。另一个需要编写的函数是OSTimeTickHooK该函数被时钟节拍中断服务函数OSTickISR中的OSTimeTick函数调用,用来清除时钟节拍中断发生设备的请求 。 本移植方案使用S3C44B0X处理器的RTC模块的tick中断作为时钟节拍中断, 该函数编写如下:void OSTimeTickHook (void )rI_ISPC =(INT32U)0x01) OSTCBStkPtr = sp; /*OSTCBCur 目前指向的是被打断的任务 TCB 此操作将该任务的栈顶指针保存到其 OSTCBStkPtr中去,便于下次恢复时从这 里获取栈顶指针*/
10、OSTCBCur = OSTCBHighRdy/*OSTCBHighRdy指向的是就绪的高优先级任务的 TCB将其装载到 OSTCBCu中来 */SP = OSTCBHighRdy-OSTCBStkPtr; /*取得就绪的高优先级任务的栈顶指针 */恢复该任务的现场();/*于是便可通过刚取得的栈顶指针恢复该任务*/执行中断返回指令;/若OSCtxSw含有软中断指令则需中断返回,本移植不使用软中断*/3) OSI ntCtxSw()函数该函数用于中断级的上下文切换。由于CPU响应时钟节拍中断后,处理器从SVC 进入了 irq模式,并进入时钟节拍中断服务函数 OSTicklSR, OSTickl
11、SR函数发 现若有高优先级任务需要运行,则系统不返回中断前的任务,而直接调度就绪 的高优先级任务使之尽快得到执行,以保证实时性能。但是由于OSTicklSR函数一开始已经保存过任务中断前的CPU现场,因此OSIntCtxSW()不需要再进行类似的操作。当OSTicklSR调用OSIntExit函数找出需要运行的更高优先级任 务后,OSIntExit会将该任务的TCB指针放在OSTCBHighRd中,然后OSIntExit 在最后调用OSIntCtxSW函数来从OSTCBHighRd沖获取堆栈指针然后恢复该高 优先级任务的现场,使得其继续执行,并不再返回时钟节拍中断服务程序。显然,OSIntCt
12、xSW函数的过程和OSCtxSV函数的后半部分操作相同,因此,OSCtxSW 可以借用OSIntCtxSW的代码。4) OSTickISR ()函数在CPU响应时钟节拍中断后,程序指针PC发生跳转后进入该函数,由于OSTickISR调用OSTimeTick函数使得所有的延时节拍不为 0的任务延时节拍数 减1,并调用OSIntExit函数来找出就绪的高优先级任务,若需要切换,则最后 由OSIntCtxSw来完成新任务的调度,否则仍然返回到被时钟节拍中断的任务。OSTickISR函数的伪码和注释:void OSTickISR(void)保存处理器寄存器 /注意在irq模式下保存CPSR_svc寸,
13、要先强制切换到svc模式*/调用OSIntEnter();/*防止在嵌套的中断中发生调度*/给产生中断的设备清中断;/*本操作已由OSTimeTick中的OSTimeTickHook函 数完成*/调用OSTimeTick(); /*将所有任务不为0的延时节拍数减1*/调用OSIntExit();/*检索就绪任务,并将需要调度的高优先级任务的堆栈指针存到OSTCBHighRd中去,然后调用OSIntCtxSW恢复该任务的现场*/恢复处理器寄存器;执行中断返回指令;/*若没有中断级任务切换,则返回到中断前的任务*/5) ARMDisablelnt 和 ARMEnablelnt 函数ARMDisab
14、leInt是用来暂时禁止 FIQ及IRQ中断的函数,ARMEnablelnt则是恢 复ARMDisableInt执行前的中断使能状态,二者成对使用,用来保护临界段代 码不被中断破坏。本移植使用方式 2,即在进入临界段代码前关中断,完成后恢 复先前的中断使能状态。下面给出OS_CPU_A.S勺全部内容和注释。;*OS_CPU_A.S文件汇编代码开始*AREA |subr|, CODE, READONLY ;声明为代码段;* OSStartHighRdy代码开始 *EXPORT OSStartHighRdy ;关键词EXPORTS示声明此函数被其他文件使用,下 同IMPORT OSTaskSwHo
15、ok关键词IMPORT声明此函数/参量在其他文件中定义,下 同IMPORT OSTCBHighRdyIMPORT OSR unningOSStartHighRdy ;使就绪表中任务最高的优先级的任务开始运行BL OSTaskSwHook ;调用用户的Hook函数,空函数LDR r4,=OSRunning ;将OSRunning置1,声明多任务 OS开始运行MOV r5, #1STRB r5, r4LDR r4, =OSTCBHighRdy ;伪指令,取得存储 OSTCBHighRd的地址LDR r4, r4;得到最高优先级任务的任务堆栈地址LDR sp, r4; 切换到新任务的堆栈LDMFD
16、sp!, r4;从新任务堆栈中读取第一个参数(CPSRX r4)MSR cpsr_cxsf, r4 ;再传给cpsr,堆栈中的CPSR单出至U CPU的cpsr寄存器LDMFD sp!, r0-r12,lr,pc;依次恢复该任务r0r12,lr,pc ,切换到该任务;* 下面开始OSCtxSw函数,完成任务级的任务切换*EXPORT OSCtxSwIMPORT OSPrioCurIMPORT OSPrioHighRdyIMPORT OSTCBCurIMPORT OSTaskSwHookIMPORT OSTCBHighRd该变量指向任务切换后即将运行的任务的OS_TCBOSCtxSwSTMFD
17、sp!, lr ; OSCtxSw是被调用的,lr的值就是调用前的PC值,入栈STMFD sp!, r0-r12,lr;将lr和其他寄存器入栈MRS r4, cpsr ;通过MRS指令将cpsr入栈STMFD sp!, r4;被挂起的当前任务的寄存器保存完毕,下面接着保存该;任务的堆栈指针,以便下次恢复时,可以找到其堆栈指针,便可恢复其寄存器LDR r4, =OSTCBCur ;得到当前TCB块的地址,传给r4LDR r5, r4;将OSTCBCu中的值传给r5 ,注意OSTCBCu存的是指针STR sp, r5;将当前任务的sp传到OSTCBCu存的指针中去;*下面OSCtxSw准备恢复优先
18、级更高的就绪任务,这部分可共用OSIntCtxSw 的代码*;*osi ntCtxSw函数开始 *EXPORT OSI ntCtxSwIMPORT OSTaskSwHookOSIntCtxSw ;准备任务切换BL OSTaskSwHook;调用Hook函数,此为空函数LDR r4, =OSTCBHighRdyLDR r4, r4;将高优先级的任务栈顶指针存到r4中LDR r5, =OSTCBCurSTR r4, r5 ; OSTCBCur = OSTCBHighRdyLDR r6, =OSPrioHighRdy;取出高优先级LDRB r6,;优先级,字节传送LDR r5, =OSPrioCur
19、STRB r6, r5 ; OSPrioCur = OSPrioHighRdyLDR sp, r4; 从r4中取得要恢复的任务的栈顶指针LDMFD sp!, r4;弹出任务栈中的第一个参数,即 cpsrMSR cpsr_cxsf, r4 ; 首先开始恢复 cpsrLDMFD sp!, r0-r12,lr,pc;依次恢复 rO r12 , lr , pc,任务切换;*OSTickISR 开始 *EXPORT OSTickISRIMPORT OSI ntE nterIMPORT OSTimeTickIMPORT OSI ntExitLINK_SAVE DCD 0 ;用来保存时钟节拍中断前的lr,以
20、便计算出pc而使之入栈PSR_SAVE DCD 0用来保存中断前的spsr,中断产生时,svc模式下的cpsr存 到 spsrOSTickISR ;时钟节拍中断服务程序入口,需要用户在主函数中安装STMFD sp!, r4;因为r4下面要使用,故先保存r4到irq模式的堆栈中LDR r4, =LINK_SAVE ;准备保存LR, SPSR以便得到中断前的 pc和cpsr_svcSTR lr, r4 ; LINK_SAVE = lr_irq,此时 lr=PC (中断发生前)+4MRS lr, spsr ;lr 已保存,用lr取得spsr(保存的是中断前的cpsr)STR lr, r4, #4 ;
21、 PSR_SAVE = spsr_irqLDMFD sp!, r4; 恢复 r4ORR lr, lr, #0x80 ;在上下文切换前,屏蔽irq中断。注意lr存的是中断前的 cpsrMSR cpsr_cxsf, lr ;中断产生前是svc模式,故必须要切换到此模式下保存现场SUB sp, sp, #4 ;按任务栈结构,空一个空间预留给 PCSTMFD sp!, r0-r12,lr; 依次保存 lr、r12 r0LDR r4, =LINK_SAVE ;准备保存pc,取得存svc模式下发生中断前lr的地址LDR lr, r4, #0SUB lr, lr, #4 ;中断前的pc = LINK_SAV
22、E - 4,此前lr为异常前pc+4的值STR lr, sp, #(14*4); 保存pc到任务栈中预留的空间LDR r4, r4, #4;开始保存 cpsr,r4 = PSR_SAVE,即中断前的 cpsr_svcSTMFD sp!, r4;保存svc模式下任务的cpsr,寄存器保护完毕LDR r4, =OSTCBCur ;下面开始将该堆栈指针传给 OSTCBCu所指向的指针LDR r4, r4; 便于OSIntExit函数判断是否当前任务优先级最高STR sp, r4;在OSTCBCur-OSTCBstkpt保存被中断的任务的栈顶指针BL OSI ntE nter ;异常前的上下文保存好之后,开始准备中断服务,将OSI ntNesti ng+BL OSTimeTick ;将所有延时节拍不为1的任务的节拍数都减1,并清
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度水利工程总承包施工合同范本
- 二零二五年度便利店会员管理顾问劳动合同
- 2025版门面房买卖与共享办公空间租赁协议
- 二零二五年度股权收购与反垄断审查合同模板
- 2025年度高端定制礼品采购与销售合作协议
- 二零二五年度城市公园绿化景观施工及养护一体化合同
- 2025版碧桂园房地产项目绿化养护服务合同范本
- 二零二五年度绿色建筑房地产合同规范范本
- 二零二五年度跨区域汽车物流第三方运输合同
- 二零二五年度教育机构廉洁协议及合同附件
- 《设备管理制度讲》课件
- 江西省赣州市于都县2024-2025学年九年级上期中化学试题含解析
- 广西百色工业投资发展集团有限公司招聘笔试真题2023
- 《无人机培训教材》课件
- 2024年度抖音健身教练账号代运营合同
- 乡村机井维修合同范例
- 药房药品规范管理
- 职业技术学院《工夹具选型和设计》课程标准
- 心理咨询记录表10篇
- 《国家学生体质健康标准》登记卡
- 创伤急救知识课件
评论
0/150
提交评论