当前位置:网站首页>Platformio create libopencm3 + FreeRTOS project
Platformio create libopencm3 + FreeRTOS project
2022-07-05 22:11:00 【IOsetting】
PlatformIO: libopencm3 + FreeRTOS
The following steps are based on common Bluepill STM32F103C8T6, Also applicable to other libopencm3 Supported by MCU model
Scheme 1 : Copy only the files you need
- stay PlatformIO in , Board choice Bluepill F103C8, Framework choice libopencm3, Create project
- In the project lib Create a new directory FreeRTOS
- Unzip the latest FreeRTOS
- Copy FreeRTOS/Source/ Under the table of contents , except portable All other files and directories except directory , to lib/FreeRTOS Next
- Copy FreeRTOS/Source/portable/GCC/ARM_CM3 All files in the directory (port.c, portmacro.h), to lib/FreeRTOS Next
- Copy FreeRTOS/Source/portable/Common All files in the directory (mpu_wrappers.c), to lib/FreeRTOS Next
- Copy FreeRTOS/Source/portable/MemMang Under the table of contents heap_4.c, to lib/FreeRTOS Next
- Copy FreeRTOSConfig.h, to lib/FreeRTOS/include Next
- To write src/main.c
After completion, the directory structure should be
├── include
│ └── README
├── lib
│ ├── FreeRTOS
│ │ ├── croutine.c
│ │ ├── event_groups.c
│ │ ├── heap_4.c
│ │ ├── include
│ │ │ ├── atomic.h
│ │ │ ├── croutine.h
│ │ │ ├── deprecated_definitions.h
│ │ │ ├── event_groups.h
│ │ │ ├── FreeRTOSConfig.h
│ │ │ ├── FreeRTOS.h
│ │ │ ├── list.h
│ │ │ ├── message_buffer.h
│ │ │ ├── mpu_prototypes.h
│ │ │ ├── mpu_wrappers.h
│ │ │ ├── portable.h
│ │ │ ├── projdefs.h
│ │ │ ├── queue.h
│ │ │ ├── semphr.h
│ │ │ ├── stack_macros.h
│ │ │ ├── StackMacros.h
│ │ │ ├── stdint.readme
│ │ │ ├── stream_buffer.h
│ │ │ ├── task.h
│ │ │ └── timers.h
│ │ ├── list.c
│ │ ├── mpu_wrappers.c
│ │ ├── port.c
│ │ ├── portmacro.h
│ │ ├── queue.c
│ │ ├── stream_buffer.c
│ │ ├── tasks.c
│ │ └── timers.c
│ └── README
├── platformio.ini
├── README.md
├── src
│ └── main.c
└── test
└── README
Option two : complete FreeRTOS, Use library.json
- stay PlatformIO in , Board choice Bluepill F103C8, Framework choice libopencm3, Create project
- In the project lib Create a new directory FreeRTOS
- Unzip the latest FreeRTOS
- Copy FreeRTOS/Source/ All files in the directory to lib/FreeRTOS Next
- Copy FreeRTOS/Source/portable/GCC/ARM_CM3 Under the table of contents portmacro.h to lib/FreeRTOS Next , because library.json Multiple... Are not supported yet include route
- Copy FreeRTOSConfig.h, to lib/FreeRTOS Next
- lib/FreeRTOS Add below library.json
- To write src/main.c
library.json The contents are as follows , Include only what you need c file
{
"name": "FreeRTOS",
"version": "10.4.6",
"build": {
"srcFilter": [
"+<*.c>",
"+<portable/GCC/ARM_CM3/port.c>",
"+<portable/MemMang/heap_4.c>"
]
}
}
If it's multi-core MCU, Need to include again mpu_wrappers.c, about F103C8 Not really
"+<portable/Common/mpu_wrappers.c>",
After completion, the directory structure is
├── include
│ └── README
├── lib
│ ├── FreeRTOS
│ │ ├── croutine.c
│ │ ├── event_groups.c
│ │ ├── FreeRTOSConfig.h
│ │ ├── include
│ │ ├── library.json
│ │ ├── list.c
│ │ ├── miniprintf.c
│ │ ├── miniprintf.h
│ │ ├── portable
│ │ ├── portmacro.h
│ │ ├── queue.c
│ │ ├── stream_buffer.c
│ │ ├── tasks.c
│ │ └── timers.c
│ └── README
├── platformio.ini
├── README.md
├── src
│ └── main.c
└── test
└── README
FreeRTOSConfig.h Function name fits
stay libopencm3/lib/cm3/vector.c in , Defined .sv_call,.pend_sv and .systick Processing function of ,
/* Those are defined only on CM3 or CM4 */
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
.memory_manage_fault = mem_manage_handler,
.bus_fault = bus_fault_handler,
.usage_fault = usage_fault_handler,
.debug_monitor = debug_monitor_handler,
#endif
.sv_call = sv_call_handler,
.pend_sv = pend_sv_handler,
.systick = sys_tick_handler,
.irq = {
IRQ_HANDLERS
}
};
These function names are similar to FreeRTOS The function names in are inconsistent , It needs to be associated . Using macro replacement is more efficient than using function forwarding , So in FreeRTOSConfig.h The following definitions need to be added , otherwise FreeRTOS Not working properly
/** * In libopencm3/lib/cm3/vector.c, these 3 handlers(right side) are for .sv_call,.pend_sv and .systick * These macro will rename the methods in port.c to make it work, more efficient than wrapped by method */
#define vPortSVCHandler sv_call_handler
#define xPortPendSVHandler pend_sv_handler
#define xPortSysTickHandler sys_tick_handler
Sample code
Use Queue Of UART Send and receive
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/cm3/nvic.h>
#define mainECHO_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
static QueueHandle_t uart_txq; // TX queue for UART
/* * Handler in case our application overflows the stack */
void vApplicationStackOverflowHook(
TaskHandle_t xTask __attribute__((unused)),
char *pcTaskName __attribute__((unused))) {
for (;;);
}
void usart1_isr(void) {
uint8_t data;
/* Check if we were called because of RXNE. */
if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
/* Retrieve the data from the peripheral. */
data = usart_recv(USART1);
xQueueSendFromISR(uart_txq, &data, NULL);
}
}
static void gpio_setup(void) {
// GPIO PB12,PC13:
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
// Turn LED off
gpio_set(GPIOB, GPIO12);
gpio_set(GPIOC, GPIO13);
rcc_periph_clock_enable(RCC_GPIOA);
gpio_set_mode(GPIOA,GPIO_MODE_OUTPUT_50_MHZ,GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,GPIO_USART1_TX);
gpio_set_mode(GPIOA,GPIO_MODE_OUTPUT_50_MHZ,GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,GPIO11);
gpio_set_mode(GPIOA,GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO_USART1_RX);
gpio_set_mode(GPIOA,GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO12);
}
/********************************************************************* * Configure and initialize USART1: *********************************************************************/
static void
uart_setup(void) {
rcc_periph_clock_enable(RCC_USART1);
usart_set_baudrate(USART1,115200);
usart_set_databits(USART1,8);
usart_set_stopbits(USART1,USART_STOPBITS_1);
usart_set_mode(USART1,USART_MODE_TX_RX);
usart_set_parity(USART1,USART_PARITY_NONE);
usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);
usart_enable(USART1);
nvic_enable_irq(NVIC_USART1_IRQ);
usart_enable_rx_interrupt(USART1);
// Create a queue for data to transmit from UART
uart_txq = xQueueCreate(256,sizeof(char));
}
static void uart_puts(const char *s) {
for ( ; *s; ++s ) {
// blocks when queue is full
xQueueSend(uart_txq,s,portMAX_DELAY);
}
}
/********************************************************************* * USART Task: *********************************************************************/
static void uart_task(void *args __attribute__((unused))) {
char ch;
for (;;) {
// Receive char to be TX
if ( xQueueReceive(uart_txq,&ch,500) == pdPASS ) {
// if not tx data buffer empty
while ( !usart_get_flag(USART1,USART_SR_TXE) )
taskYIELD(); // Yield until ready
usart_send(USART1,ch);
}
// Toggle LED to show signs of life
gpio_toggle(GPIOB,GPIO12);
gpio_toggle(GPIOC,GPIO13);
}
}
/********************************************************************* * Demo Task: * Simply queues up two line messages to be TX, one second * apart. *********************************************************************/
static void demo_task(void *args __attribute__((unused))) {
for (;;) {
uart_puts("Now this is a message..\n\r");
uart_puts(" sent via FreeRTOS queues.\n\n\r");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
/********************************************************************* * Main program & scheduler: *********************************************************************/
int main(void) {
rcc_clock_setup_in_hse_8mhz_out_72mhz(); // CPU clock is 72 MHz
gpio_setup();
uart_setup();
xTaskCreate(uart_task,"UART",100,NULL,configMAX_PRIORITIES-1,NULL);
xTaskCreate(demo_task,"DEMO",100,NULL,configMAX_PRIORITIES-2,NULL);
vTaskStartScheduler();
for (;;);
return 0;
}
边栏推荐
- Text组件新增内容通过tag_config设置前景色、背景色
- Index optimization of performance tuning methodology
- How can Bluetooth in notebook computer be used to connect headphones
- The statistics of leetcode simple question is the public string that has appeared once
- poj 3237 Tree(樹鏈拆分)
- What about data leakage? " Watson k'7 moves to eliminate security threats
- Blocking of concurrency control
- NET中小型企业项目开发框架系列(一个)
- Poj3414 extensive search
- Leetcode simple question: find the nearest point with the same X or Y coordinate
猜你喜欢

Business learning of mall commodity module

Business learning of mall order module

Daily question brushing record (XIV)

Summary of concurrency control

What changes has Web3 brought to the Internet?

【愚公系列】2022年7月 Go教学课程 004-Go代码注释

What if the files on the USB flash disk cannot be deleted? Win11 unable to delete U disk file solution tutorial

Learning of mall permission module

PyGame practical project: write Snake games with 300 lines of code

ICMP introduction
随机推荐
How can Bluetooth in notebook computer be used to connect headphones
Performance testing of software testing
Concurrency control of performance tuning methodology
Common interview questions of redis factory
Poj 3237 Tree (Tree Chain Split)
ICMP introduction
Search: Future Vision (moving sword)
The Blue Bridge Cup web application development simulation competition is open for the first time! Contestants fast forward!
How to add new fields to mongodb with code (all)
Evolution of large website architecture and knowledge system
Three "factions" in the metauniverse
Storage optimization of performance tuning methodology
How to organize an actual attack and defense drill
Regular expressions and re Libraries
Sub total of Pico development
Matlab draws a cute fat doll
What if the files on the USB flash disk cannot be deleted? Win11 unable to delete U disk file solution tutorial
Wonderful review of the digital Expo | highlight scientific research strength, and Zhongchuang computing power won the digital influence enterprise award
Understand the basic concept of datastore in Android kotlin and why SharedPreferences should be stopped in Android
AD637使用筆記