今天给大家分享一篇,如何将移植ucos到STM32F103开发板上,以及实现LED闪烁。- c/ p. P. G2 b2 x; k7 o
" ^+ s. w& O/ _( z3 N' k% Y" {& L0 F* L6 @* k
先到官方下载ucos源码9 J0 X" }: K) C7 n* g; M
具体步骤如下:/ a" u7 w" w. O; X) w9 E5 X7 Z' _
1.新建ucos工程,选择STM32F103VE,选择CMSIS下的CORE和Device下的Startup,以及Device下的StdPeriph Drivers下的Framework,RCC,和GPIO2 M: w/ I2 ?4 @3 {+ k. M" [
2.工程中和实际目录中都新建几个目录,APP,UCOS,BSP,LIB,CPU,Output! L! s4 ^5 l' d v+ g
3.工程上右键,Options,Output页签,Select Foldeer for Objects,进入Output目录,点击OK8 S- Y* w _, Q
4.把Micrium\Software\uCOS-II\Source目录中的文件拷贝到UCOS目录下,并添加到工程中4 \+ X7 D( _( k' G, r `4 C
5.工程Options中,C/C++页签,Include Paths,点击后面省略号可选择include目录,添加UCOS路径& c5 I& b# ]' ]4 z+ _
6.复制Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\OS-Probe目录下的文件app_cfg.h,os_cfg.h和includes.h到APP目录中,并在Include Paths中添加APP% @: A7 ?& E% U. `7 J
7.复制Micrium\Software\uCOS-II\Ports\arm-cortex-m3\Generic\RealView目录下的所有文件到CPU目录,添加到工程和Include Path中
- d2 @: V1 ]1 ^8.工程Options中,C/C++页签,Defines中添加 USE_STDPERIPH_DRIVER0 H) L& {% d5 A! b1 W' }3 B
9.把RTE和RTE\Device\STM32F103VE添加进Include Paths中# i, N8 n, t. p# Q
10.修改os_cfg.h文件,#define OS_APP_HOOKS_EN 1为0/ W2 I6 k5 p: B+ g0 J4 b
11.BSP目录下新建BSP.c文件,添加内容如下:
( [$ w- o: _: k2 P4 e b( o- #include <BSP.h>
- CPU_INT32U BSP_CPU_ClkFreq (void)
- {
- RCC_ClocksTypeDef rcc_clocks;
- RCC_GetClocksFreq(&rcc_clocks);
- return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);
- }
- INT32U OS_CPU_SysTickClkFreq (void)
- {
- INT32U freq;
- freq = BSP_CPU_ClkFreq();
- return (freq);
- }
- ————————————————
- 版权声明:本文为CSDN博主「zhqh100」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- 原文链接:https://blog.csdn.net/zhqh100/article/details/398953414 e8 \* W) L' r$ T
. y+ H. O( w% a* i
复制代码
# ?8 y/ s7 ~% I* F" I& y12.复制Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\BSP目录下的bsp.h到 BSP目录中
5 |5 s/ U" `( e/ s: J13.复制Micrium\Software\uC-CPU\ARM-Cortex-M3\RealView目录和Micrium\Software\uC-CPU目录下的所有文件到CPU目录下,并添加到工程和Include Path中( Y- l# B. O# e3 [9 D# `7 e2 {
14.复制Micrium\Software\uC-LIB目录下的所有.h文件到LIB目录下,并添加到Include Path中. B3 r- @) A4 x* h0 d4 z
15.注释掉bsp.h中的#include <stm32f10x_lib.h>和#include <lcd.h>
" d: o- [, [5 a7 w- ^* q16.app_cfg.h文件中,修改为#define APP_OS_PROBE_EN 0
9 a% p- C& d- B3 U17.APP目录下新建app.c文件,内容为4 Z& @) I( F3 A% W; D& t( ~
- #include <includes.h>
- int main(){
- OSInit();
- OSStart();
- return 0;
- }3 w# T2 |- w( u1 f
0 L+ z; E) g, i% {1 u2 i复制代码
8 \5 w( T4 T, D# X) j7 J# p1 B' K& E18.注释掉includes.h文件中的#include <stm32f10x_lib.h>和#include <lcd.h>
( j" u) k9 i3 d1 B! w+ G7 `
0 u& x S- R. f! p& `) g尝试新建ucos任务:" U3 g4 H# W% _, J% R. h
- #include <includes.h>
- static void App_TaskStart(void *);
- static void App_TaskCreate(void);
- static void Task_Led1(void* p_arg);
- static void Task_Led2(void* p_arg);
- static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];
- static OS_STK Task_Led1Stk[Task_Led1_STK_SIZE];
- static OS_STK Task_Led2Stk[Task_Led2_STK_SIZE];
- #define LED_LED1_ON() GPIO_SetBits(GPIOB, GPIO_Pin_5 ); //LED1 ÁÁ
- #define LED_LED1_OFF() GPIO_ResetBits(GPIOB, GPIO_Pin_5 ); //LED1 Ãð
- #define LED_LED2_ON() GPIO_SetBits(GPIOD, GPIO_Pin_6 ); //LED2 ÁÁ
- #define LED_LED2_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_6 ); //LED2 Ãð
- INT32U milsec1,milsec2;
- int main(){
- CPU_IntDis();
- OSInit();
- BSP_Init();
- milsec1=100;
- milsec2=200;
- OSTaskCreate((void(*)(void *))App_TaskStart,
- (void *)0,
- (OS_STK *)&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],
- (INT8U)APP_TASK_START_PRIO);
- OSTimeSet(0);
- OSStart();
- return 0;
- }
- static void App_TaskStart(void * p_arg){
- (void)p_arg;
- OS_CPU_SysTickInit();
- App_TaskCreate();
- while(1){
- OSTimeDlyHMSM(0,0,1,0);
- }
- }
- static void App_TaskCreate(void){
- OSTaskCreateExt(Task_Led1,(void *)0,(OS_STK *)&Task_Led1Stk[Task_Led1_STK_SIZE-1],
- Task_Led1_PRIO,Task_Led1_PRIO,(OS_STK *)&Task_Led1Stk[0],
- Task_Led1_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
- OSTaskCreateExt(Task_Led2,(void *)0,(OS_STK *)&Task_Led2Stk[Task_Led2_STK_SIZE-1],
- Task_Led2_PRIO,Task_Led2_PRIO,(OS_STK *)&Task_Led2Stk[0],
- Task_Led2_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
- }
- static void Task_Led1(void* p_arg)
- {
- (void) p_arg;
- while (1)
- {
- LED_LED1_ON();
- OSTimeDlyHMSM(0, 0, 0, milsec1);
- LED_LED1_OFF();
- OSTimeDlyHMSM(0, 0, 0, milsec1);
- }
- }
- static void Task_Led2(void* p_arg)
- {
- (void) p_arg;
- while(1)
- {
- LED_LED2_ON();
- OSTimeDlyHMSM(0, 0, 0, milsec2);
- LED_LED2_OFF();
- OSTimeDlyHMSM(0, 0, 0, milsec2);
- }
- }
: ^: }. [/ X {, S" ?: l2 U: S( _ ! e1 H/ s( `. E0 s7 T3 w/ q
复制代码) o0 z- S T8 q) W
BSP.c文件增加如下方法:3 c; x. I6 g K6 e/ N" V. a+ G
- void RCC_Configuration(void)
- {
- SystemInit();
- }
- void GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB , ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; //LED2, LED3
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- }
- void BSP_Init(void)
- {
- /* System Clocks Configuration --72M*/
- RCC_Configuration();
- GPIO_Configuration();
- }
7 k" @0 u8 j8 i) |% p i' a5 n& V2 f: F& {
. `$ R4 {, @% k复制代码9 R W% h5 ?; G' Z( f7 [8 `( }
另需要在app_cfg.h文件中添加:
+ K x4 q w4 R- #define APP_TASK_START_PRIO 3
- #define Task_Led1_PRIO 7
- #define Task_Led2_PRIO 8
- #define APP_TASK_START_STK_SIZE 128
- #define Task_Led1_STK_SIZE 128
- #define Task_Led2_STK_SIZE 128
2 I- ]5 R7 N; v8 l0 B
6 [) Q% k1 l$ y: f9 e复制代码
/ \8 O2 d5 J, w0 Z' ]6 T- D此时编译会发现,LED灯不闪烁,需要做如下修改:
2 | y9 w9 ^! J% I1.startup_stm32f10x_hd.s文件中,处理PendSV_Handler名称与os_cpu_a.asm文件中OS_CPU_PendSVHandler名称不匹配,需要把PendSV_Handler全部替换为OS_CPU_PendSVHandler+ a! P% l% j- k9 P$ t, R
% K8 n6 G9 a* v
- {" F! d$ m0 ~3 O7 m+ H2.复制Keil安装目录C:\Keil_v5\ARM\Pack\Keil\STM32F1xx_DFP\1.0.5\Device\StdPeriph_Driver\templates下的stm32f10x_it.c和stm32f10x_it.h文件到APP目录下,去掉其只读属性,并添加到工程中,然后添加头文件:9 d* b0 U; K; P, F7 M4 _; ~
- #include <includes.h>
! o2 s: [% I) f/ [0 B w: v" X2 ^
4 `3 p) r# `5 w& M1 O% @$ z% M复制代码
7 }! [; D" |' l; }6 ], R: J+ q再修改SysTick_Handler函数如下:
q, Y) I1 u6 f2 p- void SysTick_Handler(void)
- {
- OS_CPU_SR cpu_sr;
- OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/
- OSIntNesting++; //OSSemPost(NMEA_MBOX);
- OS_EXIT_CRITICAL(); //恢复全局中断标志
- OSTimeTick(); /* Call uC/OS-II's OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到*/
- OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
- }
; D: ?+ W+ H/ l" p- I 1 o7 N1 ?/ r. J: y5 p' _
复制代码# O8 H# z7 E2 k' O9 l$ ^
大家可以试一试! |
|