IAR环境下stm32上ucos的移植

        最近做项目,需要用到ucos,拿到师兄的程序后,感觉非常失望,师兄用的是直接从官网上下载的那种移植好的程序,起码在我看来很乱,有很多定义了的东西都是没有用到的,总而言之,我不想用那个很乱的程序,于是我便自己从网上找教程,尝试着移植了一下,还好最终成功了。我并没有加太多的注释,是因为我也初学,对于那些系统里的函数,我实在也没有资格注释,而我自己写的那几个函数,又实在太简单了,没有注释的必要。如果有什么函数不明白,可以百度一下,我试了试,发现基本上都是能百度的到的。对这个系统不明白的话,最好也看看邵贝贝老师的那本嵌入式实时操作系统uCOS-II吧。

        我毕竟也是个菜鸟营中的菜鸟,其中肯定有不足与错误之处,还望大伙发现的话能够不吝赐教。

        我的完整工程代码的下载链接如下:

        点击打开链接

        我是参考着百度文库上的一篇文章来的,步骤的话,基本上差不多,但是我还是稍微按照自己的喜好改了改的。该文章链接如下(点击打开链接

        建立工程:

        我建了7个文件目录,分别为APP,BSP,CMSIS,FWlib,Project,uCOS_ii,User.如下图:

        

        APP中应用程序文件,就是我自己写的任务文件;

        BSP存放外设硬件驱动程序,也就是自己写的一些硬件初始化、时钟初始化什么的程序。

        CMSIS用来存放cpu和系统的相关的文件.这里面还有个startup文件夹,用来存放启动文件。

        工程建立在Project文件夹下,也就是新建工程的时候,workplace什么的选择Project.

        Project::

        复制 STM32F10x_StdPeriph_Lib_V3.5.0\ProjectSTM32F10x_StdPeriph_Template\EWARM\stm32f10x_flash.icf 到Project下

        CMSIS::

        复制固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport 目录下的core_cm3.ccore_cm3.h 到工程文件夹下的CMSIS目录中。

        复制固件库 STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x 目录下的 stm32f10x.h 到工程文件夹下的CMSIS目录中

        在固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\iar 目录中选取相应的开始文件,这里我选取的是startup_stm32f10x_md.s,复制到CMSIS下的startup文件夹内。

        User::

        复制固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x 目录下的 system_stm32f10x.c、system_stm32f10x.hUser中,

        复制固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template目录中的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h三个文件到User中.

        在User下新建 main.c includes.h 文件.

        FWlib::

        复制固件库 \STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver下的incsrc到 FWlib 下。

        uCOS_ii::

        在工程目录 uCOS_ii 下建立Ports目录,并复制 ucos 解压目录\Micrium\Software\uCOS-II\Ports\arm-cortex-m3\Generic\IAR下的所有文件到此文件夹中。  在工程目录uCOS_ii 下建立Source目录,并复制 ucos 解压目录\Micrium\Software\uCOS-II\Source 下的所有文件到此文件夹中。

        APP::

        接着,os_cfg.h,用来配置ucos各个功能,app_cfg.h用来配置任务所需的各项参数。

        这两个文件我是从\Micrium\Software\EvalBoards\ST\STM32F103ZE-SK\IAR\OS-Probe-LCD目录中借鉴的,用户也可以根据自己的需求来更改,具体更改方法网上有很多说明这里就不多说了。将这两个文件复制到APP目录下。

        在APP下新建两个文件,分别为azhu_led.h和azhu_led.c,这是我写的用来实现LED灯亮灭的程序及其头文件。

        BSP::

        在BSP下新建两个文件BSP.h,,BSP.c,这是我自己写的配置GPIO啊什么硬件初始化,时钟初始化的程序。

        建立工程:

        建立一个空的工程,取名为azhuty,保存在Project文件夹下。向工程添加Group以及files如下图所示。

                

        选取相应的芯片:右键单击azhuty-Debug,选择Options,在target里选择相应芯片。如下图所示

                

        接着,单击C/C++Compiler,单击Proprocessor,配置如下:

                

        哦,目录那里没有显示全,全部的是如下所示:

                $PROJ_DIR$\..\APP
                $PROJ_DIR$\..\BSP
                $PROJ_DIR$\..\CMSIS
                $PROJ_DIR$\..\CMSIS\startup
                $PROJ_DIR$\..\FWlib\inc
                $PROJ_DIR$\..\FWlib\src
                $PROJ_DIR$\..\uCOS_ii\Ports
                $PROJ_DIR$\..\uCOS_ii\Source
                $PROJ_DIR$\..\User

        接着单击Linker,配置如下:

                

        接着,单击Debugger,配置如下:

                

        至此,工程新建并配置完毕。

        移植配置:

        由于这个版本是官方已经移植好的,我们所需要修改的东西很少。

        打开startup_stm32f10x_md.s  (注意要去掉文件默认的只读属性,否则修改不成功

        把所有出现PendSV_Handler的地方替换成OS_CPU_PendSVHandler 

        把所有出现SysTick_Handler的地方替换成OS_CPU_SysTickHandler  

之所以要修改这两个地方,是因为我们一般的中断向量用的是CMSIS给的,而ucos的中断向量是自己写的,我们修改CMSIS的向量表来统一这两个向量。 

        还要修改os_cfg.h中的
        #define OS_APP_HOOKS_EN  0   /* Application-defined hooks are called from the uC/OS-II hooks*/  
        #define OS_ARG_CHK_EN  0        /*Enable (1) or Disable  (0) argument checking */  
        #define OS_TMR_EN   0                  /* Enable (1) or Disable (0) code generation for TIMERS    */ 
这三个地方,这些功能我们暂时不用,要用的话要定义一些东西,这里不做介绍,参见邵老师的书吧。

        还缺少一个函数定义如下  

INT32U OS_CPU_SysTickClkFreq(void)   
{    
    RCC_ClocksTypeDef   rcc_clocks;     
    RCC_GetClocksFreq(&rcc_clocks);     
    return ((INT32U)rcc_clocks.HCLK_Frequency);   //return SYSCLK_FREQ_72MHz;
}  
这个函数主要是用来获得cpu频率,用来确定系统滴答的时间。如果知道系统时钟是多少可以不用这么复杂,
直接  
INT32U OS_CPU_SysTickClkFreq(void)   
{      
    return 72000000; 
}  

也可以。 


因为我知道我用的  stm32f103vbt6  时钟是72MHz,所以我直接把后面那个简单的函数复制到了os_cpu_c.c中。

我自己添加的文件内含代码如下:
APP下azhu_led.h中代码如下:
#ifndef  __AZHULED_H__
#define  __AZHULED_H__

#include "stm32f10x.h" 
#include "ucos_ii.h" 

void Azhu_LED1(void);
void Azhu_LED2(void);
void Azhu_LED3(void);
void Azhu_LED4(void);

#endif
azhu_led.c中代码如下:
#include "azhu_led.h"
void Azhu_LED1()
{
  GPIO_ResetBits(GPIOA,GPIO_Pin_10); 
  OSTimeDly(500); 
  GPIO_SetBits(GPIOA,GPIO_Pin_10);
  OSTimeDly(500);
}

void Azhu_LED2()
{
  GPIO_ResetBits(GPIOA,GPIO_Pin_11); 
  OSTimeDly(500); 
  GPIO_SetBits(GPIOA,GPIO_Pin_11);
  OSTimeDly(500);
}

void Azhu_LED3()
{
  GPIO_ResetBits(GPIOA,GPIO_Pin_12); 
  OSTimeDly(500); 
  GPIO_SetBits(GPIOA,GPIO_Pin_12);
  OSTimeDly(500);
}

void Azhu_LED4()
{
  GPIO_ResetBits(GPIOA,GPIO_Pin_13); 
  OSTimeDly(500); 
  GPIO_SetBits(GPIOA,GPIO_Pin_13);
  OSTimeDly(500);
}



BSP下BSP.h中代码如下:
#ifndef __BSP_H
#define __BSP_H

#include "stm32f10x.h" 
#include "ucos_ii.h" 

void BSP_Init(void);
void Azhu_LED_GPIO_Init(void);
void Azhu_NVIC_Config(void);

#endif // __BSP_H

BSP.c中代码如下:
#include "BSP.h"

void BSP_Init()
{
  SystemInit(); 

  Azhu_LED_GPIO_Init();
  Azhu_NVIC_Config();
}
//下面是初始化控制LED灯的GPIO的程序,
//我是用的GPIOA端口,其中,
//GPIO_Pin_10 控制LED1,
//GPIO_Pin_11 控制LED2,
//GPIO_Pin_12 控制LED3,
//GPIO_Pin_13 控制LED4.
void Azhu_LED_GPIO_Init()
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  
  GPIO_InitTypeDef GPIO_InitStructure; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; 
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
}


void Azhu_NVIC_Config()
{
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
 
User下includes.h中代码如下:
#ifndef  __INCLUDES_H__
#define  __INCLUDES_H__

#include "ucos_ii.h"  
#include "BSP.h"
#include "azhu_led.h"

#endif
main.c中,代码如下:
#include "includes.h"

OS_STK startup_stk[STARTUP_TASK_STK_SIZE]; 
OS_STK task1_stk[TASK1_STK_SIZE]; 
OS_STK task2_stk[TASK2_STK_SIZE]; 
OS_STK task3_stk[TASK3_STK_SIZE]; 
OS_STK task4_stk[TASK4_STK_SIZE]; 

static void startup(void *p_arg);

static void task1(void *p_arg);
static void task2(void *p_arg);
static void task3(void *p_arg);
static void task4(void *p_arg);

u8 os_err; 

int main(void) 
{ 
  OSInit(); 
  OSTaskCreate(startup, 
               (void *)0, 
               &startup_stk[STARTUP_TASK_STK_SIZE-1], 
               STARTUP_TASK_PRIO); 
  OSStart(); 
  return 0; 
}

static void startup(void *p_arg)
{
  BSP_Init();
  OS_CPU_SysTickInit(); //初始化时钟滴答
  os_err = OSTaskCreate(task1,  
                        (void *)0, 
                        (OS_STK *)&task1_stk[TASK1_STK_SIZE - 1],
                        (INT8U)TASK1_PRIO);
  
  os_err = OSTaskCreate(task2,
                        (void *)0,
                        (OS_STK *)&task2_stk[TASK2_STK_SIZE - 1],
                        (INT8U)TASK2_PRIO); 
  os_err = OSTaskCreate(task3, 
                        (void *)0, 
                        (OS_STK *)&task3_stk[TASK3_STK_SIZE - 1],
                        (INT8U)TASK3_PRIO); 
  os_err = OSTaskCreate(task4, 
                        (void *)0,
                        (OS_STK *)&task4_stk[TASK4_STK_SIZE - 1],
                        (INT8U)TASK4_PRIO); 
 
  OSTaskDel(OS_PRIO_SELF); 
}

static void task1(void *p_arg) 
{
  while(1)
  {
    Azhu_LED1();
  }
}

static void task2(void *p_arg) 
{
  while(1)
  {
    Azhu_LED2();
  }
}

static void task3(void *p_arg) 
{
  while(1)
  {
    Azhu_LED3();
  }
}

static void task4(void *p_arg) 
{
  while(1)
  {
    Azhu_LED4();
  }
}

至此,所有工作已经结束,编译运行然后下载到开发板中,就可以了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值