今天给大家分享一篇,如何将移植ucos到STM32F103开发板上,以及实现LED闪烁。
( Z1 x5 M$ ]6 @4 ]# \% [$ w$ x# {) J. \: V
|+ ~7 S: W2 |% I; |0 f/ {' e先到官方下载ucos源码
2 u+ m- R# k* b8 O8 v5 d# R( n具体步骤如下:/ F! o6 @7 r# F- K7 y$ A0 y
1.新建ucos工程,选择STM32F103VE,选择CMSIS下的CORE和Device下的Startup,以及Device下的StdPeriph Drivers下的Framework,RCC,和GPIO1 S) l- S0 E( [: j" |1 @# m" B n% Z5 _
2.工程中和实际目录中都新建几个目录,APP,UCOS,BSP,LIB,CPU,Output
3 F; o' `4 J% I% \) D3.工程上右键,Options,Output页签,Select Foldeer for Objects,进入Output目录,点击OK& N- P: S- E9 x1 ]# a, L. p8 S
4.把Micrium\Software\uCOS-II\Source目录中的文件拷贝到UCOS目录下,并添加到工程中
; h! W7 g* C6 t% X# u5.工程Options中,C/C++页签,Include Paths,点击后面省略号可选择include目录,添加UCOS路径
$ U% n! L c1 R" N# Y9 ^4 X6.复制Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\OS-Probe目录下的文件app_cfg.h,os_cfg.h和includes.h到APP目录中,并在Include Paths中添加APP3 J: i) R! W/ C! B- a& p
7.复制Micrium\Software\uCOS-II\Ports\arm-cortex-m3\Generic\RealView目录下的所有文件到CPU目录,添加到工程和Include Path中! N0 R. q& M( H/ y
8.工程Options中,C/C++页签,Defines中添加 USE_STDPERIPH_DRIVER5 L5 h5 b# Q g0 N2 q5 _2 w: e
9.把RTE和RTE\Device\STM32F103VE添加进Include Paths中! E% k |8 f% p8 _ [8 c. u
10.修改os_cfg.h文件,#define OS_APP_HOOKS_EN 1为0
) X- Y' `2 h6 ?11.BSP目录下新建BSP.c文件,添加内容如下:
2 N, Q' Q8 Y2 V5 C3 B' C( F- #include <BSP.h>
) c* a: G: O8 u1 ~3 S# E9 {9 d - # Y' K2 u; @. k- B; `
- CPU_INT32U BSP_CPU_ClkFreq (void)) o; o- l4 Q! |2 E. \
- {
3 e2 N- j: n9 f! Q4 u1 K - RCC_ClocksTypeDef rcc_clocks;$ {! z% r- T9 j- `4 ^
- RCC_GetClocksFreq(&rcc_clocks);4 \0 Z( H+ h6 X% h
- return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);
% K6 |1 j9 a4 v - }* L0 I2 N; ?9 X8 p/ J
-
- w1 Y% X9 n Y/ t - INT32U OS_CPU_SysTickClkFreq (void)
4 G% p7 Q6 p+ z% @5 b" p A! H' L - {0 Z3 m3 P# L$ y6 B4 K
- INT32U freq;
$ {. S$ k# M6 l; h - freq = BSP_CPU_ClkFreq();7 [" Z# m6 I4 h- u& z
- return (freq);. Q3 |) E: Y" B
- }
. Y8 R" h* X8 ]; f. P" u$ } - ————————————————$ Z* N3 Y7 n$ B2 K- @+ i$ L
- 版权声明:本文为CSDN博主「zhqh100」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。+ F, s: Y3 k* a! O& c% K* x8 g
- 原文链接:https://blog.csdn.net/zhqh100/article/details/39895341
复制代码 12.复制Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\BSP目录下的bsp.h到 BSP目录中
7 B1 m1 d0 `- Z1 G$ U13.复制Micrium\Software\uC-CPU\ARM-Cortex-M3\RealView目录和Micrium\Software\uC-CPU目录下的所有文件到CPU目录下,并添加到工程和Include Path中
, A& |4 L: M3 @/ U( z) p' W3 z14.复制Micrium\Software\uC-LIB目录下的所有.h文件到LIB目录下,并添加到Include Path中
4 P3 T2 s3 T% n# U$ E15.注释掉bsp.h中的#include <stm32f10x_lib.h>和#include <lcd.h> 4 y3 F% T3 a# _% W' ~0 d
16.app_cfg.h文件中,修改为#define APP_OS_PROBE_EN 0 6 w: u2 N1 ?' O0 m! z3 U6 u
17.APP目录下新建app.c文件,内容为 : F) n$ Y) w* u4 t
- #include <includes.h> i! s5 \$ V# b+ V% H# f3 |
-
* h+ `% i9 @( t0 r( N - int main(){3 o" r( n F7 I" W8 _
- OSInit();$ B5 k* I. \) y6 m% i. n1 u# R
- OSStart();
1 ]' H6 D' l: d, V6 X4 V - return 0;$ h* k2 b4 e; Z- W' X5 R% c
- }
复制代码 18.注释掉includes.h文件中的#include <stm32f10x_lib.h>和#include <lcd.h>
$ A, f1 W: U k6 A5 X8 j3 C# H& a L. I' u* t
尝试新建ucos任务:
8 @' |* \; h1 @7 w+ W% D) j- #include <includes.h>. Y1 F' U9 b$ i# J: e. k: v
-
" q: z9 T5 |6 [) _; @" N0 D - static void App_TaskStart(void *); o$ j" H r. n( n& F5 }4 ]9 V. M
- static void App_TaskCreate(void);3 x, s, q( e: e7 {, E5 J1 \+ e
- static void Task_Led1(void* p_arg);" J% r$ E+ N R3 `
- static void Task_Led2(void* p_arg);/ E9 a8 j! K! n1 |5 ^
-
' q' N+ C# |: O$ x" s& l - static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];
) Q" o+ G2 \0 V" c: b7 | - 5 C* l) z) m8 T9 ]. e$ L& l) [
- static OS_STK Task_Led1Stk[Task_Led1_STK_SIZE];
3 ?6 T- W5 g8 u: N6 O0 J% C - static OS_STK Task_Led2Stk[Task_Led2_STK_SIZE];
+ b8 c$ L! {: q7 U - 0 v9 o8 a* {, C2 u* ~
- #define LED_LED1_ON() GPIO_SetBits(GPIOB, GPIO_Pin_5 ); //LED1 ÁÁ! r- \2 U- S) x: D
- #define LED_LED1_OFF() GPIO_ResetBits(GPIOB, GPIO_Pin_5 ); //LED1 Ãð( `# s4 f& k* G8 }2 h
- # G4 o$ Y& k) A; C& _2 f1 b
- #define LED_LED2_ON() GPIO_SetBits(GPIOD, GPIO_Pin_6 ); //LED2 ÁÁ
( l4 o3 Z2 X6 \ p, W! v - #define LED_LED2_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_6 ); //LED2 Ãð4 q0 x+ ]; o9 T$ I" d V
- 8 b$ k7 f5 Z: ~5 k* F* [% W; A
- INT32U milsec1,milsec2;6 W2 R9 R: P3 d* n$ }6 L
- + w6 _- |% M0 ^ C0 c1 b' x2 {
- int main(){% C' L! o9 |* K( U4 R( X* z- l) d
- CPU_IntDis();
4 p. s; V% H* U; A ~- I0 I -
) E2 {' n: B( t, T( W - OSInit();. K) {5 X3 v# L; x6 B* z5 ~$ ]
- BSP_Init();
! W `4 A& ]# f8 t D O& q -
3 E, h- |# f( K6 p4 v) {6 [& k1 _3 C. w - milsec1=100;
. S' e7 E) I; _: \, B" B - milsec2=200;
7 S, B/ ~/ U# R) w7 i9 [ -
! U, u# }2 z( X+ a3 w Q - OSTaskCreate((void(*)(void *))App_TaskStart,
$ v, d: x. H8 \) k7 V& P - (void *)0,
* O+ }6 c' P& E4 j - (OS_STK *)&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],
% _! W9 @8 w% a: `+ l3 M% V" r6 l/ I/ U g - (INT8U)APP_TASK_START_PRIO);
, u# X; w/ d1 T& X. W - OSTimeSet(0);
2 s% ~: V9 x B3 _. |/ H - OSStart();
2 a& n6 _( a* n9 [3 d" s( ?# g- U - return 0;, f! S# d" @5 R
- }
% h d$ R/ b3 E( m, ]8 ~ @1 ~ -
; i( V7 R6 r8 w, Q. p) u7 v - static void App_TaskStart(void * p_arg){
/ z. ?0 P' @( J9 _' V) N - (void)p_arg;
. |% D7 E `% W: {$ w0 S - OS_CPU_SysTickInit();
2 T' j: ]4 r* b6 K; z. h* \ - App_TaskCreate();
c% S( J8 h- L) x" L - while(1){4 J* D. k) o6 k5 H$ [: P6 g
- OSTimeDlyHMSM(0,0,1,0);, I1 `/ M. V+ m, C- J
- }
7 {1 z% G* a5 }. q- I+ x - }6 a( A! M; _3 H
-
* Q' y4 G8 r" r; {9 t& [& d - static void App_TaskCreate(void){
) A, ~) @# }5 k" @, N& J1 y - OSTaskCreateExt(Task_Led1,(void *)0,(OS_STK *)&Task_Led1Stk[Task_Led1_STK_SIZE-1],
3 R T9 b" p6 U6 T8 z - Task_Led1_PRIO,Task_Led1_PRIO,(OS_STK *)&Task_Led1Stk[0],- |. u& J" c0 c& ^
- Task_Led1_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);( m* s0 X% V; Y5 Q8 R. N
- OSTaskCreateExt(Task_Led2,(void *)0,(OS_STK *)&Task_Led2Stk[Task_Led2_STK_SIZE-1],
. e) g) f1 j+ m) G/ l2 ^ - Task_Led2_PRIO,Task_Led2_PRIO,(OS_STK *)&Task_Led2Stk[0],
5 ?. F0 P8 Z8 M( I - Task_Led2_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);/ y3 e# B7 ?, G0 R
- }: Q# t0 ]* F$ P3 N6 t
-
- G4 w$ E) Q. w Y. } - static void Task_Led1(void* p_arg)
2 v( e1 ^$ M$ {/ ?/ Z0 v M - {7 }3 Q8 c- J( j" v. k) |
- (void) p_arg;
. @9 j1 G! W9 y$ s2 w9 \ - while (1)$ S0 C0 I8 Y( B y
- {
6 D3 s6 z1 R6 n; d - LED_LED1_ON();
$ \7 x. k: L# ^$ v/ @ - OSTimeDlyHMSM(0, 0, 0, milsec1);' v" t% ^- F, H/ E0 g+ L
-
% @5 D. K/ g5 y# F1 S: T- ` - LED_LED1_OFF();& i2 K+ ?8 {0 q' I
- OSTimeDlyHMSM(0, 0, 0, milsec1);
) d5 L4 [% e" I+ m0 ?" _9 x- W! n; F - }
; X8 e' Q0 `" M; t2 ]$ { - }* O9 }/ m6 H0 P1 K0 p0 Q3 @) W, L
- static void Task_Led2(void* p_arg)& F; G( n. n0 a' D7 F
- {
; Y% K1 {# Y& s T3 O. C9 R - (void) p_arg; ! t8 e6 Y5 x5 a/ b
- while(1)
" P9 N. k. y- U j' B) z - {/ z' ]9 q0 C, b, p9 U
- LED_LED2_ON();
! @9 C( H4 F& }9 w0 ]2 c; k% C - OSTimeDlyHMSM(0, 0, 0, milsec2);, {( r! \) e; P! ^1 e
- 2 C' Z) q* D& h
- LED_LED2_OFF();3 \& u, F l3 s. c
- OSTimeDlyHMSM(0, 0, 0, milsec2); * \: z' _5 ~9 P
- }) z1 {# C0 O: w( V( N, L
- }* t$ P2 J3 ]" e) m4 @
复制代码 BSP.c文件增加如下方法:
, n3 \4 ?- P _2 w& c- void RCC_Configuration(void)# X! f! y6 T: c1 e
- {
3 J, I3 {' s& { - SystemInit(); . z! l4 y: r9 ?+ y
- }
9 m: k" F$ ^/ | S, v/ t3 ? -
. |7 V+ I Y$ j% y1 S7 C' J - void GPIO_Configuration(void)
/ E0 V; {* h& u2 P% I& R - {
8 }9 Y. j- n/ j1 A/ `0 d - GPIO_InitTypeDef GPIO_InitStructure;0 a% k1 @8 G0 \7 n' Z6 k5 d* d. h9 C
-
) T b0 o' G( ?! j# l2 X) |9 { - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB , ENABLE); ) ^9 Z/ N4 h6 ^! c! U: P3 L2 J' K
- # G& ~6 d$ {: y
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1. U. l; ?) p( I! H' d
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;9 C, `7 k: J: H8 R- ]$ ?1 c
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;9 p& a' k/ }$ q2 j
- GPIO_Init(GPIOB, &GPIO_InitStructure);
+ i- Q, y; r& x! r2 b -
3 A4 i( W# S; X9 z5 Q$ V# | - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; //LED2, LED3
4 o7 A# _$ X; g% |4 j j - GPIO_Init(GPIOD, &GPIO_InitStructure);: l5 ]/ u8 M) ]
- }
: r6 e! a' W2 u) z7 d4 G -
I7 M4 d$ C3 t5 R/ e9 s9 d) G3 R( V - void BSP_Init(void)1 K9 L4 s& o9 y6 C
- {, w9 q4 K: T; Q: w o& x
- /* System Clocks Configuration --72M*/
2 \; s* N5 |- }# m4 z3 u - RCC_Configuration();
- g) s! s4 z+ u$ Y( o -
% A& [7 _% S$ ^; J( L( B P - GPIO_Configuration(); + [% p, E, I$ y
- }
# j+ r, e; w9 I) w) o" K2 ~
复制代码 另需要在app_cfg.h文件中添加:; B1 K+ l) I) E& w1 V% l: @7 ?, Q
- #define APP_TASK_START_PRIO 3
* ~$ s& t# V6 M7 S a" Z - #define Task_Led1_PRIO 7& D5 \; G% V$ O6 h# D
- #define Task_Led2_PRIO 88 C; `: E! {, p$ L }
- 4 I, O1 ?3 M+ {5 p" ~
- #define APP_TASK_START_STK_SIZE 128) b" c+ ^; L( d4 @8 b( m
- #define Task_Led1_STK_SIZE 128
( M. A; t: Z. N1 x1 `8 q - #define Task_Led2_STK_SIZE 1287 X9 {% Q! P6 @' ^; e! ]
复制代码 此时编译会发现,LED灯不闪烁,需要做如下修改:
3 @# D8 W, W4 w* V9 `; y+ a5 p) B5 l1.startup_stm32f10x_hd.s文件中,处理PendSV_Handler名称与os_cpu_a.asm文件中OS_CPU_PendSVHandler名称不匹配,需要把PendSV_Handler全部替换为OS_CPU_PendSVHandler
$ _% ]$ {8 Y+ d' O+ x
$ s8 L6 a7 b7 g( G( I6 R% [1 x7 `* l" Y8 W" V+ t$ g
2.复制Keil安装目录C:\Keil_v5\ARM\Pack\Keil\STM32F1xx_DFP\1.0.5\Device\StdPeriph_Driver\templates下的stm32f10x_it.c和stm32f10x_it.h文件到APP目录下,去掉其只读属性,并添加到工程中,然后添加头文件:& v9 ^( Y$ o0 i n* {
再修改SysTick_Handler函数如下: c- ~6 U+ G1 [) g( z; l7 E
- void SysTick_Handler(void)
/ L5 I, ?3 l6 ?1 t, [6 B6 O6 X& h) {% g - {5 B! H5 c* w! H# W [
- OS_CPU_SR cpu_sr;
5 J& S* d# Z! C- ~: w% f2 X1 ~% R -
- d! g8 E; [" I" q+ \ - OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/' z7 a4 J9 t- E
- OSIntNesting++; //OSSemPost(NMEA_MBOX);
. M7 L% v6 O6 }4 F; E% S# e - OS_EXIT_CRITICAL(); //恢复全局中断标志7 M& ~' D9 T2 N# D! r4 R* r7 d4 c9 ~
-
, Q' g+ _) w1 t. D( x8 R - OSTimeTick(); /* Call uC/OS-II's OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到*/) O$ M2 B4 T2 P+ g' k( N* ]
-
3 V' a4 ^9 }/ T8 @! M# M - OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换 % ` C8 h4 C+ q7 L' o4 f
- }, G! |" l: _; N3 K" ^
复制代码 大家可以试一试!
# b0 J+ m! t" n2 c* Q8 v6 V6 e6 P8 V4 \' n D" ?' `
|