基于STM32103移植FreeRTOS
目录
一、FreeRTOS协议栈下载
二、准备工程文件与协议代码
三、移植FreeRTOS协议栈
一、FreeRTOS协议栈下载
1、官网下载
FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions
https://www.freertos.org/zh-cn-cmn-s/

2、网盘下载(访问密码:1666)
二、准备工程文件与协议代码


三、移植FreeRTOS协议栈
(FreeRTOS协议栈内容请自行百度,此处只是应用)
1、将\FreeRTOSv202212.00\FreeRTOS\Source内协议代码均复制到工程文件内新建文件夹“FreeRTOS”中

2、根据需求,删除 FreeRTOS\portable 内多余文件(也可不删,只为了精简工程文件的大小),最后保留文件如下

- Keil:基于Keil使用的底层接口文件,指向RVDS
- MemMang:内存管理选择
- RVDS:底层接口文件需要实际修改的文件
- readme:内核的基本介绍
3、在工程内添加协议栈

核心文件:
来源于 FreeRTOSv202212.00\FreeRTOS\Source 的C文件
底层接口:
- port:来源于 FreeRTOSv202212.00\FreeRTOS\Source\portable\RVDS\ARM_CM3
- heap_4:来源于 FreeRTOSv202212.00\FreeRTOS\Source\portable\MemMang
4、编译
报错:缺失文件 "FreeRTOSConfig.h"

5、补充文件
从例程中直接复制 "FreeRTOSConfig.h" 使用

6、重复编译
编译通过,移植完成。

四、示例演示
1、要实际使用FreeRTOS,需要提供滴答计时器作为OS系统刷新中断
#include "HW_SysTick_Interrupt.h"
#include "stm32f10x.h"
#include "FreeRTOS.h" //os 使用
#include "task.h"extern void xPortSysTickHandler(void);static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数/* 功 能: 滴答定时器 - 初始化* 输 入: * 输 出: * 返 回:* 备 注: 此处启用中断版本,故默认使用 1/1000 = 1ms 中断*/
void HW_SysTick_Interrupt_Init(void)
{ u32 reload;SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择外部时钟 HCLK/8fac_us=SystemCoreClock/1000000; //为系统时钟的1/8 reload=SystemCoreClock/1000000; //每秒钟的计数次数 单位为K reload*=1000000/configTICK_RATE_HZ; //根据delay_ostickspersec设定溢出时间//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 fac_ms=1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK }///* 功 能: 滴答定时 - 中断
// * 输 入:
// * 输 出:
// * 返 回:
// * 备 注: OS初始化中断1000Hz
// */
//void HW_SysTick_Interrupt_Handler(void)
//{
// if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
// {
// xPortSysTickHandler();
// }
//}/* 功 能: 延时nus* 输 入: * 输 出: * 返 回:* 备 注: */
void delay_us(u32 nus)
{ u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD; //LOAD的值 ticks=nus*fac_us; //需要的节拍数 told=SysTick->VAL; //刚进入时的计数器值while(1){tnow=SysTick->VAL; if(tnow!=told){ if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.else tcnt+=reload-tnow+told; told=tnow;if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出.} };
}/* 功 能: 延时nms* 输 入: * 输 出: * 返 回:* 备 注: */
void delay_ms(u16 nms)
{ if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度) { if(nms>=fac_ms) //延时的时间大于OS的最少时间周期 { vTaskDelay(nms/fac_ms); //OS延时}nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时 }delay_us((u32)(nms*1000)); //普通方式延时
}/* 功 能: 延时nms* 输 入: * 输 出: * 返 回:* 备 注: 此处启用中断版本,故默认使用 1/1000 = 1ms 中断*/
void delay_xms(u32 nms)
{u32 i;for(i = 0;i < nms;i++)delay_us(1000);
}
编译报警

需要开启(置一)

再次编译正常

2、main函数中创建开始任务 start_task

3、开始任务(start_task)中创建其他任务

4、执行其他任务

5、设置头文件,以及配置好任务参数后,编译通过。

6、实际运行后,在 vTaskStartScheduler (开启任务调度) -> xPortStartScheduler (开启时钟) -> prvStartFirstTask (开启第一个任务) 中跳到 HardFault_Handler(硬件错误)


7、排查错误
为中断异常导致的,FreeRTOS 使用的中断如下,需要修改中断

8、修改中断方法
①、修改启动文件,直接映射到port文件中

②宏定义

需要删除 stm32f10x_it 中的中断入口,避免二定义


9、编译运行后,预期正常

项目代码(访问密码:1666)
相关文章:
基于STM32103移植FreeRTOS
目录 一、FreeRTOS协议栈下载 二、准备工程文件与协议代码 三、移植FreeRTOS协议栈 一、FreeRTOS协议栈下载 1、官网下载 FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensionshttps://www.freertos.or…...
docker compose一键部署lnmt环境
创建docker compose 目录 [rootlocalhost ~]# mkdir -p /compose_lnmt 编写nginx的dockerfile文件 创建目录 [rootlocalhost compose_lnmt]# mkdir -p nginx 编写nginx配置文件 [rootlocalhost nginx]# vim nginx.conf user root; #运行身份#nginx自动设置进程…...
Eeny Meeny Moo
Eeny Meeny Moo 题目描述输入输出格式输入格式输出格式 输入输出样例输入样例输出样例 正确解法A C 代码 题目描述 你肯定有过这样的经验,那就是当很多一起使用网络的时候,网速变得很慢很慢。为了解决这个问题,德国的Ulm大学开发了一份意外事…...
flask---闪现/请求扩展/g对象
闪现 # 一个请求---》假设出错了---》重定向到另一个地址---》把错误信息在另一个返回中看到 错误信息放个位置----》另一个请求过来,去那个位置拿 # 把一些数据,放在某个位置---》后期可以去取出来----》取完不用删除,就没了 def index():s…...
Qt视频播放器
一、设置好ui界面二、打开文件槽函数1.QDir::homePath()作用介绍2.QFileDialog::getOpenFileName()介绍3.QFileInfo介绍4.player 指针解释5.打开文件槽函数完整代码 三、视频播放器初始化1.QMediaPlayer()函数2.设置时间间隔的作用3. QGraphicsScene介绍4.QGraphicsVideoItem介…...
Stable Diffusion教程(8) - X/Y/Z 图表使用
1. 介绍 这项功能可以在 文生图/图生图 界面的左下角种 “脚本” 一栏内选择 “X/Y/Z 图表” 以启用。 它创建具有不同参数的图像网格。使用 X 类型和 Y 类型字段选择应由行和列共享的参数,并将这些参数以逗号分隔输入 X 值 / Y 值字段。支持整数、浮点数和范围。…...
Android 获取网关 ip 和 DNS ip
参考下方 PingUtil.java 代码 import android.content.Context; import android.net.DhcpInfo; import android.net.wifi.WifiManager; import android.text.format.Formatter;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; impor…...
Docker root用户的pip使用方法
Docker下root用户 pip install XX 显示pip命令不存在 # 原始目标:pip install XX pip install --root-user-actionignore 【XX】# (要安装的包)参考:WARNING: Running pip as the ‘root‘ user can result in broken permissions Linux 中 root 与 su…...
企业新片场排名如何优化
企业新片场排名如何优化 要如何去做关键SEO?第一个我们要做的就是做好 SEO 关键词的选词,一般就是会有第一个常用的选词方法,第一是以常用的提问词去做,不实像是情人节买什么礼物,母亲节买什么礼物, 618 有…...
Database Name
概述 DB_NAME与INSTANCE_NAME DB_NAME 数据库名称,也就是数据库的名字标示。这里,数据库里可能有多个实例,比如RAC里的多节点,这多个节点是不同的实例,但是却有相同的名字,他们的 DB_NAME是相同的…...
git代码版本管理
git 文章目录 git基本使用 基本使用 在一台新的电脑上使用git 你要下载安装git, 然后把git的安装路径配到系统环境变量里 然后把这台电脑的.ssh/ id_rsa.pub里的公钥整到github里 然后在github上新建仓库,它会生成一些指令引导上你传本地的代码 之后就可以在终…...
k8s概念-ConfigMap
回到目录 一般用于去存储 Pod 中应用所需的一些配置信息,或者环境变量,将配置于 Pod 分开,避免应为修改配置导致还需要重新构建 镜像与容器。 1 创建ConfigMap #使用 kubectl create configmap -h 查看示例,构建 configmap 对象…...
Mybatis 实体类属性名和表中字段名不一致怎么处理
一. 前言 最近耀哥有学生出去面试,被问到 “Mybatis实体类的属性名和表中的字段名不一致该怎么处理?”,这其实是一个很经典的面试题,接下来耀哥就为大家详细解析一下这道面试题。 二. 分析 2.1 实体类和字段名不一致所带来的后果…...
CAS - 从AtomicInteger窥探CAS
Unsafe类是CAS的核心,由于Java方法无法直接访问底层,需要通过本地方法(native)来实现,Unsafe类相当于一个桥梁。基于Unsafe类,可以直接操作特定的内存数据。 我们从上一篇说CAS基本原理的时候,有说到一个“资源”被100…...
micro-ros IMU ML 代码
示例代码: #include <micro_ros_arduino.h>#include "LSM6DSOXSensor.h" #include "lsm6dsox_activity_recognition_for_mobile.h"#include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #inclu…...
二十三种设计模式第二十四篇--访问者模式(完结撒花)
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。 通过这种方式,元素的执行算法可以随着访问者改变而改变。 这种类型的设计模式属于行为型模式。根据模式,元素对象已接…...
月报总结|Moonbeam 7月份大事一览
炎炎夏日,Moonbeam于越南举办了线下交流会,在EthCC 2023和以太坊社区成员共同讨论多链应用,在Polkadot Decoded中分享了Moonbeam的与众不同之处。 Bear Necessities Hackathon也于本月圆满结束,选出了每个赛道最杰出的项目&#…...
【2023.8】docker一键部署wvp-GB28181-pro和ZLMediaKit过程全记录
安装docker 使用的操作系统是ubuntu20.04 如何在 Ubuntu 20.04 上安装和使用 Docker https://developer.aliyun.com/article/762674 docker拉取配置好的ZLMediaKIt和wvp-GB28181-pro docker pull 648540858/wvp_pro第一次运行 docker一键运行ZLMediaKIt和wvp-GB28181-pro …...
【2023】字节跳动 10 日心动计划——第四关
目录 1. 买卖股票的最佳时机2. 打家劫舍 II 1. 买卖股票的最佳时机 🔗 原题链接:121. 买卖股票的最佳时机 假设在第 i i i 天卖出股票可获得最大利润,那么买入股票必然是在前 i − 1 i-1 i−1 天中的某一天。更进一步,买入股票应…...
数据库与数据仓库的区别及关系
数据库与数据仓库的区别及关系 数据库数据仓库异同差异联系例子 数据库 数据库是结构化信息或数据的有序集合,一般以电子形式存储在计算机系统中。通常由数据库管理系统 (DBMS) 来控制。它是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集…...
tao-8k嵌入模型惊艳体验:Xinference WebUI界面操作,效果一目了然
tao-8k嵌入模型惊艳体验:Xinference WebUI界面操作,效果一目了然 1. tao-8k模型核心能力展示 tao-8k是由Hugging Face开发者amu研发的开源文本嵌入模型,专注于将文本转换为高维向量表示。这款模型最引人注目的特点是支持长达8192个token的上…...
云原生环境中的大数据处理架构
云原生环境中的大数据处理架构 🔥 硬核开场 各位技术老铁,今天咱们聊聊云原生环境中的大数据处理架构。别跟我扯那些理论,直接上干货!在大数据时代,如何高效处理和分析海量数据成为了一个挑战。不搞云原生大数据处理&a…...
Pixel Mind Decoder 创意应用展示:AI 驱动的情感化故事生成器
Pixel Mind Decoder 创意应用展示:AI 驱动的情感化故事生成器 1. 当AI学会感知情绪 你有没有想过,一个故事生成器不仅能理解文字,还能感知情绪?这就是我们最新开发的"情感化故事生成器"的核心能力。通过结合Pixel Min…...
RetinaFace在合影场景中的应用:多人脸检测与关键点绘制实战
RetinaFace在合影场景中的应用:多人脸检测与关键点绘制实战 1. 合影场景中的人脸检测挑战 在合影场景中,人脸检测面临着诸多独特挑战: 密集人脸:多人聚集导致人脸间距小,容易造成检测框重叠或漏检尺度差异ÿ…...
本地化部署MT5:无需联网,保障敏感数据隐私的文本处理方案
本地化部署MT5:无需联网,保障敏感数据隐私的文本处理方案 1. 为什么选择本地化部署的文本处理方案 1.1 数据隐私保护的刚性需求 在当今数据驱动的商业环境中,企业面临着越来越严格的数据合规要求。许多行业如金融、医疗、法律等࿰…...
Open Interpreter多场景落地:浏览器操控与媒体处理实操手册
Open Interpreter多场景落地:浏览器操控与媒体处理实操手册 1. 开篇:为什么你需要Open Interpreter? 你是不是经常遇到这样的情况:想要批量处理一些文件,但不想写复杂的脚本;或者需要从网站抓取数据&…...
前端面试题(九九八十一难)
⼀、JavaScript核⼼原理1.computed与watch监听变化的原理核⼼:均依赖Vue响应式系统(Proxy/Object.defifineProperty)。 -computed:⾃动收集内部依赖的响应式数据,依赖变化⾃动重新计算,有缓存。 -watch&…...
Idiap研究院:让语音识别AI学会聆听对话历史,压缩音频记忆
语音识别技术在我们的生活中越来越常见,从手机语音助手到客服电话,从会议记录到智能搜索。但你有没有想过,为什么这些系统有时候会犯一些很明显的错误?比如当你在和语音助手对话时,明明在前一句话中提到了"张三&q…...
方差的数学意义
方差(Variance)是统计学中一个非常基础且核心的概念。简单来说,它的数学意义就是衡量一组数据的离散程度,或者叫波动性。 如果说“平均值”(均值)告诉我们数据的中心在哪里,那么“方差”告诉我们…...
LeetCode hot100-114 二叉树展开为链表
class Solution { public:void flatten(TreeNode* root) {if (root nullptr) return;// 先展开左右子树flatten(root->left);flatten(root->right);// 保存右子树TreeNode* right root->right;// 将左子树移到右边root->right root->left;root->left nul…...
