(一)说明
6 e( n: r# k+ _% w( P$ p$ G D
& ^8 r( U5 B& b
{5 E) T/ \) G& l: p; h9 Z
. q5 C! L& O# {( B9 c f T
(二)裸机工程创建% c1 \8 X$ K, z$ M4 I/ z" Q; T
使用STM32CubeMX创建裸机工程:3 u: o6 ~% j% ^% K7 l, c6 N3 L
Q& A. i5 p+ H' x0 ?# k这里我是用的芯片是STM32F103RBT6,时钟主频为72MHz,配置时钟树:: W4 p. S3 d* }; j: d" E
0 ]8 H5 a( Q3 |. t1 ?
, v; z2 m2 a. r2 T8 W
# h) v( Y0 K, E6 O- }$ d) J
配置调试串口1:
* o! L4 z7 b4 Y9 h4 O) h0 F+ M" I1 [7 b
9 ?6 [% o% U+ u# |+ e! X9 v" |5 u7 e) G" m1 k' ~
配置两个LED灯:2 Y$ O- M( p# s, C, U4 v4 \
( `% ~9 q, w5 s/ o$ R
8 C/ o5 z% R2 A2 P3 V# q0 S8 r% F* Q, t. W% ?
由于LiteOS使用系统嘀嗒定时器当作心跳,HAL库也使用了这个定时器,所以我们将HAL库的定时器改为其他,这里我该为了定时器4:5 I+ ~3 p% {' ?
: m) p2 [; p l+ S
3 v) }- _. x. V$ N1 t$ n& C) L
2 O! y9 S7 h) C& \ H$ s5 e配置中断,这里我选择了组4,也就是全部为抢占优先级:
# h& n6 ], [# K4 `* G, H& E, R; i- M( H1 ~$ f, ~
6 ~8 r+ [9 F- d2 z# `' |8 V7 E: S3 K8 n8 o
取消掉以下两个中断服务函数的生成,因为ListOS已经实现了这两个函数:
2 ^9 E3 I6 z/ m8 _' {1 {4 L9 {0 Q8 a9 [1 u1 U) g
6 k0 s n1 Y& l' d( c
: s6 `- }) w3 u& S最后输出工程即可!
6 q- x# B, z9 E ?" @" A3 C" X; y# W
& [& c4 W. L) E6 V0 ]/ H, E(三)移植LiteOS4 h6 L7 p, H( y+ x- y1 P
下载解压LiteOS,文件目录如下:
0 @- h9 t8 K3 y0 F& O
3 @; l. h- w* m+ w' g7 V
( q" ]) I; H8 L8 V# E5 o4 C4 M0 N% B: ]2 M# v3 Z# C7 |0 ]
文件目录说明:) o9 W6 I& Z5 X* C3 b1 g3 r
arch:这个文件夹与平台有关,我们这里的平台是ARM# ^' o9 Y) u6 l/ P9 a Z7 ]+ Y
components:这是一些组件,例如fatfs文件系统、mqtt协议栈等: `/ C, I/ X8 P% o& W
kernel:内核文件
9 g& I* F$ K$ T( b/ xosdepends:CMSIS的API接口,如果系统需要使用CMSIS接口,那么需要移植这里面的文件4 J6 N( `% C. j. Q7 D
targets:各个不同平台的示例工程
$ @' R- u4 e0 |# r7 c8 P4 X
3 Y, z$ N5 ~8 k5 _我们需要的文件有:- i: W; v- M5 o% \7 ]* Z+ a
`3 _% y: U" ^# ILiteOS-develop\arch\arm\arm-m\cortex-m3\keil\los_dispatch_keil.S
6 G" W: u+ J' \(注:因为我使用的是STM32F1系列是M3内核所以选择cortex-m3文件夹下的,如果是F4系列那么就是M4内核应该选择cortex-m4文件夹下的文件)5 o, }: g3 ~/ @ }. v: v1 q
LiteOS-develop\arch\arm\arm-m\src目录下全部源文件
" r( V( Y, [& l" U$ V$ @2 eLiteOS-develop\kernel\base\core目录下全部源文件
! n7 l( A% m3 {! SLiteOS-develop\kernel\base\ipc目录下全部源文件8 Y6 A2 c6 a/ F5 z' q
LiteOS-develop\kernel\base\mem\bestfit_little目录下全部源文件6 S. d9 y2 G6 j+ r3 O4 L0 m x% M
LiteOS-develop\kernel\base\mem\common目录下全部源文件' U- d/ K: I+ A I# w, f. k" ?' I7 Y' a
LiteOS-develop\kernel\base\mem\membox目录下全部源文件: m* o$ d! w1 k/ j0 o6 p( d
LiteOS-develop\kernel\base\misc目录下全部源文件3 d' B+ m& U: E7 E5 v
LiteOS-develop\kernel\base\om目录下全部源文件6 N3 T: `8 a' X6 K
LiteOS\kernel\extended\tickless目录下全部源文件. Q# t8 u/ O8 ?' P) L; ]
LiteOS\kernel\los_init.c
- G2 x1 Q' y, \, [: w* }4 \0 N6 B拷贝示例工程下的OS_CONFIG目录下的头文件 (此目录是在示例工程LiteOS-develop\targets\STM32F103VET6_NB_GCC\OS_CONFIG中)) F( ~8 B: E0 f& \! J0 E/ ]
在Keil中添加源码,如下图所示:
+ ]$ [2 _9 Q( ^/ D8 a) }9 P1 z2 \( X
7 U; d& i. W* ]
" _$ X8 G8 B, ?* f1 U
添加头文件包含,如下图所示:0 |) d5 u w& V' {
7 d/ ?( g- T# ?# ~+ l: ^) D
) K5 z7 X3 g, I* W: o- y; ]% \+ V& H% C1 z
修改OS_CONFIG/target_config.h文件,找到BOARD_SRAM_SIZE_KB宏,此宏定义了SRAM(内存)的大小,STM32F103RB是20K,所以此处改为20。& N" a8 D& ?5 v7 |
3 _0 f" X) f4 N. i8 C
修改宏LOSCFG_PLATFORM_HWI为NO。此宏控制着系统中断的管理方式,为NO表示系统中断不被系统管理,为YES表示系统接管中断。STM32的中断管理已经很好了不需要系统接管。
9 B9 _2 I7 }$ v& j' Y: w
7 q; }) b8 C# ^/ ](四)系统运行测试3 t' C; _% }" I/ E7 d
1、原始LiteOS-API测试
, J* r9 C' x3 t这里创建了三个任务:
/ E* @+ |1 ?1 J/ H2 x Zled1灯间隔1s反转电平' \0 L0 o+ L# M C
led2灯间隔300ms反转电平
) [' M9 Y3 |" c3 t& k. x% Uprint每隔2s串口打印任务
1 f+ P+ c) M, |4 H8 N4 J+ L& N' B! u$ ^( p6 v
- int fputc(int ch, FILE* fp)+ y9 F. Y- S+ e/ M1 h( {: U0 X' Y
- {- j/ J4 a. |0 o x. i7 O7 e8 b
- while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);
- D; h; m4 O# P. q - huart1.Instance->DR = ch & 0XFF;
0 I; e# Q( o3 J4 d, w) `( Q7 S! c - return ch;
7 h3 B( W! s1 Q) Z: v2 W) L% L - }
0 O9 _8 R5 n* |5 B7 m
- ~) I; {5 r+ e- k8 h3 u0 U5 ]- void* led1_task(UINT32 arg)
2 m7 s$ k1 M, h2 y1 Q' i7 w2 w* X - {3 V& {& n5 J5 k- C& F( Z8 k
- for(;;): w. A8 s1 N* {
- {
% G) L& I" n! Q. Y# t% N - HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);, a |, T; l1 W" N+ P' j. K
- LOS_TaskDelay(1000);
2 L3 s. B" R1 P8 C( w3 k& P - }5 N/ t6 [! [2 Y- K3 g0 A
- }+ I4 A9 O# v, ?' P1 Q( f W
- ; r: o5 M# t$ b* f+ ?: {
- void* led2_task(UINT32 arg)7 ~5 j( V1 Y: b! n& G# m
- {
# F2 ]$ o* a0 Y" ~+ |$ D0 J) g& P! L - for(;;)
4 x; g7 ]# P$ s% B - {
$ y3 G( i$ x% J% y) V - HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
( p9 B; `2 i. S# e5 z - LOS_TaskDelay(300);7 N$ j4 y$ C7 R$ G6 _! T
- }( f* S, Z1 }7 n* P5 O6 u
- }7 f) K: d [) i& R8 }. B
7 u) Y# X. \* K2 A! S! N( X- void* print_task(UINT32 arg)1 @* u( `5 E# ]* w
- {& ^8 x. K* Z Y3 n0 D7 X6 R
- for(;;) ?) y3 `1 h, w; {5 R2 L1 E6 T
- {$ l2 z6 i9 \0 V1 X* d! ^" f. I
- PRINTK("Hello LiteOS !\r\n");
4 h0 [& S: n8 @8 ]( n7 F4 _( j - LOS_TaskDelay(2000);
+ {) B" \6 `) e) L4 K/ r - }
$ N1 f: T. `, i" N# U - }
3 I( @) x. w3 F- w6 v M# z+ A5 c - ! Y) E% g! H& R+ k D8 a& L
- UINT32 led1_task_handle;
+ q3 i5 R' \6 \8 ?3 h - UINT32 led2_task_handle;% Q6 A7 o$ s9 f' d `8 |, q$ i+ u
- UINT32 print_task_handle;. J$ P4 L: Q2 T7 z3 y
0 M: L9 Q8 o1 [1 C- int main(void)7 x& w0 V8 N; y
- {/ V3 N% U' L( h* Y0 `
- TSK_INIT_PARAM_S task_param;
6 c4 |/ g( p0 S8 ~5 U9 U) \# r - 6 q! P4 D$ j6 t" _7 R" Y
- HAL_Init();
0 f5 l0 z5 ?! i4 B% W6 D1 Z% y - SystemClock_Config();- H3 e4 c( j7 I- ]' t+ A3 n
- MX_GPIO_Init();
: Z$ W: g6 ^- ]' i - MX_USART1_UART_Init();
3 D& Y( _8 O( O$ f8 {- J -
; P0 ^+ P- s0 ?" G7 F - LOS_KernelInit();
8 |& a4 N. v% G7 Q4 D - # C2 {* M# {5 k$ j' `2 F/ O5 v
- task_param.pcName = "led1_task";
: W/ c1 K7 Q; V$ W! B b" i - task_param.pfnTaskEntry = led1_task;5 g2 F$ g0 j+ T. a: f
- task_param.uwStackSize = 512;3 c5 ?9 A5 T1 X( k/ b
- task_param.usTaskPrio = 4;
6 F/ F: O& W' U+ K: r8 v - if(LOS_TaskCreate(&led1_task_handle, &task_param) != LOS_OK)
|" W4 |, u' I0 e4 r/ ^: K! H - {
$ @- ^1 |, L T$ e9 F9 J+ U - PRINT_ERR("create led1 task failed!\r\n");- M- q+ k4 k" ] E* ]
- }' A6 w4 c0 v; ^. y
-
& Y, W7 }/ ~0 ~( U. c j - task_param.pcName = "led2_task";
" y; o( t f( f; J; w: X$ |' c - task_param.pfnTaskEntry = led2_task;# c5 S( {- V. O
- task_param.uwStackSize = 512;
# E l6 o) O4 S) u% l9 G5 |6 u - task_param.usTaskPrio = 4;
; U2 T6 Y: F0 B4 r8 H - if(LOS_TaskCreate(&led2_task_handle, &task_param) != LOS_OK)
6 I, N; ?8 \$ ?5 W. D- `# k1 I - {2 a( Q {& F: y3 j
- PRINT_ERR("create led2 task failed!\r\n");4 a; N2 O; E- D) ?* C3 d
- }0 a2 |, ^( D; D4 [- L% m: O' T
-
; C) J$ V7 x7 L1 _7 F - task_param.pcName = "print_task";2 S9 d. D; |2 h* r8 y
- task_param.pfnTaskEntry = print_task;
1 D5 D6 q, A5 C L1 S - task_param.uwStackSize = 512;
6 l, b& W7 O- d( Y( J" L - task_param.usTaskPrio = 4;6 }: |. N7 r/ P$ J4 n
- if(LOS_TaskCreate(&print_task_handle, &task_param) != LOS_OK)5 H" s, w- b9 b) t& I+ F- C4 Z) Z
- {
1 v! v5 c4 I$ {* Q/ ^ - PRINT_ERR("create print task failed!\r\n");
- w7 l9 T. }# y% Q3 m - }
* o; x# m% T+ K5 K! m -
$ {( g* {1 J+ |2 o4 Z) f9 B5 g$ R% R - LOS_Start();
& H9 f0 B$ z& W. [) q9 p1 Z8 |' { - 8 v. X2 q& n: k. B( c' C
- for(;;)
/ [8 v9 ?/ h. u: P9 X( D: O2 U) } - {
2 |) f0 e. Z# s* h - }7 }: l) q( G- h' l3 K! D* J
- }
复制代码 , x* f w, } b# ^1 n- y
2、CMSIS-API测试
3 I; c* E9 H5 r9 f由于使用CMSIS接口,那么只需要包含头文件#include "cmsis_os.h"即可:$ t) ?" |0 G" T: H; }; [1 {
6 ~6 a1 c/ r9 |! X' c+ c2 e
示例代码:# _' X; S6 Z# s7 i/ E2 h' E" Z
4 v1 q o2 C! n7 T1 b# I' a4 _. E- osThreadId_t LED0TaskHandle;7 Y" s8 v1 R# W3 _" x) v; l
- const osThreadAttr_t LED0Task_attributes = {
$ H3 U* p8 L0 B4 }* P4 Q; y8 Z - .name = "led0task",# a5 l# g8 b2 m
- .priority = (osPriority_t) osPriorityNormal,
* i: z3 n- s; ?3 P3 A: a9 X - .stack_size = 128 * 4( h7 f* Q9 N' H
- };
0 R* }0 L0 ?: v" v: w- n - void LED0TaskEntry(void* arg);
0 b* _* g- O( l$ ]3 v2 \
& _7 [, V7 {+ O+ Z: c1 `8 \! `4 e- * e7 s1 @7 m8 B( n7 }& [1 n
: i$ B6 @4 X/ V( S
4 O, A: T1 M# a8 F0 O- osThreadId_t LED1TaskHandle;
. Q7 k9 D: H0 |* a- z0 P% ^) b7 P7 ]- L - const osThreadAttr_t LED1Task_attributes = {. U( N9 C1 G* S8 i3 m8 T
- .name = "led1task",
/ Z' `" f9 n0 D4 m- v1 N9 E: K - .priority = (osPriority_t) osPriorityNormal,7 f$ ~+ J |& i3 p$ f4 S2 m
- .stack_size = 128 * 4
5 ~7 M0 I+ z' D B& L& h - };
& ]1 n+ ^- U f; Y - void LED1TaskEntry(void* arg);
$ \1 o- ~6 O! b* F2 D& o2 Q1 H/ u
" v3 h7 |( F# \: U- 0 \+ X1 C, a6 T1 z' j c
- ) V7 l U- W* d; b1 M. H7 ~
- 6 _( R r. b# Q! b( }1 r- }8 J
1 g9 J- F5 _. ~$ t- Q/ p, D) _- int main(void)
) k5 ^6 T* U o) c - {+ E( C( p3 E& R
- HAL_Init();" {/ n$ Q$ V* X) J
- SystemClock_Config();
" I4 {8 l# M, G4 [" p - MX_GPIO_Init();- g2 k3 P; Z+ j+ X+ C! k; y
- MX_USART1_UART_Init();, z, q3 X6 m6 K
-
3 b- D( `' B4 P. O - // 初始化内核8 E9 m& H/ i+ U8 J% F" `- |8 s" s% Y
- osKernelInitialize();0 D) J, d3 A4 z7 u. }3 B
- " G; Y, F/ s9 ]% ?
- // 创建LED0任务6 H) v. Z% ?8 d* b
- LED0TaskHandle = osThreadNew(LED0TaskEntry, NULL, &LED0Task_attributes);
$ q$ k6 B; V; B0 t3 v - , Z9 P$ }* z2 z" `6 `
- // 创建LED1任务2 V) A* K0 k5 r& k) L* N7 h
- LED1TaskHandle = osThreadNew(LED1TaskEntry, NULL, &LED1Task_attributes);
! ?* a9 `" ~ @/ @, { - 7 [ y' f! Q: w% D/ d
- // 启动内核调度
) [, i, ^# m4 w% z - osKernelStart();* j! w( @) D' ^7 `. Y
- 5 z+ Q9 X; o9 Z* n4 z; s. r
- while (1)" H. h6 A8 W! h1 r7 G! y9 _( s
- {6 ~7 }9 a5 T" Y, v: j9 L
- }
* i1 L6 m8 Y7 d - }
: r W$ @2 \- s4 I& ^
# |" d$ E' g) \8 O0 s+ ?5 G
* w! L2 [( C* v* [7 _- 5 C. C& |* x8 w& Z6 }7 B
- void LED0TaskEntry(void* arg)5 g- u3 y; p7 m+ }+ R6 ~
- {; D3 y5 J$ m- ^* q0 ?3 J* R
- for(;;)
+ |$ Q2 K& l( `. d G0 A - {
4 q6 i4 T8 A% s! y$ s - HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
, p0 y" D1 n( ]+ ~: W - osDelay(300);- Q, O9 ?, J1 }3 P `
- }
7 Q3 v% K, m8 O/ `5 H; S - }) z2 D0 w& ^# s& h; }
- 0 E) H8 f7 X; n) f- ]2 L, B
- void LED1TaskEntry(void* arg)1 ], t% [& o# M
- {! ~0 q, h2 F% t2 L8 c! e
- for(;;)$ S W, C' p2 [- I8 E9 f- F
- {
$ r6 C& l$ L* K5 j6 {5 X- R5 y7 X - HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
! v( n6 \% D! @; d; Y! `; N - osDelay(1000);* k9 r# {# W5 Y# r$ Y! a7 S7 _! k+ h
- }# E. ^0 N l% O
- }$ z6 U0 k. C" m. `& s9 I/ w
复制代码 4 C" u7 J- @2 m0 s# I
, ^* k1 L; M" Y4 h, Z$ Rends…2 ~2 T' p8 f7 y1 o" g
# y0 c4 j1 T% [. v
% R% u0 x, U/ h0 w
/ R5 Q6 h' i3 N9 |5 f4 A |