STM32完全学习——RT-thread在STM32F407上移植
一、写在前面
关于源码的下载,以及在KEIL工程里面添加操作系统的源代码,这里就不再赘述了。需要注意的是RT-thread默认里面是会使用串口的,因此需要额外的进行串口的初始化,有些人可能会问,为什么不直接使用CubMAX直接进行系统的移植,经过我的尝试发现,这个玩意移植的RT-thread会有一些小的bug,比如直接生成的代码FinSH工作不正常,修改方法和第七节一样。虽然整个系统的调度啥的都是正常的。因此我决定另辟蹊径,其他的功能使用CubMAX进行设置,因为他简直太方便了,然后RT-thread的移植采用手动的方法进行。
二、移植前的准备工作

因为RT-thread的源码里面有这些中断处理函数的实现,因此需要将上面的这些都关闭掉,不然编译会出现重复定义的错误。

我这里使用的是串口1,因此先完成他的相关设置。
三、将RT-thread的源码添加到工程里面

都添加进行以后,然后不要忘了设置头文件的包含路径。
四、进行第一次的编译

会发现错误很多,不慌。透过查看错误发现是因为va_list没有定义引起的,我们知道va_list是定义在stdarg.h里面的,然后通过观察头文件的包含发现,这个头文件在下面这个文件里面定义着,显然是因为RT_USING_LIBC这个宏,没有打开导致的。在rtconfig.h里面添加这个宏定义即可。

五、进行第二次编译
我们发现编译很成功,没有错误也没有警告,这时你可能已经觉得成功了,我只能说我当时也是这么想的,结果发现程序运行那是,相当的不正常。需要解决这个问题我们得知道RT-thread启动的流程,其实你只需要知道他在运行我们的main函数之前,会运行一段自己的代码,

然后我们进入这个函数发现,这里是关于系统的初始化,有很多。

接下来我们进入第一个初始化函数里面。将串口的初始化放在这里,注意需要包含相关的头文件。有了串口我们就可以使用printf函数来进行调试了。

当我们进入到第二个初始化函数里面我们发现,这里有一些输出,但是要想使用这些输出我们需要实现void rt_hw_console_output(const char *str)这个函数,在board.c里面其实已经有关于这个函数的实现,他是用RT_USING_CONSOLE这个宏来进行控制的,因此需要在trconfig.h里面打开这个宏

你会发现串口里面还是没有我们想要的输出,通过观察发现虽然我们自己将串口进行了初始化,但是系统这里使用的是串口2,因此需要将他改成你初始化的那个串口,我这里改成串口1。

到这里我们的串口就能正常工作了。下面这个是串口的输出。

到这里如果你创建一个任务,然后你会神奇的发现这个任务好像并没有执行,也就是说我们的系统并没有完全初始化成功。因为在RT-thread里面创建任务的时候有两种分配内存的方式,第一种就是静态分配,第二种就是动态分配。RT-thread默认使用的是动态分配,我想会不会是这里的问题,我就将关于动态分配的相关配置注释掉了。到这里整个系统就算是初始化完毕,也正常运行起来了。需要注意的是我们这里所有的内存分配都是静态的,因此创建变量的时候一定要分配它的大小,不然会有很奇怪的问题。

六、使用静态方式创建任务
static struct rt_thread led1_thread;
/* 线程主体函数 */
static void led1_thread_entry(void* parameter);
/* 定义线程栈 */
static rt_uint8_t rt_led1_thread_stack[1024];static struct rt_thread led0_thread;
/* 线程主体函数 */
static void led0_thread_entry(void* parameter);
/* 定义线程栈 */
static rt_uint8_t rt_led0_thread_stack[1024];int main(void)
{MX_GPIO_Init();/* USER CODE BEGIN 2 */rt_thread_init(&led1_thread, /* 线程控制块 */"led1", /* 线程名字 */led1_thread_entry, /* 线程入口函数 */RT_NULL, /* 线程入口函数参数 */&rt_led1_thread_stack[0], /* 线程栈起始地址 */sizeof(rt_led1_thread_stack), /* 线程栈大小 */3, /* 线程的优先级 */20); /* 线程时间片 */rt_thread_init(&led0_thread, /* 线程控制块 */"led0", /* 线程名字 */led0_thread_entry, /* 线程入口函数 */RT_NULL, /* 线程入口函数参数 */&rt_led0_thread_stack[0], /* 线程栈起始地址 */sizeof(rt_led0_thread_stack), /* 线程栈大小 */4, /* 线程的优先级 */20); /* 线程时间片 */rt_thread_startup(&led1_thread);rt_thread_startup(&led0_thread); while (1){}}//LED1线程
static void led1_thread_entry(void* parameter)
{ while(1){LED1 = 0;rt_thread_delay(200); /* 延时200个tick */rt_kprintf("led1_thread running,LED1_ON\r\n");LED1 = 1; rt_thread_delay(500); /* 延时500个tick */rt_kprintf("led1_thread running,LED1_OFF\r\n");}
}static void led0_thread_entry(void* parameter)
{ while(1){LED0 = 0;rt_thread_delay(200); /* 延时200个tick */rt_kprintf("led0_thread running,LED0_ON\r\n");LED0 = 1; rt_thread_delay(500); /* 延时500个tick */rt_kprintf("led0_thread running,LED0_OFF\r\n");}
}
七、实现FinSH


这个头文件你可以通过CubMAX来生成,也可以在项目例程里面复制一个。然后运行有可能你的会运行成功,有可能并不会成功。失败的界面是这样的;

成功的界面是这样的

如果失败了,尝试调整下图的参数即可。

相关文章:
STM32完全学习——RT-thread在STM32F407上移植
一、写在前面 关于源码的下载,以及在KEIL工程里面添加操作系统的源代码,这里就不再赘述了。需要注意的是RT-thread默认里面是会使用串口的,因此需要额外的进行串口的初始化,有些人可能会问,为什么不直接使用CubMAX直接…...
基于51单片机和ESP8266(01S)、LCD1602、DS1302、独立按键的WiFi时钟
目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、延时2、定时器03、串口通信4、DS13025、LCD16026、独立按键 四、主函数总结 系列文章目录 前言 之前做了一个WiFi定时器时钟,用八位数码管进行显示,但是定时器时钟的精度较低࿰…...
启元世界(Inspir.ai)技术浅析(二):深度强化学习
深度强化学习(Deep Reinforcement Learning, DRL)是启元世界在人工智能领域的一项核心技术,广泛应用于游戏AI、智能决策等领域。 一、状态(State) 1.1 概念与作用 **状态(State)**是指智能体对环境的感知,是智能体进行决策的基础。在深度强化学习中,状态通常是一个高…...
LeetCode100之子集(78)--Java
1.问题描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例1 输入:nums [1,2,3]输出:[[],[1],[2],[1,2],[3],[1…...
React第二十五章(受控组件/非受控组件)
React 受控组件理解和应用 React 受控组件 受控组件一般是指表单元素,表单的数据由React的 State 管理,更新数据时,需要手动调用setState()方法,更新数据。因为React没有类似于Vue的v-model,所以需要自己实现绑定事件…...
使用 Confluent Cloud 的 Elasticsearch Connector 部署 Elastic Agent
作者:来自 Elastic Nima Rezainia Confluent Cloud 用户现在可以使用更新后的 Elasticsearch Sink Connector 与 Elastic Agent 和 Elastic Integrations 来实现完全托管且高度可扩展的数据提取架构。 Elastic 和 Confluent 是关键的技术合作伙伴,我们很…...
嵌入式知识点总结 Linux驱动 (三)-文件系统
针对于嵌入式软件杂乱的知识点总结起来,提供给读者学习复习对下述内容的强化。 目录 1.什么是文件系统? 2.根文件系统为什么这么重要?编辑 3.可执行映像文件通常由几部分构成,他们有什么特点? 1.什么是文件系统&a…...
【知识】可视化理解git中的cherry-pick、merge、rebase
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 这三个确实非常像,以至于对于初学者来说比较难理解。 总结对比 先给出对比: 特性git mergegit rebasegit cherry-pick功能合并…...
【deepseek】deepseek-r1本地部署-第二步:huggingface.co替换为hf-mirror.com国内镜像
一、背景 由于国际镜像国内无法直接访问,会导致搜索模型时加载失败,如下: 因此需将国际地址替换为国内镜像地址。 二、操作 1、使用vscode打开下载路径 2、全局地址替换 关键字 huggingface.co 替换为 hf-mirror.com 注意:务…...
新站如何快速获得搜索引擎收录?
本文来自:百万收录网 原文链接:https://www.baiwanshoulu.com/8.html 新站想要快速获得搜索引擎收录,需要采取一系列有针对性的策略。以下是一些具体的建议: 一、网站内容优化 高质量原创内容: 确保网站内容原创、…...
如何使用tushare pro获取股票数据——附爬虫代码以及tushare积分获取方式
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据 总结 一、Tushare 介绍 Tushare 是一个提供中国股市数据的API接口服务,它允许用户…...
解决vsocde ssh远程连接同一ip,不同端口情况下,无法区分的问题
一般服务器会通过镜像分身或者容器的方式,一个ip分出多个端口给多人使用,但如果碰到需要连接同一user,同一个ip,不同端口的情况,vscode就无法识别,如下图所示,vscode无法区分该ip下不同端口的连接ÿ…...
Elasticsearch 自定义分成器 拼音搜索 搜索自动补全 Java对接
介绍 通常用于将文档中的文本数据拆分成易于索引的词项(tokens)。有时,默认的分词器无法满足特定应用需求,这时就可以创建 自定义分词器 来实现定制化的文本分析。 自定义分词器组成 Char Filters(字符过滤器&#x…...
基于物联网设计的疫苗冷链物流监测系统
一、前言 1.1 项目开发背景 随着全球经济的发展和物流行业的不断创新,疫苗和生物制品的运输要求变得越来越高。尤其是疫苗的冷链物流,温度、湿度等环境因素的控制直接关系到疫苗的质量和效力,因此高效、可靠的冷链监控系统显得尤为重要。冷…...
RocketMQ消息是如何存储的?
大家好,我是锋哥。今天分享关于【RocketMQ消息是如何存储的?】面试题。希望对大家有帮助; RocketMQ消息是如何存储的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RocketMQ 使用了一个高性能、分布式的消息存储架构…...
Ubuntu 16.04安装Lua
个人博客地址:Ubuntu 16.04安装Lua | 一张假钞的真实世界 在Linux系统上使用以下命令编译安装Lua: curl -R -O http://www.lua.org/ftp/lua-5.3.3.tar.gz tar zxf lua-5.3.3.tar.gz cd lua-5.3.3 make linux test 安装make 编译过程如果提示以下信息…...
【JavaSE】String类常用字符串方法总结
目录 1. length() 求字符串长度 2. isEmpty() 判断字符串是否为空 3. String对象的比较 3.1 equals() 判断字符串是否相同 3.2 compareTo() 比较字符串大小 3.3 compareToIgnoreCase 忽略大小写比较 4. 字符串查找 4.1 charAt() 返回指定索引处的字符 4.2 indexOf() 4…...
python3+TensorFlow 2.x(二) 回归模型
目录 回归算法 1、线性回归 (Linear Regression) 一元线性回归举例 2、非线性回归 3、回归分类 回归算法 回归算法用于预测连续的数值输出。回归分析的目标是建立一个模型,以便根据输入特征预测目标变量,在使用 TensorFlow 2.x 实现线性回归模型时&…...
机器人抓取与操作概述(深蓝)——1
工业机器人:① “臂”的形态 ② “手”的形态 ③ 视觉,力和触觉 1 机器人的不同形态 “臂”的形态 “手”的形态 2 常见的操作任务 操作:插入、推和滑 抓取:两指(平行夹爪)抓取、灵巧手抓取 落地-产…...
简单聊聊“DeepSeek”
目录 DeepSeek一夜火爆并受到广泛关注的优势 技术实力与创新 低成本与高效率 开源与免费 市场策略与应用领域 团队与资金优势 行业认可与媒体关注 DeepSeek在推理效率上的特别之处 多头潜在注意力(MLA) 多词元预测(MTP)…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
