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