RTThread-Nano学习二-RT-Thread启动流程
一、简介
上一章,我们已经了解了如何通过MDK来移植RTT,不熟悉的可以看如下链接:RTThread-Nano学习一-基于MDK移植-CSDN博客本章我们就来继续了解一下,RTT的启动流程。
二、启动流程
官方给了一幅非常清晰的启动流程图,可以看下:

使用 MDK来开发的芯片,大部分都是从startip_XXX.s开始。

程序在这里开始启动,这里本来是要调用main函数的,但是RTT添加了$Sub$$main函数。该功能是MDK特有的,可以在main函数之前补充一些其他函数。最后通过$Super$$main来调用真正的main函数。
全局搜索一下$Sub$$main函数。

可以看到在components.c中找到了$Sub$$main。该函数调用了rtthread_startup。在进入看一下。

可以看到,这里面调用了一堆函数,这里用中文备注一下这些函数。
int rtthread_startup(void)
{/* 关闭系统中断 */rt_hw_interrupt_disable();/* 板级初始化:需在该函数内部进行系统堆的初始化 */rt_hw_board_init();/* 打印 RT-Thread 版本信息 */rt_show_version();/* 定时器初始化 */rt_system_timer_init();/* 调度器初始化 */rt_system_scheduler_init();/* 由此创建一个用户 main 线程 */rt_application_init();/* 定时器线程初始化 */rt_system_timer_thread_init();/* 空闲线程初始化 */rt_thread_idle_init();/* 启动调度器 */rt_system_scheduler_start();/* 不会执行至此 */return 0;
}
需要注意的是,很多文件是只读属性,开发者只能看,无法修改。只有board.c和rtconfig,h两个文件是可以修改的。

可以看到,在关闭中断后,首先运行的就是rt_hw_board_init()函数。这个函数是不是看着有点眼熟?没错,这个函数就是在移植系统是要操作的函数,在该函数中,必须要给系统提供底层节拍。

在看一下rt_application_init()函数。

该函数创建了main线程,但是没有运行。看一下这个main线程。

在这里,找到了$Super$$main函数。
那什么时候调用main线程呢?
再看rt_system_scheduler_start()函数。

这里之后,就跳转到我们自己的main函数中开始执行。
那总结一下, rtthread_startup()函数总体可以分为4个部分。
(1)初始化与系统相关的硬件。(rt_hw_board_init)
(2)初始化系统内核对象,例如定时器、调度器、信号量(rt_system_timer_init、rt_system_scheduler_init)
(3)创建main线程。(rt_application_init)
(4)初始化定时器线程、空闲线程,并启动调度器(rt_system_timer_thread_init、rt_thread_idle_init、rt_system_scheduler_start)。
注: 创建的线程在rt_thread_startup()执行后,并不会立马执行,他们会处于就绪状态等待系统调度,直到rt_system_scheduler_start调度器被调用后,才会开始执行。在启动调度器后,系统会转入第一个线程开始执行,根据调度规则,选择的是就绪队列中优先级最高的线程。
三、自动初始化机制
RTT提供了一种自动初始化机制,来满足用户在对外设初始化时的运行顺序的需求。
自动初始化机制是指初始化函数不需要被显性调用,只需要在函数定义处通过宏定义的方式进行申明,就会在系统启动过程中被执行。
该机制主要涉及以下宏定义
| INIT_BOARD_EXPORT(fn) | 非常早期的初始化,此时调度器还未启动 |
| INIT_PREV_EXPORT(fn) | 主要是用于纯软件的初始化、没有太多依赖的函数 |
| INIT_DEVICE_EXPORT(fn) | 外设驱动初始化相关,比如网卡设备 |
| INIT_COMPONENT_EXPORT(fn) | 组件初始化,比如文件系统或者 LWIP |
| INIT_ENV_EXPORT(fn) | 系统环境初始化,比如挂载文件系统 |
| INIT_APP_EXPORT(fn) | 应用初始化,比如 GUI 应用 |
那这些定义是在哪里执行呢?

执行位置对应如下:
| 宏定义 | 执行位置 |
| INIT_BOARD_EXPORT(fn) | board init functions |
| INIT_PREV_EXPORT(fn) | pre-initialization functions |
| INIT_DEVICE_EXPORT(fn) | device init functions |
| INIT_COMPONENT_EXPORT(fn) | components init functions |
| INIT_ENV_EXPORT(fn) | enviroment init functions |
| INIT_APP_EXPORT(fn) | application init functions |
这里以实际的例子来演示一下:

在rt_components_board_init()函数前后各加一行打印。main函数如下

打印结果:

可以看到,main函数在最后才调用,并且sys_init最后被调用。
接下来,使用INIT_BOARD_EXPORT函数,将sys_init的执行提前。


可以看到,sys_init已经出现在了rt_components_board_init中,与官方图对应。

可能会有人问,这么做的意义是什么?
上面已经介绍过了,最后执行main,实际上是创建了一个main任务,既然是任务,那就一定会有栈的分配,查看一下main任务的栈是多少。

![]()

可以看到,main线程的栈大小是256。
如果程序要初始化的东西不多,那确实可以把sys_init放在main任务中执行。但是如果系统初始化的东西很多,如果都放在main任务中执行,那么很有可能会造成main任务的栈溢出,导致整个程序崩溃。所以,如果要初始化的东西比较多,且种类很多的时候,就可以通过自动初始化的方式,来在不同的位置进行外设的初始化。
相关文章:
RTThread-Nano学习二-RT-Thread启动流程
一、简介 上一章,我们已经了解了如何通过MDK来移植RTT,不熟悉的可以看如下链接:RTThread-Nano学习一-基于MDK移植-CSDN博客本章我们就来继续了解一下,RTT的启动流程。 二、启动流程 官方给了一幅非常清晰的启动流程图&am…...
排查sshfs挂载失败的问题
#排查sshfs挂载失败的问题 写代码在Linux上运行,但是熟悉的IDE(比如VS code)在自己的电脑上,可以使用sshfs把linux上的目录挂载到本地,再用VScode打开即可,可以使用下面的命令: sshfs -odebug…...
【002】基于Spring Boot+Unipp的古诗词学习小程序【原创】
一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构:B/S架构 运行环境:win10/win11、jdk17 前端: 技术:框架Vue.js;UI库:ElementUI; 开发工具&…...
PageHelper循环依赖问题
1. 问题 2. 原因 项目中SpringBoot的版本为2.7.18。 SpringBoot2.6.x后不推荐使用循环依赖,也就是说从2.6.x版本开始,如果项目里还存在循环依赖,SpringBoot将拒绝启动! 3. 解决 去pageHelper github看,才看到新版本…...
k8s部署Kafka集群超详细讲解
准备部署环境 Kubernetes集群信息 NAMEVERSIONk8s-masterv1.29.2k8s-node01v1.29.2k8s-node02v1.29.2 Kafka:3.7.1版本,apche版本 Zookeeper:3.6.3版本 准备StorageClass # kubectl get sc NAME PROVISIONER RECLA…...
【数据采集工具】Sqoop从入门到面试学习总结
国科大学习生活(期末复习资料、课程大作业解析、大厂实习经验心得等): 文章专栏(点击跳转) 大数据开发学习文档(分布式文件系统的实现,大数据生态圈学习文档等): 文章专栏(点击跳转&…...
Matlab绘图总结(进阶)
本文在前文的基础上进一步整理画图方法 MATLAB画动图_CSDN博客 1. 基础图形绘制 1.1 rectangle(矩形,圆形) 在前文中,讲解了如何使用rectangle,rectangle本意是用来画矩形的,其中,Curvature可…...
QExcel 保存数据 (QtXlsxWriter库 编译)
QtXlsxWriter 是一个用于在 Qt 应用程序中创建和操作 Excel XLSX 文件的库。它提供了一个简单的 API,使开发者能够轻松地生成和修改 Excel 文件,而无需依赖 Microsoft Excel 或其他外部应用程序。支持初始化、写文件、读文件、格式设置、合并单元格、加粗…...
k8s ETCD数据备份与恢复
在 Kubernetes 集群中,etcd 是一个分布式键值存储,它保存着整个集群的状态,包括节点、Pod、ConfigMap、Secrets 等关键信息。因此,定期对 etcd 进行备份是非常重要的,特别是在集群发生故障或需要恢复数据的情况下。本文…...
【C语言】循环嵌套:乘法表
循环嵌套,外层循环执行一次,内层循环执行i次。分别控制 在循环的过程中加一层循环。 多层循环属于循环嵌套、嵌套循环 #include <stdio.h> #include <math.h> /* 功能:循环嵌套 乘法表 时间:2024年10月 地点…...
基于Java微信小程序的水果销售系统详细设计和实现(源码+lw+部署文档+讲解等)
详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不…...
从0开始深度学习(11)——多层感知机
前面介绍了线性神经网络,但是线性模型是有可能出错的,因为线性模型意味着是单调假设,但是现实中往往很复杂。例如,我们想要根据体温预测死亡率。 对体温高于37摄氏度的人来说,温度越高风险越大。 然而,对体…...
SQL语句查询
SQL语句查询 查询产生一个虚拟表 看到的是表形式显示的结果,但结果并不真正存储 每次执行查询只是从数据表中提取数据,并按照表的形式显示出来 查询语法 SELECT <列名> FROM <表名> [WHERE <查询条件表达式>] SELECT …...
OSI参考模型与TCP/IP模型
OSI参考模型 物理层 定义电压、接口、线缆标准、传输距离、传输介质等物理参数。数据链路层(确定范围里的某一个) MAC地址寻址网络层(确定一个范围) 网络地址层寻址、路由传输层(区分不同的程序) 数据分段…...
深度学习-26-基于PyTorch的多层感知机DNN
文章目录 1 代码分析1.1 加载数据集1.2 定义模型1.3 定义损失函数和优化器1.4 定义训练函数1.4.1 定义累加器Accumulator1.4.2 计算准确率accuracy1.4.3 评估函数evaluate_accuracy1.4.4 单轮训练函数train_epoch1.4.5 训练函数train1.2 执行训练2 整体代码3 参考附录1 代码分析…...
华为杯”第十三届中国研究生数学建模竞赛-B题:具有遗传性疾病和性状的遗传位点分析(附MATLAB代码实现)
目录 摘要: 1. 问题重述 1.1 问题背景 1.2 待解决问题 2. 符号说明 3. 问题一 3.1 问题分析 3.2 问题解决 4. 问题二 4.1 问题分析 4.2 问题解决 5. 问题三 5.1 问题分析 5.2 问题解决 6. 问题四 6.1 问题分析 6.2 问题解决 7. 总结 参考文献 代码实现 摘要: 人体的每条染色…...
滚雪球学Redis[8.2讲]:Redis的未来发展趋势:从云服务到AI与物联网的前沿探索
全文目录: 🎉前言🔄Redis在云服务中的应用🪁1. Redis作为云缓存服务🪄示例:使用AWS ElastiCache Redis实例 🎮️2. 云原生应用中的持久化与高可用 ⚙️Redis 6.x及后续版本的新特性🕹…...
针对考研的C语言学习(二叉树专题层次遍历---广度优先遍历)
层次便利需要一个队列来辅助保存节点信息 代码 #include<stdio.h> #include<stdlib.h> typedef char ElemType;//树 typedef struct trees{ElemType data;struct trees*lc;struct trees*rc; }treeNode,*Tree;//链表 typedef struct Links{Tree tree;struct Links…...
spring揭秘31-spring任务调度01-spring集成Quartz及JDKTimer定时器
文章目录 【README】【1】Quartz任务调度框架【1.1】Job调度任务【1.2】任务调度触发器Trigger【1.3】\*Quartz框架执行调度任务代码实践【1.3.1】硬编码执行Quartz调度任务【1.3.2】基于生产者模式执行quartz调度任务(推荐) 【2】spring集成Quartz【2.1…...
Kafka之资源容量评估
编写目的意义 应用场景为如果有租户需要部署kafka集群,并给出业务压力,根据业务评估kafka资源情况,如cpu 磁盘 内存 带宽等维度。为业务解决因资源过小故障和新业务部署提供了参考和计算方法,减少后续的维护成本 资源容量评估 …...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
