当前位置: 首页 > news >正文

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定时器时钟,用八位数码管进行显示,但是定时器时钟的精度较低&#xff0…...

启元世界(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下不同端口的连接&#xff…...

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)…...

使用 Docker + Nginx + Certbot 实现自动化管理 SSL 证书

使用 Docker Nginx Certbot 实现自动化管理 SSL 证书 在互联网安全环境日益重要的今天,为站点或应用部署 HTTPS 已经成为一种常态。然而,手动申请并续期证书既繁琐又容易出错。本文将以 Nginx Certbot 为示例,基于 Docker 容器来搭建一个…...

粒子群算法 笔记 数学建模

引入: 如何找到全局最大值:如果只是贪心的话,容易被局部最大解锁定 方法有:盲目搜索,启发式搜索 盲目搜索:枚举法和蒙特卡洛模拟,但是样例太多花费巨量时间 所以启发式算法就来了,通过经验和规…...

【C语言】结构体与共用体深入解析

在C语言中,结构体(struct)和共用体(union)都是用来存储不同类型数据的复合数据类型,它们在程序设计中具有重要的作用。 推荐阅读:操作符详细解说,让你的编程技能更上一层楼 1. 结构体…...

es6.7.1分词器ik插件安装-和head插件连接es特殊配置

es6.7.1分词器ik插件安装-和head插件连接es特殊配置 如果对运维课程感兴趣,可以在b站上、A站或csdn上搜索我的账号: 运维实战课程,可以关注我,学习更多免费的运维实战技术视频 1.查看es6.7.1和es-head安装位置和es插件路径 [ro…...

java求职学习day18

常用的设计原则和设计模式 1 常用的设计原则(记住) 1.1 软件开发的流程 需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级 1.2 常用的设计原则 (1)开闭原则(Open Close Principle…...

单链表专题(上)

链表的定义与创建 线性表: 1. 物理结构上不一定是线性的 2. 逻辑结构上一定是线性的 链表是一种物理存储结构上非连续,非顺序的存储结构 链表也是线性表的一种,但是在物理结构上不是连续的 链表是由一个一个的节点组成,需要数…...

【stm32学习】STM32F103相关特性

| 名称 | 缩写 | 频率 | 外部连接 | 功能 | 用途 | 特性 | |--------------------|------|----------------|---------------|------------|--------------|----------------| | 外部高速晶体振荡器 | HSE | 4~16MHz …...

PostGIS笔记:PostgreSQL中表、键和索引的基础操作

创建、查看与删除表 在数据库中创建一个表,使用如下代码: create table streets (id serial not null primary key, name varchar(50));这里的表名是streets,id是主键所以非空,采用serial数据类型,这个数据类型会自动…...

蓝桥杯python语言基础(3)——循环结构

一、for语句 理解range函数 range(start, stop, step) start: 序列开始的数字(默认为0)。stop: 序列结束的数字(不包含stop)。step: 步长(默认为1)。 练习 输出在 l 和 r 之间的所有偶数: pri…...

微服务网关鉴权之sa-token

目录 前言 项目描述 使用技术 项目结构 要点 实现 前期准备 依赖准备 统一依赖版本 模块依赖 配置文件准备 登录准备 网关配置token解析拦截器 网关集成sa-token 配置sa-token接口鉴权 配置satoken权限、角色获取 通用模块配置用户拦截器 api模块配置feign…...