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