Zephyr学习 第四章 -2:初始化 level、priority 与启动顺序
04-2初始化 level、priority 与启动顺序验证方式SYS_INIT()、device init、ELF/map、native_sim/native/64验证结论源码确认 编译确认 模拟确认1. 本节目标上一节确认 device init 会在main()前执行。本节进一步回答Zephyr 有哪些初始化 level同一个 level 内priority 如何决定顺序SYS_INIT()与 device init 是否使用同一套基础设施驱动为什么不能随便选择一个更早的 level本节最终验证的时间线EARLY - PRE_KERNEL_1 - PRE_KERNEL_2 - POST_KERNEL - APPLICATION - main2. Zephyr 的初始化基础设施本地源码zephyr/include/zephyr/init.hZephyr 使用同一套 init entry 基础设施支持SYS_INIT 注册的系统初始化函数 DEVICE_DT_DEFINE 注册的设备初始化函数init entry 的核心结构structinit_entry{unioninit_function init_fn;union{conststructdevice*dev;/* 可选 mutable device */};};其中union init_function能保存两种签名int(*sys)(void);int(*dev)(conststructdevice*dev);所以SYS_INIT callback 没有 device 参数 device init callback 接收对应 struct device *源码确认3. 初始化 level 总览本地init.h按顺序定义level执行阶段主要限制/用途EARLY刚进入 C 环境后的极早期架构、SoC 极早期设置系统服务不可假设可用PRE_KERNEL_1kernel 初始化上下文使用 interrupt stackkernel services 尚不可用PRE_KERNEL_2仍在 pre-kernel 上下文与 PRE_KERNEL_1 相同限制但阶段更晚POST_KERNELkernel 已可用可以使用 kernel primitives常用于普通 device driverAPPLICATIONmain()之前应用/子系统级初始化SMPSMP 专用阶段仅在CONFIG_SMP启用时可用本次native_sim没有验证 SMP 阶段因此实验只覆盖到APPLICATION。4. EARLY 阶段为什么要非常谨慎EARLY发生在系统启动的最前面。通常不应假设下面内容已经可用schedulersemaphore、mutexheaplogging backend普通 device object readyconsole driver 已完成初始化。本实验的 EARLY callback 只做boot_events[boot_event_count]EARLY:50;即只修改已经清零的静态 RAM不调用printk()从而避免依赖早期 console。5. PRE_KERNEL_1 与 PRE_KERNEL_2本地源码说明这两个阶段运行在 kernel initialization context 使用 interrupt stack kernel services 尚不可用因此 pre-kernel init 不适合阻塞等待 semaphore创建依赖 scheduler 的工作睡眠依赖普通 POST_KERNEL device使用尚未初始化的子系统。两个 level 的区别主要是全局顺序所有 PRE_KERNEL_1 都早于 所有 PRE_KERNEL_2即使PRE_KERNEL_1 priority 99 PRE_KERNEL_2 priority 0前者仍先执行因为 level 排序优先于 priority。6. POST_KERNEL本地定义Executed after Kernel is alive. From this point on, Kernel primitives can be used.普通传感器、总线和外设驱动经常使用POST_KERNEL因为初始化中可能需要semaphore、mutex 等内核对象已初始化的父总线 device日志或较完整的系统服务设备依赖检查。本节伪驱动使用DEVICE_DT_INST_DEFINE(...,POST_KERNEL,50,...)7. APPLICATIONAPPLICATIONinit 在应用main()前执行。适合应用级注册订阅系统事件在 main 前完成的子系统设置不属于具体 device object 的初始化逻辑。实验SYS_INIT(trace_application_20,APPLICATION,20);最终记录证明APPLICATION:20 早于 main8. priority 的规则priority 范围0 ... 99同一个 level 内数值越小 - 越早执行 数值越大 - 越晚执行例如POST_KERNEL priority 10 POST_KERNEL priority 50 POST_KERNEL priority 90顺序为10 - 50 - 90注意这与之后学习的 thread priority 不是同一套对象。这里只讨论启动 init entry 的链接排序。9. level 比 priority 更高一级错误理解priority 0 永远比 priority 99 早正确理解先按 level 排序 再在同一个 level 内按 priority 排序例如PRE_KERNEL_2:99 仍早于 POST_KERNEL:0可以把完整排序 key 简化理解为(level ordinal, priority, sub-priority)10. priority 必须是可用于 section 名的值SYS_INIT()文档要求 priority 是无前导零、无符号的十进制整数 literal或展开为这种整数的 symbolic name/Kconfig symbol。可以SYS_INIT(foo,POST_KERNEL,32);#defineMY_INIT_PRIORITY32SYS_INIT(foo,POST_KERNEL,MY_INIT_PRIORITY);不可以SYS_INIT(foo,POST_KERNEL,CONFIG_KERNEL_INIT_PRIORITY_DEFAULT5);原因是 priority 被拼进 linker section 名普通 C 算术表达式无法在这个位置使用。11. SYS_INIT 的基本形式系统初始化函数staticintmy_init(void){return0;}SYS_INIT(my_init,POST_KERNEL,50);SYS_INIT()创建一个静态struct init_entry并把它放入.z_init_LEVELPRIORITY_SUBPRIORITY_形式的 linker section。它不代表创建了struct deviceSYS_INIT 只有 system init entrydev 指针为 NULL DEVICE_DT_DEFINE 同时有 device object、device state 和 device init entry12. 本节 boot trace 设计实验注册EARLY:50 PRE_KERNEL_1:80 先写在源码中 PRE_KERNEL_1:20 后写在源码中 PRE_KERNEL_2:50 POST_KERNEL:90 先写在源码中 POST_KERNEL:10 后写在源码中 POST_KERNEL:device:50 APPLICATION:20 main故意逆序书写 priority 80/20 和 90/10是为了排除“按源码出现顺序执行”的错误理解。每个 callback 只调用boot_trace_record(LEVEL:priority);最后由 main 统一打印数组。13. 实际运行结果[init] devicelearning-device-0 initial42 current_before0 *** Booting Zephyr OS build v4.1.0-rc1 *** boot_trace_count9 boot_trace[0]EARLY:50 boot_trace[1]PRE_KERNEL_1:20 boot_trace[2]PRE_KERNEL_1:80 boot_trace[3]PRE_KERNEL_2:50 boot_trace[4]POST_KERNEL:10 boot_trace[5]POST_KERNEL:device:50 boot_trace[6]POST_KERNEL:90 boot_trace[7]APPLICATION:20 boot_trace[8]main [main] devicelearning-device-0 ready1 init_called1 initial42 current42验证结论level 顺序正确 同 level 内数值较小的 priority 先执行 device init 和 SYS_INIT entry 参与同一 POST_KERNEL 排序 APPLICATION 在 main 前执行模拟确认14. linker map 的直接证据查看rg-n-C2\.z_init_(EARLY|PRE_KERNEL_1|PRE_KERNEL_2|POST_KERNEL|APPLICATION)\/mnt/c/study/1-zephyr/work/ch04_init_order/zephyr/zephyr.map实际 section 顺序.z_init_EARLY50_0_ .z_init_PRE_KERNEL_120_0_ .z_init_PRE_KERNEL_180_0_ .z_init_PRE_KERNEL_199_0_ native console .z_init_PRE_KERNEL_20_0_ native timer .z_init_PRE_KERNEL_250_0_ .z_init_POST_KERNEL10_0_ .z_init_POST_KERNEL50_00012_ learning device .z_init_POST_KERNEL90_0_ .z_init_APPLICATION20_0_这说明 linker 不只排列实验代码也把 Zephyr 自带的 console、timer 和 device init 放进同一全局序列。编译确认15. 为什么源码逆序但执行仍有序init.h中#defineZ_INIT_ENTRY_SECTION(level,prio,sub_prio)\__attribute__((__section__(\.z_init_#levelSTRINGIFY(prio)\_STRINGIFY(sub_prio)_)))链接脚本再使用排序SORT_BY_NAME SORT_BY_ALIGNMENT因此真正决定顺序的是section 名 linker script不是C 文件中的函数位置CMake 中源码列出的顺序object 文件碰巧的顺序。16. sub-priority 是什么普通SYS_INIT()本次生成..._0_learning device 生成.z_init_POST_KERNEL50_00012_其中00012对应当前 node 的 dependency ordinal 相关排序信息。它帮助 Zephyr 在相同 level/priority 下处理设备依赖顺序。本节只观察到它存在设备依赖、required handles 和初始化失败传播将在 04-3 展开。不要在应用代码中手工依赖这个生成数字。17. nm 证据nm-n/mnt/c/study/1-zephyr/work/ch04_init_order/zephyr/zephyr.elf\|rgdevice_dts_ord_12|__init_trace实际地址顺序0x10 __init_trace_early_50 0x20 __init_trace_pre1_20 0x30 __init_trace_pre1_80 0x60 __init_trace_pre2_50 0x70 __init_trace_post_10 0x80 __init___device_dts_ord_12 0x90 __init_trace_post_90 0xa0 __init_trace_application_20与运行时记录一致。编译确认18. device init 可以选哪些 levelDEVICE_DEFINE()/DEVICE_DT_DEFINE()文档面向普通 device 时列出PRE_KERNEL_1 PRE_KERNEL_2 POST_KERNEL选择原则必须在 kernel 前准备的底层设备 - PRE_KERNEL level但必须遵守严格限制 需要 kernel primitives 或常规设备依赖 - POST_KERNEL 纯应用初始化 - 通常使用 SYS_INIT(..., APPLICATION, ...)不要为了“更早”而盲目选择 PRE_KERNEL。过早会让可用 API 更少、依赖关系更难满足。19. 初始化 priority 不是延时priority 10 priority 90不表示相差 80 ms每个 init 有固定时间片priority 10 一定执行得更快调度器 thread priority。它只表示同一 level 中 init entry 的相对排序键。如果 priority 10 的 init 阻塞很久priority 90 仍必须等待它返回。21. 常见错误21.1 认为所有 priority 在全局比较priority 只在相同 level 内比较。21.2 把 init priority 与 thread priority 混淆init priority 是链接排序thread priority 是 scheduler 概念。21.3 PRE_KERNEL 中使用 kernel primitive此时 kernel services 尚不可用。21.4 EARLY 阶段打印大量日志console/logging backend 可能尚未初始化。应使用最小、无依赖的状态记录。21.5 使用 priority 算术表达式section 名生成要求 literal 或可直接展开的 symbolic integer。21.6 用源码书写顺序推断执行顺序应检查 level、priority、生成 section 和最终 map。21.7 随意调整 driver priority 修复依赖如果 Devicetree 已表达设备依赖应优先理解依赖图和自动排序而不是靠不断试 priority 数字。下一节会专门学习。22. 可迁移到其他驱动的结论SYS_INIT 和 device init 使用同一 init entry/linker section 基础设施初始化先按 level、再按 priority、最后按 sub-priority 排序同 level 中数值较小的 priority 先执行PRE_KERNEL 阶段不能假设 kernel services 可用POST_KERNEL 是普通 device driver 的常见选择APPLICATION init 发生在 main 之前最终zephyr.map是确认真实 init 顺序的重要证据。23. 练习与自测请执行rg-n-C2\.z_init_(EARLY|PRE_KERNEL_1|PRE_KERNEL_2|POST_KERNEL|APPLICATION)\/mnt/c/study/1-zephyr/work/ch04_init_order/zephyr/zephyr.map然后回答PRE_KERNEL_2:99与POST_KERNEL:0哪个先执行为什么同为POST_KERNEL时priority 10、50、90 的顺序是什么为什么实验在 EARLY 阶段只记录内存而不直接打印为什么源码中 priority 80 写在 20 前面最终仍是 20 先执行SYS_INIT()与DEVICE_DT_DEFINE()的 init entry 有什么共同点和区别下一节04-3-初始化失败、设备依赖与device_is_ready。

相关新闻

第三篇:《在 Kubernetes 中部署 Istio:安装、配置与 Sidecar 注入》

第三篇:《在 Kubernetes 中部署 Istio:安装、配置与 Sidecar 注入》

理解了 Istio 的架构之后,是时候亲手搭建一个 Istio 环境了。在 Kubernetes 集群中安装 Istio 有多种方式,最常用的是 istioctl 命令行工具和 Helm。本文将详细介绍使用 istioctl 安装 Istio 的完整流程,涵盖环境准备、安装配置文件的选型、命…

2026/8/5 8:15:35 阅读更多 →
AI音乐生成实战:Spark项目本地部署与结构化音乐生成解析

AI音乐生成实战:Spark项目本地部署与结构化音乐生成解析

如果你是一位音乐爱好者、内容创作者,或者正在寻找一种高效、低成本的方式为自己的视频或项目制作高质量背景音乐,那么你很可能已经对“AI音乐生成”这个领域产生了兴趣。但面对市面上众多的AI音乐工具,一个核心的痛点始终存在:生…

2026/8/5 8:15:35 阅读更多 →
黄金价格软件国内外价格实时监控超方便

黄金价格软件国内外价格实时监控超方便

软件介绍 GOLDALL,一款黄金价格实时监控工具。最近黄金价格跌得厉害,今天的价格好像已经到866一克了,真的是跌跌不休。如果你也在关注黄金行情,这款软件值得了解一下。 国内外价格实时显示 软件可以同时显示黄金的国内价格和国…

2026/8/5 8:15:35 阅读更多 →

最新新闻

第10讲:上线与生产化——把 Agent 部署到真实环境

第10讲:上线与生产化——把 Agent 部署到真实环境

前九讲我们构建了一个功能完整的 Agent 系统:能调用工具、管理记忆、查阅文档、连接 MCP 服务、多 Agent 协作。但所有这些都还在本地开发环境中运行。 这一讲,我们要解决最后一个问题:如何把 Agent 安全、稳定、可控地部署到生产环境? 一、生产环境的核心挑战 开发环境和…

2026/8/5 9:03:54 阅读更多 →
海光DCU大模型推理生产落地:从环境搭建到稳定运维的完整实战笔记

海光DCU大模型推理生产落地:从环境搭建到稳定运维的完整实战笔记

海光DCU大模型推理生产落地:从环境搭建到稳定运维的完整实战笔记 国产算力落地到生产环境,从来不是“把模型跑起来”这么简单。很多团队都遇到过类似的问题:实验室里单卡跑demo一切正常,一到线上高并发场景就性能跳水、显存泄漏、…

2026/8/5 9:03:54 阅读更多 →
计算机毕业设计之大学生求职招聘微信小程序

计算机毕业设计之大学生求职招聘微信小程序

随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,大学生求职招聘被用户普遍使用,为方便管理员能够可以…

2026/8/5 9:03:54 阅读更多 →
通知!2026年度恩施州中、初级职称申报时间+申报材料清单

通知!2026年度恩施州中、初级职称申报时间+申报材料清单

一、2026年恩施中级、初级职称申报时间⏰: 1.网上个人申报、主管部门、县市人社部门送审时间:2026年8月3日至8月30日17:00。2.纸质材料受理时间:2026年9月7日至9月18日(每个地区纸质版材料时间不一样)💥注意…

2026/8/5 9:03:54 阅读更多 →
第9讲:多 Agent 协作——让多个智能体分工合作

第9讲:多 Agent 协作——让多个智能体分工合作

前八讲我们都在构建单个 Agent。单个 Agent 能做的事已经不少了:能调用工具、能规划任务、能查阅文档、能连接真实系统。 但现实世界中的复杂任务,往往需要多人协作才能完成。比如: 开发一个功能:产品经理写需求 → 开发写代码 → QA 测试 → 运维部署 撰写一份报告:研究…

2026/8/5 9:03:54 阅读更多 →
一个关于显示器的笑话

一个关于显示器的笑话

一个嵌入式工程师买了台新显示器,回家发现画面一直闪。老婆问:"是不是线松了?"工程师:"不是。我抓 I2C 总线看了,EDID 读出来的时序参数是 1920x108060Hz,但显卡驱动硬要输出 144Hz。DDC/CI…

2026/8/5 9:02:54 阅读更多 →

日新闻

Java缓存框架:JetCache

Java缓存框架:JetCache

TOC 一、简介 JetCache 是一个 Java 缓存抽象框架,为不同的缓存解决方案提供了统一的使用方式。 它提供的注解比 Spring Cache 更加强大。 JetCache 的注解支持原生 TTL、两级缓存以及在分布式环境中的自动刷新功能,同时你也可以通过代码直接操作 Cach…

2026/8/5 0:00:43 阅读更多 →
AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

需求:通孔焊盘 十字花;过孔 Via 实心直连;贴片焊盘按需设置 AD 测试版本AD24 很多工程师踩坑:全部统一十字,导致接地过孔阻抗高、大电流发热! 一、快捷键打开规则 PCB 界面按下:D R 展开…

2026/8/5 0:00:43 阅读更多 →
AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

更多请点击: https://kaifayun.com 第一章:AI生成素描效果 AI生成素描效果是计算机视觉与风格迁移技术融合的典型应用,其核心在于将彩色照片或RGB图像转换为具有手绘质感、明暗对比强烈、边缘清晰的单色素描图像。该过程通常依赖于深度学习模…

2026/8/5 0:00:43 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/4 13:24:41 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/4 11:41:39 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/4 5:26:40 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/4 13:38:24 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/4 11:09:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/4 13:38:40 阅读更多 →