uCOSII在ARM微处理器上的移植及编译课程设计_第1页
uCOSII在ARM微处理器上的移植及编译课程设计_第2页
uCOSII在ARM微处理器上的移植及编译课程设计_第3页
uCOSII在ARM微处理器上的移植及编译课程设计_第4页
uCOSII在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 转换线;软件:,Windows XP系统,ADS1.2 IDE编译环境,LPC2000 Flash Utility烧写程序、超级终端通讯程序.原理与说明:1.ARM原理与应用课程设计题目涉及ARM应用的诸多方面,须经过思考和认真的学习,有一定难度,在深度方面主要要求学生对具体ARM指令的分析理解,目标板ARM处理器的硬件认识了解,ADS1.2 IDE软件的操作能力,解读u

4、C/OS-II 内核的自学能力以及自我解决问题的能力。2.C/OS-II是一个完整的,可移植、可固化、可裁减的占先式实时多任务内核,它功能强大,支持56个用户任务,支持信号量、邮箱、消息队列等多种常用的进程间通信机制。公开源代码,程序可读性强、移植性好,同时可免费获得。LPC2119是由PHILIPS生产的一款32位ARM7TDMI-S微处理器,其核心为高性能的32位RISC体系结构,并具有高密度的16位指令集和极低的功耗。具有零等待128K字节的片内Flash,16k的SRAM,无需扩展存储器,使系统更为简单、可靠。四、 设计过程(步骤)或程序代码源代码:1. OS_CPU.H文件该文件定义

5、了和处理器相关的定义及一些全局函数声明。由于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#define OS_CPU_EXT extern#endiftypedef unsigned char BOOLEAN;typedef unsigned char INT8U; /* Unsigned 8 bit quantity */typedef signe

6、d char INT8S; /* Signed 8 bit quantity */typedef unsigned int INT16U; /* Unsigned 16 bit quantity */typedef signed int INT16S; /* Signed 16 bit quantity */typedef unsigned long INT32U; /* Unsigned 32 bit quantity */typedef signed long INT32S; /* Signed 32 bit quantity */typedef float FP32; /* Single

7、 precision floating point */typedef double FP64; /* Double precision floating point */typedef unsigned int OS_STK; /* Each stack entry is 16-bit wide */typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */#define BYTE INT8S /* Define data types for backward compati

8、bility . */#define UBYTE INT8U /* . to uC/OS V1.xx. Not actually needed for . */#define WORD INT16S /* . uC/OS-II. */#define UWORD INT16U#define LONG INT32S#define ULONG INT32U从上面定义可看出,uC/OS-代码不使用C的short,int和long等数据类型,这是因为它们是与编译器相关的,不可移植。uC/OS-需要先禁止中断再访问代码的临界段,并且在访问后重新允许中断,这就使得uC/OS-能够保护临界段代码免受多任务或中

9、断服务例程的破坏。uC/OS-对关中断以及开中断的宏定义如下:#define OS_CRITICAL_METHOD 3#if OS_CRITICAL_METHOD = 3 /* critical section macros use "method 3" (save to local var "cpu_sr") */extern int INTS_OFF(void); /* ASM routines to twiddle bits */extern void INTS_ON(void);#define OS_ENTER_CRITICAL() cpu_sr

10、 = 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 HIGH to LOW memory on 80x86 */#define OS_TASK_SW() OSCtxSw()#endif /*_OS_CPU_H_*/uC/OS-可以处理从下往上长以及从上往下长两种堆栈方式,但由于ARM处理器的堆栈都是从上往下生长,也就是高地址到低地址

11、的生长方向,因此宏定义如下:#define OS_STK_GROWTH 1 /*堆栈从上往下增长,1向上,0向下*/2. OS_CPU_C.C文件在这个文件里主要是OSTaskStkInit()函数和一些钩子函数,需要关心的是OSTaskStkInit()。OSTaskStkInit()是任务堆栈初始化函数,它由任务建立函数OSTaskCreateExt()调用,用于初始化任务的堆栈,堆栈的结构初始化成看起来刚刚发生过中断一样,所有的寄存器都被入栈。在ARM体系结构下,任务堆栈空间由高至低依次将保存着pc、lr、r12、r11、r10、r1、r0、cpsr、spsr。OSTaskStkInit

12、()函数有四个参数,task,pdata,ptos,opt,它们和建立任务所使用的参数是一致的。函数返回堆栈指针所指的地址。当我们使用OSTaskCreateExt()来建立任务时,就把上述四个参数传递给OSTaskStkInit()函数,初始化好堆栈,再返回给OSTaskCreateExt()堆栈指针,继续走下去。OSTaskStkInit()函数代码最后,使用R0来传递参数,这是符合ARM汇编的规范,使用R0来传递第一个参数。#include "includes.h" /* from uCOS directory */#include "ipport.h&qu

13、ot; /* from Interniche directory */* ARM CPU "supervisor" mode for PSR registers, with INTs enabled */#define SUPMODE 0x13OS_STK * OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) unsigned int * stk; stk = (unsigned int *)ptos; /* 加载堆栈指针 */ /USE_ARG(opt); opt+;

14、 /* build a stack for the new task */*建立任务环境,ADS1.2使用满递减堆栈*/ *-stk = (unsigned int) task; /* pc */ *-stk = (unsigned int) task; /* lr */ *-stk = 12; /* r12 */ *-stk = 11; /* r11 */ *-stk = 10; /* r10 */ *-stk = 9; /* r9 */ *-stk = 8; /* r8 */ *-stk = 7; /* r7 */ *-stk = 6; /* r6 */ *-stk = 5; /* r5

15、*/ *-stk = 4; /* r4 */ *-stk = 3; /* r3 */ *-stk = 2; /* r2 */ *-stk = 1; /* r1 */ *-stk = (unsigned int) pdata; /* r0, 第一个参数使用R0传递*/ *-stk = (SUPMODE); /* cpsr */ *-stk = (SUPMODE); /* spsr */ return (OS_STK *)stk);#if OS_CPU_HOOKS_ENvoid OSTaskCreateHook (OS_TCB *ptcb) /*任务创建钩子函数,当任务被创建时调用该函数*/ pt

16、cb = ptcb; /* ptcb没有用,是为了防止编译器警告*/void OSTaskDelHook (OS_TCB *ptcb) /*任务删除钩子函数,当任务被删除时调用该函数*/ptcb = ptcb; /* ptcb没有用,是为了防止编译器警告*/void OSTaskSwHook (void) /*任务切换函数,可以在执行其他操作时进行上下文切换。*/void OSTaskStatHook (void) /*任务统计钩子函数*/void OSTimeTickHook (void)void OSTCBInitHook (OS_TCB *ptcb) ptcb = ptcb; /* Pr

17、event Compiler warning */void OSTaskIdleHook (void)void OSInitHookEnd (void)void OSInitHookBegin (void)#endif文件该文件的是移植的关键所在,在本文件中必须完成四个函数的编写工作,它们分别为OSIntCtxSw( ),OSCtxSw( ), OSStartHighRdy( )和OSTickISR( )。其中前两个函数是重中之重,它们必须用汇编语言编写,主要完成任务环境的切换工作。AREA|subr|, CODE, READONLYEXPORTOSIntCtxSwEXPORTOS_TASK_

18、SWEXPORT INTS_OFFEXPORT INTS_ONINTS_OFF mrs r0, cpsr ; current CSR mov r1, r0 ; make a copy for masking orr r1, r1, #0xC0 ; mask off int bits msr CPSR_cxsf, r1 ; disable ints (IRQ and FIQ) and r0, r0, #0x80 ; return FIQ bit from original CSR mov pc,lr ; returnINTS_ON mrs r0, cpsr ; current CSR bic r

19、0, r0, #0xC0 ; mask on ints msr CPSR_cxsf, r0 ; enable ints (IRQ and FIQ) mov pc,lr ; return; External symbols we need the addresses ofIMPORTOSTCBCuraddr_OSTCBCurDCDOSTCBCurIMPORTOSTCBHighRdyaddr_OSTCBHighRdyDCDOSTCBHighRdyIMPORTOSPrioCuraddr_OSPrioCurDCDOSPrioCurIMPORTOSPrioHighRdyaddr_OSPrioHighRd

20、yDCDOSPrioHighRdy IMPORT IRQStack;FIQ_STACKOSIntCtxSw; post FIQ 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_Fi

21、qHandler saved interrupted context ; ISR entry only saves first seven regs and LR. ;add r7, sp, #24 ; save pointer to register file, we must adjust this pointer to the position that just Enter InterruptLDRsp, =IRQStack;IRQ_STACK ;test to del itsubr7, sp, #4;r7 is the position that just Enter Interru

22、pt; Change ARM CPU to SVC mode for stack operations.; This gets the CPU off the interrupt stack and back to the; interrupted task's stack, which is the one we want to alter.;mrs r1, SPSR ; get suspended PSRorr r1, r1, #0xC0 ; disable IRQ, FIQ.msr CPSR_cxsf, r1 ; switch mode (shold be SVC_MODE) ;

23、 PSR, SP, LR regs are now restored to the interrupted SVC_MODE. ; now set up the task's stack frame as OS_TASK_SW does.;ldr r0, r7, #52 ; get IRQ's LR (tasks PC) from IRQ stack /r0-r12ldr r0, r7; get IRQ's LR (tasks PC) from IRQ stacksub r0, r0, #4 ; Actual PC address is (saved_LR - 4)ST

24、MFDsp!, r0 ; save task PCSTMFDsp!, lr ; save LRsublr, r7, #52;/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 stackSTMFDsp!, r0-r12 ; save registers on task stack ; save PSR and PSR for task on task's

25、 stackMRSr4, CPSRbic r4, r4, #0xC0 ; leave interrupt bits in enabled modeSTMFDsp!, r4; save task's current PSRMRSr4, SPSRSTMFDsp!, r4; SPSR too; OSPrioCur = OSPrioHighRdy / change the current processLDRr4, addr_OSPrioCurLDRr5, addr_OSPrioHighRdyLDRBr6, r5STRBr6, r4; Get preempted tasks's TCB

26、LDRr4, addr_OSTCBCurLDRr5, r4STRsp, r5; store sp in preempted tasks's TCB; Get new task TCB addressLDRr6, addr_OSTCBHighRdyLDRr6, r6LDRsp, r6; get new task's stack pointer; OSTCBCur = OSTCBHighRdySTRr6, r4 ; set new current task TCB addressLDMFDsp!, r4MSRSPSR_cxsf, r4LDMFDsp!, r4BIC r4, r4,

27、#0xC0 ; we must exit to new task with ints enabledMSRCPSR_cxsf, r4LDMFDsp!, 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 follow

28、ing code assumes that the virtual memory is directly;mapped into physical memory. If this is not true, the cache must ;be flushed at context switch to avoid address aliasing.OS_TASK_SWSTMFDsp!, lr; save pcSTMFDsp!, lr; save lrSTMFDsp!, r0-r12; save registers and ret addressMRSr4, CPSRSTMFDsp!, r4; s

29、ave current PSRMRSr4, SPSRSTMFDsp!, r4; save SPSR; OSPrioCur = OSPrioHighRdyLDRr4, addr_OSPrioCurLDRr5, addr_OSPrioHighRdyLDRBr6, r5STRBr6, r4; Get current task TCB addressLDRr4, addr_OSTCBCurLDRr5, r4STRsp, r5; store sp in preempted tasks's TCB; Get highest priority task TCB addressLDRr6, addr_

30、OSTCBHighRdyLDRr6, r6LDRsp, r6; get new task's stack pointer; OSTCBCur = OSTCBHighRdySTRr6, r4; set new current task TCB address ; restore task's mode regsitersLDMFDsp!, r4MSRSPSR_cxsf, r4LDMFDsp!, r4MSRCPSR_cxsf, r4 ; return in new task contextLDMFDsp!, r0-r12, lr, pc;void OSStartHighRdy(vo

31、id);Start the task with the highest priority;EXPORTOSStartHighRdyOSStartHighRdyLDRr4, addr_OSTCBCur; Get current task TCB addressLDRr5, addr_OSTCBHighRdy; Get highest priority task TCB addressLDRr5, r5; get stack pointerLDRsp, r5; switch to the new stackSTRr5, r4; set new current task TCB addressLDM

32、FDsp!, r4; YYYMSRSPSR_cxsf, r4LDMFDsp!, r4; get new state from top of the stackMSRCPSR_cxsf, r4; CPSR should be SVC32ModeLDMFDsp!, r0-r12, lr, pc ; start the new taskEND4. main.c文件#include "./inc/sys/lib.h"#include <string.h>#include <stdio.h>#include "./inc/drv/register.h

33、"#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endiftypedef 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

34、 signed int int32; /* 有符号32位整型变量 */typedef float fp32; /* 单精度浮点数(32位长度) */typedef double fp64; /* 双精度浮点数(64位长度) */#define Fosc12000000 /晶振频率,10MHz25MHz,应当与实际一至#define Fcclk(Fosc * 5) /系统频率,必须为Fosc的整数倍(132),且<=60MHZ#define Fcco(Fcclk * 4) /CCO频率,必须为Fcclk的2、4、8、16倍,范围为156MHz320MHz#define Fpclk(Fccl

35、k / 4) * 4 /VPB时钟频率,只能为(Fcclk / 4)的1、2、4倍void DelayNS(uint32 dly) uint32 i; for(; dly>0; dly-) for(i=0; i<5000; i+);#define UART_BPS115200/* 定义通讯波特率 */void UART0_Ini(void) uint16 Fdiv; U0LCR = 0x83; / DLAB = 1,可设置波特率 Fdiv = (Fpclk / 16) / UART_BPS; / 设置波特率 U0DLM = Fdiv / 256; U0DLL = Fdiv % 25

36、6; U0LCR = 0x03;void UART0_SendByte(uint8 data) U0THR = data; / 发送数据 while( (U0LSR&0x40)=0 ); / 等待数据发送完毕void UART0_SendStr(uint8 const *str) while(1) if( *str = '0' ) break; UART0_SendByte(*str+); / 发送数据int main(void) PINSEL0 = 0x00000005; / 设置I/O连接到UART0 UART0_Ini();/ while(1) UART0_Sen

37、dStr(SEND_STRING); DelayNS(10);/ return(0);实验过程:uCOS-II 在ARM 微处理器上的移植及编译1在linux系统中用gcc编译已给出的.c和.h文件生成一个可执行的文件,在修改完编译器的报错后,无法实现,出现函数未定义undefined reference错误汇报。2后来经过老师的指导,要在ADS1.2 IDE编译环境下生成课执行的文件。3我重新修改了main.c头文件的输出结果,并重新deubug,生成输出文件,然后再次烧写,通信显示并成功。4进行虚拟机内的超级终端的通讯交互测试,参数设置为波特率115200,以防显示乱码

38、,数据位8 位,停止位1,无奇偶校验,软件硬件流控设为无,成功建立超级终端。设置虚拟机的端口选择端口COM1,并选择等待调试器打开端口。经过几次测试,终于通信成功。五、 设计结果与分析1串口线连接到ucos实验模块下方的串口上。 2做好以上第一步准备工作后,打开随光盘附带的软件LPC2000 Flash Utility。3点击Read Device ID按键,然后重新启动目标机,然后点击确定获得相应的Part ID和BootLoader ID4结果失败,后来问老师才知道在up-techpxa270-s实验箱ucos实验模块的上方有一跳线:JP1501 LPC2119。烧写时应把跳线跳至1和2之

39、间。5获取ID后,选择要烧写到Flash中的文件,system.hex。6选中文件后,选择Upload to Flash。7进度条完成之后,在对话框左下方出现提示:File Upload Successfully Completed.8关闭up-techpxa270-s的电源,并且把模块上方的跳线跳至2和3之间。再打开电源和超级终端,观察从串口输出的信息,并且查看ucos实验模块显示的实验现象。9结果不正确,后来在虚拟机里新建了一个超级终端后,重启目标机,就可以看到显示结果了。分析:(一)对uC/OS-移植代码的理解uC/OS-的移植代码,主要涉及到三个文件,即OS_CPU.H、OS_CPU_

40、C.C、OS_CPU_A.S。对这三个文件的理解花费了我很长的时间,可能是因为之前从未接触过uC/OS-,因此对里面的一些定义以及为什么要这样定义都不怎么明白,特别是OS_CPU_A.S这个主文件,里面包含了许多ARM指令,包括在C中调用汇编时所要用到的汇编函数,基本每一条指令实现什么功能都能看懂,而结合在一起却并不了解它们所实现的功能是什么,于是便去搜索一些材料,包括查阅相关书籍,才大致明白了uC/OS-移植的相关信息。(二)将代码移植到开发板这部分采用的代码是原本的程序代码,在烧写的时候,读取设备ID这一步一直不成功,后来才知道是虚拟机里的串口设置设为None而导致的结果,更改了设置后再试一次就可以了。六、设计体会1. 通过此次实验,让我复习了嵌入式ARM系统软、硬件的基本知识,分析了uC/OS-II的源代码,对移植相关部分的代码作了分析解读,熟悉了ARM体系架构,最后基于ARM微处理器作了uC/OS-II的具体移植工作。不管是移植还是自己设计的,我想最终的目的是解决这个问题,这首先要有个好的学习态度,通过它让我自己认识到自

温馨提示

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

评论

0/150

提交评论