网上基于MDK的移植数不胜数,但是基于IAR的移植几乎没有,因为官方的例程就是基于IAR的,所以移植起来很简单,没人介绍,但还是得小心谨慎,一不小心就出错,对于新手来说,查找错误可不是那么容易的。IAR建立工程,这里就不介绍。
- }/ c* }8 D$ d. |* H" ` z$ n9 ?; g
/ V7 C0 F( i0 f( w; N$ T以下红色部分需要与MCU型号对应
# @+ t2 g2 `5 C0 f6 v3 T' `+ |3 d) o- e: f
(1)在官网下载适合自己STM32的uCOS-II库,连接如下,我用的MCU是STM32F103VCT6,属于大容量的,所以选择的库是STMicroelectronics STM32F103ZE。, y; r" X* F* O1 R' H9 g8 L
, r E. X9 r* V' n
(2)下载下来的是(.exe)文件,双击解压得到名称为Micrium的文件夹。( h" a2 m1 i, ~$ L1 v/ r
( V0 X" l$ l$ f7 `1 R9 G" @
(3)在自己的工程中建立文件夹ucosii,里面包含3个子文件夹,分别是config,port,source,文件夹名称随意。
) ? ^! |7 N* h, C# P7 a7 w
# Q3 @: z0 p9 g(4)将文件夹Micrium\Software\uCOS-II\Ports\ARM-Cortex-M3\Generic\IAR中的文件全部复制到port文件夹中。
' L5 ]( R% o% n3 v5 M2 Z. e& C+ Z6 `& ^) b$ U& D6 X
将文件夹Micrium\Software\uCOS-II\Source中的文件全部复制到source文件夹中。
2 R# S G$ t8 W& I$ N
' ~% }4 }$ @! m2 ^4 {# k5 ~5 D 将文件夹Micrium\Software\EvalBoards\ST\STM3210E-EVAL\IAR\OS-Probe中的app_cfg.h和os_cfg.h复制到config文件夹中。2 k u- j7 b' }# n# A3 t6 ]0 H7 J1 }
4 t4 Z% y$ \- O C$ P* J7 Q$ q* H
(STM3210E-EVAL此目录根据STM型号而定,型号不相符是否有影响,未测试)- ^- B* \( B% A* j0 n# E4 I( s
* @. m" f: L* Y( r2 G# I3 N
(5)为了防止修改错误,这里暂时可以将port和source这两个文件夹中的文件设置为只读,以后用的时候再取消。
/ q7 Z$ u) Q0 \' x: f$ U0 N0 E0 k1 w! ~. }2 _
(6)修改os_cfg.h中的第一个宏定义为#define OS_APP_HOOKS_EN 0 (取消钩子函数)。
y. U3 |7 q; [6 F2 f( P0 k- V1 v
(7)将启动程序startup_stm32f10x_hd.s中所有PendSV_Handler替换成OS_CPU_PendSVHandler,SysTick_Handler替换成OS_CPU_SysTickHandler。3 o% v" l. G$ H5 N
( ~- t9 o$ `' X8 S8 f; T1 Z% ?注意:下面这种注释是错误的,会导致进入硬件错位中断,害的我浪费了好几天时间。' h& q8 f9 t0 }6 i, I
# T9 {: R5 }9 F PUBWEAK OS_CPU_PendSVHandler endSV_Handler; c. w% ]0 v2 @7 D
I7 B) E) Z& Y
SECTION .text:CODE:REORDER(1): Y- z' ~7 m/ ^
OS_CPU_PendSVHandler endSV_Handler
# J" m+ r2 `* M s, z3 u B OS_CPU_PendSVHandler endSV_Handler
6 ]% k. \/ j- }6 v) {5 p) P6 ]& M4 L4 K
PUBWEAK OS_CPU_SysTickHandler;SysTick_Handler
1 W8 I( n n0 a. _, c) v SECTION .text:CODE:REORDER(1)3 X, u' C2 D, g( |) N! A: O) U8 v
OS_CPU_SysTickHandler;SysTick_Handler
) T0 U7 H6 W; b B OS_CPU_SysTickHandler;SysTick_Handler ]1 Y ^1 t: v8 c+ }% ~8 f, C
2 i! Z2 B" x8 v z
6 ] b! y; [5 r# e6 c o: }(8)打开Micrium\Software\EvalBoards\ST\STM3210E-EVAL\IAR\BSP\bsp.c文件,复制函数CPU_INT32U BSP_CPU_ClkFreq (void)和INT32U OS_CPU_SysTickClkFreq (void)到main.c中。
1 \2 n' F9 _$ p2 f% e$ n- s% L
2 q" q0 c0 e& E/ C0 [: n% d (注意将所有CPU_INT32U修改为INT32U,不然会报错)
" a" N8 t- K9 O# O0 k- D8 F1 P' x0 @9 ?7 u
( k4 j4 m% f8 L; c& q
(9)在main.c中创建任务。3 h+ k- t# c0 y5 P+ g: ^3 o
- #include "ucos_ii.h"
. h( c2 h% D1 C - #include "os_cpu.h"& T, [( l: Q* J% Q9 D! j) @
- #include "stm32f10x.h"
9 Q0 s& p/ R3 n& V/ J% `- Q
}( H1 D) z4 T4 y+ d' E- #define STARTUP_TASK_PRIO 10
/ i2 M3 Y0 e3 t2 N& h& Q9 [. r$ | - #define STARTUP_TASK_STK_SIZE 64- m! G, Y8 c# o \2 L
- OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE];4 L! M( m. H/ j& h. K: M5 G& V* N$ E
- % P) E0 Y8 P2 n: A2 l; v7 V
- //LED1任务
1 ~" y Y* K7 J; a/ k - //设置任务优先级
+ y+ H; g& @$ E& l3 D% d, } - #define LED1_TASK_PRIO 5 # n# r( v' V, O4 Y- l, }/ W
- //设置任务堆栈大小
# p; r& t. s& `# r+ H - #define LED1_STK_SIZE 64$ _# z. U$ g6 K9 d' C3 e1 r/ y
- //创建任务堆栈空间
* S2 q. U) X/ e# Q2 y8 {3 j - OS_STK LED1_TASK_STK[LED1_STK_SIZE];
4 p8 Y: F7 }' n - 9 x0 T) H& `/ M4 [* V$ t
- //LED2任务5 p3 l$ i; ]6 Y
- //设置任务优先级. t. S; i( Y( E
- #define LED2_TASK_PRIO 6
* }4 y0 G, J& u% E" K5 v) M. H6 m0 h - //设置任务堆栈大小
; p) l' B- o* {, q7 V$ F - #define LED2_STK_SIZE 643 Z1 e) D$ M5 b! V9 k% Z1 }
- //创建任务堆栈空间7 i# e. I1 Q- x1 Y
- OS_STK LED2_TASK_STK[LED2_STK_SIZE];
" V% C& ]% r1 _9 A
5 u! K* q- _. v; s6 ~) K9 |- void led1_task(void *p_arg);8 U1 f0 E$ n5 f$ @2 b: M2 `7 c, Y% S
- void led2_task(void *p_arg);
! g8 U) I# _* g& c - 9 v& V$ ~& a) | r2 B6 _
- INT32U OS_CPU_SysTickClkFreq (void)& p9 L/ W7 u7 U: C
- {
4 n6 q: n+ G1 D- L; Z: p' H - INT32U freq;
" C! p: G. m) Q* A o' \7 | C - 7 Q9 u% W- F2 v8 ]' x1 G
- RCC_ClocksTypeDef rcc_clocks;
/ o4 ^& O5 r! }; i
' K+ D& i( r O* V- RCC_GetClocksFreq(&rcc_clocks);$ ~: {4 q# b% s7 E: h! H$ K
1 F6 Q% \" {6 k6 @4 g. q- freq = (INT32U)rcc_clocks.HCLK_Frequency;* |7 `$ t: o3 x% C
-
1 Q# n$ t( I0 K0 d! g - return (freq);
( J+ I4 M6 B' S - }# l2 F3 f4 j6 I, l: D% s1 s
- O* v [: A+ s1 E' W
- void LED_Init(void), k& p9 H D& f1 Q' H
- {
Y3 w5 D& U% s1 R/ G; @9 f -
- |: w, X) G& q" ] - GPIO_InitTypeDef GPIO_InitStructure;
0 l; Q. D1 u# h, R0 @1 r' O - 1 y, T; z t* J4 p6 ^$ c
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PE端口时钟( M. J4 c3 v3 D# \ G4 e
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED0-->PA.2 端口配置
/ A) c; n! I: ~& w3 m0 n - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出! k9 i, _7 w1 w6 I$ ?+ E* B' w
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
/ V9 |) u _. L! c - GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.23 i# B. s4 p y) f
- GPIO_ResetBits(GPIOA,GPIO_Pin_2); //PA.2 输出高
+ o6 A7 D6 L, q2 n8 E6 H - 4 J4 ~- Y, Y1 e8 W: ?
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //LED1-->PB.12 端口配置, 推挽输出! j0 l- z+ s! ]! L ?9 k* S
- GPIO_Init(GPIOB, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz, H- b1 Q7 f( n( {) \
- GPIO_ResetBits(GPIOB,GPIO_Pin_12); //PB.12 输出高
* P" R& b1 ]' d2 W! E - }" b; S" c% C3 m1 e& B+ \, W1 \
- ]4 t3 T. z7 j# ~- static void startup_task(void *p_arg)
6 a* S. U' `$ r5 t - {
6 O5 _( [& N7 M! k, D - INT8U err;, P9 X- x8 `$ i% a( E
- OS_CPU_SR cpu_sr=0;
/ o' R. t+ W0 H- I -
+ i4 Z7 i5 s) x( r* Q. S - OS_CPU_SysTickInit();
+ C6 E. h% @2 P' H; t -
7 c+ K" Z9 z5 e. Z - #if (OS_TASK_STAT_EN > 0)
( F" L) U! ?# n1 m- Y& q# L, r: } - OSStatInit();1 B! O" ~$ K# K# {$ Y7 \. s7 t
- #endif
* o1 }/ U% v+ \. F* J - - I6 D. g0 f6 t$ C! k" Y) C
- OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断) 2 F7 A5 Y5 D2 H$ S" u
- + i' w& M' m. ~7 q$ ?
-
& T* b5 ~. i1 w+ k9 W - err = OSTaskCreate(led1_task, (void *)0,, f' s6 \& A. |
- (OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1], LED1_TASK_PRIO); - t4 N# p' A! F1 g( D
- err = OSTaskCreate(led2_task, (void *)0," {5 z: @' l; v7 l
- (OS_STK*)&LED2_TASK_STK[LED2_STK_SIZE-1], LED2_TASK_PRIO);
6 {( g; x/ ]. w# B' X6 V3 | -
0 D. d6 d) d& T1 e" i - OSTaskSuspend(STARTUP_TASK_PRIO); //挂起起始任务.3 _5 s9 Y0 t( c: Z
- OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
4 E( i' j- y) ? - % c( b7 V2 d% ~8 n/ J ~5 W* ~" d, z
- if (OS_ERR_NONE != err): C' A; {) V5 {# j
- while(1);. E' X8 V( R8 T3 t, i: S: F% U* h
- + }7 W; a- O2 E5 X/ O
- OSTaskDel(OS_PRIO_SELF);! e! Z1 D% Z0 C
- }
6 G. E* `8 W9 M! |3 I; r
4 ~( Q e" u) w; P: L s, e- int main(void)
$ @0 M; R( ^: A% n5 G - {
& ^: b/ g, c0 x% \* Q+ A5 v9 _ - LED_Init();
; b" S; }, u# I' x7 q - OSInit();2 U' X1 D, `* m- k/ }2 c/ x% I! y
- OSTaskCreate(startup_task, (void *)0,
( f. V& Y* i! p: c) E" S - (OS_STK*)&startup_task_stk[STARTUP_TASK_STK_SIZE-1],6 V+ O1 |+ ]6 \' B
- STARTUP_TASK_PRIO);
9 F& Y/ s2 j: U4 C1 m# Y0 v - OSStart();
3 F! R! z9 o, `8 F - return 0;: p; y6 z( p/ D8 i+ m2 S3 L
- }
8 V4 n7 L8 e( F8 i6 W
; t8 s4 K9 ]& j/ X- //LED1任务
" a4 Q" I# W! \+ D* R$ E: h - void led1_task(void *p_arg)
. ~5 Z7 ~1 r6 V' D5 n - {
3 _2 p# }5 R7 X9 E- c - while(1)
( {/ z! _ A/ K( S$ [4 Z* m( I - {! c$ h; o: `2 v7 L+ b
- GPIO_ResetBits(GPIOA,GPIO_Pin_2);
p% ^ @8 [! o% S5 @- `( o$ a3 f - OSTimeDly(500);4 W- l' {0 H1 v+ q+ g
- GPIO_SetBits(GPIOA,GPIO_Pin_2);
5 d+ d k, p, @7 } - OSTimeDly(500);! g/ \+ M8 u4 ?2 E
- }+ e; l3 P. H! T( h
- }
# b4 }7 M N& D; ]
8 Q, e) Z9 S5 A9 y! H; h" }8 I+ m- //LED2任务
& X1 J& @! f( w' R, d - void led2_task(void *p_arg)& ^9 M! n1 }' _; T" \0 B9 r
- {
2 a9 L9 U/ y8 a( s% m" G, p% s - while(1)
' u: q. H$ x0 {/ u/ c - {' m1 d( |) R1 f2 h5 o
- GPIO_ResetBits(GPIOB,GPIO_Pin_12);
) E" a" L# s9 ?# h/ P - OSTimeDly(500);: o: Y0 _5 V8 S3 d
- GPIO_SetBits(GPIOB,GPIO_Pin_12);
. n3 Z; @" _; D2 c - OSTimeDly(500);% W, e& o" q# U% f2 m! J D y7 O
- }
& z3 b% I) t. H2 | - }) d! y1 W! Q/ z4 Z5 S d
2 `' n/ ?% p# p1 Z
复制代码
5 y/ n( [& {& X4 C* W————————————————
* U* V3 `8 g" C" O版权声明:鱼入大海_# ]# V$ l0 h# R- U
1 E6 X3 V9 n5 _) O
|