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

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

[复制链接]
攻城狮Melo 发布时间:2023-10-19 15:54

! |0 @  o) O. b
微信图片_20231019155406.png
2 _) r# V5 t) H
官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。$ \. f: |3 I5 H" N8 c
* n/ w0 _+ S5 x2 |4 E" y
xTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄
微信图片_20231019155403.png
. y( x! C2 Y8 o7 |5 F
vTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。+ M9 z# E6 h% I8 u+ V6 u& k. Z  q( q

# L, e0 u9 ]8 i; E
微信图片_20231019155400.png
+ Q9 e8 \/ _7 d/ a6 ]3 v) F6 v
因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。
, L1 g. o$ e& I1 X0 G
微信图片_20231019155357.png

, a( B2 e9 x, ^- E任务函数编写
  Z7 p! x9 h: Q: R8 Y! s
  1. /*% ]' o3 W; }) z, w3 q: i' H
  2. LED1翻转
    ; h+ ?3 K4 ^5 ~# D+ Y
  3. */9 s9 N3 N7 q3 ?" P6 {& L  B
  4. void LED_TOG(void * pvParameters)//参数为 void * pvParameters+ D  {# q4 c8 F; i
  5. {
    # s( M" a' @/ v5 q! `0 w( [' j8 X
  6.   while(1)
    + m. i9 a" ]7 g/ m* v! ~! i
  7.   {- N& f1 T) A7 n) T* r
  8.     printf("LED_TOG running\r\n");//串口打印运行信息- f( Y; h- u3 p7 P' V) n1 r
  9.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转
    ; k! \1 u) X- b2 V
  10.     vTaskDelay(500);//延迟500ms
    - P$ p# ?, A' z+ |( e
  11.   }
    ; K2 H- o3 Y' n6 W8 t8 e2 X' B0 ?
  12. }
复制代码


+ Q* {+ i, ]' X1 |2 g% H3 d9 _

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


  i8 \7 \  x: Q) G2 `8 o; J
微信图片_20231019155354.png
/ J# f6 I* t4 Q; K: b: M

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

  1. TaskHandle_t Start_LED_Handler;3 d' d4 ^' k# b# S4 x

  2. & Q8 m( H0 z' D( E/ A: t$ `
  3. void Start_LED(void * pvParameters)$ v4 Z% T0 `) A
  4. {% y" L* C' |& V
  5.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
    $ B2 S1 R; E  g2 g: ?
  6.               (char *                )"LED_TOG",//任务名称
    0 ?, b( @8 }1 p5 t5 B9 ^7 ]
  7.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    ! u5 z- |0 k9 [" ~1 A
  8.               (void*                 ) NULL,//无返回8 [0 I# U! A  |8 k
  9.               (UBaseType_t          ) 1,//优先级14 n8 ?! v+ K3 U' Y8 Y. d
  10.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄
    9 V9 S, v9 R, e6 Y/ ?
  11.   vTaskDelete(NULL);' r& X% \6 t  K1 w" l
  12. }
    : r) u' Q8 Y' F0 X& h( q. e
复制代码
7 U3 {& B  A# y- M  J! v9 W# F

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

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

  1. void FreeRTOS_Init()
    ! q( m! w' o5 U
  2. {, h& L! k+ O' f
  3.   xTaskCreate((TaskFunction_t        )Start_LED,' x" |1 E$ \( @4 s; \. w
  4.               (char *                )"Start_LED",: _  s( O6 C8 L0 Q$ }  S" k- ~8 _
  5.               (configSTACK_DEPTH_TYPE) 128,2 j0 Q$ o6 R4 L" a3 g/ X+ M1 B
  6.               (void*                 ) NULL,
      u; o/ k& z! ]5 a, E8 @, v4 }
  7.               (UBaseType_t          ) 0," O. o; L) I4 C, s9 Q6 A( W) M, ~5 r
  8.               (TaskHandle_t *        )Start_LED_Handler);
    + j4 h( N' {% F/ o3 j" r
  9.   vTaskStartScheduler();//启动运行函数! ]$ q  H1 O6 `1 A2 Q: }: A
  10. }
复制代码

; |$ m. X: a5 \, [1 x7 L( ]( ^

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

  1. int main(void)
      H2 m/ @8 m4 M* _% C' k9 ~5 C
  2. {
    * z9 X9 S9 a* U% {$ {
  3.   /* USER CODE BEGIN 1 */- ^) {/ w. ?2 x3 a
  4. ; t. ]# B$ \! ?4 @$ n
  5.   /* USER CODE END 1 */
    " e6 o. E/ M/ U8 P
  6. 3 {/ r# ~2 X. ?& e, r
  7.   /* MCU Configuration--------------------------------------------------------*/
    * h+ \6 b1 ?2 u8 I+ y6 B7 N
  8. " V0 }6 d7 d8 x4 _
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    $ E5 @& {# A5 X) `1 X- m
  10.   HAL_Init();
    # `# R8 q, j$ e* y3 A9 b$ o- U+ O

  11. 5 @0 p# ?$ U9 p5 ]7 t* t
  12.   /* USER CODE BEGIN Init */
      N  P  |. W8 I
  13.   KEY_Init();" u1 ~( A7 d8 R
  14.   /* USER CODE END Init */
    . W) m- r( _+ Z- Z; R% U4 f
  15. 2 v3 ?. N3 }: @  @$ P: ?
  16.   /* Configure the system clock */
    " I- q; f; I7 c: Y$ B  N7 J
  17.   SystemClock_Config();0 N& K" L3 k8 `. H# |' K

  18. 4 m! Q2 D/ a2 Q8 ?" S
  19.   /* USER CODE BEGIN SysInit */- Y: w0 J& R8 I, L; `  }; X0 N9 B& q
  20. 1 w: _) ~8 Z9 }  T7 z5 t
  21.   /* USER CODE END SysInit */
    ( \- c4 N' m6 Y" Z$ U

  22. 6 ^$ }6 f9 o) y- b4 E) J* q2 y" `
  23.   /* Initialize all configured peripherals */
    ; G/ G4 C8 x, Y7 G
  24.   MX_GPIO_Init();' K4 P& Q9 q6 o  r+ O
  25.   MX_USART1_UART_Init();/ ~/ V( V1 z" X, H1 {7 W) |
  26.   /* USER CODE BEGIN 2 */+ x1 A0 V1 v* K0 F) O
  27.   FreeRTOS_Init();; J7 Q- Y" C8 s# N
  28.   /* USER CODE END 2 */# ?" ?$ t% y: ?; i
  29. 8 D3 X7 q9 z* F/ u- W3 @: _
  30.   /* Infinite loop */% r# h; ?0 i0 X( Y3 ^
  31.   /* USER CODE BEGIN WHILE */
    " G% _6 J' k8 u2 c* M/ Q4 C
  32.   while (1)2 c8 {3 r; d+ w  p
  33.   {
    3 k; B  o7 {) }7 l' T2 u6 q
  34.     /* USER CODE END WHILE */# W3 p. _: A' G1 O$ h$ {% W) d3 y& J* p

  35. 5 l0 K4 t' p  e  _
  36.     /* USER CODE BEGIN 3 */# d# Y+ E  B# C& V
  37.   }
    4 M0 R+ z* A2 o0 Z7 c
  38.   /* USER CODE END 3 */
    / q  q; x3 x9 C1 t1 I" }
  39. }
    ' q: g! P+ y# d7 @, b
复制代码

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

' I, a# N4 \; ]' i) T% n
我们在用上述的方法实现两个灯一起翻转

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

  1. TaskHandle_t LED_TOG2_Handler;
      }& j- e; `( M# r( s5 a9 N2 ?
  2. void LED_TOG2(void * pvParameters)//参数为 void * pvParameters
    ; t2 E5 a/ e, K3 ^6 \* f
  3. {
    % \! c# S# q4 A" L
  4.   while(1)2 L$ ^& @# |* _- L
  5.   {3 ?1 {# ]+ q$ P' P, ^
  6.     printf("LED_TOG running\r\n");//串口打印运行信息8 t  _6 k, C  J
  7.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转8 h; ~. m9 [, _% x" [
  8.     vTaskDelay(500);//延迟500ms/ N# `; m8 r, s8 ?2 R6 C9 k
  9.   }' R% Y! s: l2 w- H3 {, y
  10. }
复制代码

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

  1. void Start_LED(void * pvParameters)4 l8 d) a2 U4 p! E+ a* e
  2. {
    " j3 [) B* b3 ^) `7 [
  3.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数* M, i- w+ T, W
  4.               (char *                )"LED_TOG",//任务名称; G! _- y1 N; J8 v& v( H  w
  5.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    % B' B  H" N6 u6 h1 d1 B
  6.               (void*                 ) NULL,//无返回! i/ i$ Z) i" l" i3 w
  7.               (UBaseType_t          ) 1,//优先级1
    4 s- d8 I2 Z5 N) B( h" Z
  8.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄
    ! B- w! k9 X+ a4 ~+ V* t3 L
  9.   
    . P& s$ z0 {; _6 {
  10.    xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数
    7 y$ b6 N, M! O: l3 c3 S" ]* R
  11.               (char *                )"LED_TOG2",//任务名称
    & S; o3 \3 b3 q$ S4 b# d' W
  12.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    6 s; ^5 K- m  h$ N2 `& q
  13.               (void*                 ) NULL,//无返回
    5 s5 O2 @! i9 v% k. q! M
  14.               (UBaseType_t          ) 2,//优先级2) T- b* v6 f0 b9 D! ~6 v: S% N+ n. S
  15.               (TaskHandle_t *        )LED_TOG2_Handler);//任务函数句柄$ ^" `& Q0 F5 e9 |* l" i2 }
  16.               
    2 K" e$ J7 B. n7 ~
  17.   vTaskDelete(NULL);4 h& E9 i% T9 F$ n9 [
  18. }
复制代码

再次运行我们的代码。


& k) k8 @# H( k1 r$ e& b% {

转载自: 电路小白

如有侵权请联系删除
& {4 Y$ {# N# t* ?+ `: w


, E" b/ J% l3 B8 @2 z# C: U
/ [: R8 c, |" y6 K: ~# K4 @; M1 S4 h% e- ^
收藏 评论0 发布时间:2023-10-19 15:54

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版