基于arm平台的uCOSII移植.docx
《基于arm平台的uCOSII移植.docx》由会员分享,可在线阅读,更多相关《基于arm平台的uCOSII移植.docx(51页珍藏版)》请在冰豆网上搜索。
![基于arm平台的uCOSII移植.docx](https://file1.bdocx.com/fileroot1/2023-2/21/22f9e064-4a83-4d3d-842f-eadbc5b0af24/22f9e064-4a83-4d3d-842f-eadbc5b0af241.gif)
基于arm平台的uCOSII移植
西南科技大学
创新基金项目过程与结果总结报告
基于ARM7平台的μC/OS-Ⅱ的移植
年级:
2007级
学号:
20076012
姓名:
吴友强
专业:
计算机科学与技术
二零一零年五月
一.准备工作
1.μC/OS-Ⅱ简介
uC/OS-II读做“microCOS2”,意为“微控制器操作系统版本2”。
uC/OS-II是著名的,源代码公开的实时内核,可用于各类8位,16位和32位单片机或DSP。
从uC/OS算起,该内核已有十多年应用历史,在诸多领域得到广泛应用。
简要说明一下该题目的特点和它的实际意义和社会价值。
(约250字并翻译英文)
2.μC/OS-Ⅱ的特点
(1)提供源代码
(2)可固化
(3)可裁剪
(4)可剥夺
(5)多任务
(6)可确定性
(7)任务栈
(8)系统服务
(9)中断管理
(10)稳定性与可靠性
3.编译器的选择
ARM处理器核的C编译器有很多,大概有SDT,ADS1.2,IAR,TASKING和GCC等。
我最终选择的是ADS1.2编译程序和调试。
为什么要选择ADS1.2,要简要说明理由。
(约200字)
4.ARM7简介
ARM7处理器核具有用户,系统,管理,中止,未定义,中断和快中断7中工作模式。
其中除了用户模式外其他均为特权模式。
同时支持两个指令集:
16位Thumb指令集和32位ARM指令集。
为什么要选择ARM7,而不选ARM9或ARMX的高版本进行uC/OS-II的移植,简要说明理由。
(约200字)
5.开发环境的搭建
操作系统:
WindowsXP
集成开发环境:
ADS1.2
调试环境:
AXD(ADS1.2配套的软件)
串口调试工具
6.项目中所运用到的技术创新
(1)实现了加密程序,保护了用户应用程序代码,利用在特定的地址0x1fc处写入特定的值0x87654321实现加密
(2)通过工程配置文件加载程序代码,实现了写应用程序的模板工程,不用每次配置工程设置
(3)初始化程序和操作系统代码都留有很多扩充的接口,方便不同的用户需要实现不同的启动代码功能和扩充操作系统的功能
7.项目的特色
(1)在本文档中有完整的源代码,并且有很详细的注释
(2)只要具备同样的软硬件环境,根据我的《过程与结果总结报告》完全可以实现这个项目
(3)同时完成了引导程序和操作系统的移植
(4)涉及到软硬件的知识,不仅仅只是软件
2.移植过程
1.编写bootloader(ARM启动代码)
1.启动代码综述(精确简述移植过程,关键程序不要省略,其它程序可用流程图表达和说明即可。
)
在一般32位ARM应用系统中,软件大多数采用C语言进行编程,并且以嵌入式操作系统为开发平台,这样大大的提高了开发效率及软件性能。
为了能够进行系统初始化,通常会用一个汇编文件作为启动代码。
它可以实现向量表定义、堆栈初始化、系统变量初始化、中断系统初始化、I/O初始化、外围初始化和地址重映射等操作。
ARM公司之设计内核,不生产芯片,只是把内核授权给其他厂商。
其他厂商购买了授权后加入自己的外设,生产出各具特色的芯片。
这样就促进了基于ARM处理器核的芯片的多元化,但也使得各种芯片的启动代码差别很大,不易编写出统一的启动代码。
2.文件的组成
汇编文件1.Startup.S:
异常向量表、各模式堆栈初始化和跳到main()函数入口等
2.IRQ.S:
负责管理中断嵌套
C文件Target.C:
初始化目标板
头文件Config.H:
系统配置和类型定义
Target.H:
一些和目标板相关的声明
LPC2294.H:
LPC2000系列芯片特殊寄存器定义
分散加载文件mem_a.Scf:
在片内Flash发布,RelInFLASH
Mem_b.Scf:
在片内RAM调试,DebugInRAM,在uCOSII中不使用这种布局模式
Mem_c.Scf:
在片内Flash调试,DebugInFLASH
3.各源代码文件内容及其注释
1.Startup.S:
;**--------------FileInfo---------------------------------------------
;**Filename:
Startup.s
;**LastmodifiedDate:
2009-08-17
;**LastVersion:
1.0
;**Descriptions:
为LPC2100系列芯片的启动代码,从这里开始执行,包括初始化代码,为每一种模
;**式的进入口和任务的堆栈
;定义堆栈的大小
SVC_STACK_LEGTHEQU0
FIQ_STACK_LEGTHEQU0
IRQ_STACK_LEGTHEQU256
ABT_STACK_LEGTHEQU0
UND_STACK_LEGTHEQU0
NoIntEQU0x80;Bit7,I位
NoFIQEQU0x40;Bit6,F位
USR32ModeEQU0x10;M[4:
0]=10000,用户模式
SVC32ModeEQU0x13;M[4:
0]=10011,管理模式
SYS32ModeEQU0x1f;M[4:
0]=11111,系统模式
IRQ32ModeEQU0x12;M[4:
0]=10010,IRQ中断
FIQ32ModeEQU0x11;M[4:
0]=10001,快速中断
IMPORT__use_no_semihosting_swi
;引入的外部标号在这声明
IMPORTFIQ_Exception;快速中断异常处理程序
IMPORT__main;C语言主程序入口
IMPORTTargetResetInit;目标板基本初始化
;给外部使用的标号在这声明
EXPORTbottom_of_heap
EXPORTStackUsr
EXPORTReset
EXPORT__user_initial_stackheap
CODE32
AREAvectors,CODE,READONLY
ENTRY
;中断向量表
Reset
LDRPC,ResetAddr;0x00,复位
LDRPC,UndefinedAddr;0x04,未定义地址
LDRPC,SWI_Addr;0x08,软件中断
LDRPC,PrefetchAddr;0x0c,预取指中止
LDRPC,DataAbortAddr;0x10,数据中止
DCD0xb9205f80;0x14,保留
LDRPC,[PC,#-0xff0];0x18,IRQ中断
LDRPC,FIQ_Addr;0x1C,快速中断
ResetAddrDCDResetInit;复位初始化处理程序地址
UndefinedAddrDCDUndefined;未定义指令处理程序地址
SWI_AddrDCDSoftwareInterrupt;软件中断处理程序地址
PrefetchAddrDCDPrefetchAbort;预取指中止处理程序地址
DataAbortAddrDCDDataAbort;数据中止处理程序地址
NouseDCD0;未使用
IRQ_AddrDCD0;IRQ中断,已在"LDR[PC,#-0xff0]"中处理
FIQ_AddrDCDFIQ_Handler
;未定义指令
Undefined
BUndefined;死循环
;软中断
SoftwareInterrupt
;BSoftwareInterrupt
;//增加开/关中断处理
CMPR0,#4;判断传过来的参数是否大于4
LDRLOPC,[PC,R0,LSL#2];小于4(参数正确),进行查表
MOVSPC,LR;大于或者等于4(参数出错),则返回
SwiFunction
DCDIRQDisable;0号调用,禁止IRQ中断
DCDIRQEnable;1号调用,使能IRQ中断
DCDFIQDisable;2号调用,禁止FIQ中断
DCDFIQEnable;3号调用,使能FIQ中断
IRQDisable
;关IRQ中断
MRSR0,SPSR;读取SPSR的值
ORRR0,R0,#NoInt;置位I位,设置关IRQ中断
MSRSPSR_c,R0;回写SPSR
MOVSPC,LR;返回
IRQEnable
;开IRQ中断
MRSR0,SPSR
BICR0,R0,#NoInt;清零I位,设置开IRQ中断
MSRSPSR_c,R0
MOVSPC,LR
FIQDisable
;关FIQ中断
MRSR0,SPSR
ORRR0,R0,#NoFIQ;置位F位,设置关FIQ中断
MSRSPSR_c,R0
MOVSPC,LR
FIQEnable
;开FIQ中断
MRSR0,SPSR
BICR0,R0,#NoFIQ;清零F位,设置开FIQ中断
MSRSPSR_c,R0
MOVSPC,LR
;取指令中止
PrefetchAbort
BPrefetchAbort;死循环
;取数据中止
DataAbort
BDataAbort;死循环
;快速中断
FIQ_Handler
STMFDSP!
{R0-R3,LR};寄存器R0~R3,LR入栈
BLFIQ_Exception;调用FIQ处理程序
LDMFDSP!
{R0-R3,LR};寄存器R0~R3,LR出栈
SUBSPC,LR,#4;计算返回地址
;/*****************************************************************************************
;**unctionname函数名称:
InitStack
;**Descriptions功能描述:
初始化堆栈
;**Createdby作 者:
吴友强
;**CreatedDate日 期:
2009/07/202009年7月20日
;*****************************************************************************************/
;初始化堆栈,此时禁止IRQ和FIQ中断,处于ARM状态
InitStack
MOVR0,LR
;BuildtheSVCstack
;设置管理模式堆栈
MSRCPSR_c,#0xd3
LDRSP,StackSvc
;BuildtheIRQstack
;设置中断模式堆栈
MSRCPSR_c,#0xd2
LDRSP,StackIrq
;BuildtheFIQstack
;设置快速中断模式堆栈
MSRCPSR_c,#0xd1
LDRSP,StackFiq
;BuildtheDATAABORTstack
;设置中止模式堆栈
MSRCPSR_c,#0xd7
LDRSP,StackAbt
;BuildtheUDFstack
;设置未定义模式堆栈
MSRCPSR_c,#0xdb
LDRSP,StackUnd
;BuildtheSYSstack
;设置系统模式堆栈
MSRCPSR_c,#0xdf;切换到系统模式,之后将在系统模式下运行
LDRSP,=StackUsr;除非进行模式切换
MOVPC,R0
;/*****************************************************************************************
;**unctionname函数名称:
ResetInit
;**Descriptions功能描述:
复位入口
;**Createdby作 者:
吴友强
;**CreatedDate日 期:
2009/07/202009年7月20日
;**----------------------------------------------------------------------------------------
;*****************************************************************************************/
ResetInit
BLInitStack;初始化堆栈
BLTargetResetInit;目标板基本初始化
B__main;跳转到c语言入口
;/*****************************************************************************************
;**unctionname函数名称:
__user_initial_stackheap
;**Descriptions功能描述:
库函数初始化堆和栈,不能删除
;**Createdby作 者:
吴友强
;**CreatedDate日 期:
2009/07/202009年7月20日
;*****************************************************************************************/
__user_initial_stackheap
LDRr0,=bottom_of_heap
;LDRr1,=StackUsr
MOVpc,lr
StackSvcDCDSvcStackSpace+(SVC_STACK_LEGTH-1)*4;管理模式堆栈
StackIrqDCDIrqStackSpace+(IRQ_STACK_LEGTH-1)*4;IRQ模式堆栈
StackFiqDCDFiqStackSpace+(FIQ_STACK_LEGTH-1)*4;FIQ模式堆栈
StackAbtDCDAbtStackSpace+(ABT_STACK_LEGTH-1)*4;中止模式堆栈
StackUndDCDUndtStackSpace+(UND_STACK_LEGTH-1)*4;未定义模式堆栈
;/*****************************************************************************************
;**unctionname函数名称:
CrpData
;**Descriptions功能描述:
芯片加密,代码保护
;**inputparameters输 入:
None无
;**Returnedvalue输 出:
None无
;**Usedglobalvariables全局变量:
None无
;**Callingmodules调用模块:
None无
;**
;**Createdby作 者:
吴友强
;**CreatedDate日 期:
2009/07/202009年7月20日
;*****************************************************************************************/
IF:
DEF:
EN_CRP
IF.>=0x1fc
INFO1,"\nThedataat0x000001fcmustbe0x87654321.\nPleasedeletesomesourcebeforethisline."
ENDIF
CrpData
WHILE.<0x1fc;循环用NOP填充,直到0x1FC
NOP
WEND
CrpData1
DCD0x87654321;/*当此数为0x87654321时,用户程序被保护*/
ENDIF
;/*分配堆栈空间*/
AREAMyStacks,DATA,NOINIT,ALIGN=2
SvcStackSpaceSPACESVC_STACK_LEGTH*4;管理模式堆栈空间
IrqStackSpaceSPACEIRQ_STACK_LEGTH*4;中断模式堆栈空间
FiqStackSpaceSPACEFIQ_STACK_LEGTH*4;快速中断模式堆栈空间
AbtStackSpaceSPACEABT_STACK_LEGTH*4;中止义模式堆栈空间
UndtStackSpaceSPACEUND_STACK_LEGTH*4;未定义模式堆栈
AREAHeap,DATA,NOINIT;Heap通过分散加载文件定位
bottom_of_heapSPACE1
AREAStacks,DATA,NOINIT;Stack通过分散加载文件定位
StackUsr
END
2.IRQ.S
NoIntEQU0x80
USR32ModeEQU0x10
SVC32ModeEQU0x13
SYS32ModeEQU0x1f
IRQ32ModeEQU0x12
FIQ32ModeEQU0x11
CODE32
AREAIRQ,CODE,READONLY
MACRO
$IRQ_LabelHANDLER$IRQ_Exception_Function
EXPORT$IRQ_Label;输出的标号
IMPORT$IRQ_Exception_Function;引用的外部标号
$IRQ_Label
SUBLR,LR,#4;计算返回地址
STMFDSP!
{R0-R3,R12,LR};保存任务环境
MRSR3,SPSR;保存状态
STMFDSP,{R3,LR}^;保存SPSR和用户状态的SP,注意不能回写
;如果回写的是用户的SP,所以后面要调整SP
NOP
SUBSP,SP,#4*2
MSRCPSR_c,#(NoInt|SYS32Mode);切换到系统模式
BL$IRQ_Exception_Function;调用c语言的中断处理程序
MSRCPSR_c,#(NoInt|IRQ32Mode);SwitchbaktoIRQmode切换回irq模式
LDMFDSP,{R3,LR}^;恢复SPSR和用户状态的SP,注意不能回写
;如果回写的是用户的SP,所以后面要调整SP
MSRSPSR_cxsf,R3
ADDSP,SP,#4*2
LDMFDSP!
{R0-R3,R12,PC}^
MEND
;/*以下可添加中断句柄,根据实际情况改变*/
;Timer0_HandlerHANDLERTimer0
END
3.Target.C
#defineIN_TARGET
#include"config.h"
void__irqIRQ_Exception(void)
{
while
(1);//这一句替换为自己的代码
}
voidFIQ_Exception(void)
{
while
(1);//这一句替换为自己的代码
}
voidTargetInit(void)
{
/*添加自己的代码*/
}
voidTargetResetInit(void)
{
#ifdef__DEBUG_RAM//如果在片内RAM调试
MEMMAP=0x2;//映射到片内RAM
#endif
#ifdef__DEBUG_FLASH//如果在片内Flash调试
MEMMAP=0x1;//映射到片内FLASH
#endif
#ifdef__IN_CHIP//如果在片内Flash发布(将会被加密)
MEMMAP=0x1;//映射到片内FLASH
#endif
/*设置系统各部分时钟*/
PLLCON=1;//设置激活但未连接PLL
#if(Fpclk/(Fcclk/4))==1
VPBDIV=0;
#endif
#if(Fpclk/(Fcclk/4))==2
VPBDIV=2;
#endif
#if(Fpclk/(Fcclk/4))==4
VPBDIV=1;
#endif
//设定PLL的乘因子M和除因子P的值
#if(Fcco/Fcclk)==2
PLLCFG=((Fcclk/Fosc)-1)|(0<<5);
#endif
#if(Fcco/Fcclk)==4
PLLCFG=((Fcclk/Fosc)-1)|(1<<5);
#endif
#if(Fcco/Fcclk)==8
PLLCFG=((Fcclk/Fosc)-1)|(2<<5);
#endif
#if(Fcco/Fcclk)==16
PLLCFG=((Fcclk/Fosc)-1)|(3<<5);
#endif
PLLFEED=0xaa;//发送PLL馈送序列,执行设定PLL的动作
PLLFEED=0x55;
while((PLLSTAT&(1<<10))==0);//等待PLL锁定
PLLCON=3;//设置激活并连接PLL
PLLFEED=0xaa;//发送PLL馈送序列,执行激活和链接动作
PLLFEED=0x55;
/*设置存储器加速模块*/
MAMCR=0;//禁止MAM功能
#ifFcclk<20000000//根据Fcclk的大小来设置MAM定时寄存器
MAMTIM=1;
#else
#ifFcclk<40000000
MAMTIM=2;
#else
MAMTIM=3;
#endif
#endif
MAMCR=2;//使能M