Chinaunix首页 | 论坛 | 博客
  • 博客访问: 342829
  • 博文数量: 76
  • 博客积分: 180
  • 博客等级: 入伍新兵
  • 技术积分: 193
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-04 10:36
个人简介

E_mail:czqwust@163.com 专注于linux、嵌入式

文章分类

全部博文(76)

文章存档

2016年(1)

2015年(38)

2014年(12)

2012年(25)

我的朋友

分类: 嵌入式

2012-08-11 18:13:04

Ucosii移植到STM32

1.使用的开发环境是IAR 5.4       STM32芯片为STM32F103ZET6

使用ST官方提供的标准固件库,建立工程,

我下载的苦艰苦的版本为STM32F10x_StdPeriph_Lib_V3.5.0,里面的文件分布为:

其中,Libraries文件夹里面放的是标准库文件,Project文件夹里面放的是STM32的各个外设的使用范例和一个工程模板,Utilities文件夹里面放的是ST公司的评估板例子,剩下的文件就是教我们怎样使用标准库,而我们主要使用的就是LibrariesProject里面的文件。

1.1首先新建stm32这个文件夹,在里面再新建3个文件夹includeprojectsrc,用来存放头文件、工程文件和源文件。

   对标准库文件进行整理,将我们需要的文件拷出来,由于Libraries下的CMSIS文件夹中很多代码是和编译器及芯片相关的,导致文件夹多且深度大,不利于工程维护,实际上一个项目往往是用固定的编译器和芯片,因此有必要对库进行整理。
   
src下建立libstm32目录
    1.
Libraries\STM32F10x_StdPeriph_Driver\下的内容拷贝到libstm32目录下
    2.
libstm32目录下建立cmsis文件夹,把Libraries\CMSIS\CM3\CoreSupport\下的core_cm3.ccore_cm3.hLibraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\下的stm32f10x.hsystem_stm32f10x.csystem_stm32f10x.h拷贝到cmsis文件夹中。
    3.
根据你所选的芯片类型将

Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\下对应的启动文件拷贝到cmsis文件夹中。这里我拷贝的是startup_stm32f10x_hd.s(大容量型stm32芯片的启动文件)。

下面对这几个文件简单介绍:
    Libraries\STM32F10x_StdPeriph_Driver\
下的内容很好理解就是stm32的各个外设模块驱动代码。
    misc.h
misc.c是和CM3内核有关的NVICSysTick的驱动代码。  
       core_cm3.c, core_cm3.h
   
它们的目录名为CoreSupport,说明这两个文件是CM3内核支撑文件,其他使用CM3内核的芯片也可以用,不一定是stm32。这两个文件用来获取设置CM3内核,配置一些内核寄存器。

    stm32f10x.h, system_stm32f10x.c, system_stm32f10x.h
startup_stm32f10x_hd.sDeviceSupport目录下,说明这几个文件是和具体的芯片有关的,也就是stm32芯片的支撑文件。其中stm32f10x.h是标准外设库的入口,使用标准外设库的代码中必须包含该头文件。system_stm32f10x.c, system_stm32f10x.h这两个文件提供函数用来初始化stm32芯片,配置PLL、系统时钟和内置flash接口。startup_stm32f10x_hd.s是大容量型stm32芯片的启动文件。

1.2建立工程

IAR中新建ARM工程,工程名为stm32,将工程文件放在project文件夹中,在IAR中对工程添加组(add groupincludesrcsrc\bspsrc\applibstm32

libstm32目录下所有的c文件和s文件加载到工程中的libstm32

src目录下新建一个app目录用来放用户文件,将Project\STM32F10x_StdPeriph_Template\下的stm32f10x_it.c拷贝到app目录,并在此目录下新建一个main.c文件,作为系统的主文件。

stm32f10x_it.hstm32f10x_conf.h拷贝到include文件夹中。

根据所选芯片,把Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\iar\ startup_stm32f10x_hd.s加载到工程中。

stm32f10x_it.cstm32f10x_it.h是中断服务程序文件。stm32f10x_conf.h是标准外设库的配置文件,对于工程中不需要的外设,可以注释掉里面的包含的头文件。这里我建议先仅留下stm32f10x_gpio.hstm32f10x_rcc.hmisc.h,用到什么再打开什么,这样编译起来快一点,当然也可都留着。

1.3修改标准库文件,使其适合自己的芯片

stm32f10x.h66-73行,根据所选芯片类型,去掉相应注释,这里我去掉STM32F10X_HD行的注释(大容量型stm32芯片)。

去掉105行的USE_STDPERIPH_DRIVER注释,启用stm32标准外设库。

system_stm32f10x.c110-115行,根据所选芯片主频,去掉相应注释,默认SYSCLK_FREQ_72MHz注释已去掉,如果你的芯片主频是72MHz,就不用做修改了。

1.4点亮一个led

src下建立一个bsp目录用来放置板级支持代码,建立led.cled.h

led.h


点击(此处)折叠或打开

  1. #ifndef _LED_H_

  2. #define _LED_H_



  3. #include <stdint.h>

  4. #define LED_0 0

  5. void led_init(void);

  6. void led_on(uint32_t n);

  7. void led_off(uint32_t n);



  8. #endif


 

 

 

 

 

led.c


点击(此处)折叠或打开

  1. #include "stm32f10x.h"



  2. #include "led.h"



  3. void led_init(void)

  4. {

  5.        GPIO_InitTypeDef GPIO_InitStructure;

  6.        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

  7.        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;

  8.        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

  9.        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;

  10.        GPIO_Init(GPIOF,&GPIO_InitStructure);

  11. }



  12. void led_on(uint32_t n)

  13. {

  14.        switch(n)

  15.        {

  16.               case LED_0:

  17.               GPIO_SetBits(GPIOF,GPIO_Pin_6);

  18.               break;

  19.               

  20.               default:

  21.               break;

  22.        }

  23. }



  24. void led_off(uint32_t n)

  25. {

  26.        switch(n)

  27.        {

  28.               case LED_0:

  29.               GPIO_ResetBits(GPIOF,GPIO_Pin_6);

  30.               break;

  31.               

  32.               default:

  33.               break;

  34.        }

  35. }


 

 

 

 

 

main.c


 

点击(此处)折叠或打开

  1. #include "led.h"





  2. int main(void)

  3. {

  4.        led_init();

  5.        for(;;)

  6.        {

  7.        led_on(LED_0);

  8.        

  9.        }

  10. }


 

将相应的头文件加载到工程中,编译下载,没有什么问题的话,led灯会亮,此时,工程已建立。

2.移植ucosii

micrium官网上下载官方移植版本ucosii2.86 iar

解压后得到如下文件:

      

AppNotes包含ucosii移植说明文件。这两个文件中我们仅需关心Micrium\AppNotes\AN1xxx-RTOS\AN1018-uCOS-II-Cortex-M3\AN-1018.pdf。因为这个文件对ucosiiCM3内核移植过程中需要修改的代码进行了说明。
   Licensing
包含ucosii使用许可证。
   Software
下有好几个文件夹,在本文的移植中仅需关心uCOS-II即可。

src下新建目录ucosii,在ucosii下新建目录portssrc

Micrium\Software\uCOS—II\ports下的文件拷贝到src\ucosii\ports

Micrium\Software\uCOS—II\Source下的文件拷贝到src\ucosii\src

其中,ports下的文件是一只需要修改的,而src下的文件是不需要修改的。

移植步骤:

2.1.os_cpu_c.h文件中的最后的三个函数void       OS_CPU_SysTickHandler(void);
void       OS_CPU_SysTickInit(void);
INT32U     OS_CPU_SysTickClkFreq(void);

注释掉。

OS_CPU_SysTickHandler()定义在os_cpu_c.c中,是SysTick中断的中断处理函数,而stm32f10x_it.c,中已经有该中断函数的定义SysTick_Handler(),这里也就不需要了。
    OS_CPU_SysTickInit()
定义在os_cpu_c.c中,用于初始化SysTick定时器,它依赖于OS_CPU_SysTickClkFreq(),而此函数我们自己会实现,所以注释掉。
    OS_CPU_SysTickClkFreq()
定义在BSP.C (Micrium\Software\EvalBoards)中,而本文移植中并未用到BSP.C,后面我们会自己实现,因此可以把它注释掉。

2.2.由于我们开发程序时,使用的是标准外设库提供的启动文件,而该启动文件已经有SysTick中断函数的定义,micrium公司开发移植版的ucosii时没有使用标准外设库的SysTick中断函数,自定义的中断向量为OS_CPU_SysTickHandlerOS_CPU_PendSVHandler,这就涉及到一个统一的问题了,问题的解决办法是,在启动文件中,PendSV中断向量名为PendSV_Handler,所以只需用OS_CPU_PendSVHandler把所有出现PendSV_Handler的地方替换掉就可以了。

至于OS_CPU_SysTickHandler,我们采用的方法是自己重新写一个,避免对启动文件的修改,方便以后开发。

2.3在工程中添加组ucosii,在ucosii下添加组portsrc,将src\ucosii\portssrc\ucosii\src下的文件添加进工程,别忘了os_cpu_a.asm文件。工程目录为:

2.4include目录下建立一个新的app_cfg.h文件,拷贝Micrium\Software\EvalBoards\ST\STM32F103ZE-SK\IAR\OS-Probe-LCD目录下的os_cfg.hinclude目录下,将这两个文件添加到工程中。

修改os_cfg.h中的

#define OS_APP_HOOKS_EN           0
#define OS_DEBUG_EN               0
#define OS_EVENT_MULTI_EN         0
#define OS_SCHED_LOCK_EN          0
#define OS_TICK_STEP_EN           0
#define OS_TASK_CHANGE_PRIO_EN    0
#define OS_TASK_QUERY_EN          0
#define OS_TASK_STAT_EN           0
#define OS_TASK_STAT_STK_CHK_EN   0
#define OS_TASK_SUSPEND_EN        0
#define OS_FLAG_EN                0
#define OS_MBOX_EN                0
#define OS_TIME_DLY_HMSM_EN       0
#define OS_TIME_DLY_RESUME_EN     0
#define OS_TIME_GET_SET_EN        0
#define OS_TIME_TICK_HOOK_EN      0

编写app_cfg.h


 

点击(此处)折叠或打开

  1. #ifndef _APP_CFG_

  2. #define _APP_CFG_





  3. #define OS_TASK_TMR_PRIO 3

  4. /* task priority */

  5. #define STARTUP_TASK_PRIO 6

  6. /* task stack size */

  7. #define STARTUP_TASK_STK_SIZE 80



  8. #define Task1_Stk_Size 64

  9. #define Task1_Prio 11

  10. #endif


 

2.5编写系统SysTick中断和任务。

   还要在stm32f10x_it.c中添加SysTick中断处理代码:

      

点击(此处)折叠或打开

  1. void SysTick_Handler(void)

  2. {

  3.        OS_CPU_SR cpu_sr;

  4.        OS_ENTER_CRITICAL();

  5.        OSIntNesting++;

  6.        OS_EXIT_CRITICAL();

  7.     

  8.     OSTimeTick();

  9.     OSIntExit();

  10. }


main.c


 

点击(此处)折叠或打开

  1. #include "ucos_ii.h"

  2. #include "stm32f10x.h"

  3. #include "led.h"

  4. #include "stm32f10x_rcc.h"





  5. static OS_STK Task1_stk[Task1_Stk_Size];



  6. static void Task1(void *p_arg)

  7. {

  8.          for (;;)

  9.          {

  10.                  led_on(LED_0);

  11.                  OSTimeDly(500);

  12.                  led_off(LED_0);

  13.                  OSTimeDly(500);

  14.          }

  15. }





  16. static void systick_init(void)

  17. {

  18.           SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);

  19.     

  20. }





  21. int main(void)

  22. {

  23.         INT8U err;

  24.        SystemInit();

  25.         systick_init();

  26.          led_init();

  27.          OSInit();

  28.          OSTaskCreate(Task1, (void *)0,

  29.                   &Task1_stk[Task1_Stk_Size-1], Task1_Prio);

  30.           OSStart();

  31.           return 0;

  32. }


 

编译下载运行,没有什么问题的话,灯亮一下灭一下,移植成功。

3.移植过程中,遇到的问题和解决办法:

3.1 程序停止在os_cpu_a.asm中的CPSIE   I,其实是因为os_cpu_a.s中切换任务用了一个软件中断OSPendSV,但在stm32f10x_it.c中定义的名字是PendSVC,所以一中断则跑到stm32f10x_it.c的中断去了而不是进入os_cpu_a.s中的OSPendSV, 将启动文件中PendSVC_Handler改为OS_CPU_PendSVHandler

3.2 程序一直在空闲任务中循环

定时器没有配置好,使用程序中的SystemInit()Systick_Init()函数进行设置。

阅读(6988) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~