PlatformIO: libopencm3 + FreeRTOS

以下步骤基于常见的 Bluepill STM32F103C8T6, 也适用于其它 libopencm3 支持的MCU型号

方案一: 只复制需要的文件

  1. 在 PlatformIO 中, Board 选择 Bluepill F103C8, Framework 选择 libopencm3, 创建项目
  2. 在项目的lib下新建目录 FreeRTOS
  3. 解压缩最新的 FreeRTOS
    1. 复制 FreeRTOS/Source/ 目录下, 除 portable 目录以外其它全部文件和目录, 至 lib/FreeRTOS 下
    2. 复制 FreeRTOS/Source/portable/GCC/ARM_CM3 目录下所有文件(port.c, portmacro.h), 至 lib/FreeRTOS 下
    3. 复制 FreeRTOS/Source/portable/Common 目录下所有文件(mpu_wrappers.c), 至 lib/FreeRTOS 下
    4. 复制 FreeRTOS/Source/portable/MemMang 目录下 heap_4.c, 至 lib/FreeRTOS 下
  4. 复制 FreeRTOSConfig.h, 至 lib/FreeRTOS/include 下
  5. 编写 src/main.c

完成后目录结构应当为

├── 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

方案二: 完整的FreeRTOS, 使用library.json

  1. 在 PlatformIO 中, Board 选择 Bluepill F103C8, Framework 选择 libopencm3, 创建项目
  2. 在项目的lib下新建目录 FreeRTOS
  3. 解压缩最新的 FreeRTOS
  4. 复制 FreeRTOS/Source/ 目录下所有文件至 lib/FreeRTOS 下
  5. 复制 FreeRTOS/Source/portable/GCC/ARM_CM3 目录下 portmacro.h 至 lib/FreeRTOS 下, 因为 library.json 还不支持多个 include 路径
  6. 复制 FreeRTOSConfig.h, 至 lib/FreeRTOS 下
  7. lib/FreeRTOS 下添加 library.json
  8. 编写 src/main.c

library.json 内容如下, 只包含需要的 c 文件

{
"name": "FreeRTOS",
"version": "10.4.6",
"build": {
"srcFilter": [
"+<*.c>",
"+<portable/GCC/ARM_CM3/port.c>",
"+<portable/MemMang/heap_4.c>"
]
}
}

如果是多核MCU, 需要再包含 mpu_wrappers.c, 对于 F103C8 就不需要了

"+<portable/Common/mpu_wrappers.c>",

完成后目录结构为

├── 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

示例代码

使用Queue的UART收发

/* Task based UART demo, using queued communication.
*
* TX: A9 ====> RX of TTL serial
* RX: A10 <==== TX of TTL serial (not used)
*/
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h> #include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h> static QueueHandle_t uart_txq; // TX queue for UART /*********************************************************************
* Configure and initialize USART1:
*********************************************************************/
static void
uart_setup(void) { rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_USART1); // UART TX on PA9 (GPIO_USART1_TX)
gpio_set_mode(GPIOA,
GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_USART1_TX); usart_set_baudrate(USART1,115200);
usart_set_databits(USART1,8);
usart_set_stopbits(USART1,USART_STOPBITS_1);
usart_set_mode(USART1,USART_MODE_TX);
usart_set_parity(USART1,USART_PARITY_NONE);
usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);
usart_enable(USART1); // Create a queue for data to transmit from UART
uart_txq = xQueueCreate(256,sizeof(char));
} /*********************************************************************
* 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);
}
} /*********************************************************************
* Queue a string of characters to be TX
*********************************************************************/
static void
uart_puts(const char *s) { for ( ; *s; ++s ) {
// blocks when queue is full
xQueueSend(uart_txq,s,portMAX_DELAY);
}
} /*********************************************************************
* 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 PB12,PC13:
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
gpio_set_mode(
GPIOC,
GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
GPIO13);
gpio_set_mode(
GPIOB,
GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
GPIO12);
// Turn LED off
gpio_set(GPIOB, GPIO12);
gpio_set(GPIOC, GPIO13); uart_setup(); xTaskCreate(uart_task,"UART",100,NULL,configMAX_PRIORITIES-1,NULL);
xTaskCreate(demo_task,"DEMO",100,NULL,configMAX_PRIORITIES-1,NULL); vTaskStartScheduler();
for (;;);
return 0;
}

PlatformIO 创建 libopencm3 + FreeRTOS 项目的更多相关文章

  1. 如果没有Visual Studio 2015,我们如何创建.NET Core项目 ?

    对于.NET开发人员来说,我们已经习惯了VS这个世界上最强大的IDE,所以对他们来说,项目的创建直接利用安装到VS中相应的项目模板即可.当.NET Core跨出了Windows的围栏,正式拥抱其他平台 ...

  2. eclipse 创建maven web项目

    参考:http://www.cnblogs.com/hongwz/p/5456616.html eclipse 创建maven web项目

  3. 《HiWind企业快速开发框架实战》(2)使用HiWind创建自己的项目

    <HiWind企业快速开发框架实战>(2)使用HiWind创建自己的项目 关于HiWind HiWind企业快速开发框架,是基于.NET+EasyUi(支持各种前端扩展,后面将扩展Boot ...

  4. 【Cocos2d-x for WP8 学习整理】(1)创建一个新项目

    喜大普奔                         10.1假期之前看到了一个很振奋的消息,就是随着Cocos2d-x 2.2的发布,WP8/WIN8有史以来第一次的合并到主版本了. 之前 V2 ...

  5. 快速创建一个springboot项目

    创建一个maven项目(springboot.mybatis-plus) 目标:可以访问ftl页面.对象(json字符串),可以进行单元测试 1.新建一个maven项目,选择模板maven-arche ...

  6. Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目

    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目 新建一个maven工程,这里不赘述如何新建maven工程. 添加Neo4j jar到你的工程 有两种方 ...

  7. eclipse创建maven web项目

    eclipse创建maven web项目: 1.安装eclipse maven插件 2.新建maven project选择webapp模板. 3.改造为maven文档结构. 4.添加项目的JAVAEE ...

  8. 创建Maven web项目时 出现 web.xml is missing and <failOnMissingWebXml> is set to true错误 pox.xml编译错误

    今天创建一个maven项目 pom.xml出现如下错误: web.xml is missing and <failOnMissingWebXml> is set to true 这是因为你 ...

  9. IDEA 创建Maven Web项目(图文版)

    前言:IDEA作为一款广泛使用的开发工具,无论是后台人员,还是前段工作者,都能在它上面发现它的魅力. IDEA提供了诸多项目模板,今天就以创建Maven Web项目作为示例,和大家一起分享: 第一步: ...

随机推荐

  1. getRequestDispatcher 中请求转发和请求包含的使用说明

    getRequestDispatcher() getRequestDispatcher() 包含两个方法,分别是请求转发和请求包含. RequestDispatcher rd = request.ge ...

  2. Selenium_使用Select类对象处理下拉框(15)

    select标签的下拉框可以使用selenium的 Select模拟下拉框选择操作. Select需要导入才能使用,导入路径如下 from selenium.webdriver.support.ui ...

  3. Selenium_按钮的点击、文本框的输入和清除操作(3)

    from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.get(" ...

  4. 安装devstack中遇到的一些问题整理

    1.执行stack.sh文件后提示 ./stack.sh:528:check_path_perm_sanity /opt/devstack/functions:582:die [ERROR] /opt ...

  5. Python操作数据库实战

    pymysql # -*- coding: utf-8 -*- """ @Datetime: 2018/12/26 @Author: Zhang Yafei " ...

  6. 【填坑往事】使用Rxjava2的distinct操作符处理自定义数据类型去重的问题

    最近碰到一个问题,自定义数据类型列表中出现了重复数据,需要去重.处理去重的办法很多,比如借助Set集合类,使用双重循环拿每一个元素和其他元素对比等.这里介绍一种简单而且比较优雅的方式:使用Rxjava ...

  7. 使用NSSM把任意exe程序注册成Windows服务

    1.登录NSSM官网下载最新版本: http://www.nssm.cc/download 2.解压之后可以看到win32和win64位的nssm.exe,根据自己的电脑选择使用 3.拷贝一份nssm ...

  8. Springboot+Druid 动态数据源配置监控

    一.引入maven依赖,使用 starter 与原生 druid 依赖配置有所不同 <dependency> <groupId>com.alibaba</groupId& ...

  9. Redis 事务支持 ACID 么?

    腾讯面试官:「数据库事务机制了解么?」 「内心独白:小意思,不就 ACID 嘛,转眼一想,我面试的可是技术专家,不会这么简单的问题吧」 程许远:「balabala-- 极其自信且从容淡定的说了一通.」 ...

  10. How to die?

    下次给一个 vector 搞 unique 之前,一定要记得给它排序!!1(少点自以为是) 对一个 set "同时"删除两个数时,一定要注意特判两个数是否重复/重叠. 有两个序列, ...