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