UCOSII移植笔记(UCOSII+STM32F103+LED)

时间:2022-09-05 14:03:52

编译环境使用的是MDK,先实现ucosii的最基本功能,可以实现任务的调度,什么信号量,邮箱,队列那些东西先不管。

1:文件准备
之前下载的是官方没有移植的源码,教程说只需要改一下os_cpu.h,os_cpu_a.asm 和os_cpu_c.c 就可以了,但是一看源码中
就是少了几个文件。未移植的源码文件列表如下图所示。
UCOSII移植笔记(UCOSII+STM32F103+LED)

后来查了一些资料,原来别人用的是官方移植好的案例。在官网找了一下,有STM32的案例,但是只有IAR环境下的。
先下下来再说,后来发现果然有在我们需要这里面三个文件都有。
说一个小的诀窍,用sourceinsight直接打开工程里面所有的文件,看看有没有我们所需要的文件,就不需要一个一个文件夹去找了,工程里面的所有文件一目了然。
然后将所需要的文件复制过来(uc/os-ii port的里面源文件全都复制过来),其文件如下所示。同时将app_cfg.h复制过来(在移植的案例中,一些宏定义定义在这里)。ucosii.c删了(没有啥用)。
UCOSII移植笔记(UCOSII+STM32F103+LED)

需要说明一下的情况是,工程模板里面用的是ucos v2.86 但是我下载的源码是v2.90版本的。这里面系统稍微有点不同,文件名也有不同。我的策略是文件名一样的就用v2.90版本的文件,有差别的就用工程模板里面的。

然后将LED灯驱动源文件和stm32的库文件添加进工程

UCOSII移植笔记(UCOSII+STM32F103+LED)

注意在注意在魔术棒那里添加头文件的路径,不要漏了,要不很恼火。

2:文件配置和修改
(1)os_cfg.h 是用来配置系统功能的,我们需要通过修改它来达到剪裁系统功能的目的。
     首先肯定是禁用信号量、互斥信号量、邮箱、队列、信号量集、定时器、内存管理,关闭调试模式:
     也用不着应用软件的钩子函数,也禁掉;多重事件控制也禁掉。
(2)修改 os_cpu_a.asm
     PUBIC 改为 EXPORT 声明函数名称。
     ·RSEG CODE:CODE:NOROOT(2)换成(记住,千万不要顶格啊,要不错误在哪里都不知道)
      AREA |.text|,CODE, READONLY, ALIGN=2;AREA |.text| 表示:选择段 |.text|
     ;CODE表示代码段,READONLY 表示只读(缺省)
      ;ALIGN=2表示 4 字节对齐。若 ALIGN=n,这 2^n
     THUMB;Thumb 代码
     REQUIRE8;指定当前文件要求堆栈八字节对齐
     PRESERVE8;令指定当前文件保持堆栈八字节对齐
(3)修改 startup_stm32f10x_hd.s中PendSV_Handler 的地方替换成OS_CPU_PendSVHandler。即修改pendsv中断函数的名称
         SysTick_Handler替换成OS_CPU_SysTickHandler,即修改系统时钟中断函数的名称。
3:调试
其他地方其实根本不需要修改。IAR与mdk都是通用的,基于cortex-M3内核进行开发的。什么os_ctx,systickinit等都不需要进行修改。
在debug的时候,看哪些东西是是报错未定义的,再到下载的工程案例中去找,或者是将文件添加进来,或者是将函数或者宏定义添加源码中(我的话是因为不想将为了一个函数或者宏定义就将工程模板中的的一个文件就拉倒工程中来,就粘贴将报错未定义的函数和宏在工程模板文件中找到,复制粘贴)。有些宏定义因为配置的不对会报错,也要根据实际情况报错信息进行一下配置。
4:多任务执行,主函数的写法,以及多任务的启动。
#include "app.h"
#include  "ucos_ii.h"    
#include  "app_cfg.h"

#define TASK_STK_SIZE 512
#define     TaskStart_Prio 1

OS_STK TaskStk[5][TASK_STK_SIZE]; // UCOSII将用户任务堆栈的定义交给了程序员自己实现。不一定需要使用二维数组
void task1(void *p)
{
     while(1)
     {
          LED1_ON;
          delay();
          LED1_OFF;
          delay();
          OSTaskResume(2);
          OSTaskSuspend(1);
     }
    
}
void task2(void*p)
{
     while(1)
     {
          LED2_ON;
          delay();
          LED2_OFF;
          delay();
          OSTaskSuspend(2);
     }
}
void task3(void*p)
{
     while(1)
     {
          LED3_ON;
          delay();
          LED3_OFF;
          delay();
          OSTaskResume(1);
         
     }
}
int main(void)
{
     LED_GPIO_Config();
     OSInit();
     OSTaskCreate(task1,0,&TaskStk[1][TASK_STK_SIZE-1],1);
     OSTaskCreate(task2,0 ,&TaskStk[2][TASK_STK_SIZE-1],2);
     OSTaskCreate(task3,0 ,&TaskStk[3][TASK_STK_SIZE-1],3);
     OSStart();
     return 0;
}
然后编译运行。下载到板子上,我的是完全可以运行。