ucosii在arm移植.docx
- 文档编号:23486547
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:21
- 大小:103.96KB
ucosii在arm移植.docx
《ucosii在arm移植.docx》由会员分享,可在线阅读,更多相关《ucosii在arm移植.docx(21页珍藏版)》请在冰豆网上搜索。
ucosii在arm移植
设计题目
1uCOS-II 在ARM 微处理器上的移植及编译
2设计目的与要求
1.了解uCOS-II内核的主要结构。
2.掌握将uCOS-II内核移植到ARM处理器上的基本方法。
3.在给定的设备(UP-TECHPXA270-S嵌入式开发平台、PC机、WinXP、ADS1.2集成开发环境、仿真器驱动程序、超级终端通讯程序。
)上加以实验,学会自己分析、找出解决问题的方法;
4.对设计中遇到的问题和困难,独立思考,查阅资料,分析、观察、判断、试验、再判断以寻找答案。
5.分析结果,写出设计总结报告论述自己的观点,并应将参考资料列在报告后面以备查询。
内容尽量翔实(如上机过程、环境搭建),其中必须有按自己所理解、用自己的语言所描述的内容,否则不予计分。
3设计环境或器材、原理与说明
4设计过程(步骤)或程序代码
Main.c:
Cmain函数,ucos-ii初始化等定义
#include"../inc/sys/lib.h"
#include
#include
#include"../inc/drv/register.h"/*register.h中时对philipsarm2xxx寄存器的定义*/
#ifndefTRUE
#defineTRUE1
#endif
#ifndefFALSE
#defineFALSE0
#endif
typedefunsignedcharuint8;/*无符号8位整型变量*/
typedefsignedcharint8;/*有符号8位整型变量*/
typedefunsignedshortuint16;/*无符号16位整型变量*/
typedefsignedshortint16;/*有符号16位整型变量*/
typedefunsignedintuint32;/*无符号32位整型变量*/
typedefsignedintint32;/*有符号32位整型变量*/
typedeffloatfp32;/*单精度浮点数(32位长度)*/
typedefdoublefp64;/*双精度浮点数(64位长度)*/
/*系统设置,Fosc、Fcclk、Fcco、Fpclk必须定义*/
#defineFosc12000000//晶振频率,10MHz~25MHz,应当与实际一至
#defineFcclk(Fosc*5)//系统频率,必须为Fosc的
整数倍(1~32),且<=60MHZ
#defineFcco(Fcclk*4)//CCO频率,必须为Fcclk的2、4、
8、16倍,范围为156MHz~320MHz
#defineFpclk(Fcclk/4)*4//VPB时钟频率,只能为
(Fcclk/4)的1、2、4倍
(上面这些系统频率的设置是要与我们要连接的硬件(即目标机)相一致的,只有这些频率与目标机相一致才可以观察到实验现象,否则会出错。
)
voidDelayNS(uint32dly)
{uint32i;
for(;dly>0;dly--)
for(i=0;i<5000;i++);
}/*长软件延时*/
#defineUART_BPS115200/*定义通讯波特率*/
voidUART0_Ini(void)
{uint16Fdiv;
U0LCR=0x83;//DLAB=1,可设置波特率
Fdiv=(Fpclk/16)/UART_BPS;//设置波特率
U0DLM=Fdiv/256;
U0DLL=Fdiv%256;
U0LCR=0x03;
}/*初始化串口0。
设置为8位数据位,1位停止位,无奇偶校验,波特率为115200*/
voidUART0_SendByte(uint8data)
{U0THR=data;//发送数据(data为要发送的数据)
while((U0LSR&0x40)==0);//等待数据发送完毕
}/*向串口发送字节数据,并等待发送完毕*/
voidUART0_SendStr(uint8const*str)
{while
(1)
{if(*str=='\0')break;
UART0_SendByte(*str++);//发送数据(str为要发送的
字符串的指针)
}
}/*向串口发送一字符串*/
uint8constSEND_STRING[]="FINISHMYWORK!
\n";
intmain(void)
{PINSEL0=0x00000005;//设置I/O连接到UART0
UART0_Ini();
//while
(1){
UART0_SendStr(SEND_STRING);
DelayNS(10);
//}
return(0);
}/*向串口UART0发送字符串"FINISHMYWORK!
"*/
头文件lib.h:
C库函数定义头文件
#ifndef__LIB_H__
#define__LIB_H__
#include"io.h"//标准输入输出函数
#include"sysdrv.h"//驱动抽象层头文件
#include"../inc/marco.h"//环行缓冲区的添加以及管理的宏定义
#include
/*VERSION版本号定义*/
#defineMAJOR_VERSION1
#defineMINOR_VERSION0
#defineBUILD_VERSION1
#defineVERSION((MAJOR_VERSION)|(MINOR_VERSION<<8)|(BUILD_VERSION<<16))
#defineVERSION_STR"BuildVersion%d.%d.%4.4d\n",MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION/*定义它们的类型*/
/*CONSOLE宏定义,定义串口输出输出的控制台*/
#defineCONSOLE0//fordebug
#defineTRACEprintf//forkernelinformationoutput
#defineprintkprintf
voidprintfNULL(char*fmt,...);
#definegetchartimeout(buffer,n,timeout)
Uart_GetchTimeout(CONSOLE,(char*)buffer,n,timeout)
#defineUart_SendChar(nUart,ch)do{if((ch)=='\n')Uart_SendByte((nUart),'\r');\
Uart_SendByte((nUart),(ch));}while(0)
//定义标准控制台输出函数(CONSOLE_PUTC)
#defineCONSOLE_PUTC(ch)Uart_SendChar(CONSOLE,(ch))
//定义标准控制台输入函数(CONSOLE_GETC)
#defineCONSOLE_GETC()Uart_Getch(CONSOLE)
/*定义系统配置*/
#defineMCLKFcclk
#defineMBASECLKFosc
/*定义mdelay宏,毫秒级延时*/
#definemdelay(n)udelay(n*1000)
#defineSECONDOS_TICKS_PER_SEC
/*功能定义*/
typedefvoid(*serial_loop_func_t)(void);
/*定义缓冲区(P15为内存管理的协处理器)*/
//#defineFlushCache()__asm{mcrp15,0,r0,c7,c7,0}
/*lib.c*/
voidudelay(inttime);//WatchdogTimerisused.
voidPort_Init(void);//端口初始化
intUart_Init(intwhichUart,intbaud);
intSet_UartLoopFunc(serial_loop_func_tfunc);
intClear_UartLoopFunc(intindex);
charUart_Getch(intwhichUart);
intUart_GetchTimeout(intwhichUart,char*pbuffer,intn,inttimeout);
intUart_Poll(intwhichUart);
intUart_SendByte(intwhichUart,intdata);
intUart_GetIntNum(intwhichUart);
voidUart_Printf(intwhichUart,char*fmt,...);
voidUart_SendString(intwhichUart,char*pt);
intSet_UartLoopFunc(serial_loop_func_tfunc);
intClear_UartLoopFunc(intindex);
#endif
观察并分析ucos-ii文件夹内容:
A、与处理器无关的文件:
os_core.c
os_flag.c
os_mbox.c
os_mem.c
os_mutex.c
os_q.c
os_sem.c
os_task.c
os_time.c
ucos_II.C
ucos_ii.h
这些文件在移植过程中,只需要给函数加上重入属性即可。
B、与应用相关的文件:
includes.h:
包含内核的标准库头文件;
os_cfg.h:
“OS_TICKS_PER_SEC”、“OS_FLAGS”注意可能需要修改。
C、与处理器相关的文件:
os_cpu.h:
数据类型、关中断方法、任务堆栈方向、任务切换的宏定义都需要修改。
os_cpu_a.s:
OSTickISR()、OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()这几个函数的编写,是整个移植的关键。
os_cpu_c.c:
OSTaskStkInit()函数的编写,移植μC/OS-II需要在OS_CPU_C.C中定义六个函数,而实际上需要定义的只有OSTaskStkInit()一个函数。
该函数用来初始化任务的堆栈
OSADDTASK.C:
(其中调用了osaddition.h和OSADDTASK.h)
#include"../ucos-ii/includes.h"/*uC/OSinterface*/
#include"../ucos-ii/add/osaddition.h"//包含创建系统附加任务的头文件
#include"../inc/drivers.h"//系统设置以及定义各个频率的头文件
#include"../inc/marco.h"//环行缓冲区的添加以及管理的宏定义
#include"../inc/sys/lib.h"
#include"../inc/drv/tchScr.h"//触摸屏任务的头文件
OS_STKSYS_Task_Stack[64];//systemtask刷新任务堆栈
#defineSYS_Task_Prio//定义OS任务
staticvoidSYS_Task(void*Id);
/***************************************
系统任务,有最高的优先级
(1),启动系统的其他任务
****************************************/
staticvoidSYS_Task(void*Id)
{
OSRunning=TRUE;//系统开始运行
uHALr_InstallSystemTimer();//OpenUartRev(0)打开缓冲区;
printk("startsystemtask.\n");
#ifOS_KeyBoard_Scan_Task==1//键盘初始化
#endif
OSTaskDel(OS_PRIO_SELF);
}
voidOSAddTask_Init()//系统附加任务的初始化定义
{
#ifOS_KeyBoard_Scan_Task==1
Key_init();
#endif
OSTaskCreate(SYS_Task,(void*)0,(OS_STK*)&SYS_Task_Stack[64-1],SYS_Task_Prio);//创建系统任务(STACKSIZE=8*8=64)
}
os_cpu_c.c:
#include"includes.h"/*fromuCOSdirectory*/
//#include"ipport.h"/*fromInternichedirectory*/
/*初始化任务的堆栈
OSTaskCreate()和OSTaskCreateExt()通过调用OSTaskStkInit()来初始化任务的堆栈结构。
因此,堆栈看起来就像刚发生过中断并将所有的寄存器保存到堆栈中的情形一样。
这里我们定义了堆栈是从上往下长的。
在用户建立任务的时候,用户传递任务的地址,pdata指针,任务的堆栈栈顶和任务的优先级给OSTaskCreate()和OSTaskCreateExt()。
一旦用户初始化了堆栈,OSTaskStkInit()就需要返回堆栈指针所指的地址。
OSTaskCreate()和OSTaskCreateExt()会获得该地址并将它保存到任务控制块(OS_TCB)中。
*/
OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt)
{
unsignedint*stk;/*把指针定义成无符号数*/
stk=(unsignedint*)ptos;/*装载堆栈指针*/
opt++;
/*建立任务环境,使用满递减堆栈*/
*--stk=(unsignedint)task;/*pc*/
*--stk=(unsignedint)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*/
*--stk=4;/*r4*/
*--stk=3;/*r3*/
*--stk=2;/*r2*/
*--stk=1;/*r1*/
*--stk=(unsignedint)pdata;/*r0第一个参数使用R0传递*/
*--stk=(SUPMODE);/*cpsr*/
*--stk=(SUPMODE);/*spsr允许IRQ,FIQ中断*/
return((OS_STK*)stk);//返回堆栈指针
}
#ifOS_CPU_HOOKS_EN
/*当用OSTaskCreate()和OSTaskCreateExt()建立任务的时候就会调用OSTaskCreateHook()。
该函数允许用户或使用移植实例的用户扩展μC/OS-Ⅱ功能。
当μC/OS-Ⅱ设置完了自己的内部结构后,会在调用任务调度程序之前调用OSTaskCreateHook()。
该函数被调用的时候中断是禁止的。
因此用户应尽量减少该函数中的代码以缩短中断的响应时间。
当OSTaskCreateHook()被调用的时候,它会收到指向已建立任务的OS_TCB的指针,这样它就可以访问所有的结构成员了。
*/
voidOSTaskCreateHook(OS_TCB*ptcb)
{
ptcb=ptcb;/*Preventcompilerwarning*/
}
/*当任务被删除的时候就会调用OSTaskDelHook()。
该函数在把任务从μC/OS-Ⅱ的内部任务链表中解开之前被调用。
当OSTaskDelHook()被调用的时候,它会收到指向正被删除任务的OS_TCB的指针,这样它就可以访问所有的结构成员了。
OSTaskDelHook()可以来检验TCB扩展是否被建立(一个非空指针)并进行一些清除操作*/
voidOSTaskDelHook(OS_TCB*ptcb)
{
ptcb=ptcb;/*Preventcompilerwarning*/
}
/*当发生任务切换的时候就会调用OSTaskSwHook()。
OSTaskSwHook()可以直接访问OSTCBCur和OSTCBHighRdy,因为它们是全局变量。
OSTCBCur指向被切换出去的任务OS_TCB,而OSTCBHighRdy指向新任务OS_TCB。
注意在调用OSTaskSwHook()期间中断一直是被禁止的。
因此用户应尽量减少该函数中的代码以缩短中断的响应时间。
*/
voidOSTaskSwHook(void)
{
}
/*OSTaskStatHook()每秒钟都会被OSTaskStat()调用一次。
用户可以用OSTaskStatHook()来扩展统计功能。
例如,用户可以保持并显示每个任务的执行时间,每个任务所用的CPU份额,以及每个任务执行的频率等。
*/
voidOSTaskStatHook(void)
{
}
/*OSTimeTickHook()在每个时钟节拍都会被OSTaskTick()调用。
实际上,OSTimeTickHook()是在节拍被μC/OS-Ⅱ真正处理,并通知用户的移植实例或应用程序之前被调用的。
*/
voidOSTimeTickHook(void)
{
}
/*任务控制块TCB的初始化*/
voidOSTCBInitHook(OS_TCB*ptcb)
{
ptcb=ptcb;/*PreventCompilerwarning*/
}
voidOSTaskIdleHook(void)
{
}
voidOSInitHookEnd(void)
{
}
voidOSInitHookBegin(void)
{
}
#endif
Os_cpu_a.s
;改写了OSIntCtxSw函数中栈指针调整的算法,根据:
;1、IRQStack栈的位置是固定的
;2、IRQ中断以后,在调用ISR_IrqHandler函数之前,仅仅有
;STMFDsp!
{r0-r12,lr}
;入栈,计算出栈指针调整的位置。
避免了因为OSIntExit等函数经过编译器优化入栈不固定的问题
EXPORTOSIntCtxSw//中断退出时的入口
EXPORTOS_TASK_SW
EXPORTINTS_OFF
EXPORTINTS_ON
INTS_OFF//关中断
mrsr0,cpsr;//当前CSR
movr1,r0;//复制屏蔽
orrr1,r1,#0xC0;//屏蔽中断位
msrCPSR_cxsf,r1;//关中断(IRQandFIQ)
andr0,r0,#0x80;//从初始CSR返回FIQ位
movpc,lr;//返回
INTS_ON//开中断
mrsr0,cpsr;//当前CSR
bicr0,r0,#0xC0;//屏蔽中断
msrCPSR_cxsf,r0;//开中断(IRQandFIQ)
movpc,lr;//返回
;Externalsymbolsweneedtheaddressesof
IMPORTOSTCBCur
addr_OSTCBCurDCDOSTCBCur
IMPORTOSTCBHighRdy
addr_OSTCBHighRdyDCDOSTCBHighRdy
IMPORTOSPrioCur
addr_OSPrioCurDCDOSPrioCur
IMPORTOSPrioHighRdy
addr_OSPrioHighRdyDCDOSPrioHighRdy
IMPORTIRQStack;FIQ_STACK
OSIntCtxSw//中断级的任务切换函数
/*
**函数名称:
OSIntCtxSw
**功能描述:
中断退出时的入口
**全局变量:
OSPrioCur,OSPrioHighRdy,OSPrioCur,OSPrioHighRdy*/
addr7,sp,#24;//保存寄存器指针
LDRsp,=IRQStack;IRQ_STACK;testtodelit
subr7,sp,#4;r7isthepositionthatjustEnterInterrupt
mrsr1,SPSR;//得到暂停的PSR
orrr1,r1,#0xC0;//关闭IRQ,FIQ.
msrCPSR_cxsf,r1;//转换模式(应该是SVC_MODE)
ldrr0,[r7,#52];
ldrr0,[r7];//从IRQ堆栈中得到IRQ'sLR(任务PC)
subr0,r0,#4;//当前PC地址是(saved_LR-4)
STMFDsp!
{r0};//保存任务PC
STMFDsp!
{lr};//保存LR
sublr,r7,#52;//进入IRQ中断的时候保存r0-r12
;movlr,r7;//保存FIQ堆栈ptrinLR(转到nuker7)ldmfdlr!
{r0-r12};//从FIQ堆栈中得到保存的寄存器
STMFDsp!
{r0-r12};//在任务堆栈中保存寄存器
//在任务堆栈上保存PSR和任务PSR
MRSr4,CPSR
bicr4,r4,#0xC0;//使中断位处于使能态
STMFDsp!
{r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ucosii arm 移植