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

STM32G0-Platformio+libopencm3-FreeRTOS基本使用

[复制链接]
STMCU小助手 发布时间:2023-2-22 16:44
使用Platformio平台的libopencm3开发框架来开发STM32G0,下面为使用FreeRTOS系统。
" \2 ?6 `% \, `' G4 M- q& s* n
1 新建项目
  • 在PIO主页新建项目,框架选择libopencm3,开发板选择 MonkeyPi_STM32_G070RB;
  • 新建完成后在src目录新建主程序文件main.c;
  • 然后更改项目文件platformio.ini的烧写和调试方式:

    . `$ j' b% L  P+ y$ N# O) p
  1. 1upload_protocol = cmsis-dap' q' [/ a% ?- J0 G  s0 P- D
  2. 2debug_tool = cmsis-dap
复制代码

5 U% k: P4 Z# S. S! d
8 L1 @% b, S. I$ v' l. x
2 添加FreeRTOS源码
  • 下载FreeRTOS源码

    / @$ R+ ]) v+ V# U

# l( K" U1 u5 L, k
  • 添加源码到项目:
    $ ]" h1 ]6 d; t/ w
直接拷贝源码下的FreeRTOS文件夹到项目的lib目录中;

  w) X9 \( B" f  X$ v
  • 添加到项目编译

    , H2 j7 B0 u2 V
在lib目录的FreeRTOS文件夹下新建 library.json 文件,内容如下:
  1. 1{
    3 g& W7 N0 v6 {# V+ [7 X
  2. 2    "name": "FreeRTOS"," `9 t, F' ^3 M2 n# X
  3. 3    "version": "202112.00",' _- `5 C' k" b3 e
  4. 4    "build": {7 h9 G' _7 j/ u5 h, Y
  5. 5        "flags": [
    5 y* K7 v# o/ Z1 w+ \' q
  6. 6            "-Isource",6 ~0 M" m6 z& @% e
  7. 7            "-Isource/include",
    1 Q. O! m) h0 N. N( M, A& G
  8. 8            "-Isource/portable/GCC/ARM_CM0",
    ' k7 J# E4 g7 J2 O
  9. 9            "-Isource/portable/RVDS/ARM_CM0"
    % C# E1 {1 G1 R8 ]7 n% _
  10. 10        ],8 W6 S* h( i, S0 y) ~, X3 r3 c
  11. 11        "srcFilter": [
    9 U5 ^" T4 ^1 R% S9 A: ^6 R0 T, R! T
  12. 12            "+<source/*.c>",  D6 Q3 J, z4 X! I
  13. 13            "+<source/portable/GCC/ARM_CM0/*.c>",
    & N& D9 C; ^6 z2 C: I
  14. 14            "+<source/portable/MemMang/heap_4.c>"
    6 @- v$ `2 c1 h( k! b( a
  15. 15        ]2 k: i  }0 y& W4 e# _
  16. 16    }
    $ U$ B! w( C/ u% {
  17. 17}
复制代码
  • 添加FreeRTOS配置
    & S1 q9 x( @+ u4 @* s; P, u8 J
从FreeRTOS源码下的demo目录中拷贝一个FreeRTOSConfig.h文件到 lib/FreeRTOS/Source目录,并更改为如下内容:
  1. 1/**$ v& `6 ?+ G: N3 D
  2. 2 * @file FreeRTOSConfig.h
    " ~: f4 }: ~) s8 S6 u" }
  3. 3 *
    1 U: S; q) Z* ?
  4. 4 * http://www.FreeRTOS.org' C9 \9 |7 Q  \- \/ h
  5. 5 * http://aws.amazon.com/freertos
    8 O8 x1 @2 k; i4 `0 s: }3 M. m
  6. 6 *
    0 |4 f* [( h" u, w; [3 L. R
  7. 7 */
    0 D" e) l4 y9 j4 U+ s6 J
  8. 82 W  d. Z# X. f$ `  V) Z
  9. 9#ifndef FREERTOS_CONFIG_H
    # D* e# q8 k; p( e1 X$ t
  10. 10#define FREERTOS_CONFIG_H$ I& G/ o9 W2 p
  11. 11& ], E" B" \' n9 j
  12. 12/*-----------------------------------------------------------
    6 W6 r2 {1 w& y  t
  13. 13 * Application specific definitions.6 I( }7 t" R2 F
  14. 14 *  o/ [3 P3 I7 f/ n
  15. 15 * These definitions should be adjusted for your particular hardware and2 M& [% S% I8 l
  16. 16 * application requirements.
      Y6 O$ i4 k1 O& M$ ~( D
  17. 17 *
    ; {& e) e; K4 B5 |  J# \
  18. 18 * These parameters and more are described within the 'configuration' section of the
    & G2 g2 T% R4 H
  19. 19 * FreeRTOS API documentation available on the FreeRTOS.org web site.
    + Z# u; m8 N9 a1 n4 K6 e: p
  20. 20 *; Y0 H+ y0 E/ M" z! U6 |
  21. 21 * See http://www.freertos.org/a00110.html
    " Y: \: Y6 R* o3 C6 H( @% f% U% g
  22. 22 *----------------------------------------------------------*/
    6 K& `4 e  E1 X+ G7 s' G2 {+ e- W
  23. 23
    5 v6 l- ^' X1 N  c4 A
  24. 24/* USER CODE BEGIN Includes */
    / j- l4 t/ r6 C
  25. 25/* Section where include file can be added */
    # Q, i; Z% Z5 V4 n4 \
  26. 26/* USER CODE END Includes */
    3 L) l. V# _$ W4 T
  27. 27  p. e6 i( P9 L' w
  28. 28/* Ensure definitions are only used by the compiler, and not by the assembler. */& _  D1 F' Z$ D0 C
  29. 29#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
    1 \* m9 I$ F" y' n1 @2 D
  30. 30  #include <stdint.h>
    * r! J0 O  O4 s* Q
  31. 31#endif% p+ o  V! s. V8 C6 Y
  32. 32#define configENABLE_FPU                         0" J. W, N; k2 M  f3 ]
  33. 33#define configENABLE_MPU                         0- z" N( K! z+ B! |
  34. 347 f4 `7 P) b& F+ b
  35. 35#define configUSE_PREEMPTION                     1
    ' ]/ V$ H6 I: ^6 g* |1 J' X
  36. 36#define configSUPPORT_STATIC_ALLOCATION          0" a5 b6 o, ?9 d& `1 q1 x( V. T. B
  37. 37#define configSUPPORT_DYNAMIC_ALLOCATION         1' Z; Z% T' D4 e; L: ^/ K
  38. 38#define configUSE_IDLE_HOOK                      0
    / G  f1 ?6 B# z8 J9 c3 H+ y) R
  39. 39#define configUSE_TICK_HOOK                      0
    5 _$ U5 E" a# u6 }# ?# R
  40. 40#define configCPU_CLOCK_HZ                         ( ( unsigned long ) 64000000 ) $ O5 v# d8 G6 n  `6 X$ d& y( V
  41. 41#define configTICK_RATE_HZ                       ((TickType_t)1000)
    9 d5 u6 {2 |* j
  42. 42#define configMAX_PRIORITIES                     ( 7 )
    1 v) s# C- X+ S7 _6 h9 R' ~
  43. 43#define configMINIMAL_STACK_SIZE                 ((uint16_t)256). N# q+ X# {/ J, N
  44. 44#define configTOTAL_HEAP_SIZE                    ((size_t)1024*16)
    4 t1 _0 b; W2 `& G
  45. 45#define configMAX_TASK_NAME_LEN                  ( 16 )
    ) z! j/ M: W# j0 W8 ~3 z4 U
  46. 46#define configUSE_16_BIT_TICKS                   02 q- ?# C! _* u( Z/ }. t+ _$ f
  47. 47#define configUSE_MUTEXES                        1
    7 \3 \, H5 |' u; {
  48. 48#define configQUEUE_REGISTRY_SIZE                8
    0 d9 l" A6 k! ^$ a: f, Q$ T
  49. 49#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0" N1 u6 q- }6 {4 K  \! x& o; r
  50. 50
    ; [0 P& S  A$ O" D
  51. 51/*Software timer related definitions. */
    # x7 E: p6 j$ b
  52. 52#define configUSE_TIMERS                        1% w  a0 ^% |% D/ H9 n( c, Z+ i0 }. d
  53. 53#define configTIMER_TASK_PRIORITY               58 |" l" u6 d8 O; P4 F+ O
  54. 54#define configTIMER_QUEUE_LENGTH                10  e6 {- c" g" m8 M6 Y& E
  55. 55#define configTIMER_TASK_STACK_DEPTH            configMINIMAL_STACK_SIZE! T, F4 W) {5 w+ {& q" W- [
  56. 561 Q7 R" j9 R4 x2 A
  57. 57/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
    & o$ v! r, L9 I9 V
  58. 58/* Defaults to size_t for backward compatibility, but can be changed' A% o/ i; @! ]8 G* j5 w" I5 @4 M
  59. 59   if lengths will always be less than the number of bytes in a size_t. */
    ; Z& W6 _8 F7 ?
  60. 60#define configMESSAGE_BUFFER_LENGTH_TYPE         size_t
    ! f' G3 y- n- r- `
  61. 61/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */- n8 I* e1 s8 {4 V2 G
  62. 624 I6 H+ M, F' g; M! y% c  H& O, V
  63. 63/* Co-routine definitions. */
    1 g, Q6 j: T9 a
  64. 64#define configUSE_CO_ROUTINES                    0- D4 K: H' s3 z) \) b, L' C: Q
  65. 65#define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )
    6 W9 }; A; ]; z& P2 t, \
  66. 66
    0 v* B0 _/ m  N) M
  67. 67/* Set the following definitions to 1 to include the API function, or zero
    ; I8 {- m- W7 l+ F! ~
  68. 68to exclude the API function. */7 R1 e" J5 `9 g: w# n" N7 C) Z
  69. 69#define INCLUDE_vTaskPrioritySet             1# q6 K5 ~: g' c# C& _+ B5 e7 p$ N
  70. 70#define INCLUDE_uxTaskPriorityGet            1
    ) Q/ m% T9 q. V0 X+ J
  71. 71#define INCLUDE_vTaskDelete                  1  Q- E4 y/ u2 c! q/ O
  72. 72#define INCLUDE_vTaskCleanUpResources        0. E& c. J' N6 O: a$ X  W
  73. 73#define INCLUDE_vTaskSuspend                 1
    1 J& u& H) a3 H
  74. 74#define INCLUDE_vTaskDelayUntil              0' v5 b# W% \0 R7 D0 u& u% `/ m
  75. 75#define INCLUDE_vTaskDelay                   1
    4 x* {2 r% H  F
  76. 76#define INCLUDE_xTaskGetSchedulerState       1
    $ d8 r# N! E+ Y, B
  77. 77
    : K! x# U% @* L- W' [5 K
  78. 78/* Normal assert() semantics without relying on the provision of an assert.h
    3 O) t1 L& S. n$ p! t5 m
  79. 79header file. */4 A0 S' m) T; a! P
  80. 80/* USER CODE BEGIN 1 */# `0 f: b" w+ t% C, L" S# N; G/ s4 L# N
  81. 81//void vAssertCalled(const char *file, int line);9 _) Z/ ~( l0 D9 T0 J: O: C+ Q
  82. 82//#define configASSERT( x )       if( x == 0 ) { taskDISABLE_INTERRUPTS(); vAssertCalled(__FILE__,__LINE__); for(;;); }
    % F3 z% G$ q# X: q; u7 |+ p
  83. 83/* USER CODE END 1 */
    ! u2 W9 u" V: _. C: r. T! {
  84. 84
    2 \) [7 u! p/ ]4 ^. R$ b, K; e
  85. 85/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
    % H3 |4 Y- |1 ^1 b6 ~
  86. 86standard names. */# G" P0 X1 f% F/ ~9 q
  87. 87#define vPortSVCHandler    sv_call_handler  [  ]/ j6 f  x# H
  88. 88#define xPortPendSVHandler pend_sv_handler6 D; I: F9 P# F: Z
  89. 89
    ; n6 D( P8 ~6 `8 L  N
  90. 90/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
    : l) X8 W) Z0 {4 [# m( |! t# Y2 r
  91. 91              to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
    1 C% @1 G4 M5 I# \6 ]( P' \  _/ k8 v6 z
  92. 92
    : t, V# e& N/ q: i) z
  93. 93#define xPortSysTickHandler sys_tick_handler
    7 H( p" X. n& q3 d( Y
  94. 94
    0 ]# N) E8 `/ B0 g' h9 Z
  95. 95/* USER CODE BEGIN Defines */  L0 v8 Q  N. ^' ~- v) t" g
  96. 96/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
    - ~/ Z9 ?* W: c; y$ G& v8 A. F
  97. 97/* USER CODE END Defines */
    ! K; N( E& w. A4 |: D2 b1 C
  98. 98) F4 q* Q& |# e- M
  99. 99#endif /* FREERTOS_CONFIG_H */
复制代码

' W& m1 c% y( L6 R! ^/ c; V, e
上面配置需要根据自己的需要进行更改,如CPU频率,是否需要打开某项功能等;
  • 配置好后的目录结构如下:
    # E' j/ {$ y3 \3 g
微信图片_20230222164400.png
/ ~1 Z: P( u1 K' o; G
3 FreeRTOS示例
  • 首先需要设置FreeRTOS需要的时钟
    6 i, p+ d* p6 M5 l
  1. 1/**5 }; p( h* Q( C1 n
  2. 2 * @brief systick setup for rtos tick' ]& m5 p. u& H+ t% S
  3. 3 */
    $ R8 w' E: o1 ?8 N% h8 D0 L9 R
  4. 4static void systick_setup(void)
    5 \. U. |0 S9 H
  5. 5{
    4 ]4 k8 X# h. p  e5 C: u4 S
  6. 6    systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
    $ Q' N) f; A" `! [+ A+ P/ `" M; ^
  7. 7    systick_set_reload(64*1000);
    / O( c6 S) i4 g' ^! L2 C
  8. 8
    % P- t1 h$ z/ s7 U
  9. 9    systick_interrupt_enable();
    ( t, K! n; H& \- B
  10. 10
      P/ O. u% L3 }: [" t; I- x
  11. 11    /* Start counting. */
    * }9 S/ Q2 G  Q& d5 k
  12. 12    systick_counter_enable();
    / c( {% p9 a+ S# p5 @  C
  13. 13}
复制代码
- o' N! ^9 s+ h5 J1 X/ i
2 O8 _6 |4 t0 d. v3 @8 P
这样在FreeRTOSConfig.h 文件中定义的
  1. 1#define xPortSysTickHandler sys_tick_handler
复制代码

4 t1 T' ^9 G, ?4 e0 {% O( g! u7 m
就可以通过systick中断提供FreeRTOS时钟;
  • LED任务函数
    " v/ g  ~# l( x
  1. 1static void led1_task(void *args)
      |8 x0 S0 |% E  B0 q* g
  2. 2{' \) Z7 F" S# ]$ l; |) e! ?8 N4 s1 [. G
  3. 3    rcc_periph_clock_enable(RCC_GPIOC);
    ; V, L' |! Q6 y: h& T4 F
  4. 4    gpio_mode_setup(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO12);
    9 ?/ H4 R* G  b! Q6 n3 a- j
  5. 5; W  g! f" [8 N& K* }8 j: D& x8 {
  6. 6    while (1)% W2 h: e9 l2 b% l% x
  7. 7    {
    . t; `( O3 l! h% W* s- ?4 ~
  8. 8        gpio_toggle(GPIOC,GPIO12);+ }1 i- T# H& W' n4 [" q% n! N- r
  9. 9        vTaskDelay(pdMS_TO_TICKS(500));- F. D+ p  o" R# c5 j
  10. 10    }
    $ q# o+ Z# T$ w' z4 O# M
  11. 11}
复制代码

  m7 @- T+ Z/ B0 ]9 ~9 b
5 U2 r! W7 o$ ^- q. S
  • 主程序中创建任务并开启多任务调度
    " S; ?/ ^* F. j8 X- o& H
  1. 1#include <libopencm3/stm32/rcc.h>
    ; G5 i% b- V: U" q. d
  2. 2#include <libopencm3/stm32/gpio.h>
    - \( ]+ H( L8 q
  3. 3#include <libopencm3/cm3/systick.h>
    / O) Y$ m' q- B
  4. 4' k! X  B, ^# T9 e) l
  5. 5#include "FreeRTOS.h"
    - Z- A" h. c+ u- `$ ?# R: g
  6. 6#include "task.h"
    0 W& M% R0 {+ T+ {
  7. 7
    / _1 }) F- v* Q6 u7 o
  8. 84 N) u7 o$ @! y9 v
  9. 9int main(void): A( X1 e( A& m( ]
  10. 10{7 j+ K, L+ }; y  [% |0 F9 ~- J2 A# W
  11. 11    //system clock1 j+ J/ @0 Y! j& b" d2 j
  12. 12    rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);
    % d- A5 ], O, r3 w  x- q
  13. 136 C2 G1 q3 y. Q. \( X  e; x8 n
  14. 14    systick_setup();
    5 R5 n( o  v  r# F6 T2 y7 b. N
  15. 15. Y! r3 Z$ b( \* n
  16. 16    xTaskCreate(led_task,"led task", 256, NULL,2,NULL);) y$ T0 X! E2 w7 u! c
  17. 176 _" J5 h" }. A: R
  18. 18    vTaskStartScheduler();
    3 Q) c/ ]; k! H9 y, ?: {( {+ b
  19. 199 x) E. E: J  u2 e7 C' p7 g
  20. 20    while(1){}
    , Y7 {8 p7 t' m6 ]* i
  21. 21
    7 h9 n; ?* A% p
  22. 22    return 0;" y( \: @% l) X' h9 B/ e
  23. 23}
复制代码

  o$ |4 h8 E/ |0 l6 b7 @0 ^# B# [9 {' S) f, q+ B, M6 {2 |
通过xTaskCreate创建多任务函数,然后使用 vTaskStartScheduler 开始调度;
注:如果VSCode中提示 FreeRTOS.h 头文件include path问题,可以将项目文件夹关闭,再重新打开即可;如果是在Clion中,可以在添加lib文件夹后,右键platformio.ini文件选择re init即可;

% K' o9 N- r# e  e
4 烧写测试
点击 PlatformIO:Upload按钮或Ctrl+Alt+U快捷键可以直接编译烧写到目标板,看到LED按预定的程序闪烁运行;

7 b( j! n; [' X! P! u! H
转载自: MakerInChina.cn
7 Y/ r3 S% Z7 ]( U  S3 |+ s
赞 收藏 评论0 发布时间:2023-2-22 16:44

举报

0个回答

所属标签

相似技术帖

官网相关资源

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