UCOSII移植到STM32F103C8T6上之移植记录(一)

准备
1.C8T6工程模板(我用的是我平时的)
2.ucosii源码,官网下载的
链接: UCOS源码下载地址.

一,分析

源码打开后如图示
在这里插入图片描述

EvalBoards: 评估板相关文件,移植时提取部分
uC-CPU: 这是和CPU紧密相关的文件,我们不需要
uC-LIB: Micrium公司提供的官方库,诸如字符串操作、内存操作等接口,可用可不用
uCOS-II: 关键目录,Ports与Source所在。

Ports文件夹
没有基于MDK平台的代码版本,IAR跟MDK最为相近,以此目录为例。
os_cpu.h:定义数据类型、处理器相关代码、声明函数原型
oc_cpu_a.asm:与处理器相关的汇编代码,主要是与任务切换相关
os_cpu_c.c:定义用户钩子函数,提供扩充软件功能的的接口
os_dbg.c:内核调试相关数据和相关函数
Source文件夹
os_core.c:内核数据结构管理,ucos-ii的核心,涵盖内核的初始化,任务切换,事件块管理、事件标志组管理等功能
os_flag.c:事件标志组
os_mbox.c:消息邮箱
os_mem.c:内存管理
os_q.c:队列
os_sem.c:信号量
os_task.c:任务管理
os_time.c:时间管理,主要实现延时
os_tmr.c:定时器管理,设置定时时间,超时则调用超时函数
ucos_ii.h:内部函数参数设置
有图解释
UCOSII移植到STM32F103C8T6上之移植记录(一)_第1张图片

二,创建

根据个人习惯创建三个文件夹
app:app.c + app_cfg.h+includes.h +os_cfg.h
Src:os_core.c + os_flag.c+os_mbox.c + os_mem.c+kbdos_mutex.c + os_q.c+os_sem.c + os_task.c+ os_time.c+ os_tmr.c + ucos_ii.h
port:os_cpu.h + os_cpu_a.asm+os_cpu_c.c + os_dbg.c
其中app.c和app_cfg.h为手动创建,空的。
好了,然后添加到工程,然后解决报错。

三,解决报错

os_cfg.h  //配置uCOS-ii系统功能的头文件
#define OS_APP_HOOKS_EN           0    //禁用钩子函数
OS内部的函数名实际上是OSTCBInitHook,micrium在移植过程中为了层次清晰,
在 OS钩子函数内部增加了相应的APP***HOOK调用,同时通过功能开关OS_APP_HOOKS_EN来控制是否启用这些功能。
我们当前的代码除了 OS系统代码,其他什么应用代码都还没有,因此编译会出错。
这种情况下我们需要暂时关闭这个功能将在OS_CFG.h中的OS_APP_HOOKS_EN配置为0OS_CPU_A.ASM 
//MDK编程环境不认识PUBLIC,要用EXPORT(34-39行)
    EXPORT  OS_CPU_SR_Save                                      ; Functions declared in this file
    EXPORT  OS_CPU_SR_Restore
    EXPORT  OSStartHighRdy
    EXPORT  OSCtxSw
    EXPORT  OSIntCtxSw
    EXPORT  OS_CPU_PendSVHandler
 //同上(54-61行) (;是汇编的注释,同//)
;        RSEG CODE:CODE:NOROOT(2)
;        THUMB

			AREA | .text |,CODE,READONLY,ALIGN=2
				
			THUMB
			REQUIRE8
			PRESERVE8

OS_DBG.C
#define  OS_COMPILER_OPT  //__root也是编译环境问题

app_cfg.h
#define OS_TASK_TMR_PRIO 				(OS_LOWEST_PRIO - 2)
//加上这句,暂时还不知道干啥的

堆栈溢出
Program Size: Code=11022 RO-data=526 RW-data=160 ZI-data=21912
ZI-data=21912是RAM的大小,而C8T6一个才20K,也就是20000.
查找工程的.map文件(后缀名.map):
UCOSII移植到STM32F103C8T6上之移植记录(一)_第2张图片
改小任务堆栈大小:

typedef unsigned int   OS_STK; 
#define   STK_SERVERSIZE          (1024)//改成512
OS_STK      STK_SERVER_BUFF[STK_SERVERSIZE];
//这个占了4K   (栈宽int是4,长度1000,4K)
OSTaskCreate(proc_mhpp_frame_task,(void *)0,&STK_SERVER_BUFF[STK_SERVERSIZE-1],OS_USER_APP_PRIO); 

四,时钟问题

uCOS-ii的核心作用就是任务调度,要使用STM32的一个特殊中断——PendSV,就是可挂起系统任务中断,通过该中断进行系统的调度。还有就是uCOS-ii需要一个基准时间,那么STM32中有一个专用的定时器,嘀嗒定时器SysTick,这个定时器,就是专为操作系统而设计的,通过这个滴答定时器给uCOS-ii提供一个时间基准,每隔固定的时间出发一个PendSV中断,进行任务的调度。所以呢,在官方案例的移植文档AN-1018中也特别提到这一点,要将启动代码startup_stm32f10x_md.s中所有“PendSV_Handler”和“SysTick_Handler”,替换成“OS_CPU_PendSVHandler”和“OS_CPU_SysTickHandler”,这样就相当于将uCOS-ii的“神经”跟你的项目的“神经”搭在了一起。
呵呵,以上是我找到的做法。我不想改
os_cpu_a.asm里所有的OS_CPU_PendSVHandler改成PendSV_Handler。
中断服务函数里要加
OSIntEnter();
OSTimeTick();
OSIntExit();
如:

//软件定时器和UCOS的系统定时用的都是SysTick,不知道会不会冲突,回头试一下
void SysTick_IRQHandle(void)   
{   
	OSIntEnter();
	SysTickCnt += SYS_TICK_TIME; 
	OSTimeTick();
	OSIntExit();	
}

五,到这就可以用了

你可能感兴趣的:(UCOSII移植到STM32F103C8T6上之移植记录(一))