μCOS-II移植实验
- 格式:doc
- 大小:963.50 KB
- 文档页数:6
1、引言为了实现嵌入式系统终端连入互联网,而有必要为其引入了网络功能。
μC/OS II 是一个源代码开放的实时操作系统,但是它只是一个实时的任务调度及通信内核,并没有集成TCP/IP 通信协议,为了实现网络功能,需要在μC/OS II 移植一个轻量级的TCP/IP 通信协议LwIP。
本文主要论述μC/OS II 下通信协议LwIP 的移植以及测试。
2、LwIP 简介LwIP ( light weight IP)是瑞士计算机科学院的Adam Dunkels 等开发的一套开放TCP/IP 协议栈源代码。
LwIP 既可以移植到操作系统上,又可以在无操作系统的情况下独立运行。
LwIP 实现的重点是在保持TCP/IP 协议主要功能的基础上减少对RAM 的占用,这使LwIP 适合在低端嵌入式系统中使用。
其主要特点如下:(1)支持多网络接口下IP 转发;(2)支持ICMP 协议;(3)包括试验性扩展的UDP;(4)包括简单的拥塞控制,RTT 估算和快速恢复和快速转发的TCP;(5)提供专门的内部回调接口(Raw API)用于提高应用程序性能;(6)可选择的Berkeley 接口API;3、LwIP 协议栈移植到μC/OS II 操作系统的具体实现3.1 嵌入式系统结构和LwIP 接口整个嵌入式系统的结构如图 1 所示,由ARM 微处理器、网卡、网络设备驱动、μC/OSII 操作系统、LwIP 协议栈和应用程序组成。
图 1 嵌入式系统结构图LwIP 在设计时为了适应不同的操作系统,并没有在代码中使用和某个特定的操作系统相关的系统调用和数据结构,而是在LwIP 和操作系统之间提供了一个接口层(sys_arch interface),该接口主要实现的功能包括数据类型的定义、存储模式的选择、任务间的同步、时间和内存的管理等。
因此,完成LwIP 在μC/OS II 移植,我们就是要通过修改这个接口层来实现。
同时,还要根据自己所要实现的具体目的,可以对LwIP 协议栈进行一定的裁减。
昆明理工大学信息工程与自动化学院学生实验报告(2012—2013 学年第 2 学期)课程名称:嵌入式系统设计开课实验室:实验五μC/OS-II移植实验一、实验目的●了解μC/OS-II移植条件和内核基本结构。
●掌握将μC/OS-II内核移植到ARM7处理器上的方法和步骤。
二、实验原理1.μC/OS-II文件体系μC/OS-II的文件体系结构见图1,其中应用软件层是基于μC/OS-II上的代码。
μC/OS-II包括3个部分:1)核心代码部分:这部分代码与处理器无关,包括7个源代码文件和1个头文件。
它们负责的功能是内核管理、事件管理、消息队列管理、存储管理、消息管理、信号量处理、任务调度和定时管理。
2)设置代码部分:包括2个头文件,用来配置事件控制块的数目以及是否包含消息管理相关代码等。
3)处理器相关的移植代码部分:包括1个头文件、1个汇编文件和1个C代码文件。
在μC/OS-II的移植过程中,用户所需关注的就是这部分文件。
图1 μC/OS-II文件体系结构2.μC/OS-II移植条件1)处理器的C编译器能产生可重入代码。
可重入代码指的是可以被多个任务同时调用,而不会破坏数据的一段代码;或者说代码具有在执行过程中打断后再次被调用的能力。
2)用C语言就可以打开和关闭中断。
ARM处理器核包含一个CPSR寄存器。
该寄存器包括一个全局中断禁止位,控制它打开和关闭中断。
3)处理器支持中断并且能产生定时中断。
ARM处理器都支持中断并能产生定时中断。
4)处理器支持容纳一定量数据的硬件堆栈。
对于一些只有10根地址线的8位控制器,芯片最多可访问1KB存储单元。
在这样的条件下移植是比较困难的。
5)处理器有将堆栈指针和其他CPU寄存器读出和存储到堆栈或内存中的指令。
ARM处理器中汇编指令STMFD可以将所有寄存器压栈,对应也有一个出栈的指令LDMFD。
三、实验内容移植μC/OS-II内核到ARM处理器S3C44B0,在IDE中观察其运行状况。
四、实验步骤1.基本的配置和定义所有需要完成的基本配置和定义全部集中在OS_CPU.H中。
1)定义与编译器相关的数据类型μC/OS-II为保证可移植性,程序中没有直接使用int、unsigned int等定义,而是自己定义了一套数据类型。
2)定义使能和禁止中断宏3)定义栈的增长方向用户规划好栈的增长方向后,定义符号OS_STK_GROWTH的值。
4)定义OS_TASK_SW宏此宏是μC/OS-II从低优先级任务切换到高优先级任务时的调用,可采用两种方式定义:若处理器支持软中断,可使用软中断将中断向量指向OSCtxSW函数;也可直接调用OSCtxSW函数。
2.移植OS_CPU_A.ASM汇编代码文件OS_CPU_A.ASM汇编代码文件有4个汇编函数需要移植。
1)OSStartHighRdy()该函数由OSStart()调用。
OSStart()负责使就绪状态的任务开始运行,其中OSStartHighRdy()负责获取新任务的堆栈指针,并从堆栈指针中恢复新任务的所有处理器。
2)OSCtxSw()该函数由OS_TASK_SW宏调用。
OS_TASK_SW宏由OSSched()调用。
OSSched()负责任务之间的切换。
OSCtxSw()在OSSched()中负责将当前任务对应的处理器寄存器保存到堆栈中,并将任务中需要恢复的处理器寄存器从堆栈中恢复出来。
3)OSIntCtxSw()该函数由OSIntExit()调用。
OSIntExit()由OSTickISR()调用。
OSIntCtxSw()负责在定时中断中任务之间的切换。
4)OSTickISR()时钟节拍函数,由定时中断产生,主要负责在进入时保存处理器寄存器,完成任务切换,退出时恢复寄存器并返回。
3.移植OS_CPU_C.C标准C代码文件OS_CPU_C.C标准C代码文件中有6个函数需要移植。
1)OSTaskStkInit();2)OSTaskCreatHook();3)OSTaskDelHook();4)OSTaskSwHook();5)OSTaskStatHook();6)OSTimeTickHook();后面5个Hook函数又称为钩子函数,主要用来扩展μC/OS-II功能,但必须声明,并不一定要包含任何代码。
唯一必须移植的函数是OSTaskStkInit函数,该函数在任务创建时被调用,它负责初始化任务的堆栈结构。
五、实验参考程序1.OSStartHighRdyldr r4, =addr_OSTCBCur //获得当前任务的TCB地址ldr r5, =addr_OSTCBHighRdy //获得高优先级任务的TCB地址ldr r5, [r5] //获得堆栈指针ldr sp, [r5] //切换到新的堆栈str r5, [r4] //设置当前新任务的TCB地址ldmfd sp!, {r4}msr SPSR_cxsf, r4ldmfd sp!, {r4} //从栈顶获得新状态msr CPSR_cxsf, r4ldmfd sp!, {r0-r12, lr, pc} //启动新任务2.OSCtxSwstmfd sp!, {lr} //保存PC指针stmfd sp!, {lr} //保存LR寄存器stmfd sp!, {r0-r12 } //保存寄存器返回地址mrs r4, cpsrstmfd sp!, {r4} //保存当前CPSR寄存器mrs r4, spsrstmfd sp!, {r4} //保存当前SPSR寄存器# 赋值OSPrioCur = OSPrioHighRdyldr r4, =OSPrioCurldr r5, =OSPrioHighRdy //赋OSPrioCur为当前优先级最高级ldrb r6, [r5]strb r6, [r4]# 获得当前任务的TCB地址ldr r4, =OSTCBCurldr r5, [r4]str sp, [r5] //保存堆栈指针到抢先任务的TCB # 获得高优先级任务的TCB地址ldr r6, =OSTCBHighRdyldr r6, [r6]ldr sp, [r6] //获得新任务的堆栈指针#赋值OSTCBCur = OSTCBHighRdyStr r6, [r4] //设置当前新任务的TCB地址ldmfd sp!, {r4} //按寄存器压栈顺序出栈msr SPSR_cxsf, r4ldmfd sp!, {r4}msr CPSR_cxsf, r4ldmfd sp!, {r0-r12, lr, pc}3.OSIntCtxSwldmia sp!,{ r0-r11, lr} //寄存器压栈sub lr, lr, #4str lr, SA VED_LR //保存LR寄存器#切换到管理员模式mrs lr, SPSRand lr, lr, #0xFFFFFFE0orr lr, lr, #0x13msr CPSR_cxsf, lr#进入管理模式str r12, [sp, # - 8] //保存R12寄存器ldr r12, SA VED_LRstmfd sp!, {r12} //恢复R12保存的任务的PC指针sub sp, sp, #4 //栈指针增加ldmia sp!, {r12} //恢复R12寄存器stmfd sp!, {r12} //保存LR寄存器stmfd sp!, {r0 – r12} //保存寄存器和返回地址mrs r4, CPSRstmfd sp!, {r4} //保存当前CPSR寄存器mrs r4, SPSRstmfd sp!, {r4} //保存当前SPSR寄存器#赋值OSPrioCur= OSPrioHighRdyldr r4, addr_OSPrioCurldr r5, addr_OSPrioHighRdy //赋值OSPrioCur为当前优先级最高级ldrb r6, [r5]ldrb r6, [r4]#获得当前任务的TCB地址ldr r4, addr_OSTCBCurldr r5, [r4]str sp, [r5] //将堆栈指针保存到抢先任务的TCB #获得高优先级任务的TCB地址ldr r6, addr_OSTCBHighRdyldr r6, [r6]ldr sp, [r6]#赋值OSPrioCur= OSPrioHighRdystr r6, [r4] //设置当前新任务的TCB地址ldmfd sp!, {r4} //弹出保存的寄存器并返回msr SPSR_cxsf, r4ldmfd sp!, {r4}msr CPSR_cxsf, r4ldmfd sp!, {r0 – r12, lr, pc}4.OSTickISRstmdb sp!, {r0 – r11,lr}#禁止中断mrs r0, CPSRorr r0, r0, #0x80msr CPSR_cxsf, r0#中断结束清除中断挂起位ldr ro, =I_ISPCldr r1, =BIT_TIMER0str r1, [r0]bl IrqStartbl OSTimeTickbl IrqFinishcmp a1, #0ldrne pc, =_OSIntCtxSw六、实验结果和实验分析体会本次实验通过在老师的指导和同学的帮助下,让我掌握了μC/OS-II的应用以及启动流程;并了解了μC/OS-II操作系统的软件体系结构,掌握μC/OS-II 应用程序的基本结构,虽然对μC/OS-II的学习不是很到位,但是做到了解相关的概念以及基本的操作,并进一步提高了对μC/OS-II移植及应用的理解。