今天给大家分享一篇,如何将移植ucos到STM32F103开发板上,以及实现LED闪烁。
0 R& g9 C* K, @% D: T4 D4 O1 Q0 G2 q* w% e
& q, V( m0 l, e q
先到官方下载ucos源码% u3 [7 y5 c2 k* b! c3 B+ o1 w3 q
具体步骤如下:/ O0 v% }) p* r: N0 @! @
1.新建ucos工程,选择STM32F103VE,选择CMSIS下的CORE和Device下的Startup,以及Device下的StdPeriph Drivers下的Framework,RCC,和GPIO4 v9 o8 S( t# {' H: l) t$ h l; i
2.工程中和实际目录中都新建几个目录,APP,UCOS,BSP,LIB,CPU,Output# p! O, _1 {- o6 o
3.工程上右键,Options,Output页签,Select Foldeer for Objects,进入Output目录,点击OK" Z; m) w0 u- V- _
4.把Micrium\Software\uCOS-II\Source目录中的文件拷贝到UCOS目录下,并添加到工程中
, b; ]9 P2 e+ d; n5.工程Options中,C/C++页签,Include Paths,点击后面省略号可选择include目录,添加UCOS路径
# I+ s0 g% R/ z$ b: V5 z6.复制Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\OS-Probe目录下的文件app_cfg.h,os_cfg.h和includes.h到APP目录中,并在Include Paths中添加APP
1 d2 d# r: O) ?: R/ Q7.复制Micrium\Software\uCOS-II\Ports\arm-cortex-m3\Generic\RealView目录下的所有文件到CPU目录,添加到工程和Include Path中
. M" j+ W7 I5 c: h7 H8.工程Options中,C/C++页签,Defines中添加 USE_STDPERIPH_DRIVER
$ p2 n: f5 J% h7 {( r F+ p- V. A6 E9.把RTE和RTE\Device\STM32F103VE添加进Include Paths中+ n# B2 S& O6 x0 Z
10.修改os_cfg.h文件,#define OS_APP_HOOKS_EN 1为0
7 q/ y% s/ `. p11.BSP目录下新建BSP.c文件,添加内容如下:/ ]# M6 j: I2 s$ k$ Q7 Y& d! p3 g- g6 r
- #include <BSP.h>
5 k$ F' I" A. Y - ! n' R2 L. ]" s. @0 d4 Q
- CPU_INT32U BSP_CPU_ClkFreq (void)) L5 Y6 ^9 X. _/ _% d$ z8 S
- {
+ ?. ~4 `: ^# G- C4 f, } - RCC_ClocksTypeDef rcc_clocks;/ ^8 f$ g6 D) M: d* t! N3 e
- RCC_GetClocksFreq(&rcc_clocks);6 {( b1 ^" c4 F# d2 k& H4 K# Z
- return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);% u- Q3 e) K! B6 Q* i
- }
# o% @/ U7 _. X! A0 L - 0 }+ d8 y4 Y9 l8 B0 p
- INT32U OS_CPU_SysTickClkFreq (void): }6 `5 ?& \3 N g: \2 A5 P
- {
y- n. m( k- w( T9 k$ t - INT32U freq;
0 p5 y, h1 f$ u0 k - freq = BSP_CPU_ClkFreq();# ~8 L' i9 d2 y4 ^
- return (freq);
" |# W- T- I* E& h - }( n z6 t" s# q
- ————————————————0 C; I6 @* g% h( u* ` A
- 版权声明:本文为CSDN博主「zhqh100」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
9 Q9 g: G4 _9 V | - 原文链接:https://blog.csdn.net/zhqh100/article/details/39895341
复制代码 12.复制Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\BSP目录下的bsp.h到 BSP目录中
R0 _( H+ J" S4 T13.复制Micrium\Software\uC-CPU\ARM-Cortex-M3\RealView目录和Micrium\Software\uC-CPU目录下的所有文件到CPU目录下,并添加到工程和Include Path中
# x* N: s+ W5 u( ~14.复制Micrium\Software\uC-LIB目录下的所有.h文件到LIB目录下,并添加到Include Path中
1 _9 }+ o4 \# W/ X; n x15.注释掉bsp.h中的#include <stm32f10x_lib.h>和#include <lcd.h>
# n, E( _1 Q# ?+ i# ?16.app_cfg.h文件中,修改为#define APP_OS_PROBE_EN 0
; c- W0 o7 z! h- ?* R17.APP目录下新建app.c文件,内容为
+ e% H+ F/ C- @; ?5 j; K1 v- #include <includes.h>
8 _1 Y) } r/ t* E8 K - - Y# a8 S; ^8 y4 R
- int main(){( i& f3 d6 t P6 T: D! S) P
- OSInit(); S2 A" q. G. n, ~5 u, B: d% L; X
- OSStart();3 z- v( t+ I! x7 V
- return 0;- ]: b6 }3 g1 H6 W% v# i& ]
- }
复制代码 18.注释掉includes.h文件中的#include <stm32f10x_lib.h>和#include <lcd.h> 3 C. }: O* f' T8 {6 q2 x! M
' _. H7 J7 f* l! f0 M( ]尝试新建ucos任务:' k! F8 A3 Z2 [; Q" L
- #include <includes.h>
) b$ n% ~; I3 ]% n% {# Y -
2 Z+ \/ h I6 H5 P; ^ - static void App_TaskStart(void *);
, `5 R3 t9 i# z( y - static void App_TaskCreate(void);8 B* w* J7 q0 @7 ?% b( c1 [: L
- static void Task_Led1(void* p_arg);& d: T: ~ X7 Z8 X
- static void Task_Led2(void* p_arg);
; z' u4 i- |2 ?& J5 r( X6 o - + g, s% b- G1 h; T
- static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];5 r) L6 Y3 Q+ {8 K( m, K- R
-
" Y# H+ P1 w; R( o$ A9 ? - static OS_STK Task_Led1Stk[Task_Led1_STK_SIZE];* \' L3 E: @9 F2 Y( B# q8 z7 Z
- static OS_STK Task_Led2Stk[Task_Led2_STK_SIZE];$ O0 Y8 L8 {9 n2 n* V3 }- |% _
- 1 j" c. `8 B- s+ I9 F$ Q+ y! k
- #define LED_LED1_ON() GPIO_SetBits(GPIOB, GPIO_Pin_5 ); //LED1 ÁÁ
4 b. z/ L+ B1 d+ V$ o/ @ - #define LED_LED1_OFF() GPIO_ResetBits(GPIOB, GPIO_Pin_5 ); //LED1 Ãð
: `0 x/ t# C" l" e- N; P -
2 |' ^! B2 \$ f3 Q7 M - #define LED_LED2_ON() GPIO_SetBits(GPIOD, GPIO_Pin_6 ); //LED2 ÁÁ
/ a; h1 V6 N0 l% I4 S - #define LED_LED2_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_6 ); //LED2 Ãð
4 K: d6 Y9 V# B5 m/ e7 E7 x - 2 g! k8 t3 o" g3 ]1 h
- INT32U milsec1,milsec2;
; B) J J0 g- @ - K( \1 Y4 r( |$ e6 h5 Q
- int main(){
/ c( {% g8 Y0 p! q- S) T - CPU_IntDis();
' x! d- |3 ~" j; d -
! x; q% k/ t, \, V# M - OSInit();
: m, a# x5 f: [5 L5 r - BSP_Init();2 \: ~5 m# w" `* W& q A# ~& ]3 Y( a& s
-
" R' l# i- \) _* @& q" U$ y - milsec1=100;( a! c6 u( r4 X2 q& X8 F. d8 a
- milsec2=200;+ [# d/ c! G! c; X8 k- Q$ p4 [: Q
- 2 H2 C& P0 v: o5 E2 H
- OSTaskCreate((void(*)(void *))App_TaskStart,
. v V8 Q: K8 Y5 r/ v4 } - (void *)0,
( j- H: O# r' `6 |/ H- D. O( t - (OS_STK *)&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],+ g) w+ O1 U6 _1 v
- (INT8U)APP_TASK_START_PRIO);
* w7 n8 U" a+ g8 s6 ]( Y+ e - OSTimeSet(0);
6 E" Y/ |1 d5 r: u e# o - OSStart();
1 V5 a1 l% @6 g2 Y# k" _4 H - return 0;5 H( H3 Z5 {* Z1 N+ ^1 Q0 G! R
- }
$ d6 U* G: x" c3 G, z& S* f- V - / O) {' b% g r/ }6 Z( w/ k
- static void App_TaskStart(void * p_arg){
) F/ d! n) P, s2 j8 I3 u - (void)p_arg;
: c3 {1 y$ d1 ?9 ` - OS_CPU_SysTickInit();: `! i+ o/ c Q3 Y9 E! O5 \
- App_TaskCreate();
; M- p$ x4 m ]- t, _: G - while(1){3 d: T2 R* K& f3 \
- OSTimeDlyHMSM(0,0,1,0);
e( k! u% n4 W$ _ - }" h I2 J6 Z& Q* O# W8 N8 V
- }' ]# c& j# Y8 w0 |& f/ A
-
7 \3 ]. y, v! K; _8 Y - static void App_TaskCreate(void){
) M% o, s* r! S* ^: X: v: E8 ?; | - OSTaskCreateExt(Task_Led1,(void *)0,(OS_STK *)&Task_Led1Stk[Task_Led1_STK_SIZE-1],. ^. N. |6 n* S3 l3 s
- Task_Led1_PRIO,Task_Led1_PRIO,(OS_STK *)&Task_Led1Stk[0],
+ I; [* ^/ G" u& B7 {9 e0 T - Task_Led1_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
+ s2 }8 I& |1 u& E0 d - OSTaskCreateExt(Task_Led2,(void *)0,(OS_STK *)&Task_Led2Stk[Task_Led2_STK_SIZE-1],
5 a- m, S7 O2 F, S6 A - Task_Led2_PRIO,Task_Led2_PRIO,(OS_STK *)&Task_Led2Stk[0],$ `1 L1 d! K# j# ?8 E7 I
- Task_Led2_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
8 B5 g: o% w# p; _1 A, e - }' D9 l" n2 ]( s' ^5 a \7 X
- - L+ {+ {% Y2 `) f. C, b
- static void Task_Led1(void* p_arg)' X! v- Y8 }4 k* g4 U+ B
- {9 Y7 K. @4 t0 k, s) r* }" E
- (void) p_arg; 7 _8 A" |9 u/ P3 M
- while (1)/ h- g: M( `. J7 {
- {
% F* _: n4 M& j& s( i - LED_LED1_ON();
9 V* k. D0 |- |) |. Q7 G - OSTimeDlyHMSM(0, 0, 0, milsec1);9 u7 y: @7 p* @
-
/ z4 s9 r4 |7 G- q - LED_LED1_OFF();
* l/ `0 P4 n+ Q% | - OSTimeDlyHMSM(0, 0, 0, milsec1); ! r7 d- @) Q" ]8 j
- }: Z, s" `3 C" G
- }3 U+ e& N |" t8 v/ M* s* E
- static void Task_Led2(void* p_arg)
) l4 [7 i" b# F8 D: a( w - {0 V9 B4 a6 w% F z
- (void) p_arg; ; W! g& X Q, k1 h d0 b
- while(1)
* \) Z7 g% T+ V( P7 e - {& b; \5 N8 @! ]7 J# t1 x& P
- LED_LED2_ON();
$ t" V+ B3 X: R& L7 W- ^+ _ - OSTimeDlyHMSM(0, 0, 0, milsec2);/ c8 l! i* y* a' d% w
- + Q7 t: x5 Q# k: \
- LED_LED2_OFF();% Z* o( X$ [1 y+ B2 Z
- OSTimeDlyHMSM(0, 0, 0, milsec2);
$ _% M& p% }, S1 A - }
* s! u! _7 W! \ - }$ K( B' X9 w, E9 W5 U
复制代码 BSP.c文件增加如下方法:
- T! K0 j8 O6 a# E0 X( F- void RCC_Configuration(void)
3 b& O2 O$ W' B2 R - {
! r; l/ H8 R8 O9 N- v8 e& d - SystemInit(); 7 f1 m W8 {- j0 g
- }4 W& e' K9 p; f+ b) Z/ U
-
+ C# H- }" W# j - void GPIO_Configuration(void): S& e' E0 \" A* B; G0 y
- {
0 Y6 e0 R+ n) T5 G - GPIO_InitTypeDef GPIO_InitStructure;
! P' R" m3 a( q# H. A -
6 P4 c7 }% z2 ?- a e! C0 i5 s - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB , ENABLE);
K' ^# I% W* u - " g' }! `" `" o5 N9 e; G( L
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1" S) b$ F& V: |! f
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;- l6 `2 Y) O# _$ T/ t0 E ^% |; R; |
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
0 ]5 B9 K U1 `2 g3 o - GPIO_Init(GPIOB, &GPIO_InitStructure); 0 Q* ^; {+ W* g4 V- u
-
9 K3 S6 O/ v6 O8 U - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; //LED2, LED3+ H3 K" y* T* ~: S( G0 X6 k6 Y" }3 x
- GPIO_Init(GPIOD, &GPIO_InitStructure);9 Z$ b/ m( F+ {( u- ~
- }
3 S3 n' E2 F1 h. W( p; u5 _ - + ` {& B3 a+ B% ^
- void BSP_Init(void)
) W. [; E4 w5 ]; }/ t# j8 G2 h3 e - {' h' W E( c4 ?. ?9 e% X- B
- /* System Clocks Configuration --72M*/% P! H4 T; ~# f8 D
- RCC_Configuration();
3 m) n8 ^, {( X9 X- g3 c6 ^% F B - 6 R' ? N+ k6 Y3 b9 J
- GPIO_Configuration();
! {: Z" x: h+ V$ c - }! r M! w# U8 H. S$ b
复制代码 另需要在app_cfg.h文件中添加:
) h. j2 g, O3 G* e2 y" z- #define APP_TASK_START_PRIO 3; `" H2 O1 E8 J
- #define Task_Led1_PRIO 7
. Z" ^0 y6 Q2 c c - #define Task_Led2_PRIO 8. T9 }' v2 U: f" Z2 h
- 6 e/ w- M: c$ ^9 y' i% ?4 [
- #define APP_TASK_START_STK_SIZE 128 ]1 }( q8 J* i( m
- #define Task_Led1_STK_SIZE 1288 V0 X$ n+ Z1 W' N& d
- #define Task_Led2_STK_SIZE 1287 J% j1 }: s% B; x: B
复制代码 此时编译会发现,LED灯不闪烁,需要做如下修改:( e6 Z2 } W0 d* K3 g
1.startup_stm32f10x_hd.s文件中,处理PendSV_Handler名称与os_cpu_a.asm文件中OS_CPU_PendSVHandler名称不匹配,需要把PendSV_Handler全部替换为OS_CPU_PendSVHandler% y. h g& n: ~1 n) ^" M, M* M
6 L7 C+ f' k. h: p0 [
. q6 k3 _8 N! V2 D. C h
2.复制Keil安装目录C:\Keil_v5\ARM\Pack\Keil\STM32F1xx_DFP\1.0.5\Device\StdPeriph_Driver\templates下的stm32f10x_it.c和stm32f10x_it.h文件到APP目录下,去掉其只读属性,并添加到工程中,然后添加头文件:
5 j- T9 y- {- }2 ?再修改SysTick_Handler函数如下:
% \ h. [" K/ I; c' I- void SysTick_Handler(void)
# N& X; o. i' W4 R - {6 b* Q* N7 ~9 K
- OS_CPU_SR cpu_sr;: G2 w" ?2 ]% M0 e6 y
-
8 H* c- b( r, X - OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/9 o2 @( n1 ^6 U6 w( D8 \9 n
- OSIntNesting++; //OSSemPost(NMEA_MBOX); / b4 C3 o, J3 \0 x
- OS_EXIT_CRITICAL(); //恢复全局中断标志
- N* }) C$ f+ ], d& f - 6 V+ a( D4 A( o5 m
- OSTimeTick(); /* Call uC/OS-II's OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到*/) ^; e- c" \# [8 g# A( H
-
: {/ J, p' f! v! H) k C6 z - OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
( b1 V0 R9 x7 m! C# S - }+ v* M; S+ J$ f& ~9 j; A" O: ]+ J
复制代码 大家可以试一试!( a+ g- Q' J4 W" O, e
: {" J# H G6 X) _4 {
|