你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F407的FreeRTOS任务的创建与删除经验分享(2)

[复制链接]
攻城狮Melo 发布时间:2023-10-19 15:54
7 `2 t1 M, _* S: P
微信图片_20231019155406.png

, o& b6 ~6 }1 V( d官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。6 j/ E/ n  ?, H9 i# c+ t
- x! Z  ^& g. s8 `
xTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄
微信图片_20231019155403.png

7 t5 g& l' n; `% ~vTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。) e4 `8 h8 y5 h0 f6 F! Q4 }
  F, F# O7 R  G0 h' f- A* B/ |
微信图片_20231019155400.png

9 D7 ?. ~- }) V' s( b" ~' ^因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。" Z/ w2 b# b+ s5 B1 f- C
微信图片_20231019155357.png

* r, ^* q1 _$ i) s2 A4 d& Q任务函数编写
/ e! H" D! t# f6 n; r, z# I
  1. /*
    * M( D, w# f  V4 k" p
  2. LED1翻转
    2 V0 T7 Z/ p( K1 W' R; D
  3. */
    3 J& a8 Z2 {+ U* _
  4. void LED_TOG(void * pvParameters)//参数为 void * pvParameters/ k4 O0 Z4 P8 i$ ]* m
  5. {$ W6 @6 c4 Q  H) c2 n1 m
  6.   while(1)% Q$ x# j! p; W5 V, t- G
  7.   {
    8 `9 o7 J/ ~! Q2 b- i$ W* k  S
  8.     printf("LED_TOG running\r\n");//串口打印运行信息7 V6 ~/ E" A# ~8 c
  9.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转1 ^( O+ e. |5 o2 a4 j" `
  10.     vTaskDelay(500);//延迟500ms
    . P+ f, w& d7 n$ J6 ]' v4 [1 ]
  11.   }. P! R; R& P- y1 A
  12. }
复制代码


; d) K  U4 f, A" i- H

要注意的是vTaskDelay是FreeRTOS用来延时的函数。


8 B5 F8 D4 h1 H& [& W
微信图片_20231019155354.png

3 [! ]+ k0 @9 A

之后我们要创建任务函数的启动函数

  1. TaskHandle_t Start_LED_Handler;
    7 a/ A6 g0 A5 Z' {+ \- x/ j
  2. 6 R( L! T' ?1 t$ r
  3. void Start_LED(void * pvParameters)
    / u/ F* U1 i" @# Y  Q9 D
  4. {, o2 ?0 u9 @' K$ p7 R# Y) B
  5.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数1 ^$ b+ a3 }- R" f* p( C9 u
  6.               (char *                )"LED_TOG",//任务名称/ c. u5 u6 ~. s2 Z! C
  7.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte: O( s4 d- F$ o/ ^/ O# q
  8.               (void*                 ) NULL,//无返回5 k: {& s' o. ]. y8 _, ?5 H2 A- _5 W
  9.               (UBaseType_t          ) 1,//优先级1
    ; {5 |: b( e* I% H) t0 q- m# C7 x
  10.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄
    5 e3 s. n! e3 ?* q7 Z
  11.   vTaskDelete(NULL);
    * ~" X& U. O' i! f2 H* I5 V
  12. }8 H! M4 U: D& T1 M0 e
复制代码
1 S% i& P/ i' Q' e

我们创建启动任务的函数,将任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄,填入vTaskCreate函数中,其中每个参数都使用了强制类型转换防止出现错误。

同样的方法,我们创建启动 启动函数的任务(有点绕口因为启动函数本身是一个任务)

  1. void FreeRTOS_Init()" q0 X  Y' t* l4 @
  2. {
    3 ]" h$ J$ \. j% x9 D- r: w& u. [
  3.   xTaskCreate((TaskFunction_t        )Start_LED,. i2 d) \/ K# A' N* ~5 Y0 x
  4.               (char *                )"Start_LED",
    7 W8 r! J( u' d7 Q% n& Q: U
  5.               (configSTACK_DEPTH_TYPE) 128,: I) t6 U; \- X0 o+ E6 y6 I' G
  6.               (void*                 ) NULL,
    0 Z$ H" v" F2 V- r
  7.               (UBaseType_t          ) 0,
    5 ~' ^- }' b6 o* A
  8.               (TaskHandle_t *        )Start_LED_Handler);1 y7 Q& W* c7 ?- X4 o- d+ `
  9.   vTaskStartScheduler();//启动运行函数
    ! X7 n# b' e' d* i! x
  10. }
复制代码
# W9 w1 x: Q% i4 [

这样子我们在主函数中添加刚刚定义的启动启动函数

  1. int main(void)
    % g6 ]2 V+ }& b* [
  2. {9 ]# J" b% m6 \0 k6 {1 }- y- F
  3.   /* USER CODE BEGIN 1 */
    : @6 Z8 i/ c/ J* P7 G4 J. L# P
  4. 2 J* E$ r/ Y* c7 w
  5.   /* USER CODE END 1 */
    4 }% x2 J0 v7 ^1 H5 Z+ E. h" |
  6. " }) Q2 B# O4 U2 }- J
  7.   /* MCU Configuration--------------------------------------------------------*/& E5 b5 z8 h5 o4 F  h+ B& S1 l8 R

  8. 2 O  H& [; j; z) u8 O9 \& f' _$ `- F& e
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */. Z/ ^4 L2 x1 a, S  |2 O5 V0 |( I
  10.   HAL_Init();
    # [# F8 h1 `9 _2 w9 o4 K$ n; ^+ u
  11.   _3 S  G/ [3 g& O
  12.   /* USER CODE BEGIN Init */0 f: C  Y8 |+ C+ ]4 Z
  13.   KEY_Init();  g1 |* E6 l  q/ z; \
  14.   /* USER CODE END Init */
    - P& G# ~$ J1 H8 n
  15. . k, k8 d. z4 [, L. h5 |9 z
  16.   /* Configure the system clock */
    3 |8 ?: b/ q3 p0 c- q. n1 N
  17.   SystemClock_Config();
    ) P3 |' r1 d( ]( H. E

  18. ' R  D3 Y4 i+ c% `, x
  19.   /* USER CODE BEGIN SysInit */" T  l8 g9 y% |  q8 x1 a+ m; M
  20. ) Y* r# r; X- b1 i
  21.   /* USER CODE END SysInit */
    2 a: v& M- x# b: a0 v+ Z
  22. 3 e8 n9 H% _( M$ T
  23.   /* Initialize all configured peripherals */1 X0 B6 ^4 v0 ~) N9 Z
  24.   MX_GPIO_Init();7 W8 K' j, I8 I( C( I
  25.   MX_USART1_UART_Init();
    6 R% V9 ]6 ^, C# H. K
  26.   /* USER CODE BEGIN 2 */
    1 [7 \) ~; @3 R$ E
  27.   FreeRTOS_Init();
    : H; W/ ^+ c3 k$ i/ D8 J6 M
  28.   /* USER CODE END 2 */
    ) w) o1 K. \' G3 A6 W

  29. ) ^& N+ U6 }) \) Q/ C
  30.   /* Infinite loop *// s0 a5 Y2 p4 w
  31.   /* USER CODE BEGIN WHILE */
    , `" E$ ]4 a( M8 A# }; l, I9 m* x
  32.   while (1)
    $ I% T2 B/ y3 {2 L
  33.   {  P; A+ ?+ o' L; U& N# F! A
  34.     /* USER CODE END WHILE */0 N& Q! R, w. v4 m8 ?2 R" k

  35. 1 T1 l: T: X3 o# _1 s- c! K
  36.     /* USER CODE BEGIN 3 */
    ; T; C! F- O. W8 Y6 O8 e/ N3 v
  37.   }' i8 V+ z. \3 @! y. v; g& O
  38.   /* USER CODE END 3 */" I9 o% d% u0 w5 A/ H8 y
  39. }
    & g# R, p. F* w: V
复制代码

我们的代码就可以正常运行啦!


% s. \/ y0 W" U# J" w我们在用上述的方法实现两个灯一起翻转

还是先编辑任务函数如下,并且定义其相关句柄

  1. TaskHandle_t LED_TOG2_Handler;
    9 S. }& \8 k  R. H( ?
  2. void LED_TOG2(void * pvParameters)//参数为 void * pvParameters
    * s9 N/ U- D1 G. j( M  g3 O( N% x
  3. {
    8 X# s3 E: k  _( `- Y
  4.   while(1)
    . D3 {4 n1 L: Y! h# B
  5.   {
    ) v9 P, a$ e! P1 a5 J) }% W
  6.     printf("LED_TOG running\r\n");//串口打印运行信息/ U( O5 v, a. w& n: b5 k; H! ~
  7.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转
    " A, c: X, e* j0 \7 y" i
  8.     vTaskDelay(500);//延迟500ms3 k& F4 d+ x! o
  9.   }
    1 p( T4 G' a% W! U! @
  10. }
复制代码

在任务启动函数中加入我们新建的任务。

  1. void Start_LED(void * pvParameters)7 K7 H9 Z# z: Q. t' n
  2. {- J: N. b* I4 y# E8 ?& \
  3.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数/ O" O1 g2 b2 z: N
  4.               (char *                )"LED_TOG",//任务名称
    ( f0 ?) W3 Z% N. D3 v! [
  5.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    & v# {6 O8 |2 z  {# t
  6.               (void*                 ) NULL,//无返回
    ( r/ O" Y  L( z) E, l
  7.               (UBaseType_t          ) 1,//优先级1
    4 `) Z5 @7 f: k6 Q
  8.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄
    4 v' R, I7 e0 C7 A8 @
  9.   $ s- h5 A! u* P  b4 T1 {
  10.    xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数2 e) J" j) L2 o  j0 w
  11.               (char *                )"LED_TOG2",//任务名称$ r2 G& L' i) z- [2 E
  12.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte: {' S( U0 z4 C& l- y* o
  13.               (void*                 ) NULL,//无返回' `- ?- G1 ]" `/ H" x
  14.               (UBaseType_t          ) 2,//优先级2
    ' d2 S# _+ X4 f" M( U
  15.               (TaskHandle_t *        )LED_TOG2_Handler);//任务函数句柄" [1 U% `8 V4 n( v' K, I4 e3 f
  16.               
    ; Q' s. m0 o0 t/ a/ Y. Y
  17.   vTaskDelete(NULL);- O+ f1 l' T$ @9 V$ z
  18. }
复制代码

再次运行我们的代码。

( L* W! m, H) X! m; b! {7 q

转载自: 电路小白

如有侵权请联系删除9 S# Z0 k( a( E: |8 H6 ]

* x* ~0 C2 Z% A" A+ a
1 {' }' b9 S& B" _5 Z% g

3 y0 ~4 c3 R- {/ z% l
收藏 评论0 发布时间:2023-10-19 15:54

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版