uCOS-II的移植
先对uCOS-II有了个整体了解
我们就对uCOS-II进行移植开发板
移植的一般思路:
1.先建立开发环境上的空工程(模板工程更好)
2.添加ucos2的核心代码进去
3.编译,解决报错和警告
4.下载运行,并小幅修改代码查看效果
5.添加并调试项目需要的BSP,编写并调试项目app部分
进行移植、遇到问题与解决
首先,我们按照步骤,将之前建立号的标准库模板拿出使用。标准库的模板可查看之前文章。
我们把uCOS代码附近进这里目录。这是ucos文件
我们把APP、BSP、uC-CPU、uC-LIB、uCOS-II复制进标准库文件中。usart是串口,我们可以直接把里面的文件直接复制进BSP文件中。
之后用keil打开工程:并一一添加里工程中,添加头文件包含。
开始编译就可以了。
编译后会出现三个错误:
1.我们把:stmf10x_LIB.h、stmf10x_map.h、stm32——Reg.h直接注释掉就可以了。这些是keil4中存在的文件,在keil5中直接写进stm32f10x.h里了
2.还有会报关于usart的错误:因为我们直接把com.c放bsp中了,只需要把包含头文件的绝对路径更改下就可以了
3.还有main.o重复包含:这是因为app文件中也有也好的main.c文件,user中也有我们自己写的main.c,我们只需要把user文件的其他文件复制到app中就可以了
........在编译
会出现4个定义变量未使用的警告...可以忽略
还有一个警告:..\Objects\led.axf: Warning: L6305W: Image does not have an entry point. (Not specified or not set due to multiple choices.)....分析百度就会给出答案:在Options for Target选项的Linker下的Misc controls 处加入入口地址:--entry Reset_Handler。如图:
再编译,就可以了.....
Load进32之后,接收串口数据,只打印了一遍环境...没有调度任务...
这是因为我们之前修改了ucos中的启动文件...我们用的是startup_stm32f10x_hd.s启动文件...
其实就是SysTick_Handler没有打开....根据app.c中的main.c,之前的初始化都是关闭中断的,所以要在PendSV_Handler中开启中断...
所以讲PendSV_Handler打开,SysTick_Handler...就是节拍器...节拍器开了,系统就可以进行调度了...
所以当进入复位后:
PendSV_Handler、SysTick_Handler会调度这2个函数.....
这2个函数是在stm32f10x_it.c中实现,而我们发现,在这个stm32f10x_it.c文件中,根本没有实现此函数.
没有实现....所以我们要找到ucos中是如何实现这2个函数的.....
实现PendSV_Handler:在文件UCOS-II中OS_CPU_A.ASM文件
PendSV_Handler替换OS_CPU_PendSVHandler...
声明也需要替换--
EXPORT PendSV_Handler
;EXPORT OS_CPU_PendSVHandler
实现:SysTick_Handler:在UCOS-II中OS_CPU_C.C的文件
void SysTick_Handler(void)替换//void OS_CPU_SysTickHandler (void)
之后就可以进行系统调用,正是移植了ucos-ii....在我们的f103中.......
可以阅读main函数进行bsp的适配了..
一些函数解析:
任务得创建:....创建之后就会把App_TaskStart任务就会就绪态..系统就会调度..
os_err = OSTaskCreate((void (*) (void *)) App_TaskStart,
/* Create the start task. */
(void *) 0,
(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],
(INT8U) APP_TASK_START_PRIO);
//(void (*) (void *)) App_TaskStart:这是一个函数指针,App_TaskStart是一个指针,指向一个函数...就是我们在调用App_TaskStart函数
//void (*pFun)(void*);这样就定义了一个函数指针pFun,
//我们可以跟进OSTaskCreate函数来参考下,我们需要传进来的函数....
//typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide OS_STK是无符号的整型类型
//(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], 强制转换成(OS_STK *)类型........指针数组..App_TaskStartStk数组装的是(OS_STK *)
//App_TaskStartStk是OS_STK类型的数组...............定义是static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];
//APP_TASK_START_STK_SIZE定义了数组的大小....#define APP_TASK_START_STK_SIZE 128 之前为我们定了128
//(INT8U) APP_TASK_START_PRIO 优先级设定,根据任务来...
任务开始任务函数:static void App_TaskStart(void* p_arg){.............................}
官方给我们的介绍:
App_TaskStart()
*
* Description : The startup task. The uC/OS-II ticker should only be initialize once multitasking starts.
* Caller : This is a task.
这就是一个任务开始的地方......我们可以在这里按照格式创建其他任务.....
这里有一个注意的地方就是,在这个函数结尾处要进行delay处理,因为系统会循环调度的,以免系统跑飞,我们会在结尾处加一个while(1){};
但是这样会浪费资源,所以我们在while(1)中加上delay:while(1){OSTimeDlyHMSM(0, 0, 10, 000);}交出就绪态就好了....
例如:在其中创建LED任务:
//App_TaskCreate();
OSTaskCreate((void (*) (void *)) App_TaskUser1,
/* Create the start task. */
(void *) 0,
(OS_STK *) &App_TaskLEDStk[APP_TASK_LED_STK_SIZE - 1],
(INT8U) APP_TASK_LED_PRIO);
实现了串口,我们的移植基本就算完成了....
在移植后就是项目的调试了,里面也是有很多的内容的,我们可以慢慢调试,慢慢学习吧
这里需要说明下的是
其实我们要直接用ucos给我们的其实文件是不需要这么改的,修改的会相对容易些,但基本原理都是一样的....
最重要的就是C语言了.........