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

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

[复制链接]
攻城狮Melo 发布时间:2023-10-19 15:54
, f5 A. V4 I3 X% [9 k
微信图片_20231019155406.png

: p1 w# W/ E% R8 A官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。
" T# i/ }  ]8 d. G4 P

. X( u. c6 E/ p) rxTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄
微信图片_20231019155403.png
9 M3 @6 Q$ D$ o% h  g
vTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。6 ~; Q% t0 q/ D

+ V% m" b% X7 }: a* ?1 [9 O
微信图片_20231019155400.png
3 W$ b1 C6 ?/ j
因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。/ i4 ?7 k7 d+ v, }. j- C, g0 v
微信图片_20231019155357.png

0 x, v$ r0 ]* c' q- _任务函数编写
  M/ X$ o; g1 X) i/ m" U& A
  1. /*9 a3 s; B* d5 X* `2 |
  2. LED1翻转
    - v+ D# W. C1 B- o
  3. */
    7 u6 H3 C; C1 R; c
  4. void LED_TOG(void * pvParameters)//参数为 void * pvParameters# w3 g/ H0 `! X" s8 k: D/ b
  5. {. _3 }! A- a5 O+ Q: N
  6.   while(1)
    6 U0 V1 J% Z4 V8 C' \# v$ f) `6 K
  7.   {& e% Z' F& p! r1 m* o8 S* Q
  8.     printf("LED_TOG running\r\n");//串口打印运行信息
    ' |( }6 G  {$ m, E3 `" q5 `4 M
  9.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转
    ) l! m" z  i# s" _- j  r# A
  10.     vTaskDelay(500);//延迟500ms
    0 G. [3 A2 H8 _
  11.   }$ [9 c7 O& b+ [, W
  12. }
复制代码


! ]$ n* K& s. F1 t

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


3 V/ [. J( W5 v" g) |3 o
微信图片_20231019155354.png
! }- i# X) P2 w& Q7 l

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

  1. TaskHandle_t Start_LED_Handler;( e1 T6 }! |1 S$ C: q

  2. 7 t, F4 a' e/ c& o4 X! w; W
  3. void Start_LED(void * pvParameters)2 l5 }/ W3 R# T8 z
  4. {
    0 Y) r2 `- J6 f& Q- [4 }& c- _# ]) }
  5.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数8 z/ D% }% W* W7 q
  6.               (char *                )"LED_TOG",//任务名称+ }+ F# _) e5 h
  7.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    - n) g$ u. j( Q
  8.               (void*                 ) NULL,//无返回3 J, ]% d/ p# B- n8 q
  9.               (UBaseType_t          ) 1,//优先级1& x$ R) l. E' G
  10.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄
      e2 V- Z% f' U3 C2 v2 {
  11.   vTaskDelete(NULL);- m( L( @% I6 p6 r) |) N
  12. }2 J! f& D3 X4 L$ V
复制代码

* ]; X& j' u! ]8 E+ ~+ [- K

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

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

  1. void FreeRTOS_Init()# S0 K$ E& }! _
  2. {! Q  M& R! Q/ V+ z" `# _
  3.   xTaskCreate((TaskFunction_t        )Start_LED,/ B  V) q$ I% m5 J# F: ]
  4.               (char *                )"Start_LED",
    4 U! T3 v: L( b- a/ h% P
  5.               (configSTACK_DEPTH_TYPE) 128,( D: e9 B- a! ]) u. L
  6.               (void*                 ) NULL,
    / O6 m( l: X3 [9 }+ `
  7.               (UBaseType_t          ) 0,
    : j; x/ [4 S$ ]2 L2 u- j
  8.               (TaskHandle_t *        )Start_LED_Handler);- G+ a2 c( N% b8 M( h& r
  9.   vTaskStartScheduler();//启动运行函数
    ! f2 F# L! M+ ?
  10. }
复制代码

, v6 L% v) W/ M$ ^& ?6 L7 k

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

  1. int main(void)
    % s: a! h: ]3 X& T& I- ^
  2. {
    , g& D4 n2 P. @' [; K; B* s. M
  3.   /* USER CODE BEGIN 1 */) W8 G" F' Z) w8 i& m) N, N! [

  4. $ i3 I8 w0 n# w/ Y
  5.   /* USER CODE END 1 */
    # e6 ^, ], Y+ ]; r

  6. ) B( c4 M4 g! D9 |+ h3 J
  7.   /* MCU Configuration--------------------------------------------------------*/  G2 C! {: r) Y: k* K

  8. : j$ O/ w& n4 K: _3 J$ r1 p% o- ~
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    ; N) k0 q! T* K' Y- _
  10.   HAL_Init();
    6 [! l. \6 O0 I) o. U  q. j% {
  11. ) T! k( V# W0 R6 Y0 ^
  12.   /* USER CODE BEGIN Init */
    ' p& y- q* R; j) m
  13.   KEY_Init();7 A: S4 I, U0 p! P3 S5 T5 H
  14.   /* USER CODE END Init */& D! c/ p3 I5 v- G8 J" l

  15. / ]2 ]/ m& ~# Y. Y4 U0 y. [
  16.   /* Configure the system clock */
      E7 l5 K% p' F" C6 n
  17.   SystemClock_Config();
      o7 N) R2 w+ \
  18. ; T0 ?7 B- q' G6 [9 ~& J
  19.   /* USER CODE BEGIN SysInit */2 f' _4 o( `0 N+ j# D7 @& d
  20. & w% \& M7 [+ `4 V
  21.   /* USER CODE END SysInit */
    + L9 S/ f7 F( ~; }0 z& x1 A5 f1 d

  22. : y; `0 k" c. U  _; g+ k
  23.   /* Initialize all configured peripherals */# q, X% m$ s5 R: ^4 i
  24.   MX_GPIO_Init();
    / V! v! p. p/ H+ @
  25.   MX_USART1_UART_Init();+ y9 F+ n" V# T$ u: n$ {% @
  26.   /* USER CODE BEGIN 2 */. v* K  g+ M6 K  F+ s$ q
  27.   FreeRTOS_Init();$ J9 C$ u2 @9 L/ K1 Q
  28.   /* USER CODE END 2 */! Z* v5 Z5 Q+ X  |

  29. 5 Y. V, N' l7 ~5 J0 z: Q7 a
  30.   /* Infinite loop */
    ! `5 u9 }7 |; F' E- @: t% I
  31.   /* USER CODE BEGIN WHILE */
    ( L6 N4 N% f6 N6 C2 {4 }/ @6 D
  32.   while (1)
    + b5 S: Q' a6 U$ |; H2 C* F  t7 T
  33.   {' K, C- p3 |" |0 S6 l2 Y
  34.     /* USER CODE END WHILE */
    ) r; V  I( W2 x
  35. 9 J9 v( ?4 U0 |# N; c* w
  36.     /* USER CODE BEGIN 3 *// q& W$ l: B8 J2 L7 }/ \
  37.   }
    # J0 ?& u$ n1 N1 d( k7 {3 D
  38.   /* USER CODE END 3 */
    % l8 j' h( B1 E1 D2 v7 t& }
  39. }
    3 W) }' e) _! L6 p5 n7 z* J
复制代码

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


; W" V9 g/ m  Y7 s0 H; ^; r& u7 K我们在用上述的方法实现两个灯一起翻转

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

  1. TaskHandle_t LED_TOG2_Handler;1 z& B0 b3 F" o& ]5 i
  2. void LED_TOG2(void * pvParameters)//参数为 void * pvParameters# p/ A' P) {. N* k
  3. {
    6 E9 q' U, x% s! B5 C
  4.   while(1)
    - a! s8 e% ]1 z; t4 @4 g6 m
  5.   {% P% e' [3 m4 w
  6.     printf("LED_TOG running\r\n");//串口打印运行信息4 [* q0 A; ^2 }
  7.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转( Z- f# O+ `  Z2 Y/ D& t
  8.     vTaskDelay(500);//延迟500ms9 C' w" Z  j  Q
  9.   }
    % ]% Y( o4 i4 I' w; c
  10. }
复制代码

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

  1. void Start_LED(void * pvParameters)$ u' n- u; U+ {  z
  2. {, J1 P8 a; N; k" O7 p
  3.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
    2 @3 g2 T. R  z$ M+ l, F
  4.               (char *                )"LED_TOG",//任务名称
    / y( r9 P7 ~' U: F; w# ]2 o
  5.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte) Y% F& ~1 I4 B
  6.               (void*                 ) NULL,//无返回
    , z( ^2 A# j4 |7 N- E7 I. `; S. u
  7.               (UBaseType_t          ) 1,//优先级1
    . ~. L2 k* P  Z. P  R
  8.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄, [) E7 t, _3 R8 `( X7 P
  9.   - _  O8 }$ U; H1 y& Y; V) V
  10.    xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数' ]' l( g4 G* R% I; i; i
  11.               (char *                )"LED_TOG2",//任务名称
    ) g4 V1 A8 |( ]! D. H
  12.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte9 k3 b* a4 p' A7 T4 y% u
  13.               (void*                 ) NULL,//无返回4 E# v+ U' e8 ~3 [
  14.               (UBaseType_t          ) 2,//优先级28 W# m) v- |) m, e7 u9 s' n$ o
  15.               (TaskHandle_t *        )LED_TOG2_Handler);//任务函数句柄# C' p% p3 b: Q: b# Y% i
  16.               8 G3 f! ^( A0 |7 A! ?
  17.   vTaskDelete(NULL);
    - ~- h7 E. U! l0 _$ n! X
  18. }
复制代码

再次运行我们的代码。

+ 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
赞 收藏 评论0 发布时间:2023-10-19 15:54

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版