, f5 A. V4 I3 X% [9 k
: p1 w# W/ E% R8 A官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。
" T# i/ } ]8 d. G4 P
. X( u. c6 E/ p) rxTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄9 M3 @6 Q$ D$ o% h g
vTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。6 ~; Q% t0 q/ D
+ V% m" b% X7 }: a* ?1 [9 O3 W$ b1 C6 ?/ j
因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。/ i4 ?7 k7 d+ v, }. j- C, g0 v
0 x, v$ r0 ]* c' q- _任务函数编写
M/ X$ o; g1 X) i/ m" U& A- /*9 a3 s; B* d5 X* `2 |
- LED1翻转
- v+ D# W. C1 B- o - */
7 u6 H3 C; C1 R; c - void LED_TOG(void * pvParameters)//参数为 void * pvParameters# w3 g/ H0 `! X" s8 k: D/ b
- {. _3 }! A- a5 O+ Q: N
- while(1)
6 U0 V1 J% Z4 V8 C' \# v$ f) `6 K - {& e% Z' F& p! r1 m* o8 S* Q
- printf("LED_TOG running\r\n");//串口打印运行信息
' |( }6 G {$ m, E3 `" q5 `4 M - HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转
) l! m" z i# s" _- j r# A - vTaskDelay(500);//延迟500ms
0 G. [3 A2 H8 _ - }$ [9 c7 O& b+ [, W
- }
复制代码
! ]$ n* K& s. F1 t
要注意的是vTaskDelay是FreeRTOS用来延时的函数。
3 V/ [. J( W5 v" g) |3 o! }- i# X) P2 w& Q7 l
之后我们要创建任务函数的启动函数 - TaskHandle_t Start_LED_Handler;( e1 T6 }! |1 S$ C: q
7 t, F4 a' e/ c& o4 X! w; W- void Start_LED(void * pvParameters)2 l5 }/ W3 R# T8 z
- {
0 Y) r2 `- J6 f& Q- [4 }& c- _# ]) } - xTaskCreate((TaskFunction_t )LED_TOG,//任务函数8 z/ D% }% W* W7 q
- (char * )"LED_TOG",//任务名称+ }+ F# _) e5 h
- (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
- n) g$ u. j( Q - (void* ) NULL,//无返回3 J, ]% d/ p# B- n8 q
- (UBaseType_t ) 1,//优先级1& x$ R) l. E' G
- (TaskHandle_t * )LED_TOG_Handler);//任务函数句柄
e2 V- Z% f' U3 C2 v2 { - vTaskDelete(NULL);- m( L( @% I6 p6 r) |) N
- }2 J! f& D3 X4 L$ V
复制代码
* ]; X& j' u! ]8 E+ ~+ [- K我们创建启动任务的函数,将任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄,填入vTaskCreate函数中,其中每个参数都使用了强制类型转换防止出现错误。 同样的方法,我们创建启动 启动函数的任务(有点绕口因为启动函数本身是一个任务) - void FreeRTOS_Init()# S0 K$ E& }! _
- {! Q M& R! Q/ V+ z" `# _
- xTaskCreate((TaskFunction_t )Start_LED,/ B V) q$ I% m5 J# F: ]
- (char * )"Start_LED",
4 U! T3 v: L( b- a/ h% P - (configSTACK_DEPTH_TYPE) 128,( D: e9 B- a! ]) u. L
- (void* ) NULL,
/ O6 m( l: X3 [9 }+ ` - (UBaseType_t ) 0,
: j; x/ [4 S$ ]2 L2 u- j - (TaskHandle_t * )Start_LED_Handler);- G+ a2 c( N% b8 M( h& r
- vTaskStartScheduler();//启动运行函数
! f2 F# L! M+ ? - }
复制代码
, v6 L% v) W/ M$ ^& ?6 L7 k这样子我们在主函数中添加刚刚定义的启动启动函数 - int main(void)
% s: a! h: ]3 X& T& I- ^ - {
, g& D4 n2 P. @' [; K; B* s. M - /* USER CODE BEGIN 1 */) W8 G" F' Z) w8 i& m) N, N! [
$ i3 I8 w0 n# w/ Y- /* USER CODE END 1 */
# e6 ^, ], Y+ ]; r
) B( c4 M4 g! D9 |+ h3 J- /* MCU Configuration--------------------------------------------------------*/ G2 C! {: r) Y: k* K
: j$ O/ w& n4 K: _3 J$ r1 p% o- ~- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
; N) k0 q! T* K' Y- _ - HAL_Init();
6 [! l. \6 O0 I) o. U q. j% { - ) T! k( V# W0 R6 Y0 ^
- /* USER CODE BEGIN Init */
' p& y- q* R; j) m - KEY_Init();7 A: S4 I, U0 p! P3 S5 T5 H
- /* USER CODE END Init */& D! c/ p3 I5 v- G8 J" l
/ ]2 ]/ m& ~# Y. Y4 U0 y. [- /* Configure the system clock */
E7 l5 K% p' F" C6 n - SystemClock_Config();
o7 N) R2 w+ \ - ; T0 ?7 B- q' G6 [9 ~& J
- /* USER CODE BEGIN SysInit */2 f' _4 o( `0 N+ j# D7 @& d
- & w% \& M7 [+ `4 V
- /* USER CODE END SysInit */
+ L9 S/ f7 F( ~; }0 z& x1 A5 f1 d
: y; `0 k" c. U _; g+ k- /* Initialize all configured peripherals */# q, X% m$ s5 R: ^4 i
- MX_GPIO_Init();
/ V! v! p. p/ H+ @ - MX_USART1_UART_Init();+ y9 F+ n" V# T$ u: n$ {% @
- /* USER CODE BEGIN 2 */. v* K g+ M6 K F+ s$ q
- FreeRTOS_Init();$ J9 C$ u2 @9 L/ K1 Q
- /* USER CODE END 2 */! Z* v5 Z5 Q+ X |
5 Y. V, N' l7 ~5 J0 z: Q7 a- /* Infinite loop */
! `5 u9 }7 |; F' E- @: t% I - /* USER CODE BEGIN WHILE */
( L6 N4 N% f6 N6 C2 {4 }/ @6 D - while (1)
+ b5 S: Q' a6 U$ |; H2 C* F t7 T - {' K, C- p3 |" |0 S6 l2 Y
- /* USER CODE END WHILE */
) r; V I( W2 x - 9 J9 v( ?4 U0 |# N; c* w
- /* USER CODE BEGIN 3 *// q& W$ l: B8 J2 L7 }/ \
- }
# J0 ?& u$ n1 N1 d( k7 {3 D - /* USER CODE END 3 */
% l8 j' h( B1 E1 D2 v7 t& } - }
3 W) }' e) _! L6 p5 n7 z* J
复制代码我们的代码就可以正常运行啦!
; W" V9 g/ m Y7 s0 H; ^; r& u7 K我们在用上述的方法实现两个灯一起翻转还是先编辑任务函数如下,并且定义其相关句柄 - TaskHandle_t LED_TOG2_Handler;1 z& B0 b3 F" o& ]5 i
- void LED_TOG2(void * pvParameters)//参数为 void * pvParameters# p/ A' P) {. N* k
- {
6 E9 q' U, x% s! B5 C - while(1)
- a! s8 e% ]1 z; t4 @4 g6 m - {% P% e' [3 m4 w
- printf("LED_TOG running\r\n");//串口打印运行信息4 [* q0 A; ^2 }
- HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转( Z- f# O+ ` Z2 Y/ D& t
- vTaskDelay(500);//延迟500ms9 C' w" Z j Q
- }
% ]% Y( o4 i4 I' w; c - }
复制代码在任务启动函数中加入我们新建的任务。 - void Start_LED(void * pvParameters)$ u' n- u; U+ { z
- {, J1 P8 a; N; k" O7 p
- xTaskCreate((TaskFunction_t )LED_TOG,//任务函数
2 @3 g2 T. R z$ M+ l, F - (char * )"LED_TOG",//任务名称
/ y( r9 P7 ~' U: F; w# ]2 o - (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte) Y% F& ~1 I4 B
- (void* ) NULL,//无返回
, z( ^2 A# j4 |7 N- E7 I. `; S. u - (UBaseType_t ) 1,//优先级1
. ~. L2 k* P Z. P R - (TaskHandle_t * )LED_TOG_Handler);//任务函数句柄, [) E7 t, _3 R8 `( X7 P
- - _ O8 }$ U; H1 y& Y; V) V
- xTaskCreate((TaskFunction_t )LED_TOG2,//任务函数' ]' l( g4 G* R% I; i; i
- (char * )"LED_TOG2",//任务名称
) g4 V1 A8 |( ]! D. H - (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte9 k3 b* a4 p' A7 T4 y% u
- (void* ) NULL,//无返回4 E# v+ U' e8 ~3 [
- (UBaseType_t ) 2,//优先级28 W# m) v- |) m, e7 u9 s' n$ o
- (TaskHandle_t * )LED_TOG2_Handler);//任务函数句柄# C' p% p3 b: Q: b# Y% i
- 8 G3 f! ^( A0 |7 A! ?
- vTaskDelete(NULL);
- ~- h7 E. U! l0 _$ n! X - }
复制代码再次运行我们的代码。 + e5 y3 t! w7 i! E
转载自: 电路小白 如有侵权请联系删除
6 r& }$ O. F( o4 C" b5 i) s9 v% Q 0 n. W5 ^5 N0 Z& p8 j' R
& i; H, Y2 s1 i. {
( J7 c, \9 A+ w0 c/ R" W4 K
|