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

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

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

& R2 Q5 o5 d; s4 a% W. @& [
微信图片_20231019155406.png

6 X. x  u9 Q* t" A$ ~1 h官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。
: v, N, @7 f. d2 z/ V

& P, c4 e( i' U, a7 oxTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄
微信图片_20231019155403.png

& k/ M2 p$ V4 }0 O: U- x7 c5 Q9 |vTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。
' r7 _7 ^0 R% R0 A- i5 g5 m, X* I9 ~# B) T
微信图片_20231019155400.png

* c. t4 y" @# q2 n1 g( q因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。
9 r4 b( I" {  L4 e8 U
微信图片_20231019155357.png

% Q2 H9 `" ~+ j/ \7 i  t, m任务函数编写& I7 u) e% h4 t# ^
  1. /*
    / _2 Z" c  q# B& j) l/ R
  2. LED1翻转
    . p3 q3 D+ u' u) \/ D
  3. */6 G# }1 E) V7 b8 W
  4. void LED_TOG(void * pvParameters)//参数为 void * pvParameters
    1 w6 e6 Q: ~+ B8 y
  5. {
    , u6 {& u7 X- w) R7 S0 j0 C
  6.   while(1)
    " u4 Y: d" K! S$ \( H+ X  r+ L
  7.   {
    % x9 L% n2 g9 B7 O
  8.     printf("LED_TOG running\r\n");//串口打印运行信息
    ; j( H" S9 Q  i; ^
  9.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转/ H* v* ?7 @6 V3 s% N7 H5 K
  10.     vTaskDelay(500);//延迟500ms
    ( M( h9 W4 X+ @8 N2 C0 g
  11.   }
    ( d# W7 k  U# L7 |, x! L
  12. }
复制代码

2 R) u6 B/ @& Z! j+ ?

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

, s  z! D3 P. Z3 B
微信图片_20231019155354.png

6 r$ w! b% h0 J; F. Z% y

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

  1. TaskHandle_t Start_LED_Handler;" i( x8 U4 G7 d  v& n

  2. ( p0 Y& L) {/ k+ T$ d" L
  3. void Start_LED(void * pvParameters): o4 v5 ~( Q/ o' K. x
  4. {
    + e# a" s+ B& \3 r% l" y7 @
  5.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
    1 L% Q- R8 x3 \- D1 [  B/ R
  6.               (char *                )"LED_TOG",//任务名称
    - B2 Y$ p, Y2 d7 i6 e" S: Y
  7.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    6 t$ X% P0 ]% u% l5 i$ Y: ~) P
  8.               (void*                 ) NULL,//无返回3 u# N6 `% `  Y: ^
  9.               (UBaseType_t          ) 1,//优先级1: U. P0 o1 t) M
  10.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄5 ^6 |/ X0 [2 K. |( z$ I3 |
  11.   vTaskDelete(NULL);# ~. [3 q& X- I
  12. }
    & C! N+ _- m1 J6 u) h$ H: L
复制代码
! ~  d7 I; K) v

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

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

  1. void FreeRTOS_Init()
    ' ?9 t: }$ h. O4 b/ Q
  2. {0 X: ?: A* ^7 H+ X2 m0 Y
  3.   xTaskCreate((TaskFunction_t        )Start_LED,
    % A5 j* W$ f0 J8 Y5 u; }. m& {
  4.               (char *                )"Start_LED",
    . a/ q$ B* T$ y( T3 j4 }
  5.               (configSTACK_DEPTH_TYPE) 128,
    ' Q; i5 }5 \  O8 p; c5 E3 g/ g
  6.               (void*                 ) NULL,
    # ?$ K! p/ S, u$ k+ z3 J/ ^
  7.               (UBaseType_t          ) 0,, Y  A* g9 y% m7 N; ]8 J3 ?$ \
  8.               (TaskHandle_t *        )Start_LED_Handler);% T: B/ I# e- q  z4 I. R6 O: M
  9.   vTaskStartScheduler();//启动运行函数- u+ T: u! [* V! z7 L0 v4 a
  10. }
复制代码
: D2 _+ U- }# {3 b5 z

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

  1. int main(void)" K0 q7 p/ T: j( H* ]+ }5 \- S
  2. {
    , H! g) D& X* }- T6 A$ P
  3.   /* USER CODE BEGIN 1 */  V& d5 l# i( g# o/ q; {
  4. 4 J* q- l$ T  C4 ]
  5.   /* USER CODE END 1 */8 }- n6 J3 T+ a  M2 V/ k6 F

  6. ; g& w% l9 b  ]8 X; n+ e/ Q9 h
  7.   /* MCU Configuration--------------------------------------------------------*/% J! n2 G. a7 F  y
  8. + b- O5 x; U' [( v  w) N/ {8 F
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */4 Y: m3 }' t4 m
  10.   HAL_Init();1 g4 j3 J" ?% C% I9 X. e

  11. 4 }+ U0 ~7 P& t4 Z/ G$ @
  12.   /* USER CODE BEGIN Init */5 Q) u! W- a0 b7 s$ _3 d
  13.   KEY_Init();
    1 k* w7 V: P: T. K
  14.   /* USER CODE END Init */, U* a; J, v% E

  15. 3 ?2 O/ y: ?" X6 P# Q
  16.   /* Configure the system clock */8 h' n; e0 t" _8 O
  17.   SystemClock_Config();
    % q* Y5 G. [+ ]' W2 \2 u
  18. , R% z7 Z$ s5 A( G) \3 U
  19.   /* USER CODE BEGIN SysInit */+ B% A( u1 {/ ^" r

  20. $ \& r2 G  O4 v( |( Z
  21.   /* USER CODE END SysInit */
    ! w3 a6 i, F9 D$ H; W) b' F/ ~( m8 E
  22.   `; L! t) M) w, Z4 p: i# j: ?
  23.   /* Initialize all configured peripherals */: l/ k. F+ H/ [% p  L; F
  24.   MX_GPIO_Init();
    % c' U/ y# r& ^/ i6 D5 ]
  25.   MX_USART1_UART_Init();
    + k( B! U4 {. F& h1 N7 z1 \  g  U0 [3 B
  26.   /* USER CODE BEGIN 2 */3 i' V$ m; l0 _) N$ o, G
  27.   FreeRTOS_Init();
    # O: M* I9 `0 v% D( j
  28.   /* USER CODE END 2 */
    ) b  s! f9 R5 u* }8 V

  29.   Z2 n$ ~7 H  K4 r2 R1 y- ]+ j
  30.   /* Infinite loop */6 a3 r2 M0 |; _# o7 S' J4 b+ h
  31.   /* USER CODE BEGIN WHILE */
    $ v5 ~8 X. @% W) o
  32.   while (1)2 N+ g& M' H1 s9 x( B3 V3 O
  33.   {3 I' _1 g7 w+ p* s4 q2 F6 {
  34.     /* USER CODE END WHILE */) m  I& r! ~6 `1 r7 P

  35. 0 a: J: p  |3 d' ^, i1 }
  36.     /* USER CODE BEGIN 3 *// @5 G$ E6 p. D8 ]0 B. @5 P& _
  37.   }
    & q2 M1 ~5 }( }, P) i5 [
  38.   /* USER CODE END 3 */
    6 b1 q0 m" h" |
  39. }
    : L# b# X" ~8 \0 a/ C- B
复制代码

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

+ O1 N! d  u' A' U5 m
我们在用上述的方法实现两个灯一起翻转

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

  1. TaskHandle_t LED_TOG2_Handler;
    6 M7 G$ q0 o5 Y
  2. void LED_TOG2(void * pvParameters)//参数为 void * pvParameters$ \$ k  ~5 z6 {6 @. E$ y, Y& I
  3. {( X7 ?5 s' c: o* V$ [
  4.   while(1)
    4 R" [& P" }; k
  5.   {
    6 v+ F9 z# k! D( a% a
  6.     printf("LED_TOG running\r\n");//串口打印运行信息
    7 U9 }& W( {4 i) `% T* [. W6 s
  7.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转4 d. @- V2 a* d3 e
  8.     vTaskDelay(500);//延迟500ms0 _. i- v! u) _( }2 z/ z1 q
  9.   }
    ! r, i( t0 ~+ R6 U: o* ~
  10. }
复制代码

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

  1. void Start_LED(void * pvParameters)) b% M+ u* l& M7 ?
  2. {
    0 m3 R  E# c3 Z. ]
  3.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
    . @1 o9 w) ?$ a! j7 f1 i4 K+ }
  4.               (char *                )"LED_TOG",//任务名称
    * X& N" ]$ |* b/ f2 O& S$ o
  5.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    4 f  A2 S3 `0 f* w# r
  6.               (void*                 ) NULL,//无返回
    2 [1 h: ]( G% Q# T- i
  7.               (UBaseType_t          ) 1,//优先级1
    & J$ ^1 N: V: M& O: j% x& V( P
  8.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄: d8 W& s1 f% r4 E: I/ [: H
  9.   2 u8 [9 u$ {4 C! y
  10.    xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数
    , S0 P$ T/ a* y8 Z( j
  11.               (char *                )"LED_TOG2",//任务名称% A/ }. V, Q, N0 v  R
  12.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
    $ m# E" D" z) h8 D  t2 I# b* Q
  13.               (void*                 ) NULL,//无返回! }- T  m4 I* v( M- M: @
  14.               (UBaseType_t          ) 2,//优先级2* g. }* A7 f  [/ i3 b7 e
  15.               (TaskHandle_t *        )LED_TOG2_Handler);//任务函数句柄" M8 a9 J0 b/ |+ l5 k0 D
  16.               
    3 n  Z6 `! B  q2 l5 f
  17.   vTaskDelete(NULL);
    8 c+ p( j. S+ x( R" V8 f% G
  18. }
复制代码

再次运行我们的代码。


9 S& c, D4 T+ ]) {7 K& r

转载自: 电路小白

如有侵权请联系删除8 k! D  c: b/ ]# h1 |8 I6 s

: O' r" N" h$ y! n. k7 B4 X

; U( n6 {) v$ S1 a3 X+ S
$ l8 i: G- n6 g2 X4 G) z
赞 收藏 评论0 发布时间:2023-10-19 15:54

举报

0个回答

所属标签

相似技术帖

官网相关资源

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