|
使用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
- 1upload_protocol = cmsis-dap' q' [/ a% ?- J0 G s0 P- D
- 2debug_tool = cmsis-dap
复制代码
5 U% k: P4 Z# S. S! d
8 L1 @% b, S. I$ v' l. x2 添加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
在lib目录的FreeRTOS文件夹下新建 library.json 文件,内容如下: - 1{
3 g& W7 N0 v6 {# V+ [7 X - 2 "name": "FreeRTOS"," `9 t, F' ^3 M2 n# X
- 3 "version": "202112.00",' _- `5 C' k" b3 e
- 4 "build": {7 h9 G' _7 j/ u5 h, Y
- 5 "flags": [
5 y* K7 v# o/ Z1 w+ \' q - 6 "-Isource",6 ~0 M" m6 z& @% e
- 7 "-Isource/include",
1 Q. O! m) h0 N. N( M, A& G - 8 "-Isource/portable/GCC/ARM_CM0",
' k7 J# E4 g7 J2 O - 9 "-Isource/portable/RVDS/ARM_CM0"
% C# E1 {1 G1 R8 ]7 n% _ - 10 ],8 W6 S* h( i, S0 y) ~, X3 r3 c
- 11 "srcFilter": [
9 U5 ^" T4 ^1 R% S9 A: ^6 R0 T, R! T - 12 "+<source/*.c>", D6 Q3 J, z4 X! I
- 13 "+<source/portable/GCC/ARM_CM0/*.c>",
& N& D9 C; ^6 z2 C: I - 14 "+<source/portable/MemMang/heap_4.c>"
6 @- v$ `2 c1 h( k! b( a - 15 ]2 k: i }0 y& W4 e# _
- 16 }
$ U$ B! w( C/ u% { - 17}
复制代码添加FreeRTOS配置 & S1 q9 x( @+ u4 @* s; P, u8 J
从FreeRTOS源码下的demo目录中拷贝一个FreeRTOSConfig.h文件到 lib/FreeRTOS/Source目录,并更改为如下内容: - 1/**$ v& `6 ?+ G: N3 D
- 2 * @file FreeRTOSConfig.h
" ~: f4 }: ~) s8 S6 u" } - 3 *
1 U: S; q) Z* ? - 4 * http://www.FreeRTOS.org' C9 \9 |7 Q \- \/ h
- 5 * http://aws.amazon.com/freertos
8 O8 x1 @2 k; i4 `0 s: }3 M. m - 6 *
0 |4 f* [( h" u, w; [3 L. R - 7 */
0 D" e) l4 y9 j4 U+ s6 J - 82 W d. Z# X. f$ ` V) Z
- 9#ifndef FREERTOS_CONFIG_H
# D* e# q8 k; p( e1 X$ t - 10#define FREERTOS_CONFIG_H$ I& G/ o9 W2 p
- 11& ], E" B" \' n9 j
- 12/*-----------------------------------------------------------
6 W6 r2 {1 w& y t - 13 * Application specific definitions.6 I( }7 t" R2 F
- 14 * o/ [3 P3 I7 f/ n
- 15 * These definitions should be adjusted for your particular hardware and2 M& [% S% I8 l
- 16 * application requirements.
Y6 O$ i4 k1 O& M$ ~( D - 17 *
; {& e) e; K4 B5 | J# \ - 18 * These parameters and more are described within the 'configuration' section of the
& G2 g2 T% R4 H - 19 * FreeRTOS API documentation available on the FreeRTOS.org web site.
+ Z# u; m8 N9 a1 n4 K6 e: p - 20 *; Y0 H+ y0 E/ M" z! U6 |
- 21 * See http://www.freertos.org/a00110.html
" Y: \: Y6 R* o3 C6 H( @% f% U% g - 22 *----------------------------------------------------------*/
6 K& `4 e E1 X+ G7 s' G2 {+ e- W - 23
5 v6 l- ^' X1 N c4 A - 24/* USER CODE BEGIN Includes */
/ j- l4 t/ r6 C - 25/* Section where include file can be added */
# Q, i; Z% Z5 V4 n4 \ - 26/* USER CODE END Includes */
3 L) l. V# _$ W4 T - 27 p. e6 i( P9 L' w
- 28/* Ensure definitions are only used by the compiler, and not by the assembler. */& _ D1 F' Z$ D0 C
- 29#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
1 \* m9 I$ F" y' n1 @2 D - 30 #include <stdint.h>
* r! J0 O O4 s* Q - 31#endif% p+ o V! s. V8 C6 Y
- 32#define configENABLE_FPU 0" J. W, N; k2 M f3 ]
- 33#define configENABLE_MPU 0- z" N( K! z+ B! |
- 347 f4 `7 P) b& F+ b
- 35#define configUSE_PREEMPTION 1
' ]/ V$ H6 I: ^6 g* |1 J' X - 36#define configSUPPORT_STATIC_ALLOCATION 0" a5 b6 o, ?9 d& `1 q1 x( V. T. B
- 37#define configSUPPORT_DYNAMIC_ALLOCATION 1' Z; Z% T' D4 e; L: ^/ K
- 38#define configUSE_IDLE_HOOK 0
/ G f1 ?6 B# z8 J9 c3 H+ y) R - 39#define configUSE_TICK_HOOK 0
5 _$ U5 E" a# u6 }# ?# R - 40#define configCPU_CLOCK_HZ ( ( unsigned long ) 64000000 ) $ O5 v# d8 G6 n `6 X$ d& y( V
- 41#define configTICK_RATE_HZ ((TickType_t)1000)
9 d5 u6 {2 |* j - 42#define configMAX_PRIORITIES ( 7 )
1 v) s# C- X+ S7 _6 h9 R' ~ - 43#define configMINIMAL_STACK_SIZE ((uint16_t)256). N# q+ X# {/ J, N
- 44#define configTOTAL_HEAP_SIZE ((size_t)1024*16)
4 t1 _0 b; W2 `& G - 45#define configMAX_TASK_NAME_LEN ( 16 )
) z! j/ M: W# j0 W8 ~3 z4 U - 46#define configUSE_16_BIT_TICKS 02 q- ?# C! _* u( Z/ }. t+ _$ f
- 47#define configUSE_MUTEXES 1
7 \3 \, H5 |' u; { - 48#define configQUEUE_REGISTRY_SIZE 8
0 d9 l" A6 k! ^$ a: f, Q$ T - 49#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0" N1 u6 q- }6 {4 K \! x& o; r
- 50
; [0 P& S A$ O" D - 51/*Software timer related definitions. */
# x7 E: p6 j$ b - 52#define configUSE_TIMERS 1% w a0 ^% |% D/ H9 n( c, Z+ i0 }. d
- 53#define configTIMER_TASK_PRIORITY 58 |" l" u6 d8 O; P4 F+ O
- 54#define configTIMER_QUEUE_LENGTH 10 e6 {- c" g" m8 M6 Y& E
- 55#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE! T, F4 W) {5 w+ {& q" W- [
- 561 Q7 R" j9 R4 x2 A
- 57/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
& o$ v! r, L9 I9 V - 58/* Defaults to size_t for backward compatibility, but can be changed' A% o/ i; @! ]8 G* j5 w" I5 @4 M
- 59 if lengths will always be less than the number of bytes in a size_t. */
; Z& W6 _8 F7 ? - 60#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
! f' G3 y- n- r- ` - 61/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */- n8 I* e1 s8 {4 V2 G
- 624 I6 H+ M, F' g; M! y% c H& O, V
- 63/* Co-routine definitions. */
1 g, Q6 j: T9 a - 64#define configUSE_CO_ROUTINES 0- D4 K: H' s3 z) \) b, L' C: Q
- 65#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
6 W9 }; A; ]; z& P2 t, \ - 66
0 v* B0 _/ m N) M - 67/* Set the following definitions to 1 to include the API function, or zero
; I8 {- m- W7 l+ F! ~ - 68to exclude the API function. */7 R1 e" J5 `9 g: w# n" N7 C) Z
- 69#define INCLUDE_vTaskPrioritySet 1# q6 K5 ~: g' c# C& _+ B5 e7 p$ N
- 70#define INCLUDE_uxTaskPriorityGet 1
) Q/ m% T9 q. V0 X+ J - 71#define INCLUDE_vTaskDelete 1 Q- E4 y/ u2 c! q/ O
- 72#define INCLUDE_vTaskCleanUpResources 0. E& c. J' N6 O: a$ X W
- 73#define INCLUDE_vTaskSuspend 1
1 J& u& H) a3 H - 74#define INCLUDE_vTaskDelayUntil 0' v5 b# W% \0 R7 D0 u& u% `/ m
- 75#define INCLUDE_vTaskDelay 1
4 x* {2 r% H F - 76#define INCLUDE_xTaskGetSchedulerState 1
$ d8 r# N! E+ Y, B - 77
: K! x# U% @* L- W' [5 K - 78/* Normal assert() semantics without relying on the provision of an assert.h
3 O) t1 L& S. n$ p! t5 m - 79header file. */4 A0 S' m) T; a! P
- 80/* USER CODE BEGIN 1 */# `0 f: b" w+ t% C, L" S# N; G/ s4 L# N
- 81//void vAssertCalled(const char *file, int line);9 _) Z/ ~( l0 D9 T0 J: O: C+ Q
- 82//#define configASSERT( x ) if( x == 0 ) { taskDISABLE_INTERRUPTS(); vAssertCalled(__FILE__,__LINE__); for(;;); }
% F3 z% G$ q# X: q; u7 |+ p - 83/* USER CODE END 1 */
! u2 W9 u" V: _. C: r. T! { - 84
2 \) [7 u! p/ ]4 ^. R$ b, K; e - 85/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
% H3 |4 Y- |1 ^1 b6 ~ - 86standard names. */# G" P0 X1 f% F/ ~9 q
- 87#define vPortSVCHandler sv_call_handler [ ]/ j6 f x# H
- 88#define xPortPendSVHandler pend_sv_handler6 D; I: F9 P# F: Z
- 89
; n6 D( P8 ~6 `8 L N - 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 to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
1 C% @1 G4 M5 I# \6 ]( P' \ _/ k8 v6 z - 92
: t, V# e& N/ q: i) z - 93#define xPortSysTickHandler sys_tick_handler
7 H( p" X. n& q3 d( Y - 94
0 ]# N) E8 `/ B0 g' h9 Z - 95/* USER CODE BEGIN Defines */ L0 v8 Q N. ^' ~- v) t" g
- 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/* USER CODE END Defines */
! K; N( E& w. A4 |: D2 b1 C - 98) F4 q* Q& |# e- M
- 99#endif /* FREERTOS_CONFIG_H */
复制代码
' W& m1 c% y( L6 R! ^/ c; V, e上面配置需要根据自己的需要进行更改,如CPU频率,是否需要打开某项功能等; 配置好后的目录结构如下: # E' j/ {$ y3 \3 g
/ ~1 Z: P( u1 K' o; G
3 FreeRTOS示例首先需要设置FreeRTOS需要的时钟 6 i, p+ d* p6 M5 l
- 1/**5 }; p( h* Q( C1 n
- 2 * @brief systick setup for rtos tick' ]& m5 p. u& H+ t% S
- 3 */
$ R8 w' E: o1 ?8 N% h8 D0 L9 R - 4static void systick_setup(void)
5 \. U. |0 S9 H - 5{
4 ]4 k8 X# h. p e5 C: u4 S - 6 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
$ Q' N) f; A" `! [+ A+ P/ `" M; ^ - 7 systick_set_reload(64*1000);
/ O( c6 S) i4 g' ^! L2 C - 8
% P- t1 h$ z/ s7 U - 9 systick_interrupt_enable();
( t, K! n; H& \- B - 10
P/ O. u% L3 }: [" t; I- x - 11 /* Start counting. */
* }9 S/ Q2 G Q& d5 k - 12 systick_counter_enable();
/ c( {% p9 a+ S# p5 @ C - 13}
复制代码 - o' N! ^9 s+ h5 J1 X/ i
2 O8 _6 |4 t0 d. v3 @8 P
这样在FreeRTOSConfig.h 文件中定义的 - 1#define xPortSysTickHandler sys_tick_handler
复制代码
4 t1 T' ^9 G, ?4 e0 {% O( g! u7 m就可以通过systick中断提供FreeRTOS时钟; - 1static void led1_task(void *args)
|8 x0 S0 |% E B0 q* g - 2{' \) Z7 F" S# ]$ l; |) e! ?8 N4 s1 [. G
- 3 rcc_periph_clock_enable(RCC_GPIOC);
; V, L' |! Q6 y: h& T4 F - 4 gpio_mode_setup(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO12);
9 ?/ H4 R* G b! Q6 n3 a- j - 5; W g! f" [8 N& K* }8 j: D& x8 {
- 6 while (1)% W2 h: e9 l2 b% l% x
- 7 {
. t; `( O3 l! h% W* s- ?4 ~ - 8 gpio_toggle(GPIOC,GPIO12);+ }1 i- T# H& W' n4 [" q% n! N- r
- 9 vTaskDelay(pdMS_TO_TICKS(500));- F. D+ p o" R# c5 j
- 10 }
$ q# o+ Z# T$ w' z4 O# M - 11}
复制代码
m7 @- T+ Z/ B0 ]9 ~9 b
5 U2 r! W7 o$ ^- q. S主程序中创建任务并开启多任务调度 " S; ?/ ^* F. j8 X- o& H
- 1#include <libopencm3/stm32/rcc.h>
; G5 i% b- V: U" q. d - 2#include <libopencm3/stm32/gpio.h>
- \( ]+ H( L8 q - 3#include <libopencm3/cm3/systick.h>
/ O) Y$ m' q- B - 4' k! X B, ^# T9 e) l
- 5#include "FreeRTOS.h"
- Z- A" h. c+ u- `$ ?# R: g - 6#include "task.h"
0 W& M% R0 {+ T+ { - 7
/ _1 }) F- v* Q6 u7 o - 84 N) u7 o$ @! y9 v
- 9int main(void): A( X1 e( A& m( ]
- 10{7 j+ K, L+ }; y [% |0 F9 ~- J2 A# W
- 11 //system clock1 j+ J/ @0 Y! j& b" d2 j
- 12 rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);
% d- A5 ], O, r3 w x- q - 136 C2 G1 q3 y. Q. \( X e; x8 n
- 14 systick_setup();
5 R5 n( o v r# F6 T2 y7 b. N - 15. Y! r3 Z$ b( \* n
- 16 xTaskCreate(led_task,"led task", 256, NULL,2,NULL);) y$ T0 X! E2 w7 u! c
- 176 _" J5 h" }. A: R
- 18 vTaskStartScheduler();
3 Q) c/ ]; k! H9 y, ?: {( {+ b - 199 x) E. E: J u2 e7 C' p7 g
- 20 while(1){}
, Y7 {8 p7 t' m6 ]* i - 21
7 h9 n; ?* A% p - 22 return 0;" y( \: @% l) X' h9 B/ e
- 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
|