ImageVerifierCode 换一换
格式:DOCX , 页数:8 ,大小:17.99KB ,
资源ID:30057752      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/30057752.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(S3C2410平台UCOS移植笔记.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

S3C2410平台UCOS移植笔记.docx

1、S3C2410平台UCOS移植笔记S3C2410之UCOS移植笔记2011-10-01 20:10C/OS-II大部分代码是用移植性很高的ANSI C语言编写的,只包含一小部分汇编语言代码,因此可以很方便地将它移植到各种不同构架的微处理器上。移植C/OS-II,所用处理器和该处理器所用的C语言编译器必须满足以下条件:1处理器的C编译器能产生可重入代码;2处理器支持中断,并且能产生定时中断;3用C语言就可以开/关中断;4处理器能支持一定数量的数据存储硬件堆栈;5处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令。首先,由于处理器字长不同为了方便,我们通常要修改下字长定

2、义,s3c2410是32位处理器所以定义如下: #define U32 unsigned int#define U16 unsigned short#define S32 int#define S16 short int#define U8 unsigned char#define S8 signed char下面我对以上的移植要求一次进行移植分析: 1.修改ucos源代码中OS_CPU.S中的代码如下,主要是用开关中断实现代码的可重入要求:EXPORT OSCPUSaveSROSCPUSaveSR mrs r0,CPSR orr r1,r0,#NOINT ;屏蔽irq, fiq msr CP

3、SR_c,r1 mov pc,lr ;跳回 EXPORT OSCPURestoreSROSCPURestoreSR msr CPSR_c,r0 mov pc,lr 2. s2c2410支持中断,选择一个定时器作为时钟滴答,来对任务做时间片的调度,有关s3c2410的中断介绍可以参考我得另一片文章。 产生中断后,代码自动跳转到0x0的中断向量表,然后在从中断向量表中跳到下面的程序,进行中断号的分析,然后利用ucos的中断任务切换到中断服务子程序中。UCOS_IRQHandler stmfd sp!,r0-r3,r12,lr ;保存现场 bl OSIntEnter ;跳到下面程序,实际上是中断嵌套

4、 bl C_IRQHandler ;计算出中断号 bl OSIntExit ;中断减1 ,切换最高优先级任务 ldr r0,=OSIntCtxSwFlag ; 判断是否需要中断切换 ldr r1,r0 cmp r1,#1 beq _IntCtxSw ;调用中断任务切换函数,后面分析 ldmfd sp!,r0-r3,r12,lr ;恢复现场 subs pc,lr,#4void OSIntEnter (void) if (OSRunning = OS_TRUE) if (OSIntNesting 0) 有中断,中断数-1 OSIntNesting-; if (OSIntNesting = 0) 如

5、果没有中断的话 if (OSLockNesting = 0) OS_SchedNew(); if (OSPrioHighRdy != OSPrioCur) OSTCBHighRdy = OSTCBPrioTblOSPrioHighRdy;#if OS_TASK_PROFILE_EN 0 OSTCBHighRdy-OSTCBCtxSwCtr+;#endif OSCtxSwCtr+; 将最高优先级的任务调入 OSIntCtxSw(); OS_EXIT_CRITICAL(); void C_IRQHandler(void) U32 wTemp; wTemp = rINTOFFSET2; 根据中断偏移

6、量判断是什么中断 (void(*)(void)(*(U32 *)(aISR_EINT0+wTemp)(); 关键!跳到相应中断服务程序 其中的UCOS_IRQHandler就是实现中断跳转的关键代码,C语言中将irq中断函数的入口都指向它实现中断跳转到C中对应的服务函数,代码如下:pISR_IRQ = (U32)UCOS_IRQHandler; 中断入口挂接 然后初始化一个定时器作为时钟滴答,一般选择100ms左右,产生一次中断溢出,进行一次任务调度。3.有关堆栈的设置。因为ucos进行任务切换时,就是相当于模拟的做中断操作。所以在切换任务之前必须先保存任务的现场:包括R0R12,sp,lr,

7、pc,cprs,sprs。然后用sp从旧的任务堆栈指向新的任务的堆栈。(这个堆栈在任务创建的时候已经分配好了)。 在初始化任务堆栈之前,首先要设置两个参数,在CONFIG文件中: 大小端编译模式,堆栈得生长方向。代码如下:define OS_STK_GROWTH 1 ;堆栈向上生长然后在任务创建时的堆栈初始化函数,在OS_CPU_C.c文件中:OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) OS_STK *stk; opt = opt; /* opt is not use

8、d, 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

9、)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)pdata; /* r0 : argument */ *(-stk) = (INT32U)(SVCMODE|0x0); /* PSR */ *(-stk) = (INT32U)(

10、SVCMODE|0x0); /* SPSR */ return (stk);4.有关任务调度方面的移植: 首先就是当运行OSSTART()后,系统要进入优先级最高的任务中,即第一个任务,这短代码的移植如下: OSStartHighRdy bl OSTaskSwHook ; ldr r4,=OSRunning ; 运行多任务 mov r5,#1 strb r5,r4 ldr r4,=OSTCBHighRdy ; 得到最高优先级任务的TCB地址 ldr r4,r4 ; 得到其堆栈地址 ldr sp,r4 ; 切换到新任务的堆栈 ldmfd sp!,r4 ; 把新任务堆栈的内容环境载进当片CPU m

11、sr SPSR_cxsf,r4 ldmfd sp!,r4 ; pop new tasks psr msr CPSR_cxsf,r4 ldmfd sp!,r0-r12,lr,pc ; pop new tasks r0-r12,lr & pc 其次时对任务调度函数的移植,主要是在时间片到时,读取就绪表中优先级最高的任务,并切换到该任务的环境中:OSCtxSw ;保存要被切换出去的任务环境 stmfd sp!,lr ; push pc (lr should be pushed in place of PC) stmfd sp!,r0-r12,lr ; push lr & register file

12、mrs r4,cpsr stmfd sp!,r4 ; push current psr mrs r4,spsr stmfd sp!,r4 ; push current spsr ;把就绪表中优先级 最高的任务载入到当前任务指针指向 ; OSPrioCur = OSPrioHighRdy ldr r4,=OSPrioCur ldr r5,=OSPrioHighRdy ldrb r6,r5 strb r6,r4 ;得到当前任务的TCB地址 ; Get current task TCB address ldr r4,=OSTCBCur ldr r5,r4 str sp,r5 ; store sp i

13、n preempted taskss TCB bl OSTaskSwHook ; call Task Switch Hook ;得到最高优先级任务的地址,并把堆栈指针指向它的堆栈地址 ; Get highest priority task TCB address ldr r6,=OSTCBHighRdy ldr r6,r6 ldr sp,r6 ; get new tasks stack pointer ;调出新任务的环境实现切换 ; OSTCBCur = OSTCBHighRdy str r6,r4 ; set new current task TCB address ldmfd sp!,r4

14、 ; pop new tasks spsr msr SPSR_cxsf,r4 ldmfd sp!,r4 ; pop new tasks psr msr CPSR_cxsf,r4 ldmfd sp!,r0-r12,lr,pc ; pop new tasks r0-r12,lr & pc 最后是中断级的任务切换,这种情况发生在,在中断服务程序中报告了一个或多个事件的发生,而这些事件的发生使一些更高优先级的任务进入就绪状态。因此在中断退出时不应该返回到被中断的任务,而应该返回到就绪态中优先级最高的任务。函数OSIntCtxSw()的主要功能是完成中断级的任务切换。与任务级的任务切换不同的时,在进入中

15、断后,所有寄存器的值都被入栈了。因此在进入任务级切换时寄存器的入栈操作应该再有。另外,在中断服务程序中调用了函数OSIntExit()和OSIntCtxSw(),因此应该调整当前任务的堆栈指针,让任务下次再被执行时返回中断服务程序而不是返回函数OSIntExit()和OSIntCtxSw()。剩下的任务就是进行任务切换了,这些代码同函数OSCtxSw()的大部分代码都相同。 _IntCtxSw ;对堆栈指针的调整 mov r1,#0 str r1,r0 ldmfd sp!,r0-r3,r12,lr stmfd sp!,r0-r3 mov r1,sp add sp,sp,#16 sub r2,l

16、r,#4 mrs r3,spsr orr r0,r3,#NOINT msr spsr_c,r0 ldr r0,=.+8 movs pc,r0 ;以下代码和正常的任务切换过程完全一样 stmfd sp!,r2 ; push old tasks pc stmfd sp!,r4-r12,lr ; push old tasks lr,r12-r4 mov r4,r1 ; Special optimised code below mov r5,r3 ldmfd r4!,r0-r3 stmfd sp!,r0-r3 ; push old tasks r3-r0 stmfd sp!,r5 ; push old

17、 tasks psr mrs r4,spsr stmfd sp!,r4 ; push old tasks spsr ; OSPrioCur = OSPrioHighRdy ldr r4,=OSPrioCur ldr r5,=OSPrioHighRdy ldrb r5,r5 strb r5,r4 ; Get current task TCB address ldr r4,=OSTCBCur ldr r5,r4 str sp,r5 ; store sp in preempted taskss TCB bl OSTaskSwHook ; call Task Switch Hook ; Get hig

18、hest priority task TCB address ldr r6,=OSTCBHighRdy ldr r6,r6 ldr sp,r6 ; get new tasks stack pointer ; OSTCBCur = OSTCBHighRdy str r6,r4 ; set new current task TCB address ldmfd sp!,r4 ; pop new tasks spsr msr SPSR_cxsf,r4 ldmfd sp!,r4 ; pop new tasks psr msr CPSR_cxsf,r4 ldmfd sp!,r0-r12,lr,pc ; pop new tasks r0-r12,lr & pc 这样我们就可以实现ucos在s3c2410的移植了。注意如果要是在ram中仿真时,必须把中断向量表预先烧录到0x0处才能正常实现中断的跳转。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1