μcos_II之移植篇

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*
*Author:Callon Huang
*Version:1.0
*Time:2014/11/5
*blog:/u/2451220761
*/
希望博客也能帮到你~
第一步:μcosII源码下载
/downloadcenter/
STM32固件库stm32f10x_stdperiph_lib.zip的下载
第二步:新建文件夹,并准备子目录:
其中Software是μcosII源码下载完成后拷贝过来的,其它的都自己新建.
App 用来存放应用程序文件,
Bsp 用来存放版级驱动文件,
Lib 用来存放 STM32 的标准外设库文件,
Source 用来存放uCOS 文件
第三步:把Software里的uCOS-II、uC-LIB和uC-CPU文件夹到Source里并把后两者拷贝到uCOS-II文件夹里,最后如下:
第四步:找到Software\EvalBoards\ST\STM32F103ZE-SK\IAR下的BSP文件夹,复制到Source文件夹下
第五步:找到Software\EvalBoards\ST\STM32F103ZE-SK\IAR下的OS-Probe-LCD文件夹,复制到Source文件夹下并改名为APP
第六步:解压下载好的stm32f10x_stdperiph_lib.zip固件库:
找到
stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Librari es\STM32F10x_StdPeriph_Driver下的inc和src文件夹并复制到Lib 文件夹下
第七步:复制
stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Librari es\CMSIS下的CM3文件夹到Lib文件夹下
第八步:删除一些不需要的文件:
APP文件夹只需要:
BSP文件夹只需要:
在Software\CPU\ST\STM32里也有inc和src文件夹,但是比STM32固件库的要多两个文件
stm32f10x_systick.c和stm32f10x_systick.h
把这两个文件拷贝到SysTick文件夹下.
第九步:建立工程my_ucosII,把所有的.c文件和.asm文件都加进来:

第十步:对工程进行一些设置:
Device就不用说了;
Target不变;
Output勾选上Create HEX File,并在
里选择Obj文件夹;
C/C++中
添加头文件所在路径,否则会出现大量如下编译错误:
头文件路径:
Libraries文件夹是这三个
最后这部分全部设置好后,如下:
最后总体设置完如下:
Debug里
最后
下载程序的时候,如果碰到
MDK中出现“Error Flash download failed-Cortex-M3”错误,可以通过上面的添加On-chip-Flash来解决。

其他没提的就不改变;
此时先修改部分代码做到最简化:
app.c:
#include "stm32f10x_conf.h"
#include <os_cfg.h>
#include <ucos_ii.h>
#include <bsp.h>
#define STARTUP_TASK_PRIO 4
#define LED1_TASK_PRIO 6
#define STARTUP_TASK_STK_SIZE 80
#define LED1_TASK_STK_SIZE 80
OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE];
OS_STK led1_task_stk[LED1_TASK_STK_SIZE];
static void systick_init(void)
{
RCC_ClocksTypeDef rcc_clocks;
RCC_GetClocksFreq(&rcc_clocks);
SysTick_Config(rcc_clocks.HCLK_Frequency/OS_TICKS_PER_SEC);
}
void led1_task(void *p_arg)
{
while(1)
{
LED1_ON();
OSTimeDlyHMSM(0,0,1,0);
LED1_OFF();
OSTimeDlyHMSM(0,0,1,0);
}
}
void startup_task(void *p_arg)
{
systick_init();
OSTaskCreate(led1_task,(void*)0,&led1_task_stk[LED1_TASK_STK_SIZE-1],LED1_TASK_PRIO) ;
GPIO_SetBits(GPIOF,GPIO_Pin_7);
while(1)
{
LED2_ON();
OSTimeDlyHMSM(0,0,0,500);
LED2_OFF();
OSTimeDlyHMSM(0,0,0,500);
}
}
int main(void)
{
led_config();
OSInit();
OSTaskCreate(startup_task,(void*)0,&startup_task_stk[STARTUP_TASK_STK_SIZE-1],ST ARTUP_TASK_PRIO);
OSStart();
return 0;
}
bsp.c:
#include "stm32f10x_conf.h"
void led_config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //板上LED编号D5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //板上LED编号D5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
打开bsp.h修改为:
#ifndef __BSP_H__
#define __BSP_H__
#define LED1_ON() GPIO_SetBits(GPIOF,GPIO_Pin_6)
#define LED1_OFF() GPIO_ResetBits(GPIOF,GPIO_Pin_6)
#define LED2_ON() GPIO_SetBits(GPIOF,GPIO_Pin_7)
#define LED2_OFF() GPIO_ResetBits(GPIOF,GPIO_Pin_7)
void led_config(void);
#endif
现在可以下编译试试,会出现很多很多问题:
No.1:
原因是因为stm32f10x_conf.h需要包含的很多头文件没有包含,如
没有包含stm32f10x_gpio.h,当然就会很多东西没有定义,我们彻底修改一下stm32f10x_conf.h:
#ifndef __STM32F10x_CONF_H
#define __STM32F10x_CONF_H
/* Includes ------------------------------------------------------------------*/
/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */
//#include "stm32f10x_adc.h"
//#include "stm32f10x_bkp.h"
//#include "stm32f10x_can.h"
//#include "stm32f10x_cec.h"
//#include "stm32f10x_crc.h"
//#include "stm32f10x_dac.h"
//#include "stm32f10x_dbgmcu.h"
//#include "stm32f10x_dma.h"
//#include "stm32f10x_exti.h"
//#include "stm32f10x_flash.h"
//#include "stm32f10x_fsmc.h"
#include "stm32f10x_gpio.h"
//#include "stm32f10x_i2c.h"
//#include "stm32f10x_iwdg.h"
//#include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h"
//#include "stm32f10x_rtc.h"
//#include "stm32f10x_sdio.h"
//#include "stm32f10x_spi.h"
//#include "stm32f10x_tim.h"
//#include "stm32f10x_usart.h"
//#include "stm32f10x_wwdg.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ #ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
#endif /* __STM32F10x_CONF_H */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
上面的stm32f10x_xxx.h,当你需要用到相应功能时再包含即可,这里只是点亮led灯.
No.2:
..\Libraries\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h(96): error: #35: #error directive: "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
如果出现上述错误
是需要修改stm32f10x.h配置芯片类型:打开 stm32f10x.h 文件,在大约的 66-73 行,根据所选芯片类型,去掉相应注释。

这里我去掉 STM322F10X_HD行的注释(高密度型的stm32芯片)。

对自己选用的芯片到底是属于低密度型、中密度型、高密度型还是互联型,可查看 78-92 行的官方注释
,但是会发现无法修改,因为文件是只读的,我们需要修改属性再修改:
是否启用标准外设库:继续在stm32f10x.h 文件中,去掉105行的USE_STDPERIPH_DRIVER 注释,启用 stm32 标准外设库
No.3:
D:\Program Files\keil\ARM\Inc\ST\STM32F10x\stm32f10x_type.h(23): error: #256: invalid redeclaration of type name "s32" (declared at line 487 of "..\Libraries\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h")
上述错误的原因在于重复定义,因为keil本身带的头文件和我们工程的头文件重复定义了!
我们先把回收站清除,再删除keil下的这些文件,以防以后需要恢复.
No.4:
..\Source\uCOS-II\Ports\arm-cortex-m3\Generic\IAR\os_dbg.c(32): error: #20: identifier "__root" is undefined
如果你碰到上述这个问题,那么把
里的__root去掉就好了,这个问题也是由编译器不同而产生的.
No.5:
..\Source\uCOS-II\Ports\arm-cortex-m3\Generic\IAR\os_cpu_a.asm(34): error: A1163E: Unknown opcode PUBLIC , expecting opcode or Macro
如果你碰到上述问题,问题原因在于编译器,我们需要将下面的PUBIC改为EXPORT。

(如果下载的源代码是用RealView编译的,则此处就不用改了,因为代码本来就是用EXPORT)
修改完,如下
No.6:
..\Source\uCOS-II\Ports\arm-cortex-m3\Generic\IAR\os_cpu_a.asm(54): error: A1163E: Unknown opcode RSEG , expecting opcode or Macro
如果你碰到上述问题,问题在于编译器的原因,也要将下面的内容替换一下:
我们改为
即可
No.7:
..\Source\uCOS-II\uC-CPU\ARM-Cortex-M3\IAR\cpu_a.asm(40): error: A1163E: Unknown opcode PUBLIC , expecting opcode or Macro
..\Source\uCOS-II\uC-CPU\ARM-Cortex-M3\IAR\cpu_a.asm(57): error: A1163E: Unknown opcode RSEG , expecting opcode or Macro
同样类似的问题我们在cpu_a.asm里面我们也可以看到
修改同样照做:
No.8:
..\Source\uCOS-II\uC-CPU\ARM-Cortex-M3\IAR\cpu_a.asm(136): error: A1167E: Invalid line start
问题就出在下面的红字部分,
我们删除它们,直接到END
No.9:
..\Source\uCOS-II\uC-CPU\ARM-Cortex-M3\IAR\cpu_a.asm(46): error: A1145E: Undefined exported symbol 'CPU_CntLeadZeros'
问题如果是上面这个,那么把这些没有定义的都注释掉,如下
结果编译还是出错
..\Source\uCOS-II\uC-CPU\ARM-Cortex-M3\IAR\cpu_a.asm(46): error: A1158E: Illegal line start, should be blank
因为这里面的注释需要用“;”来注释:
No.10:
..\SysTick\stm32f10x_systick.h(22): error: #5: cannot open source input file "stm32f10x_map.h": No such file or directory
这个错误并不是在于要添加stm32f10x_map.h,而是把
改为:
就好了
No.11:
..\SysTick\stm32f10x_systick.h(27): warning: #47-D: incompatible redefinition of macro "SysTick_CLKSource_HCLK_Div8" (declared at line 172 of "..\Libraries\inc\misc.h")
..\Obj\my_ucosII.axf: Error: L6200E: Symbol SysTick_CLKSourceConfig multiply defined (by stm32f10x_systick.o and misc.o).
如果你碰到上述警告和错误,我们需要把stm32f10x_systick.h 和stm32f10x_systick.c里面关于SysTick_CLKSourceConfig函数的声明和函数体都注释掉,顺带把stm32f10x_systick.h里的
也注释掉
No.12:
..\Obj\my_ucosII.axf: Error: L6218E: Undefined symbol App_TCBInitHook (referred from os_cpu_c.o).
如果你碰到类于上述的错误,那么找到os_cfg.h把里面的
改成0即可
No.13:
..\Obj\my_ucosII.axf: Error: L6218E: Undefined symbol OS_CPU_SysTickClkFreq (referred from os_cpu_c.o).
那么改成把os_cpu_c.c里的
OS_CPU_SysTickHandler和OS_CPU_SysTickInit函数全部删掉
No.14:
..\Obj\my_ucosII.axf: Error: L6218E: Undefined symbol CPU_RevBits (referred from cpu_c.o). 我们直接把cpu_c.c移出工程即可,至此我们编译
没有任何警告和错误,成功!此时,别忘了把原来从keil里面删除的.h 文件从回收站恢复哦!
但是,问题还没有结束,还是不好使,因为按理说灯会闪烁,结果却一直亮着,那么进一步修改:
No.1:
修改完了这几个必要的部分后,有一处我们也必须要注意的。

因为我们的移植是使用标准外设库CMSIS中startup_stm32f10x_hd.s作为启动文件的,还没有设置OS_CPU_SysTickHandler。

而startup_stm32f10x_hd.s文件中,PendSV 中断向量名为PendSV_Handler,因此只需把所有出现PendSV_Handler的地方替换成OS_CPU_PendSVHandler即可。

如果没有照上面修改,你的程序每次停止调试都会终止在
No.2:
然后修改完上面之后,我们发现,现象确实变了,不过是变成了灯闪一下之后灭了,我们调试时发现,每次一停止调试,程序终止都在下图位置:
这是在startup_stm32f10x_hd.s这个文件下,我们看到SysTick_Handler这个标号,说明我们的程序应该要使能Systick:
我们在bsp.c中添加如下代码:
void BSP_Init(void)
{
SystemInit();// 配置系统时钟为72M
SysTick_init(); // 初始化并使能SysTick定时器
}
void SysTick_init(void)
{
RCC_ClocksTypeDef rcc_clocks;
INT32U cnts;
RCC_GetClocksFreq(&rcc_clocks);
cnts = (INT32U)rcc_clocks.HCLK_Frequency/OS_TICKS_PER_SEC;
SysTick_Config(cnts);
}
void SysTick_Handler(void)
{
OSIntEnter();
OSTimeTick();
OSIntExit();
}
不过必须包含些头文件,
然后再在main.c里调用BSP_Init()这个函数,再编译,完全正确,运行,正确!移植彻底完成!
此时我们再调试停止的时候会在其他几个位置:
1.os_core.c的下图位置
2.os_cpu_a.asm的下图位置
3.os_cpu_c.c的下图位置
证明这是程序常会运行的部分程序,需要在进一步学习中注意。

附录:
No.1:
如果你碰到
error: L6236E: No section matches selector - no section to be FIRST/LAST.的问题
那么就是你建立工程时没有添加.s文件,添加
后问题就解决了.
cpu_c.c是用来定义用户钩子函数,提供扩充软件功能的入口点。

所谓钩子函数,就是指那些插入到某函数中拓展这些函数功能的函数。

No.2:
如果你碰到警告:
warning: function declared implicitly
那么原因是因为你调用的函数没有声明,解决如下:
在bsp.c中添加:
因为
OSIntEnter();
OSTimeTick();
OSIntExit();
这些函数实在ucos_ii.h里面声明的
如果你不解决这个警告,keil很可恶的一点是,你想Go To到这个函数的定义都Go To不了,所以编程尽量规范.。

相关文档
最新文档