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

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

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

1 f, Z* b4 b2 G8 L
微信图片_20231019155406.png

* Q5 K0 W1 b0 o: e2 G官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。/ H2 w7 l' |( c
7 ]4 H7 J9 s" X$ g: f4 V' C4 {
xTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄
微信图片_20231019155403.png

1 g1 o& a4 O' N% r" z) ~% ovTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。
. K, G4 ]+ {8 f9 w0 r
) H3 o! H0 V2 Y5 w8 `2 e
微信图片_20231019155400.png

4 {  e9 t+ h8 W) M: W因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。
9 m, R1 a- a# a- o# x5 `( z+ v+ F
微信图片_20231019155357.png
4 j2 z& Y/ i1 b. G: I- v% t
任务函数编写. d2 x0 d) d1 U$ p3 R7 i
  1. /*
    ( ]! \! L+ o& V% F/ |" d. _, s' v5 R+ q
  2. LED1翻转; w, q/ F! V8 i
  3. */
    6 G- I; N" K  d  p8 H5 [  g. C
  4. void LED_TOG(void * pvParameters)//参数为 void * pvParameters+ Z4 m/ U; G4 ^* B! `
  5. {) g5 c9 p2 l, a8 F4 A# g8 M' f2 W1 c
  6.   while(1)
    + X  v5 @8 o6 w7 B& B) n& j6 k" ^* n1 ?
  7.   {; I% Q9 k1 y$ E/ M
  8.     printf("LED_TOG running\r\n");//串口打印运行信息9 f( h: G' P" ~. ]: O" W
  9.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转
    7 g  z3 c6 p4 P6 p8 E
  10.     vTaskDelay(500);//延迟500ms
    5 t5 p; G- x  G7 v# H5 f# c8 C' h& ^
  11.   }
    : N" ]+ Z- S8 g3 s! V# z3 P. B
  12. }
复制代码

6 m% h' k1 d, x

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


" A; Z# M" Y. r" m
微信图片_20231019155354.png

! y" \! Z2 H$ |# q; e/ [# y( y& k

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

  1. TaskHandle_t Start_LED_Handler;. v4 i$ a6 c. f! T' X4 A
  2. 2 y; s- @3 J# r# A
  3. void Start_LED(void * pvParameters)0 c; |- n  I+ I/ Z) n
  4. {+ U; O3 U. ~8 a
  5.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
    $ U' h& I# S% X: E& }: o
  6.               (char *                )"LED_TOG",//任务名称" N/ r* l2 S- r! v2 x" F) O
  7.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte; m4 n# T  l; \5 Z: b7 C
  8.               (void*                 ) NULL,//无返回
    # ?. s! I9 ~. j2 r0 U+ Z
  9.               (UBaseType_t          ) 1,//优先级13 s# Q# e$ |# Y* v
  10.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄/ b% {* _3 M" O5 J6 y, K
  11.   vTaskDelete(NULL);1 ?* |4 x4 |. B
  12. }
    " O) f. A2 Q3 s5 P& {
复制代码
" m( @  ]8 H  }: p5 F) @5 G

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

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

  1. void FreeRTOS_Init()
    : b; Z- ^$ q1 T3 w3 b7 H
  2. {/ b9 L8 i# W0 j/ [+ z% d  s
  3.   xTaskCreate((TaskFunction_t        )Start_LED,
    ; _0 V  r3 o* B1 Y8 e8 c8 E3 W
  4.               (char *                )"Start_LED",
    : ?4 V. ~9 n# U+ u- c# a3 ?' ?
  5.               (configSTACK_DEPTH_TYPE) 128,4 U* ]7 {; e8 c! B5 Q
  6.               (void*                 ) NULL,- }" E- P+ z* p) I: A8 l& S
  7.               (UBaseType_t          ) 0,
    & K/ ?9 P, |! Q* [/ Z+ D1 Z4 e
  8.               (TaskHandle_t *        )Start_LED_Handler);, W2 J% c2 ]/ |( K6 W
  9.   vTaskStartScheduler();//启动运行函数5 o9 `, S' b; o; U
  10. }
复制代码
+ y$ L7 u, a5 E. F1 D- q

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

  1. int main(void)
    3 N7 Y" }; u; ~$ k' V8 q
  2. {
    * j  D$ P1 u$ r) X& [
  3.   /* USER CODE BEGIN 1 */
    & A6 l  h) `, r% D" u

  4. : w, {* b7 u3 y& k* G8 J" m3 h
  5.   /* USER CODE END 1 */* p  V; V3 c$ q( }/ g! a! C
  6. + V$ b7 Z" i( o  X  \7 n
  7.   /* MCU Configuration--------------------------------------------------------*/. D; c0 Y; I4 N

  8. 1 h- a% Y" f% P
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    9 l/ g: Y6 C3 ?% ^7 D) p
  10.   HAL_Init();
    5 o/ ]# k4 }6 p' s8 }" L

  11. 1 K. U* V- ^# q; [2 ?
  12.   /* USER CODE BEGIN Init */3 {1 @; c$ w1 R3 t) n) X
  13.   KEY_Init();# K% W9 }6 h& i: ?- f" Y6 K) F7 ]
  14.   /* USER CODE END Init */
    4 }1 D1 v, m6 e1 c0 F0 t6 b0 T
  15. * l9 e* \5 s3 n( n( i3 F# w) q
  16.   /* Configure the system clock */
    " p# w! X& @9 b$ O; Q
  17.   SystemClock_Config();, P, [; w+ v# c* }; e

  18. 1 X. L. T" ^+ I( y: l; S1 h
  19.   /* USER CODE BEGIN SysInit */; z# d  A; X# z
  20. / z5 e1 G; d5 Q# M% u9 |9 s
  21.   /* USER CODE END SysInit */0 }) S+ N6 X, Y
  22. / _: R& o0 M3 d1 k2 a) A$ j
  23.   /* Initialize all configured peripherals */
    0 B; l3 D- P9 W" z" b6 \. O
  24.   MX_GPIO_Init();2 H! q; F2 _6 U9 f
  25.   MX_USART1_UART_Init();
    2 Y& Q9 W& @: z) p  [; W, X
  26.   /* USER CODE BEGIN 2 */0 Z& O9 X4 a# N2 u
  27.   FreeRTOS_Init();! Q: N" G. T- R  J5 ~( A
  28.   /* USER CODE END 2 */
    8 E+ I9 s3 B8 t5 x+ F+ O

  29. ' V$ _( ?7 d( U+ }. w5 Y! ~
  30.   /* Infinite loop */
    / H4 o  _' \* d* r3 d9 N% u/ O! K
  31.   /* USER CODE BEGIN WHILE */( [4 K; p4 @8 x0 M' o
  32.   while (1)
    4 O" l) n7 I/ {) n
  33.   {( g* u$ i7 \0 f0 T
  34.     /* USER CODE END WHILE */$ |* e0 O. i8 p% O5 x2 y$ F% u- g
  35. 5 k" K/ U: c2 Q  f
  36.     /* USER CODE BEGIN 3 */$ C# \% f/ A. k2 O+ a; Z8 P) F$ }
  37.   }% U2 A' }% I1 ^7 t
  38.   /* USER CODE END 3 */" w: q# c) e& a3 E# d. ?
  39. }2 i  r9 \8 |6 R8 l" F7 T2 t7 ^
复制代码

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


) x' ]: o! \* _! w  H* o我们在用上述的方法实现两个灯一起翻转

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

  1. TaskHandle_t LED_TOG2_Handler;
    4 E$ t* L- _  [5 X* Q% h# ?! i
  2. void LED_TOG2(void * pvParameters)//参数为 void * pvParameters
    ; ~  _* \" E5 B- W% x( M$ R
  3. {/ h. M3 e2 @8 o0 ^! d' V* O3 q4 @
  4.   while(1)2 t6 Q! C. n9 @* f: r6 c6 n4 B7 ?
  5.   {6 q# r* j! I5 Y/ b6 n, I) w
  6.     printf("LED_TOG running\r\n");//串口打印运行信息
    6 g5 |! C4 F% I& H' S6 w
  7.     HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转
    5 n; f% F% {) G7 M
  8.     vTaskDelay(500);//延迟500ms  w5 q1 B  T( L% R; `( f
  9.   }% F) B9 O2 N3 E) x* ^2 c, ?) x" }  }
  10. }
复制代码

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

  1. void Start_LED(void * pvParameters)
    1 J( K8 Z* U' P9 W
  2. {
    / p& c5 Z$ Z0 E. y1 u# \
  3.   xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数1 k6 [6 K7 ^6 W$ S9 h! V* ]
  4.               (char *                )"LED_TOG",//任务名称
    ( F, c4 l. c- R9 ^: I4 m; B# v& D
  5.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte! n3 v3 Z" I9 Z" u
  6.               (void*                 ) NULL,//无返回( G9 W3 J, N" B
  7.               (UBaseType_t          ) 1,//优先级15 b' R- O3 P1 S' U, X% |) h( R9 ?5 q8 N
  8.               (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄: C- v0 ?- \$ _! {9 q% L8 @
  9.   
    + d2 v3 ?+ q2 Y5 k
  10.    xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数
    + |3 }3 D/ ^; n$ W- J6 ~, P+ z. `& |. g
  11.               (char *                )"LED_TOG2",//任务名称
    : Q9 U2 T1 u0 t0 X3 J# E
  12.               (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte. s7 `7 `- w  b8 T2 Z. r
  13.               (void*                 ) NULL,//无返回
    , |# [8 a9 K4 D% h& c/ f) H" Q- Q5 }
  14.               (UBaseType_t          ) 2,//优先级2
    ( F3 Q7 S9 f* S  i" Z- ^
  15.               (TaskHandle_t *        )LED_TOG2_Handler);//任务函数句柄
    ' a+ x+ R- \  P# C. L$ R4 ^- F
  16.               0 X& r- w0 P6 ]/ j! A+ _
  17.   vTaskDelete(NULL);: _; r8 G+ T! m/ ?0 }$ \$ b
  18. }
复制代码

再次运行我们的代码。

8 S$ Y' o! ^  i$ a6 K4 \" Q$ J" v

转载自: 电路小白

如有侵权请联系删除
) e4 ?. m$ ?$ d7 q& k

, G; W) P, t- I7 I

. ]: M& |& @1 v* R/ @' k4 D$ @# g, d" ?! k6 n4 U& m
收藏 评论0 发布时间:2023-10-19 15:54

举报

0个回答

所属标签

相似技术帖

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