4.1 初学者重要提示9 @" L4 S/ U+ \7 _. s) ~$ D
学习RL-USB移植前,务必保证已经熟练掌握了RTX5内核的移植
* t! ^* } D! {1 G/ `* U7 |7 M7 E STM32H7使用MDK RTE环境添加RTX5和RL-USB,需要强制运行一次STM32CubeMX,因为H7已经没有配套RTE经典添加方式,而STM32F4是支持经典方式的,所以无需运行STM32CubeMX,详情可以看我们STM32F4开发板对应的RL-USB教程。
4 S/ @( b6 L' x- ~* { T 本章配套例子使用STM32内部RAM模拟一个U盘,使用的MicroUSB接口。
& B; e. l. A, Y0 b+ t" v# G4.2 移植RL-USB整体说明
1 z) j7 h' d8 e! n0 y移植之前,有必要对移植过程有个整体的认识:
; n( B4 Q3 ?; M( C" g# P3 C% v6 v6 i. h1 c2 l9 o
第1步,准备一个RTX5工程模板。
- X- ~, ]7 b) { O' p" u% D9 i 第2步,移植RL-USB。
: v9 W2 W5 ?/ X" x! ]6 c9 i 移植RL-USB是采用MDK的RTE环境直接添加。当前H7芯片使用RTX5强制运行STM32CubeMX,所以需要大家提前安装好STM32CubeMX V6.0或者以上版本。$ _) N! x Y- I- @, k& w$ Y; O
第3步,处理HAL库时间基准,MPU配置等。
/ R4 D* o' o7 Z 第4步,创建应用。
; c1 X1 f* f# a1 \. `% j) e总的来说,这4步就可以完成移植,下面将STM32H7的移植步骤和注意事项为大家做个说明。! G6 y5 f& W, m4 s3 ~
- p4 }" z' z# E
4.3 了解RL-USB模板框架设计
1 Z6 Y+ T3 r: k移植RL-USB前,我们优先了解下移植好的RL-USB内核模板,方面大家后面移植:% K, E# ^$ }. _3 l
" b/ s. [( ]; S! J6 ^9 f* K& ^# u+ d5 Q, }$ |! Q7 l& y
2 |6 ^/ w" L1 o% C8 b
框图如下:
( J+ c$ n) A% F" x2 ]7 S, O, D2 Y. Y' J" l1 @9 S+ i
% q Z8 L0 H, b, D. Y" R' Y } @: {
4.4 第1步,安装指定的MDK软件包
& C9 T" S* `% X; O移植新版RL-USB需要大家下载当前最新的MDK软件包版本(如果有最新版,推荐大家用最新版):' F7 U* A" S7 P; ~: U) C, {8 z
+ `" @7 V. j$ B5 M6 U; K CMSIS 软件包使用当前最新的:V5.7.0
8 }8 x' G/ B3 a: N0 ~0 x3 j7 I3 U STM32H7使用当前最新的:V2.6.0" j6 z- X3 G& ]! R
STM32F4使用当前最新的:V2.15.0
+ V. j4 E+ _" K9 `* e' \9 c STM32CubeMX使用当前最新的:V6.0.x0 ]+ O4 Q/ j7 v+ q6 Q6 j7 n D
ARM_Compiler使用当前最新的:V1.6.3
4 W& t. x G' R/ ~5 G. x# X% D RTX5中间件使用当前最新的:V7.12$ E* G4 f; t' b) R& |+ d; ?) \
: Z) ?3 u; ]) o$ S# J. r
* l/ V5 v; X' ~& U; s不管以后MDK的软件包版本如何升级,当前的软件包版本和以后的新版是可以同时安装的,也就是说可以安装多个不同版本,在这里可以选择指定版本:+ Z# C+ V) {1 a5 l/ ]# M
! m/ {3 ?: U a; A. }* F
( H" t5 i0 f1 c+ H7 [: Z& R' c: W/ g$ {! T) a
4.5 第2步,准备一个工程模板
% C/ P( e/ l, [9 @首先准备好一个简单的裸机工程模板,已经为大家做好:V7-4001_RTX5 Kernal Template,准备好的工程模板如下图所示(大家也可以制作其它任意的工程模板,不限制):6 X# @" ?& n: h
, U9 M. m. C2 Q8 w) a3 q' h0 l( j% y
) v1 X j9 `" z u$ l% Z4.6 第3步,添加RL-USB并配置* A2 t M1 ^) U1 z# i o
看这部分内容前,务必保证已经熟练掌握了RTX5教程移植章节的添加方法。4 h) X- h8 V& s) S
9 t$ i( w- L4 L, m' s7 o/ d4.6.1 RL-USB相关文件和驱动$ w; Z5 u! j: k2 G T
CMSIS-Driver分组中添加USB Device驱动:+ M% s t: z$ }( a5 _
0 T7 `* y- _: A" Y7 k
9 @ Q1 H# s% d. X7 R2 v
- J2 k" ~( S+ Y' R添加USB驱动:; n. z2 @" s- S. \- L! T
* x/ L% o$ `' Q1 T6 K+ p! ^8 g7 r* R7 |0 r8 ^( P# w# L4 M
" c4 s& f; v4 h& b2 k添加RL-USB并配置:
8 F% D& c, b5 ]+ B P* ^
$ @- `$ E/ V; Z: N' m9 a4 Q5 F+ D% P2 i; F. u" B" J
+ E4 _& x% H+ H/ h* {$ E我们需要的都已经添加好,效果如下:
, n$ j5 @7 m$ I/ ]: v# w/ I8 j, \9 z1 Z' c2 H; w3 M5 S! m
& F O. g5 L4 J& M
+ v& {7 A: q$ l2 H9 G( X& _
红色方框里面驱动要隔离出来,隔离后的效果如下(隔离方法看RTX5教程移植章节):) K2 i. D% C) b+ f ^+ O' G: _1 I
0 e6 M& `- c# s* B" F9 T2 R. p1 H! C- e- o; U2 N6 Q
% _. W# r# q& u7 B: j1 _) a
4.6.2 重新添加被隔离的CMSIS-Driver文件
% P6 ~1 G9 Z- B4 D7 ~/ M将我们提供的程序模板中制作好的RL-ARM文件夹复制粘贴到大家准备好的工程模板中。
7 E" h* g6 i/ B1 P' a! Q
9 n6 Q, T7 z% J$ N3 ]* @ [7 ~) @
4 H. x' B8 N: B: d. N
( j8 f. H; N6 b. Y7 j; {RL-ARM文件夹中有如下七个文件夹,其中只有RL-USB文件夹里面有文件
$ l9 V3 l8 q% O" q9 r! U, \) M. U1 J% t" V, w2 g' V" q( `+ d
" g4 G& ?, c2 `, q) L9 U3 D
/ {) ^( P* y7 G( {9 S1 ` u" ]0 Y# |内容如下,这些文件是来自MDK安装目录:
1 ]3 ]* F0 v+ W5 r% K! {+ g3 \0 p
. m1 K& X6 g0 G8 P' k& Y4 G: X, o# W
+ d" J% Z% P2 F3 q
然后将用到的两个文件添加进来:
# `" P3 ]3 T8 F" O: O5 h2 f6 r$ k0 M; t' z% D
+ u; M' |+ U7 k- @4 H
2 o% v h" h2 d
4.6.3 重新添加被隔离的HAL库USB文件
- B3 a& |1 t3 M8 e V1 [: Y5 O文件stm32h7xx_hal_pcd.c,stm32h7xx_hal_pcd_ex.c和stm32h7xx_ll_usb.c被隔离出来了,我们单独在分组HAL_Driver里面添加。除了这三个文件,同时将两个pwr文件也添加进来:
" K/ z1 Q s r' o0 S* E, z+ P6 c) R8 t7 W8 Z" s8 @2 @2 {- G
+ Q8 S0 d! _) a! v' z
: ?' U' [( U6 m1 }1 K4.6.4 RL-USB配置
/ E+ @4 E! Y4 F x, _添加完毕RL-USB所需的文件后,就是配置RL-USB,具体每个配置所代表的含义,会在后面章节专为大家讲解。
; _5 C, W; A0 w; U: `. Y& K3 z' ?+ b7 Z7 ] q4 x6 t
USBD_Config_0.c文件配置:% v& O( J+ @+ E! j9 V
7 O* H8 J3 ]3 j' h) v; q7 T+ ?, H5 S+ a( ~1 y. E
7 H3 G" L: }) t: m! o+ u/ @3 d h
注意这个文件里面还有一个RL-USB内核线程的优先级配置,当前是将其配置为:
/ z" z, Z- q4 _" M$ e3 x8 i5 T& P1 O& C1 ]1 P0 A2 v, K
osPriorityAboveNormal:
% q6 h0 v9 F8 j6 v8 p! s; k" z) u3 g0 X E% c- q; L! `
5 V+ f/ @7 x! e( e' _# x+ p8 f
' y- S$ ]% m+ d7 \1 `5 bUSBD_Config_MSC_0.h文件的配置如下:7 y- {4 w% A- T( i1 Y
( b& k- `: s1 {- w- y
3 n* ~" N: W) h" v# ?. J. ]
' Z& v9 k) }, D% `" E4 Q2 j6 D这个文件里面有一个USB MSC任务的优先级配置,当前是将其配置为:osPriorityAboveNormal。+ Y( m3 d/ e* f
' ~2 H; O( r# @/ z
( U; F& m: t5 B- A' ]# E8 M
2 _8 b$ D5 ~* ?4.7 第4步,强制运行一次CubeMX配置USB
5 q8 ~. D4 b0 @* X0 z6 I3 V4 @8 \& W我们这里要强行运行一次STM32CubeMX来自动使能RL-USB的相关宏定义,并配置USB接口使用到的两个引脚PA11和PA12。" z( I/ L3 F/ B3 \4 U1 S
! s: S7 ~) i: E2 G
打开RTE环境,点击如下按钮:
. S& z4 N- }8 x3 \, j
: @ E% a$ m5 K' `* G
. B6 g7 M9 |9 h
" G4 C4 r& C! b6 c+ e弹出的STM32CubeMX配置如下:
6 ]( Q1 w9 h3 U/ a6 X( J$ o
; ]0 d! d0 t# r* l. B$ Q2 F$ T0 b1 a' z+ \1 N, e5 m& W
* ~3 G1 L/ [8 q6 c; w6 |
修改位置1:用于选择仅使用设备。
: g% Z( x+ J# G. D
% l( S+ g; {9 Q( T修改位置2:用于使能USB FS中断。然后点击“GENERATE CODE”9 o0 n; h5 G% N' J) R/ R% B2 l6 r
2 o Z* e9 m" N! y2 y
! |! k: w. i/ q& R
2 j0 A: O1 K4 r2 d$ X F' ^
然后弹出如下对话框,点击Close即可,然后关闭STM32CubeMX。
& m1 k$ |/ Y9 q5 a" I, k# {2 h
* W! R$ x, l! ?+ w2 J: V
, s8 K( X- |0 m4 M6 \/ V
5 n# L8 m1 J) H' j6 ?& v4 y重新回到MDK,会有一个对话框,点击“是”即可:7 A& [( n( Y0 w& ] T, d
5 j& P) E- p' c( a [3 W
7 s" [4 Z9 P6 D3 ~2 w6 M" L: c. X5 W
配置后,就可以看到stm32h7xx_hal_msp.c文件里面对USB引脚做了配置。 L+ P4 B" f3 D. t6 c1 k
; S* i! H& O/ U; a: C1 e# g4 P7 @$ D' H. E9 C& a8 G, y0 f
/ K! O" _6 m; p: C7 r
4.8 第5步,修改文件USBD_STM32H7xx.C: u% y+ K8 ?- z
这个文件开头的头文件顺序要修改,否则编译会出错,原始的顺序如下:' k9 W5 E: U' C
9 Y$ v/ a% @) h- #include "OTG_STM32H7xx.h"
6 N8 B1 g& u+ k+ i" ` - #include "USBD_STM32H7xx.h"
+ d2 \5 R# ^$ F9 \4 u/ F# ^" p) w; w - , J% z0 v x9 W _8 Q7 Y
- #include "stm32h7xx.h"
复制代码
7 T! t l* b5 }+ I修改后的顺序如下:
2 r+ u! g9 A! P" C* C; \
% T( Z$ a9 l! f5 Y" f; E- #include "stm32h7xx.h"
0 I! o: d5 E. C/ k) f: a+ \ - 6 O, ~* ~$ {/ R0 q9 T, |
- #include "OTG_STM32H7xx.h"1 \& _* X# b2 Z1 o* B
- #include "USBD_STM32H7xx.h"
复制代码 6 C& I c3 z/ }! r: @
4.9 第6步,修改文件stm32h7xx_hal_msp.c
5 p9 i4 u' {# x; }: K- |, {0 u8 V需要在这个文件开头添加一个变量PCD_HandleTypeDef hpcd_USB_OTG_FS,此贴变量会被USB的CMSIS Driver文件所调用。最好将其放在如下位置,防止重新调用STM32CubeMX时将清除掉:+ E$ ^6 j& ^/ h/ M8 Q
4 _- l7 k, ?5 P7 P+ _% t1 w
# `5 _8 o5 [2 f7 m1 b3 k$ t( Q: U J8 C& Q# {
4.10 第7步,修改文件includes/ ]% Z# M# l8 k6 m: b
添加USB头文件:#include "rl_usb.h" N0 Q7 Q: O- T9 R4 i- Y) D/ Q. Z
4 q, T8 v% ]7 v#ifndef __INCLUDES_H__
" `, O; k/ g! Y# q% }. }#define __INCLUDES_H__; V/ ]# }( Q D' ~) f: r
$ ]4 \" p: @5 w1 `7 v) h: H/*
# R) T& t( v- M0 L2 o*********************************************************************************************************
4 F& Q% e: s8 k6 X* 标准库
, u/ p$ D1 j0 U4 g; w*********************************************************************************************************. G: `; w& N7 B% |2 J* E- z
*/
& }* k: U0 |5 D; e* M4 A#include <stdarg.h>$ |' ~* f. a9 t3 ^
#include <stdio.h>) Q7 }) I3 `$ J+ k2 ]7 G5 h X$ g1 ?6 _0 M
#include <stdlib.h>
4 Z2 }' B7 |4 [3 H: o#include <math.h>
3 T2 u4 C$ g* z& U# A2 a! c$ @4 w# @6 s7 H; \ ?( A
7 j( [9 E( \) ]" [5 m8 W/*
8 ^5 C0 q! `4 x1 j4 X% g; o*********************************************************************************************************
+ U( W& {: ~% [. u, |5 T" u* 其它库( e& [2 {0 e& s. }
*********************************************************************************************************
; V1 @# R* }! _2 o9 X8 A! v! ~*/
4 |) b6 W0 B7 n) M% r/ D4 \
' C' c) k, ~" q: L' h( m
* [' m! e, F' C5 Y4 w; P/*
$ k: w; D6 i! i4 i% I5 K; W*********************************************************************************************************. I- G. X' e k( w
* OS和系统库
7 s% F# { x. R*********************************************************************************************************/ U+ |: y4 v" a7 `; J9 s7 l
*/% W& q7 G% T6 a/ g: J/ F
#include "cmsis_os2.h"
* C% H ^( _' w) l3 j#include "rl_usb.h"& }1 j3 @4 E* D- a, X+ f _: c7 G
2 n$ s% }9 m/ O7 u9 m/ |7 R/ H
/*
3 B- y" c4 Q* Q3 r*********************************************************************************************************, W" h- e; W$ Q; l& i
* 宏定义
$ t. Z" F- b+ u) Q0 r& W+ ?*********************************************************************************************************/ W* H! t/ b) {+ z+ i
*/; F4 E: j. O8 d7 C
, l' K+ G, x( T/ f1 \. T$ }9 x* C9 q3 z v& o, c
; O" b( e7 H( x/ f& |. A! _0 y
/*
/ K5 a4 k; R. B*********************************************************************************************************7 P, K3 w: z2 [( Q, c% J% Q1 c
* APP / BSP
, r+ \) G' b" ~4 z+ \" H********************************************************************************************************** l+ v/ ^8 o: B
*/: ^: [. p; J/ C; `& a
#include "bsp.h") n( X$ o5 X$ A2 x, Z' X
; n ]) x, T. D% L) ^# K
& ^: l! a. U8 A' v5 A
# v% J/ D$ o' P: i+ G) k
/** y9 t4 F2 @/ f% c
*********************************************************************************************************
& f- l/ O" f9 R1 Z* 变量和函数
4 j: ^; E7 z' r! |1 B ~. u*********************************************************************************************************
* C) l! r0 E( ]' d- z8 R*/
4 l3 J5 g& ?3 `0 S" ~2 E/* 方便RTOS里面使用 */
, T: C" P u2 W3 Z( ^+ Fextern void SysTick_ISR(void);
?5 k( S l3 m) h# i
/ h) N% Z: ? l6 N#define bsp_ProPer1ms SysTick_ISR* u7 n7 w& _- A+ v5 ?' t+ o5 X, I
, S. W* y3 K4 H2 ?& e#endif
- I; u/ V# n: _/ h
- ^: m+ J* ]2 V! Y/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
9 U0 r, ?! i! v% r& K3 j4.11 第8步,添加两个应用文件# l8 v% u3 g+ v' J/ ?
为了验证移植的USB是否成功,我们这里使用内部RAM模拟一个U盘。需要添加的两个文件在MDK安装目录里面。方便起见,大家可以直接从本章配套例子里面复制粘贴(这两个文件位于User文件夹),添加后的效果如下:
6 ]; F, ^& Z4 ^) o6 K2 Y- j1 P) q1 b4 I/ T3 n- d9 ?. e2 i
' @# J0 h$ M& j/ _; q
9 |3 u7 v- K4 ~( h4.12 第9步,添加头文件路径/ F1 j" A7 a! r
添加头文件路径:3 A# Q3 B# Z+ e4 X0 ?2 N! p
7 R1 r/ v2 a. @ U
3 ?7 g% w; X* K# U6 d/ J3 f
) k" z. q S9 X% R/ [0 h4.13 第10步,创建应用任务(重要,注意启动任务)* M, J3 s5 Q- `" W
应用程序比较简单,大家可以直接复制本章教程配置例子的main.c文件中的内容到自己工程里面测试。主要创建了如下几个任务:
7 w" j$ z+ [' u* M \: D9 e( y8 W8 F
AppTaskUserIF任务 : 按键消息处理。
0 Z) L7 h% ^& j) ~% |' _7 y, l' `
* B* j3 p& v% M- |! S; a1 J$ ZAppTaskLED任务 : LED闪烁。
9 j8 _. i) _' J7 i4 l$ A
4 Z+ j: T) O l3 k5 v. w* F5 PAppTaskMsgPro任务 : 消息处理,暂未使用。$ k/ z' z& e5 S& f8 U: S
: N$ t4 x# Y) A! p# p1 ~
AppTaskStart任务 : 启动任务,也是最高优先级任务,这里实现按键扫描。
$ x. I T4 W1 |; ~, U7 a* A6 f) f1 _2 N1 O/ y
osRtxTimerThread任务: 定时器任务,暂未使用。( {/ t' r: @( B: X+ R! z9 }/ Q
& s+ U: \4 ^4 }: e3 M3 q5 h任务栈大小和任务控制块定义如下:( W4 z" v! x' N7 w8 y
- X' p5 H+ G; r% T9 ]- v+ l2 ]
- /*
- ^* t+ c! o+ f" f3 X3 i - **********************************************************************************************************
' B4 G# _. f: k1 S - 变量0 ^) D7 Z$ N$ l5 F
- **********************************************************************************************************
# T" T8 o: m0 T3 g - */
' r! C+ O$ V/ n4 M9 w1 x) t - /* 任务的属性设置 */
B! p8 X: [5 v, V- D; t2 v+ b - const osThreadAttr_t ThreadStart_Attr = . a! ^! m% l, n* @5 `' w
- {- D8 ?' _5 W7 F* H* D; s* Q
- /* 未使用 */3 @# h- c. q( p% `# v5 q
- // .cb_mem = &worker_thread_tcb_1,
( l6 Q4 E2 }7 C+ m* E/ k' k$ ? - // .cb_size = sizeof(worker_thread_tcb_1),# {0 y" r q" u2 x$ Y3 Y4 H
- // .stack_mem = &worker_thread_stk_1[0],
8 W; D* K& m f% q9 S/ m - // .stack_size = sizeof(worker_thread_stk_1),
+ C7 B( j9 V- z7 \ - // .priority = osPriorityAboveNormal,
x& W" [8 e1 ] E) d/ e1 R - // .tz_module = 0
, w) f7 X' F$ E5 H! S" j( ~; x - ) r" J) T# @8 P9 r+ b
- .name = "osRtxStartThread",
$ z& {; B1 V/ N - .attr_bits = osThreadDetached,
; d$ R; _9 r; C c! X' N4 S - .priority = osPriorityNormal4,
# J7 M7 U* x3 b/ G A0 I/ {) W - .stack_size = 2048,
4 a5 j3 K' n4 ~/ v E5 s9 h - };
+ Y2 o. F$ f! |7 A% n! ~ - % r) M' {6 `( E9 @1 J+ `7 W! A
- const osThreadAttr_t ThreadMsgPro_Attr =
' T" @6 c+ t& X0 c8 e3 d$ N - {
! R; z4 }9 I1 j4 e - .name = "osRtxMsgProThread",2 u F- u" j# A% C1 l7 @
- .attr_bits = osThreadDetached, 2 n8 t4 ~1 y* b0 U: \8 G: `
- .priority = osPriorityNormal3,; |" s1 C) z4 g& _
- .stack_size = 1024,# @* c( E P0 c, y+ M/ z
- };
$ L2 R0 m$ S0 ^4 m* x- ^/ `; _
+ B. S" q- `: c# b( D- const osThreadAttr_t ThreadLED_Attr = 8 ~; ]. l1 z3 \8 G/ R
- {8 K: A' Z, X0 h$ s' G
- .name = "osRtxLEDThread",
* p; \ E; N' G5 ]& V! I9 t e5 ?$ H - .attr_bits = osThreadDetached,
$ ^7 r: A$ l! h: Y3 ] - .priority = osPriorityNormal2,0 O5 |' s% G( c
- .stack_size = 512,
8 q4 A4 w( t6 F) _2 c1 J' c - };0 d: m, A" Y% \
0 U, Y; T/ Z5 N; A- const osThreadAttr_t ThreadUserIF_Attr = 6 a2 @) f% F# M- E) t' ^. Y! N! h
- {, T( z# \8 T4 J3 Z
- .name = "osRtxThreadUserIF",
. Z2 f% R1 G0 d" C - .attr_bits = osThreadDetached,
9 J0 _ a( Y' f( ?: ~& Q- c - .priority = osPriorityNormal1,
5 X9 Z2 S5 y1 M: i8 k9 V1 ~ - .stack_size = 1024,& A2 q! E) T' _ R
- };
复制代码
& [! @( v; h; s, v7 w- ?; M3 P' X任务创建:
2 W% u1 H, B+ W6 A
Z, B$ H' z! o4 o. c1 ~- /*0 ?$ b! H, e: G6 P# i! ]* W2 C5 a
- *********************************************************************************************************4 H9 n3 }8 P I$ ^: K# h
- * 函 数 名: main, \" r* y7 ^6 `& m+ S
- * 功能说明: 标准c程序入口。
! E9 n A/ P9 \0 d9 ?* { - * 形 参: 无
8 L% m, z+ L x1 E, e6 `+ x - * 返 回 值: 无
1 N9 g5 U9 v. x' ]3 I+ \' { - *********************************************************************************************************
* e7 m6 b% D$ B' ] - */
: N' K, L4 k9 s7 j/ Y: r3 c* y - int main (void)
0 m3 c P2 r1 K/ Y2 x - { " u5 {, j- O0 [4 {' X) N ]$ I4 I
- /* HAL库,MPU,Cache,时钟等系统初始化 */+ m6 b7 a1 d0 P$ m4 [$ p, u7 l+ g6 G. e
- System_Init();
4 [$ ~+ O( T' B9 k% K - " C. G/ G" c! T; J' v% @
- /* 内核开启前关闭HAL的时间基准 */' @. W% y, N2 A) n2 e2 j- r
- HAL_SuspendTick();# z$ y9 Q! [ c8 R" s2 e
4 d2 ]$ p3 u6 k0 P+ t3 c- /* 内核初始化 */" c0 H' B d7 ^* z& q% d: ~- w
- osKernelInitialize();
7 o' V o+ i5 {* n4 ^
# E; J* B/ c' l- D! i6 C# c3 P- /* 创建启动任务 */
- A4 m8 ?% M) H$ |7 p! N$ Q5 K1 s - ThreadIdStart = osThreadNew(AppTaskStart, NULL, &ThreadStart_Attr);
# Z$ b5 ~; U: \1 Z7 k7 W0 o - & R0 C* u: t" q, |4 c+ |
- /* 开启多任务 */
# P0 Y# a3 s4 F5 V2 f5 X - osKernelStart();7 Z2 B4 Z% C. [6 t$ G
$ E4 G0 r$ G4 G8 n' q. e1 h- while(1);- |& V9 m. {, b, q4 q
- }4 Z- E0 ?% C* v2 n
) L3 f! v$ f1 f0 W/ C3 y/ w3 n- /*
! s& F9 W# F% b, E) F) ] - *********************************************************************************************************9 w3 ~$ F' W2 v3 i% I
- * 函 数 名: AppTaskCreate. F7 Y* {- A9 y" D
- * 功能说明: 创建应用任务1 i; [" ~5 a( B4 k: V0 q! h5 Q
- * 形 参: 无
3 }4 x! e1 T$ L; V - * 返 回 值: 无
/ S* N2 V' z( r! Y - *********************************************************************************************************5 U. q& v+ Z! B7 M; k
- */" o. e: t. c: x9 |4 C: S# Q
- static void AppTaskCreate (void)
0 W, I. ?1 m4 k; p$ t+ e - {9 \& y* K$ W! `* y
- ThreadIdTaskMsgPro = osThreadNew(AppTaskMsgPro, NULL, &ThreadMsgPro_Attr);
. l4 Q) {# b- d+ m0 b - ThreadIdTaskLED = osThreadNew(AppTaskLED, NULL, &ThreadLED_Attr);
2 d8 a2 N# L9 {( | - ThreadIdTaskUserIF = osThreadNew(AppTaskUserIF, NULL, &ThreadUserIF_Attr); 2 N! [* o b1 a
- }
复制代码 1 G$ U9 u; k2 a( n3 I
这里我们重点看下启动任务,主要做了五个工作:9 X+ D+ }' b4 k$ d( N% q5 Q
) t0 Z% _8 B2 u4 g, f 外设初始化bsp_Init。
* `* r/ O' U; k% a/ y" G 任务创建AppTaskCreate。
) ]$ H. E6 E% R5 d7 L6 E 初始化USB并连接电脑。9 E; Z7 E3 S7 s- U2 t; h& t
需要周期性处理的程序bsp_ProPer1ms,对应裸机工程调用的SysTick_ISR。这个的实现非常重要,这样之前裸机里面使用的API,就可以直接在RTX5里面直接调用。- ]& t) T& v0 X% B
- /*
9 K* k/ }9 P3 l' m, @3 C/ A, y; F - *********************************************************************************************************
+ u1 `4 x8 v+ u - * 函 数 名: AppTaskStart
- S& J! i) Z- S9 g. L0 P - * 功能说明: 启动任务,这里用作BSP驱动包处理。2 a0 J$ T @% P* F4 x3 f2 V7 t$ M, E: e
- * 形 参: 无* ]5 w! I0 P4 U/ C5 B: b+ [' {
- * 返 回 值: 无
3 f! l7 J- A) t( y- g - * 优 先 级: osPriorityHigh4
3 X$ C2 V8 E8 _# g$ ^/ s& b - *********************************************************************************************************9 ^0 ~, W2 W+ w1 Z
- */9 ?' R: h( T8 |2 ?
- void AppTaskStart(void *argument)0 I) L, z6 z0 i4 F
- {) S; M. y" c* j' k' Y) V
- const uint16_t usFrequency = 1; /* 延迟周期 */ H1 D0 {, }3 [5 z& \
- uint32_t tick;
/ G9 A% v6 R; z9 l+ B3 K9 O
' R k: [7 @5 ^8 N# [ @5 q- /* 初始化外设 */' \5 W* G. s. E! p- r$ o) w
- HAL_ResumeTick();
) k: t: U+ N0 P: k2 `7 ` - bsp_Init();( k- q& }+ W7 e# f6 w
) p/ i' T; H' Z& S- /* 创建任务 */
+ [5 C! I! z3 L# R - AppTaskCreate();
* M. t$ D* d6 N$ k! I1 a - $ Z& q" {6 `7 m0 Y
- USBD_Initialize(0U); /* 初始化USB设备 */
2 B' [9 I$ L! s2 L- P - USBD_Connect (0U); /* USB设备连接 */5 ] m( z) x# I0 `7 T& n
6 ^8 j" q/ E; z# j3 D- /* 获取当前时间 *// J& n3 j& ?' D% p2 {
- tick = osKernelGetTickCount(); 9 s3 B/ K+ C+ r4 b! \ ]' Z
- c. ]2 c; x$ V) I, n) H
- while(1)
6 x9 t4 P! f2 y4 G$ ~* f: N6 ]+ Q - {# ]* S* n8 Z N' l. S* N
- /* 需要周期性处理的程序,对应裸机工程调用的SysTick_ISR */
$ C) t$ L9 h& m- v) N6 ^ - bsp_ProPer1ms();
1 x: H" a8 O/ z O
1 U3 j* d; L1 r. A" b- /* 相对延迟 */7 h* J) _1 @* V+ V. F. G
- tick += usFrequency; : ^6 O7 O _' W; E* u
- osDelayUntil(tick);" Z4 C' k) A, ^8 x# v3 `9 G0 ?
- }8 I: f+ V( m8 F- @9 i& i: ]) t; j' N
- }
复制代码
. ]0 r) b$ e U3 L& `9 n- V X4.14 常见移植错误总结* {# ^! k: \, t$ u8 I
编译后提示如下错误:* G* M& a, c& P" q' N
error: 'Driver_USBD.h' file not found6 F. T4 \( o/ o! N, B) i0 \
# o# y$ m A0 G解决办法是将新版 CMSIS 软件包里面 Driver 文件夹全部复制到自己所创建工程里面的 CMSIS文件夹下,并添加路径:
2 h8 \3 I- W4 [; }+ V L' |7 @* \+ g/ v
1 f6 O( M4 s8 r/ ]# u# ]
& j5 [, b# `5 H# E
提示如下错误- i# E! ^# r2 S1 k. \8 @
unknown type name 'HAL_StatusTypeDef'( C+ f9 C' ^1 w% T( G/ g& `
+ J* P" ^9 D/ A1 R3 U解决办法:本章4.8小节。
8 e$ P0 J0 Q$ Q) d" f0 ^& ?0 b, V, m: L- \; G
4.15 使用的MicroUSB接口并注意跳线帽设置$ r- }* b& Q( R
本周教程移植的例子使用内部RAM模拟了一个U盘,效果如下:9 D; V3 P( @- K8 E2 _% O' l
* _4 H5 c2 j! q9 M1 Z% a. Y" O( O
/ e% |- A# R% u
. `5 K' c9 L$ D/ p! U; _注意使用的是MicroUSB接口:9 {" W9 s- k8 C" u! P/ h( ?- u
0 R2 P+ p& C% i
+ U+ N% s3 D$ H& J
6 \, M) n" R9 T s' s$ E
注意板子左下角跳线帽的设置:0 s+ y% K& u. n+ s
7 g7 f' a1 k y. |
# X2 j. O# l7 V. K! ?4 W/ R' B: K
这里是用于选择CAN1 TX使用PB9或者PA12引脚,CAN1 RX使用PB8或者PA11引脚。大家这里可以什么都不接,或者CAN1 TX通过跳线帽短接PA12,CAN1 RX通过跳线帽短接PA11。切记不可以短接到PA12和PA11引脚上,USB要使用这两个引脚。
, q8 s: N* @; T3 b
1 l$ B. Z+ t6 G/ d) ^; A4.16 实验例程
$ K! Z5 s6 [. l2 a! `本章节配套了如下几个例子供大家移植参考:
" G# n3 C, h+ z7 u6 ]8 U5 n4 U. q5 o# ^ {: c. C& V
V7-4001_RTX5 Kernal Template7 e% k2 J( O& u* H" A
2 x& }5 O, p2 d- LRTX5内核模板。- X$ R: \- a* Z2 @; D
8 s' E. z/ E. P" g G$ [
V7-4002_RL-USB Template
: B; X6 l A% V+ V. z4 B
, y% Z: k. d- R/ _ R3 hRL-USB工程内核模板,使用内部RAM模拟了一个U盘。
Q) l; w, `3 o) c* S* G- r
/ s2 ? B/ i xMDK进入调试状态后,选择周期更新:: O, j- e& k- X2 w2 j
7 U! `- i" e" e; ?# F. Q, o8 q
2 ?6 W2 }! ^9 I+ }- G/ Q3 u5 i
9 v+ B/ H- y3 N: W% |然后打开调试组件,注意和RTX4的调试组件位置不同:
* e0 L; x% K) m/ i. H7 V9 m# W6 u% l' F
( W6 M! Q( F) }2 ~# i- |) s9 ^5 }8 Q5 X
然后点击MDK的全速运行,
8 i% R7 H# N2 x: S1 ~' i' \3 R8 j0 B4 d6 E7 s/ |
) [& _- m2 P* l$ J* M- E
' F7 ]& }- U$ a至此,就可以动态实时查看RL-USB的运行状态:
- @. o8 d; e) P! m& W
" d2 i- B' @3 P) h2 n" p
0 T; K4 U0 G* h J
; O' V* K/ }3 u3 G Y1 F4.17 总结* B. A* n6 c( y& S4 ?
本章节为大家讲解了RL-USB 在MDK AC5上的移植方法,移植涉及到的知识点比较多,初学的话,建议实际动手操作一遍。
& ^8 R5 n/ `3 w1 p. Q
- Q# F1 e& G! [: h* F8 Q) w
+ {; b" n0 B. J$ i/ e
, p4 v' B9 G$ j. }( F. H+ }/ y$ d# t. y: c
1 G% J+ ~7 C5 N w6 c( o |
好好学习