当前位置:网站首页>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;
}
边栏推荐
- MySQL服务莫名宕机的解决方案
- EBS Oracle 11g cloning steps (single node)
- 华为云ModelArts文本分类–外卖评论
- The solution to the problem that Oracle hugepages are not used, causing the server to be too laggy
- Multiplexing of Oracle control files
- Performance testing of software testing
- Image editor for their AutoLayout environment
- The statistics of leetcode simple question is the public string that has appeared once
- Text组件新增内容通过tag_config设置前景色、背景色
- How to develop and introduce applet plug-ins
猜你喜欢
What if win11 is missing a DLL file? Win11 system cannot find DLL file repair method
Installation of VMware Workstation
The simple problem of leetcode is to split a string into several groups of length K
Business learning of mall commodity module
The American Championship is about to start. Are you ready?
Pl/sql basic case
Getting started with microservices (resttemplate, Eureka, Nacos, feign, gateway)
How to view Apache log4j 2 remote code execution vulnerability?
K210学习笔记(四) K210同时运行多个模型
Performance monitoring of database tuning solutions
随机推荐
元宇宙中的三大“派系”
Oracle is sorted by creation time. If the creation time is empty, the record is placed last
Evolution of large website architecture and knowledge system
Wonderful review of the digital Expo | highlight scientific research strength, and Zhongchuang computing power won the digital influence enterprise award
科技云报道荣膺全球云计算大会“云鼎奖”2013-2022十周年特别贡献奖
What about data leakage? " Watson k'7 moves to eliminate security threats
Did you brush the real title of the blue bridge cup over the years? Come here and teach you to counter attack!
Codeforces 12D ball tree array simulation 3 sorting elements
Meituan dynamic thread pool practice ideas, open source
Decorator learning 01
Three "factions" in the metauniverse
How to organize an actual attack and defense drill
【愚公系列】2022年7月 Go教学课程 004-Go代码注释
让开发效率提升的跨端方案
Recovery technology with checkpoints
How to develop and introduce applet plug-ins
微服务链路风险分析
Matlab draws a cute fat doll
Concurrency control of performance tuning methodology
Ad637 notes d'utilisation