使用C++开发STM32 FreeRTOS工程与添加DSP库

2023-05-16

  续上一篇文章的内容。由CubeMX构建的Makefile工程只支持C和汇编的编译,而且FreeRTOS的代码也需要作为C代码编译。
  当我们想使用C++时,需要做一些准备并且修改Makefile;另外本文补充了一下DSP库的调用方式。参考了另外两位博主的文章:

  • STM32 DSP库的快速添加 基于cubemx 调用,使用DSP库
  • C++开发STM32 Makefile工程

FreeRTOS与C++

  FreeRTOS的代码是必须作为C语言编译的。C++可以调用C函数,而且也可以在C++的源文件里写C函数。但是C的源文件里不能调用C++相关的东西,比如在C源文件里创建一个类的对象是不行的。
  所以我觉得最好的做法是把任务的定义放到自己的C++源文件中,而在FreeRTOS的C文件中用“extern”声明任务函数。
在这里插入图片描述
  具体做法就是在用CubeMX创建Task的时候,把任务的函数都设置成external。这里的默认选项是既有声明又有实现;exteral选项就是只有一个带extern的任务函数声明;还有一个weak选项表示这个任务函数有一个默认的实现,但可以被外部的定义覆盖,类似于C++中的虚函数的重新定义。
  我一般会把CubeMX工程中的下面的设置勾上。这样不同的外设就会有一个单独的.c和.h文件。
在这里插入图片描述
  然后就可以自己创建一个C++源文件来定义这几个任务函数。
在这里插入图片描述
  任务函数的声明需要放在 extern “C” {} 中,然后就可以在任务函数中创建类的对象,调用成员函数等。
  就像下面这个形式,可以把一堆任务函数的声明都放在一个 extern “C” {} 中,后面逐个对这些任务函数进行定义。

extern "C"
{
void BlinkTskFxn(void *argument);
...
}

...

void BlinkTskFxn(void *argument)
{
    for(;;){
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
        osDelay(500);
    }
}

修改Makefile

  Makefile的修改可以参考前面提到的另一篇博文。总得来说就是新增了一套编译C++源文件的规则。

CXX_SOURCES = \
...

ifdef GCC_PATH
CXX = $(GCC_PATH)/$(PREFIX)g++
...
else
CXX = $(PREFIX)g++
...
endif

CXXFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -std=c++11

CXXFLAGS += -g -gdwarf-2

CXXFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"

LDFLAGS = $(MCU) -specs=nano.specs -specs=nosys.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections 

OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CXX_SOURCES:.cpp=.o)))
vpath %.cpp $(sort $(dir $(CXX_SOURCES)))

$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR)
    $(CXX) -c $(CXXFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cpp=.lst)) $< -o $@

  这里的CXX_SOURCES用于列出需要编译的C++源文件;CXX表示编译器,CXXFLAGS中包含编译选项,其中沿用的C_DEFS和C_INCLUDES,这表示即使把编译器改成g++,之前gcc用的define和include路径还是相同的。
  LDFLAGS是link的选项,其中相比于之前的LDFLAGS新增了-specs=nosys.specs,这是必不可少的,如果没有的话编译就会报错,具体做了什么我没太搞明白。-specs=nano.specs表示采用精简后的C库,这个有无不会对编译是否能通过不会有影响。
在这里插入图片描述
  为了便于调试,也需要在工程的属性中为C++添加include和symbol(如果之前没有添加的话),这样就不会有那种报错的波浪线。
  在这里添加include路径和symbol的时候,有“Add to all languages”和“Add to all configurations”的选项可以勾选,这样对于一个条目就只需要添加一次就行了。不管是C还是C++,不管是Debug的配置还是Release的配置,就都能设置好,不需要再去逐个反复添加。(虽然对于Makefile工程来说没有直接的Debug和Release的区分,是否支持Debug,优化的等级都是直接改Makefile的)。

添加DSP库

  通过CubeMX添加DSP库真的非常快。参考前面提到的另一篇博文,在“Pinout & Configuration”界面点“Software Packs”选择组件。
在这里插入图片描述
  然后就可以安装DSP库并勾选它。
在这里插入图片描述
  这时候再回到CubeMX的工程就可以看到左边多了一栏Software Packs,选择它之后再把DSP Library勾选上,令当前的CubeMX工程支持DSP Library。
在这里插入图片描述
  通过这些配置生成的Makefile工程将另外生成DSP库的头文件和预编译好的lib文件,并放在Middlewares目录下。
在这里插入图片描述
  预编译好的lib文件有三种,开头的arm,iar,libarm应该是区分它们是在不同的环境下编译的。l后缀表示小端模式,f后缀表示使用FPU。
  我一开始尝试用arm_cortexM4lf_math.lib,编译会有warning,说这个库用的wchar_t类型是2字节的,而我们的工程中用的是4字节的,这不兼容。后来用iar_cortexM4lf_math.a就没有这个问题。
  关于DSP库的API,可以在官方文档里找到。如果是从源文件开始编译DSP库,还有一些宏定义可以设置,比如ARM_MATH_BIG_ENDIAN设置大端模式;ARM_MATH_MATRIX_CHECK设置输入输出矩阵的维度检查……但是像现在这样用已经编译好的库,这些宏定义是没用的。就像之前要从源码编译时,需要定义__FPU_PRESENT一样,现在即使不定义也没有关系,因为源码都已经编译完成了。
  用预先编译好的DSP库,就只需要include <arm_math.h>和定义ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML中的一种就好了。
在这里插入图片描述
  我再回过头来发现,即使不在CubeMX中添加DSP库,这些DSP库相关的文件随着CMSIS的device驱动一起就提供了。就在Drivers/CMSIS/Lib目录下。

# defines
-DARM_MATH_CM4

# includes
C_INCLUDES =  \
-IDrivers/CMSIS/DSP/Include

# libraries
LIBS = -lc -lm -lnosys  \
-l:iar_cortexM4lf_math.a
LIBDIR =  \
-LDrivers/CMSIS/Lib/IAR

  所以只需要在Makefile中增加器件相关的define和include相应的lib就行了,而不需要通过CubeMX额外导入DSP库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用C++开发STM32 FreeRTOS工程与添加DSP库 的相关文章

  • stm32学习之路---最小系统的介绍

    目标 xff1a stm32最小系统的了解 1 STM32最小系统组成 电源电路复位电路晶振电路下载电路 电源电路 xff1a DC IN1和POWER那是单片机的火牛接口它是5V的 xff0c 不能乱接不然会烧毁芯片 POWER1处是单片
  • 视频目标检测(video object detection)简单综述

    对目前看过的视频目标检测论文做一个简单的综述 xff0c 也欢迎大家补充一些其他遗漏掉的 xff0c 不错的视频目标检测论文 持续更新 github https github com breezelj video object detect
  • AAAI2021第一轮被拒经验分享

    AAAI第一轮悲剧了 俩5分 俩评委给的意见都挺中肯的 xff0c 主要还是创新性不过 xff0c 加基线算法比较不够 对实验结果解释不足 感觉他们对实验方法细节并没有很着重看 xff0c 更多的是宏观的评论 第一次投多少有点失望 xff0
  • C语言Sprintf用法

    如图 xff0c 两种简单用法 include lt iostream gt include lt stdio h gt 程序的主函数 int main char a 20 a 0 61 39 p 39 a 1 61 39 t 39 spr
  • UE4——打印函数

    输出当前类名 xff0c 注意是两个 GEngine gt AddOnScreenDebugMessage 0 30 f FColor Red FString FUNCTION 输出当前物体名 GEngine gt AddOnScreenD
  • vscode主题

    刚发现的 xff0c 代码效果比较好
  • VSCode 全局搜索正则排除不想显示的文件

    排除前 排除后 lst
  • 串口打印小数

    一般串口是打印一个8位字符 xff0c 或者打印一个数组 xff0c 如果要打印小数 xff0c 就要用到格式化输出 xff0c 把小数格式化输出到数组里面 u8 a 10 b 10 co2 61 1 001 tvoc 61 2 001 s
  • UE4——蓝图多重for循环

    1 示例 如下打印 xff0c 说明成功进行3次循环
  • C++链表

    上个简单链表 xff0c 写的有些难看 xff0c 现在更改一下 https liu endong blog csdn net article details 111934018 添加了删除尾结点 xff0c 添加了删除头结点 includ
  • 电路设计——发光二极管限流电阻

    0 序 最近在设计电路画板子了 xff0c 画完发现 xff0c 这电阻电容咋用啊我去 于是来学一下电阻和电容的使用 1 限流电阻作用 限流电阻主要是为了防止电流过大损坏器件 这里的限流其实还起到分压的作用 xff0c 比如我们单片机出来的
  • stm32cubeMX+FreeRTOS(4)—— main函数while循环

    0 发现 想在主函数中打印一下串口数据 xff0c 发现一直打印不出来 xff0c 试了下开关小灯 xff0c 发现没有进main函数的while循环 xff0c 阿西吧 xff0c 我大概要重新看一下CubeMX的rtos架构了 本来打算
  • Docker常见操作

    记录docker使用过程中的常用操作 1 xff0c 拉取镜像 docker pull image name image tag such as ubuntu 18 04 2 xff0c 列出所有镜像和容器 docker images do
  • stm32cubeMX+FreeRTOS(5)—— 串口打印

    0 序 cubeMX的FreeRtos和hal库的打印方式一样 本文基于CubeMX6 1 1版本编写 xff0c 此时CubeMX6 3 1已经无法使用此代码 xff08 2022 1 17 xff09 1 CubeMX配置串口 点一下串
  • HLK-B36 WIFI/BLE 二合一透传沙雕按键说明

    模块如下 沙雕说明如下 实际操作如下 恢复出厂设置 xff1a 插usb上电 xff0c 长按ES0 6秒以上 xff0c WIFI灯和STA灯同时灭掉然后亮起 xff0c STA开始闪烁 进入AT模式方式1 xff1a 插上USB xff
  • VScode下载安装及使用教程

    0 序 1 下载 官网下载速度特别慢 xff0c 需要用国内镜像 官网 xff1a Visual Studio Code Code Editing Redefined国内 点进去之后会过慢慢打开下载链接 xff0c 速度非常慢 跳转到这个界
  • 再探C语言链表—TypeDef Struct模式声明链表节点

    0 序 之前看到的网上的书上的都是Struct直接创建节点 我记得typedef struct是大学时候数据结构课本上用来声明链表结点的方法 xff0c 这个方法让人容易操作链表 后来书本扔了 xff0c 再买了盗版书不知道是版本问题还是什
  • STM32CubeMX(6)——Printf导致程序卡死

    0 序 换电脑 xff0c 新安装的cubemx 6 3 0 xff0c vs2019 xff0c minGW7 0 xff0c 不晓得什么原因 xff0c 可能是他们使用了安全函数printf s和scanf s xff0c 导致keil
  • 字符串链式队列入队出队

    include 34 queue h 34 include 34 stdio h 34 include 34 malloc h 34 64 brief 链式队列数据结构定义 typedef struct QueueStruct char v
  • AD21几个容易忘记的快捷键

    CTRL 43 D 打开透明模式 适合等长操作 CTRL 43 M 测量距离 SHIFT 43 R 推挤走线 D 43 K 打开层叠管理器 t 43 v 43 g 从板框选择铺铜 设置鼠标滑过显示高亮 取消自动闭合回路 xff0c 用于打多

随机推荐

  • C字符队列

    链式队列数据结构定义 typedef struct QueueStruct char value struct QueueStruct next queueStruct void QueueInit brief 链式队列初始化 void E
  • QT+OpenGL(1)——包含头文件

    关于智能提示建议放弃Cmake生成 xff0c 直接包含头文件 xff0c 包含方法如下 如果找不到头文件 xff0c 直接用everything搜相应文件 xff0c 再给包含进去 需要新建文件夹 xff0c 新建文件 c cpp pro
  • 2d激光雷达(rplidar_s1)与双目摄像头联合标定

    前段时间由于项目需要使用摄像头 xff08 realsense d435i xff09 与单线激光雷达进行融合 xff0c 于是就对这两个传感器进行了标定 xff0c 使用的是CamLaserCalibraTool xff0c 这是别人开源
  • ubuntu生成&设置core文件,调试段错误

    在用ubuntu系统编码c 43 43 程序时 xff0c 经常遇到段错误 xff0c 以下介绍ubuntu系统下如何生成core文件 xff0c 设置core文件路径 xff0c 并进行调试core文件 xff0c 找到段错误原因 1 允
  • ECharts仪表盘设置主题文字颜色

    设置仪表盘中显示字体样式 xff1a 方式如下 xff1a eChartA setOption tooltip formatter 34 a lt br gt b c 34 toolbox show true feature mark sh
  • 【LWC】Resource not found异常的一个可能原因

    Resource not found异常的一个可能原因 场景 在我当前项目中 xff0c 有一个用来创建记录的LWC组件 创建记录的流程大致为以下三步 xff1a 用户输入信息用户点击保存 xff0c 后台处理数据 xff0c 创建记录记录
  • 使用apt-get update命令卡在waiting for headers

    今天 xff0c 想在自己的debian系统里面装下java8 xff0c 添加了一个源update的时候出现的点问题就ctrl c了 没想到之后再update就不行了 一直卡在100 正在读报头waiting for headers 网上
  • 四轴飞行器基本组成及其飞行原理详解

    近日 xff0c 自己组装了一台 四轴飞行器 xff1b 组装完后 xff0c 便想深究其原理 xff1b 避免只是 知其然 xff0c 却不知其所以然 xff1b 查阅资料后 xff0c 便在其他文章的基础上 xff0c 将此文 归纳整理
  • ubuntu20.04分区方案 for deeplearning

    一共分出4个系统分区 1 设置efi引导 因为是u盘的uefi启动 xff0c 因此设置一个efi引导项 具体参数 xff1a 大小 500到1024mb即可 xff08 视自身的存储空间而定 xff09 新分区的类型 xff1a 逻辑分区
  • Linux重定向和管道符

    Linux重定向和管道符 1 Uid gid是什么 xff1f 2 linux中设置环境变量的几种方法3 管道命令符和通配符4 输入输出重定向 1 Uid gid是什么 xff1f 1 1 用户组 UID以及GID概念 用户组 xff1a
  • OpenFlow概念学习

    前言 OpenFlow交换机将原来完全由交换机 路由器控制的报文转发过程转化为由OpenFlow 交换机和控制服务器来共同完成 xff0c 目的交换机要通过of协议 xff08 OpenFlow Protocol xff09 经 安全通道
  • Ubuntu创建用户(组)与权限管理

    Ubuntu创建用户 xff08 组 xff09 与权限管理 创建用户与用户组创建和删除用户及用户组给用户配置sudo权限用户管理相关的命令 创建用户与用户组 在管理服务器时 xff0c 需要注意用户权限分配 xff0c 这样不会造成重大的
  • docker修改容器与宿主机端口映射

    1 查看容器id docker ps 2 进入容器安装目录 cd var lib docker containers 找到容器对应的文件夹 xff0c 容器id与文件夹前面的id是一样的 进入文件夹 cd 593f0dd680d77e901
  • Prometheus源码学习(1) 编译源码

    代码里面看不明白的变量或者函数可以通过两种方式观测它的值来了解其含义 一种是把代码片段摘出来 xff0c 写到一个测试程序里运行一下另一种时日志里打印它的值来观察 第一种比较简单易行 xff0c 但是代码片段要比较独立才好做 xff0c 第
  • ubuntu的命令&操作

    记录ubuntu系统使用中一些常用的操作 1 在ubuntu终端打开图像界面的文件夹 xff1a cd到指定的目录之后执行nautilus即可 参考 xff1a linux系统ubuntu中在命令行如何打开图形界面的文件夹 李照耀 博客园
  • Leetcode解题目录(Python版)

    Leetcode解题目录 xff08 Python版 xff09 题目目录1 排序算法2 哈希表3 动态规划 题目来源于LeetCode官网题库 xff0c 解题思路参考官网各大佬 xff0c 这里做一个目录方便大家查找 xff0c 另外方
  • error while loading shared libraries: libopencv_imgcorecs.so.3.4:: cannot open shared object file:

    ubuntu16 04的环境下 xff0c 编译成功C 43 43 代码 xff0c 同时也安装好了opencv3 4 在运行时却出现error xff1a error while loading shared libraries libo
  • 基于LQR的车辆LKA算法设计

    记录分享一下基于LQR控制算法的车辆LKA设计 通过carsim和simulink进行联合仿真 1控制算法设计 整体思路是通过车辆以及道路模型 得到控制器的输入 v 纵向速度 r 横摆角速度 y 侧向路径偏移 phi 横摆角误差 通过最优控
  • 软件框架

    1 概念 框架 xff08 framework xff09 是一个框子 指其约束性 xff0c 也是一个架子 指其支撑性 是一个基本概念上的结构 xff0c 用于去解决或者处理复杂的问题 框架这个广泛的定义使用的十分流行 xff0c 尤其在
  • 使用C++开发STM32 FreeRTOS工程与添加DSP库

    续上一篇文章的内容 由CubeMX构建的Makefile工程只支持C和汇编的编译 xff0c 而且FreeRTOS的代码也需要作为C代码编译 当我们想使用C 43 43 时 xff0c 需要做一些准备并且修改Makefile xff1b 另