uCOS-II 在ARM 微处理器上的移植及编译 课程设计_第1页
uCOS-II 在ARM 微处理器上的移植及编译 课程设计_第2页
uCOS-II 在ARM 微处理器上的移植及编译 课程设计_第3页
uCOS-II 在ARM 微处理器上的移植及编译 课程设计_第4页
uCOS-II 在ARM 微处理器上的移植及编译 课程设计_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、 ARM 原理与应用报告 一、设计内容 1.用 ADS1.2 IDE 软件进行程序代码编译设计,生成可执行的输出文件,并显示运行结果, 实现 uC/OS-II 内核在 ARM 处理器上移植。 2.uC/OS-II 在 ARM 微处理器上的移植及编译。 二、 设计目的与要求 目的: ARM 原理与应用课程设计是学生理论联系实际的重要实践教学环节,是对学生进行 的一次专业训练,也是对学生掌握和应用嵌入式系统相关知识能力的有效测试。通过 ARM 原理与应用课程设计,使学生初步了解嵌入式系统软件开发的一般过程和基本设计方法, 使学生进一步巩固和加深所学的专业理论知识,培养学生文献查阅、报告撰写等基本技

2、 能;培养学生独立分析和解决工程实际问题的能力;培养学生的团队协作精神、创新意 识、严肃认真的治学态度和严谨求实的工作作风。 要求 : 1) 了解 uC/OS-II 内核的主要结构。 2) 掌握将 uC/OS-II 内核移植到 ARM 处理器上的基本方法。 3)在给定的设备(UP-TECH PXA270-S 嵌入式开发平台、PC 机 、WinXP、ADS1.2 集成开 发环境、仿真器驱动程序、超级终端通讯程序)上加以实验,学会自己分析、找出解 决问题的方法。 4)对设计中遇到的问题和困难,独立思考,查阅资料,分析、观察、判断、试验、再判 断以寻找答案。 5)分析结果,写出设计总结报告论述自己的

3、观点,并应将参考资料列在报告后面以备查 询。内容尽量翔实(如上机过程、环境搭建),其中必须有按自己所理解、用自己的语 言所描述的内容。 三、 设计环境或器材、原理与说明 环境: 硬件:PC 机,博创 UP-TECHPXA27-S 目标板 ARM7TDMI 微处理器,串口线,并口 JTAG 转 换线; 软件:MS.Virtual.PC.2004,Windows XP 系统,ADS1.2 IDE 编译环境,LPC2000 Flash Utility 烧写程序、超级终端通讯程序. 原理与说明: 1.ARM 原理与应用课程设计题目涉及 ARM 应用的诸多方面,须经过思考和认真的学习, 有一定难度,在深

4、度方面主要要求学生对具体 ARM 指令的分析理解,目标板 ARM 处理 器的硬件认识了解,ADS1.2 IDE 软件的操作能力,解读 uC/OS-II 内核的自学能力以 及自我解决问题的能力。 2.C/OS-II 是一个完整的,可移植、可固化、可裁减的占先式实时多任务内核,它功能 强大,支持 56 个用户任务,支持信号量、邮箱、消息队列等多种常用的进程间通信机 制。公开源代码,程序可读性强、移植性好,同时可免费获得。LPC2119 是由 PHILIPS 生产的一款 32 位 ARM7TDMI-S 微处理器,其核心为高性能的 32 位 RISC 体系结构,并 具有高密度的 16 位指令集和极低的

5、功耗。具有零等待 128K 字节的片内 Flash,16k 的 SRAM,无需扩展存储器,使系统更为简单、可靠。 四、 设计过程(步骤)或程序代码 源代码: 1.1. OS_CPU.HOS_CPU.H 文件文件 该文件定义了和处理器相关的定义及一些全局函数声明。由于 ARM7 处理器字长为 32 位,半字长为 16 位,字节为 8 位,因此在 OS_CPU.h 文件修改了一些相关定义以确保 uC/OS-的可移植性: #ifndef _OS_CPU_H_ #define _OS_CPU_H_ #ifdef OS_CPU_GLOBALS #define OS_CPU_EXT #else #defi

6、ne OS_CPU_EXT extern #endif typedef unsigned char BOOLEAN; typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ typedef signed char INT8S; /* Signed 8 bit quantity */ typedef unsigned int INT16U; /* Unsigned 16 bit quantity */ typedef signed int INT16S; /* Signed 16 bit quantity */ typedef uns

7、igned long INT32U; /* Unsigned 32 bit quantity */ typedef signed long INT32S; /* Signed 32 bit quantity */ typedef float FP32; /* Single precision floating point */ typedef double FP64; /* Double precision floating point */ typedef unsigned int OS_STK; /* Each stack entry is 16-bit wide */ typedef u

8、nsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ #define BYTE INT8S /* Define data types for backward compatibility . */ #define UBYTE INT8U /* . to uC/OS V1.xx. Not actually needed for . */ #define WORD INT16S /* . uC/OS-II. */ #define UWORD INT16U #define LONG INT32S

9、 #define ULONG INT32U 从上面定义可看出,uC/OS-代码不使用 C 的 short,int 和 long 等数据类型, 这是因为它们是与编译器相关的,不可移植。 uC/OS-需要先禁止中断再访问代码的临界段,并且在访问后重新允许中断,这 就使得uC/OS-能够保护临界段代码免受多任务或中断服务例程的破坏。uC/OS-对关 中断以及开中断的宏定义如下: #define OS_CRITICAL_METHOD 3 #if OS_CRITICAL_METHOD = 3 /* critical section macros use method 3 (save to local v

10、ar cpu_sr) */ extern int INTS_OFF(void); /* ASM routines to twiddle bits */ extern void INTS_ON(void); #define OS_ENTER_CRITICAL() cpu_sr = INTS_OFF(); #define OS_EXIT_CRITICAL() if(cpu_sr = 0) INTS_ON(); #else #error please define critical method #endif #define OS_STK_GROWTH 1 /* Stack grows from H

11、IGH to LOW memory on 80 x86 */ /#define OS_TASK_SW() OSCtxSw() #endif /*_OS_CPU_H_*/ uC/OS-可以处理从下往上长以及从上往下长两种堆栈方式,但由于 ARM 处理器的堆栈 都是从上往下生长,也就是高地址到低地址的生长方向,因此宏定义如下: #define OS_STK_GROWTH 1 /*堆栈从上往下增长,1 向上,0 向下*/ 2.2. OS_CPU_C.COS_CPU_C.C 文件文件 在这个文件里主要是 OSTaskStkInit()函数和一些钩子函数,需要关心的是 OSTaskStkInit()。O

12、STaskStkInit()是任务堆栈初始化函数,它由任务建立函数 OSTaskCreateExt()调用,用于初始化任务的堆栈,堆栈的结构初始化成看起来刚刚发生 过中断一样,所有的寄存器都被入栈。在 ARM 体系结构下,任务堆栈空间由高至低依次 将保存着 pc、lr、r12、r11、r10、r1、r0、cpsr、spsr。OSTaskStkInit()函数有 四个参数,task,pdata,ptos,opt,它们和建立任务所使用的参数是一致的。函数返 回堆栈指针所指的地址。当我们使用 OSTaskCreateExt()来建立任务时,就把上述四个参 数传递给 OSTaskStkInit()函数

13、,初始化好堆栈,再返回给 OSTaskCreateExt()堆栈指针, 继续走下去。OSTaskStkInit()函数代码最后,使用 R0 来传递参数,这是符合 ARM 汇编 的规范,使用 R0 来传递第一个参数。 #include includes.h /* from uCOS directory */ /#include ipport.h /* from Interniche directory */ /* ARM CPU supervisor mode for PSR registers, with INTs enabled */ #define SUPMODE 0 x13 OS_STK

14、 * OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) unsigned int * stk; stk = (unsigned int *)ptos; /* 加载堆栈指针 */ /USE_ARG(opt); opt+; /* build a stack for the new task */ /*建立任务环境,ADS1.2 使用满递减堆栈*/ *-stk = (unsigned int) task; /* pc */ *-stk = (unsigned int) task; /* lr *

15、/ *-stk = 12; /* r12 */ *-stk = 11; /* r11 */ *-stk = 10; /* r10 */ *-stk = 9; /* r9 */ *-stk = 8; /* r8 */ *-stk = 7; /* r7 */ *-stk = 6; /* r6 */ *-stk = 5; /* r5 */ *-stk = 4; /* r4 */ *-stk = 3; /* r3 */ *-stk = 2; /* r2 */ *-stk = 1; /* r1 */ *-stk = (unsigned int) pdata; /* r0, 第一个参数使用 R0 传递*/

16、 *-stk = (SUPMODE); /* cpsr */ *-stk = (SUPMODE); /* spsr */ return (OS_STK *)stk); #if OS_CPU_HOOKS_EN void OSTaskCreateHook (OS_TCB *ptcb) /*任务创建钩子函数,当任务被创建时调用该函数*/ ptcb = ptcb; /* ptcb 没有用,是为了防止编译器警告*/ void OSTaskDelHook (OS_TCB *ptcb) /*任务删除钩子函数,当任务被删除时调用该函数*/ ptcb = ptcb; /* ptcb 没有用,是为了防止编译器警告

17、*/ void OSTaskSwHook (void) /*任务切换函数,可以在执行其他操作时进行上下文切换。*/ void OSTaskStatHook (void) /*任务统计钩子函数*/ void OSTimeTickHook (void) void OSTCBInitHook (OS_TCB *ptcb) ptcb = ptcb; /* Prevent Compiler warning */ void OSTaskIdleHook (void) void OSInitHookEnd (void) void OSInitHookBegin (void) #endif 3.OS_CPU_

18、A.S3.OS_CPU_A.S 文件文件 该文件的是移植的关键所在,在本文件中必须完成四个函数的编写工作,它们分别为 OSIntCtxSw( ),OSCtxSw( ), OSStartHighRdy( )和 OSTickISR( )。其中前两个函 数是重中之重,它们必须用汇编语言编写,主要完成任务环境的切换工作。 AREA |subr|, CODE, READONLY EXPORTOSIntCtxSw EXPORTOS_TASK_SW EXPORT INTS_OFF EXPORT INTS_ON INTS_OFF mrs r0, cpsr ; current CSR mov r1, r0 ;

19、make a copy for masking orr r1, r1, #0 xC0 ; mask off int bits msr CPSR_cxsf, r1 ; disable ints (IRQ and FIQ) and r0, r0, #0 x80 ; return FIQ bit from original CSR mov pc,lr ; return INTS_ON mrs r0, cpsr ; current CSR bic r0, r0, #0 xC0 ; mask on ints msr CPSR_cxsf, r0 ; enable ints (IRQ and FIQ) mo

20、v pc,lr ; return ; External symbols we need the addresses of IMPORTOSTCBCur addr_OSTCBCurDCDOSTCBCur IMPORTOSTCBHighRdy addr_OSTCBHighRdyDCDOSTCBHighRdy IMPORTOSPrioCur addr_OSPrioCurDCDOSPrioCur IMPORTOSPrioHighRdy addr_OSPrioHighRdy DCDOSPrioHighRdy IMPORT IRQStack;FIQ_STACK OSIntCtxSw ; post FIQ

21、Context switcher. This is called from OSIntExit when a hooked ISR ; wants to return in the context of another task. We load the new tasks context ; (from OSPrioHighRdy) and do the return from interrupt. ; Get pointer to stack where ISR_FiqHandler saved interrupted context ; ISR entry only saves firs

22、t seven regs and LR. ; ;add r7, sp, #24 ; save pointer to register file, we must adjust this pointer to the position that just Enter Interrupt LDRsp, =IRQStack ;IRQ_STACK ;test to del it subr7, sp, #4;r7 is the position that just Enter Interrupt ; Change ARM CPU to SVC mode for stack operations. ; T

23、his gets the CPU off the interrupt stack and back to the ; interrupted tasks stack, which is the one we want to alter. ; mrs r1, SPSR ; get suspended PSR orr r1, r1, #0 xC0 ; disable IRQ, FIQ. msr CPSR_cxsf, r1 ; switch mode (shold be SVC_MODE) ; PSR, SP, LR regs are now restored to the interrupted

24、SVC_MODE. ; now set up the tasks stack frame as OS_TASK_SW does. ;ldr r0, r7, #52 ; get IRQs LR (tasks PC) from IRQ stack /r0-r12 ldr r0, r7; get IRQs LR (tasks PC) from IRQ stack sub r0, r0, #4 ; Actual PC address is (saved_LR - 4) STMFDsp!, r0 ; save task PC STMFDsp!, lr ; save LR sublr, r7, #52;/

25、we save the r0-r12 when we enter IRQ. ;mov lr, r7 ; save FIQ stack ptr in LR (going to nuke r7) ldmfd lr!, r0-r12 ; get saved registers from FIQ stack STMFDsp!, r0-r12 ; save registers on task stack ; save PSR and PSR for task on tasks stack MRSr4, CPSR bic r4, r4, #0 xC0 ; leave interrupt bits in e

26、nabled mode STMFDsp!, r4; save tasks current PSR MRSr4, SPSR STMFDsp!, r4; SPSR too ; OSPrioCur = OSPrioHighRdy / change the current process LDRr4, addr_OSPrioCur LDRr5, addr_OSPrioHighRdy LDRB r6, r5 STRB r6, r4 ; Get preempted taskss TCB LDRr4, addr_OSTCBCur LDRr5, r4 STRsp, r5; store sp in preemp

27、ted taskss TCB ; Get new task TCB address LDRr6, addr_OSTCBHighRdy LDRr6, r6 LDRsp, r6; get new tasks stack pointer ; OSTCBCur = OSTCBHighRdy STRr6, r4 ; set new current task TCB address LDMFDsp!, r4 MSRSPSR_cxsf, r4 LDMFDsp!, r4 BIC r4, r4, #0 xC0 ; we must exit to new task with ints enabled MSRCPS

28、R_cxsf, r4 LDMFDsp!, r0-r12, lr, pc ;void OS_TASK_SW(void) ;Perform a context switch. ;On entry, OSTCBCur and OSPrioCur hold the current TCB and priority ;and OSTCBHighRdy and OSPrioHighRdy contain the same for the task ;to be switched to. ;The following code assumes that the virtual memory is direc

29、tly ;mapped into physical memory. If this is not true, the cache must ;be flushed at context switch to avoid address aliasing. OS_TASK_SW STMFDsp!, lr; save pc STMFDsp!, lr; save lr STMFDsp!, r0-r12 ; save registers and ret address MRSr4, CPSR STMFDsp!, r4; save current PSR MRSr4, SPSR STMFDsp!, r4;

30、 save SPSR ; OSPrioCur = OSPrioHighRdy LDRr4, addr_OSPrioCur LDRr5, addr_OSPrioHighRdy LDRB r6, r5 STRB r6, r4 ; Get current task TCB address LDRr4, addr_OSTCBCur LDRr5, r4 STRsp, r5; store sp in preempted taskss TCB ; Get highest priority task TCB address LDRr6, addr_OSTCBHighRdy LDRr6, r6 LDRsp, r

31、6; get new tasks stack pointer ; OSTCBCur = OSTCBHighRdy STRr6, r4; set new current task TCB address ; restore tasks mode regsiters LDMFDsp!, r4 MSRSPSR_cxsf, r4 LDMFDsp!, r4 MSRCPSR_cxsf, r4 ; return in new task context LDMFDsp!, r0-r12, lr, pc ;void OSStartHighRdy(void) ;Start the task with the hi

32、ghest priority; EXPORTOSStartHighRdy OSStartHighRdy LDRr4, addr_OSTCBCur; Get current task TCB address LDRr5, addr_OSTCBHighRdy; Get highest priority task TCB address LDRr5, r5; get stack pointer LDRsp, r5; switch to the new stack STRr5, r4; set new current task TCB address LDMFDsp!, r4; YYY MSRSPSR

33、_cxsf, r4 LDMFDsp!, r4; get new state from top of the stack MSRCPSR_cxsf, r4; CPSR should be SVC32Mode LDMFDsp!, r0-r12, lr, pc ; start the new task END 4.4. main.cmain.c 文件文件 #include ./inc/sys/lib.h #include #include #include ./inc/drv/register.h #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #d

34、efine FALSE 0 #endif typedef unsigned char uint8; /* 无符号 8 位整型变量 */ typedef signed char int8; /* 有符号 8 位整型变量 */ typedef unsigned short uint16; /* 无符号 16 位整型变量 */ typedef signed short int16; /* 有符号 16 位整型变量 */ typedef unsigned int uint32; /* 无符号 32 位整型变量 */ typedef signed int int32; /* 有符号 32 位整型变量 *

35、/ typedef float fp32; /* 单精度浮点数(32 位长度) */ typedef double fp64; /* 双精度浮点数(64 位长度) */ #define Fosc /晶振频率,10MHz25MHz,应当与实际一至 #define Fcclk(Fosc * 5) /系统频率,必须为 Fosc 的整数倍(132),且 0; dly-) for(i=0; i5000; i+); #define UART_BPS/* 定义通讯波特率 */ void UART0_Ini(void) uint16 Fdiv; U0LCR = 0 x83; / DLAB = 1,可设置波特率

36、 Fdiv = (Fpclk / 16) / UART_BPS; / 设置波特率 U0DLM = Fdiv / 256; U0DLL = Fdiv % 256; U0LCR = 0 x03; void UART0_SendByte(uint8 data) U0THR = data; / 发送数据 while( (U0LSR / 等待数据发送完毕 void UART0_SendStr(uint8 const *str) while(1) if( *str = 0 ) break; UART0_SendByte(*str+); / 发送数据 int main(void) PINSEL0 = 0 x

37、; / 设置 I/O 连接到 UART0 UART0_Ini(); / while(1) UART0_SendStr(SEND_STRING); DelayNS(10); / return(0); 实验过程:uCOS-II 在在 ARM 微处理器上的移植及编译微处理器上的移植及编译 1在linux系统中用gcc编译已给出的.c和.h文件生成一个可执行的文件,在修改完编 译器的报错后,无法实现,出现函数未定义undefined reference错误汇报。 2后来经过老师的指导,要在ADS1.2 IDE编译环境下生成课执行的文件。 3我重新修改了main.c头文件的输出结果,并重新deubug,

38、生成输出文件,然后再次 烧写,通信显示并成功。 4进行虚拟机内的超级终端的通讯交互测试,参数设置为波特率,以防显示乱码,数据 位 8 位,停止位 1,无奇偶校验,软件硬件流控设为无,成功建立超级终端。设置虚 拟机的端口选择端口 COM1,并选择等待调试器打开端口。经过几次测试,终于通信成 功。 五、 设计结果与分析 1串口线连接到ucos实验模块下方的串口上。 2做好以上第一步准备工作后,打开随光盘附带的软件LPC2000 Flash Utility。 3点击Read Device ID按键,然后重新启动目标机,然后点击确定获得相应的 Part ID和BootLoader ID 4结果失败,后

39、来问老师才知道在up-techpxa270-s实验箱ucos实验模块的上方有一跳 线:JP1501 LPC2119。烧写时应把跳线跳至1和2之间。 5获取ID后,选择要烧写到Flash中的文件,system.hex。 6选中文件后,选择Upload to Flash。 7进度条完成之后,在对话框左下方出现提示:File Upload Successfully Completed. 8关闭up-techpxa270-s的电源,并且把模块上方的跳线跳至2和3之间。再打开电源和 超级终端,观察从串口输出的信息,并且查看ucos实验模块显示的实验现象。 9结果不正确,后来在虚拟机里新建了一个超级终端后

40、,重启目标机,就可以看到显示 结果了。 分析: (一)对 uC/OS-移植代码的理解 uC/OS-的移植代码,主要涉及到三个文件,即 OS_CPU.H、OS_CPU_C.C、OS_CPU_A.S。对这三个文件的理解花费了我很长的时间, 可能是因为之前从未接触过 uC/OS-,因此对里面的一些定义以及为什么要这样 定义都不怎么明白,特别是 OS_CPU_A.S 这个主文件,里面包含了许多 ARM 指令, 包括在 C 中调用汇编时所要用到的汇编函数,基本每一条指令实现什么功能都能 看懂,而结合在一起却并不了解它们所实现的功能是什么,于是便去搜索一些材 料,包括查阅相关书籍,才大致明白了 uC/OS

41、-移植的相关信息。 (二)将代码移植到开发板 这部分采用的代码是原本的程序代码,在烧写的时候,读取设备ID这一步一直不 成功,后来才知道是虚拟机里的串口设置设为None而导致的结果,更改了设置后 再试一次就可以了。 六、设计体会 1. 通过此次实验,让我复习了嵌入式 ARM 系统软、硬件的基本知识,分析了 uC/OS-II 的源代码,对移植相关部分的代码作了分析解读,熟悉了 ARM 体系架构,最后基于 ARM 微处理器作了 uC/OS-II 的具体移植工作。不管是移植还是自己设计的,我想最 终的目的是解决这个问题,这首先要有个好的学习态度,通过它让我自己认识到自 己的不足和弱项,多分析做些实验验证,对于问题解决是帮助的。 2. 在 uC/OS-II 的 intel8086 版本上为 os_cpu.

温馨提示

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

评论

0/150

提交评论