一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Zephyr RTOS簡介及代碼下載編譯運行

yzcdx ? 來源: OS與AUTOSAR研究 ? 2024-01-10 09:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

說起來RTOS,第一印象就是單片機程序、ARM M核、微控制器低頻運行處理程序,甚至其不能算一個真正的OS。但是隨著時代發(fā)展,這些單片機程序在有限的硬件機制下非常接近像Linux這種的巨無霸O(shè)S了,例如其有線程、中斷、內(nèi)存管理、IPC、驅(qū)動、網(wǎng)絡(luò)協(xié)議棧、shell、提供POSIX接口等,可以說其已經(jīng)是一個縮小版的OS了,甚至在A核也可以運行,簡單修改下添加一點用戶空間支持等特性就可以。

嵌入式領(lǐng)域中,定制化的軟硬件,并且沒有界面展示的時候,并不需要ARM A核這種高級的CPU,M核是一個更好的選擇,其便宜,小,省電,可靠性高,偏向?qū)S每刂?/strong>,但是頻率低,功能進行了閹割。在其上運行的RTOS也有對應(yīng)的特點:

地址空間只有一個,就像Linux的內(nèi)核一樣,共享地址空間

沒有高級的硬件相關(guān)MMU功能,無虛擬地址

沒有文件系統(tǒng)、UI界面等復雜服務(wù)

各種服務(wù)例如進程調(diào)度等是一個簡單實現(xiàn)版本

之前介紹過一個典型的RTOS freeRTOS:FreeRTOS入門-概念介紹。其實RTOS的定義就是實時操作系統(tǒng),例如Linux修改下具有實時特性也可以叫RTOS了。本文講的zephyr RTOS就是一個類似freeRTOS的操作系統(tǒng),可以等價平替,下面介紹下其特點。

1. Zephyr介紹

1.1 Zephyr簡介

Zephyr最初是由Wind River公司開發(fā)的一個微內(nèi)核,在2016年的時候成為Linux基金會維護的一個項目,發(fā)展至今,已經(jīng)成為了一個功能齊全的嵌入式OS。平臺現(xiàn)在支持ARM、RISC-V、X86、Xtensa等等處理器平臺,擁有原生的BLE協(xié)議棧、完整的Net協(xié)議棧,包括TCP/IP與應(yīng)用層協(xié)議,為嵌入式應(yīng)用的開發(fā)提供了有力的支持。

Zephyr它不僅僅維護了一個RTOS內(nèi)核,還維護一些編譯鏈、libc、 IDE插件、HEL層驅(qū)動等,幾乎每一個模塊都有相關(guān)的文檔。正是因為擁有詳細的文檔,Zephyr才能源源不斷的吸引人來進行嘗試與開發(fā),以至于系統(tǒng)不斷的被完善,進入開源項目的一個良性循環(huán)。

Linux基金會維護


所以看Zephyr就很Linux里Linux氣的,比如make menuconfig支持、DTS支持等,可以說把Linux一些優(yōu)秀的通用特性吸引進來了,做到了很多代碼跟Linux同步,妥妥的Linux小弟。好處就是我們?nèi)コa的時候,不,是移植代碼的時候Zephyr就是一個很好的調(diào)研對象,其完全開源嘛!

Wind River公司

大名鼎鼎的VxWorks實時操作系統(tǒng)就是Wind River公司開發(fā)的,其在實時操作系統(tǒng)領(lǐng)域早期可謂獨領(lǐng)風騷,特別在軍工中,它以其良好的可靠性和實時性被廣泛地應(yīng)用在通信、軍事、航空、航天等高精尖技術(shù)及實時性要求極高的領(lǐng)域中,如衛(wèi)星通訊、軍事演習、彈道制導、飛機導航等。在美國的 F-16、FA-18戰(zhàn)斗機、B-2 隱形轟炸機和愛國者導彈上,甚至連1997年4月在火星表面登陸的火星探測器、2008年5月登陸的鳳凰號,和2012年8月登陸的好奇號也都使用到了VxWorks。VxWorks不開源,這里的Zephyr可以說是出身在一流家族中,其實時特性應(yīng)該很值得借鑒。

1.2 特性介紹

eb2c956e-aed6-11ee-8b88-92fbcf53809c.png

eb4659f4-aed6-11ee-8b88-92fbcf53809c.png

Zephyr OS 基于小占用內(nèi)核,設(shè)計用于資源受限嵌入式系統(tǒng):從簡單的嵌入式環(huán)境傳感器LED 可穿戴設(shè)備到復雜的嵌入式控制器、智能手表和物聯(lián)網(wǎng)無線應(yīng)用。

其中Zephyr OS為Zephyr提供的核心代碼包含了:

Kernel/HAL

內(nèi)核調(diào)度

低級的體系結(jié)構(gòu)和板級支援

各種RTOS內(nèi)核對象

電源管理框架

低級的硬件接口抽象

OS服務(wù)及底層接口

設(shè)備管理及底層驅(qū)動API

文件系統(tǒng),Logging系統(tǒng),Debugging系統(tǒng)及IPC

加密服務(wù)

平臺相關(guān)的特殊驅(qū)動

網(wǎng)絡(luò)協(xié)議棧

應(yīng)用服務(wù)

高層級的應(yīng)用API

標準化的數(shù)據(jù)模型

高層級網(wǎng)絡(luò)協(xié)議接口

對于Zephyr應(yīng)用開發(fā)者,需要熟知應(yīng)用服務(wù)和OS服務(wù),了解底層接口及Kernel/HAL特性。

Zephy也提供構(gòu)建系統(tǒng)及開發(fā)環(huán)境和Zephyr OS一起構(gòu)成了Zephyr Project,Zephyr Project包含了:

Zephyr的SDK,構(gòu)建工具,CI及開發(fā)環(huán)境

Bootloader:MCUboot

附加的中間件

Zephyr除了核心代碼之外還引入了其它優(yōu)秀的開源項目做為其功能組成部分,另外還有不同的項目也將Zephyr作為其組成部分,這些內(nèi)容在一起構(gòu)成了完整的Zephyr生態(tài)。Zephyr生態(tài)有如下內(nèi)容:

第三方模塊或庫:例如lvgl,fatfs,mcumgr,openthread,openamp,opencan等等。

第三方支持Zephyr的項目:例如Jerryscript ,Micropython , Iotivity , SwiftIO等。

SOC供應(yīng)商Hal,Zephyr將不同芯片的Hal作為外部模塊引入到Zephyr中,通過Zephyr驅(qū)動的整合讓應(yīng)用可以通過統(tǒng)一的驅(qū)動接口控制不同芯片的片上設(shè)備。例如:nxp,st,ti,nordic,silabs等等。

Kernel涵蓋以下內(nèi)容:

提供Kernel service,例如thread,同步,數(shù)據(jù)傳遞,中斷管理,時間管理,內(nèi)存管理等

進行任務(wù)調(diào)度

電源管理

平臺相關(guān)的特殊驅(qū)動,例如Radios,傳感器,加密硬件,F(xiàn)lash等

OS服務(wù)涵蓋以下內(nèi)容:

設(shè)備驅(qū)動實現(xiàn),提供統(tǒng)一的底層驅(qū)動接口

設(shè)備管理

網(wǎng)絡(luò)L2實現(xiàn)及接口抽象

網(wǎng)絡(luò)層和傳輸層協(xié)議棧(TCP/IP),socket接口

應(yīng)用服務(wù)涵蓋以下內(nèi)容:

網(wǎng)絡(luò)應(yīng)用協(xié)議及高層級接口,例如HTTP,coap,mqtt,tls,dtls等

提供標準化的數(shù)據(jù)模型,目前尚未在Zephyr的目錄樹中找到該部分內(nèi)容

提供智能物件對象,例如基于lwm2m的IPSO

eb645724-aed6-11ee-8b88-92fbcf53809c.png

Zephyr的硬件層次結(jié)構(gòu)被抽象出6層

架構(gòu)(Architecutre):指令架構(gòu)體系,例如ARM,RISC-V,x86等

CPU內(nèi)核(CPU core):架構(gòu)中特定的CPU,例如ARM中有Cortex-M0,M3,M4,M7等

芯片族(Soc family):具有相似特性的SoC,例如Cortex-M7中有STMicro STM32,NXP i.MX

芯片系列(SoC series):一小部分緊密關(guān)聯(lián)的SoC,例如i.MX中有i.MX RT 系列,i.MX 8系列等

芯片級(SoC):電路板上的SoC,例如i.MX RT系列中有RT1050,RT1060等芯片

板級(Board):PCB上特定的SoC和一些外設(shè)相連構(gòu)成有特定功能的電路板。例如Zephyr支援的mimxrt1050_evk,mm_swiftio開發(fā)板使用了rt1052芯片。

Zephyr 內(nèi)核支持多種架構(gòu),包括:

ARCv2 (EM and HS) and ARCv3 (HS6X)

ARMv6-M, ARMv7-M, and ARMv8-M (Cortex-M)

ARMv7-A and ARMv8-A (Cortex-A, 32- and 64-bit)

ARMv7-R, ARMv8-R (Cortex-R, 32- and 64-bit)

Intel x86 (32- and 64-bit)

MIPS (MIPS32 Release 1 specification)

NIOS II Gen 2

RISC-V (32- and 64-bit)

SPARC V8

Tensilica Xtensa

廣泛的內(nèi)核服務(wù)套件,Zephyr 提供了許多熟悉的開發(fā)服務(wù):

用于協(xié)作、基于優(yōu)先級、非搶占式和搶占式線程的多線程服務(wù),具有可選的循環(huán)時間切片。包括 POSIX pthreads 兼容 API 支持。

中斷服務(wù)用于中斷處理程序的編譯時注冊。

用于動態(tài)分配和釋放固定大小或可變大小內(nèi)存塊的內(nèi)存分配服務(wù)。

用于二進制信號量、計數(shù)信號量和互斥信號量的線程間同步服務(wù)。

用于基本消息隊列、增強消息隊列和字節(jié)流的線程間數(shù)據(jù)傳遞服務(wù)。

Zephyr 提供了一套全面的線程調(diào)度選擇:

協(xié)作和搶占式調(diào)度

最早截止日期優(yōu)先 (EDF)

元 IRQ 調(diào)度實現(xiàn)“中斷下半部分”或“tasklet”行為

時間切片:在同等優(yōu)先級的可搶占線程之間啟用時間切片

多種排隊策略:

簡單鏈表就緒隊列

紅/黑樹就緒隊列

傳統(tǒng)多隊列就緒隊列

高度可配置/模塊化以實現(xiàn)靈活性

允許應(yīng)用程序僅根據(jù)需要合并其所需的功能,并指定其數(shù)量和大小。

跨架構(gòu)

支持具有不同 CPU 架構(gòu)和開發(fā)工具的各種受支持的主板。貢獻增加了對越來越多 SoC、平臺和驅(qū)動程序的支持。

內(nèi)存保護

在 x86、ARC 和 ARM 架構(gòu)、用戶空間和內(nèi)存域上實現(xiàn)可配置的特定于架構(gòu)的堆棧溢出保護、內(nèi)核對象和設(shè)備驅(qū)動程序權(quán)限跟蹤以及具有線程級內(nèi)存保護的線程隔離。

對于沒有 MMU/MPU 和內(nèi)存受限設(shè)備的平臺,支持將特定于應(yīng)用程序的代碼與自定義內(nèi)核相結(jié)合,以創(chuàng)建在系統(tǒng)硬件上加載和執(zhí)行的整體映像。應(yīng)用程序代碼和內(nèi)核代碼都在單個共享地址空間中執(zhí)行。

編譯時資源定義

允許在編譯時定義系統(tǒng)資源,從而減少代碼大小并提高資源有限系統(tǒng)的性能。

優(yōu)化的設(shè)備驅(qū)動模型

提供用于配置屬于平臺/系統(tǒng)的驅(qū)動程序的一致設(shè)備模型,以及用于初始化配置到系統(tǒng)中的所有驅(qū)動程序的一致模型,并允許跨具有公共設(shè)備/IP 塊的平臺重用驅(qū)動程序。

設(shè)備樹支持

使用devicetree來描述硬件。來自 devicetree 的信息用于創(chuàng)建應(yīng)用程序映像。

支持多種協(xié)議的本機網(wǎng)絡(luò)堆棧

網(wǎng)絡(luò)支持功能齊全且經(jīng)過優(yōu)化,包括 LwM2M 和 BSD 套接字兼容支持。還提供 OpenThread 支持(在 Nordic 芯片組上) - 一個網(wǎng)狀網(wǎng)絡(luò),旨在安全可靠地連接家庭周圍的數(shù)百個產(chǎn)品。

低功耗藍牙 5.0 支持

符合藍牙 5.0 標準 (ESR10) 和藍牙低功耗控制器支持(LE 鏈路層)。包括藍牙網(wǎng)狀網(wǎng)絡(luò)和藍牙資格就緒的藍牙控制器。

網(wǎng)格支持:

中繼、朋友節(jié)點、低功耗節(jié)點 (LPN) 和 GATT 代理功能

支持兩種配置承載(PB-ADV 和 PB-GATT)

高度可配置,適合具有至少 16k RAM 的設(shè)備

具有所有可能的 LE 角色的通用訪問配置文件 (GAP)

通用屬性配置文件 (GATT)

配對支持,包括藍牙 4.2 的安全連接功能

干凈的 HCI 驅(qū)動程序抽象

原始 HCI 接口將 Zephyr 作為控制器運行,而不是完整的主機堆棧

經(jīng)多個流行控制器驗證

高度可配置

本機 Linux、macOS 和 Windows 開發(fā)

命令行 CMake 構(gòu)建環(huán)境在流行的開發(fā)人員操作系統(tǒng)上運行。本機端口 ( native_sim ) 允許您在 Linux 上構(gòu)建和運行 Zephyr 作為本機應(yīng)用程序,從而幫助開發(fā)和測試。

支持 ext2、FatFs 和 LittleFS 的虛擬文件系統(tǒng)接口

ext2、LittleFS 和 FatFS 支持;FCB(閃存循環(huán)緩沖區(qū))適用于內(nèi)存受限的應(yīng)用程序。

強大的多后端日志框架

支持日志過濾、對象轉(zhuǎn)儲、恐慌模式、多個后端(內(nèi)存、網(wǎng)絡(luò)、文件系統(tǒng)、控制臺……)以及與 shell 子系統(tǒng)的集成。

用戶友好且功能齊全的 Shell 界面

多實例 shell 子系統(tǒng),具有用戶友好的功能,例如自動完成、通配符、著色、元鍵(箭頭、退格鍵、ctrl+u 等)和歷史記錄。支持靜態(tài)命令和動態(tài)子命令。

非易失性存儲上的設(shè)置

設(shè)置子系統(tǒng)為模塊提供了一種存儲持久的每設(shè)備配置和運行時狀態(tài)的方法。設(shè)置項存儲為鍵值對字符串。

非易失性存儲 (NVS)

NVS 允許存儲二進制 blob、字符串、整數(shù)、長整型以及這些的任意組合。

本機端口

Native sim允許將 Zephyr 作為 Linux 應(yīng)用程序運行,并支持各種子系統(tǒng)和網(wǎng)絡(luò)。

2. 環(huán)境搭建和代碼下載編譯

按照本指南進行操作:

在 Ubuntu、macOS 或 Windows 上設(shè)置命令行 Zephyr 開發(fā)環(huán)境(其他 Linux 發(fā)行版的說明在安裝 Linux 主機依賴項中討論)

獲取源代碼

構(gòu)建、刷新并運行示例應(yīng)用程序

具體不贅述了,提下如果在qemu下運行,參考如下:

在QEMU中運行應(yīng)用程序

在 Linux 和 macOS 上,當面向 x86 或 ARM Cortex-M3 架構(gòu)時,您可以使用QEMU在主機系統(tǒng)上通過仿真運行 Zephyr 應(yīng)用程序。(QEMU 包含在 Zephyr SDK 安裝中。)

例如,您可以使用 x86 仿真板配置 ( ) 構(gòu)建并運行Hello Worldqemu_x86示例,其中:

# From the root of the zephyr repository
west build -b qemu_x86 samples/hello_world
west build -t run

要退出 QEMU,請鍵入,然后鍵入。Ctrl-a``x

用于qemu_cortex_m3針對模擬的 Arm Cortex-M3 示例。

3. Zephyr的內(nèi)核特性

3.1 構(gòu)建

ephyr的構(gòu)建系統(tǒng)主要有三個部分cmake、kconfig、devicetree

cmake :在前期驅(qū)動kconfig和devicetree需生成必要的頭文件,后期用來生成像ninja或makefile等編譯腳本

kconfig:平臺的區(qū)分以及代碼的裁剪,應(yīng)用開發(fā)中主要體現(xiàn)在驅(qū)動的開關(guān),如下圖顯示,在驅(qū)動的實現(xiàn)里面定義了wifi的kconfig宏,用戶在使用的時候可以在prj.config文件去打開這個宏,這個驅(qū)動就會被打開。

eb8e0f24-aed6-11ee-8b88-92fbcf53809c.png

devicetree:配置硬件參數(shù)信息,比如像WIFI的模塊,可以配置SPI引腳以及速率,還可以配置跟他相關(guān)的同步引腳。

eba48538-aed6-11ee-8b88-92fbcf53809c.png

3.2 設(shè)備驅(qū)動模型

Zephyr幾乎為所有的外設(shè)驅(qū)動都提供了統(tǒng)一的API接口,芯片原廠基于API接口提供自己的實現(xiàn),用戶在使用外設(shè)的時候可以直接使用Zephyr提供的外設(shè)接口來進行應(yīng)用開發(fā)。

Zephyr的設(shè)備驅(qū)動是在同一個地方統(tǒng)一初始化的,比如像這個SPI的驅(qū)動,它的宏函數(shù)就等效于這一段代碼,代碼的含義就是注冊了一個函數(shù)。這個函數(shù)會在main函數(shù)前運行,運行等級為application級別。驅(qū)動的等級會比application高,等級越高就會越先執(zhí)行。設(shè)備驅(qū)動一定會在main函數(shù)前初始化完畢。

ebc0676c-aed6-11ee-8b88-92fbcf53809c.png

3.3 線程調(diào)度和通信

Zephyr 在線程調(diào)度方面的功能更加強大、靈活,可以更好地滿足不同場景下的需求。

而 FreeRTOS 則更加簡單、易于使用,適合對資源需求較為簡單的嵌入式應(yīng)用場景

ebd845d0-aed6-11ee-8b88-92fbcf53809c.png

Zephyr 與 FreeRTOS 線程通信對比:

ebe8f498-aed6-11ee-8b88-92fbcf53809c.png

Zephyr提供了管道、消息隊列和信號量等多種線程通信機制,而FreeRTOS提供了二值信號量、互斥量和隊列等線程通信機制。可以看出,Zephyr提供的線程通信機制更加多樣化。

3.4 內(nèi)存管理

Zephyr在內(nèi)存管理上具備一些比起其他RTOS更加先進機制,如下

Memory Heaps:提供了基于堆的動態(tài)內(nèi)存分配和釋放機制

Memory Slabs:提供了預分配一定數(shù)量內(nèi)存塊的機制,并能夠快速分配和釋放內(nèi)存塊,避免了堆內(nèi)存管理的 開銷以及內(nèi)存碎片的產(chǎn)生

Memory Blocks Allocator:提供了固定大小內(nèi)存塊的動態(tài)分配和釋放機制,適用于需要頻繁分配、釋放同一大小內(nèi)存塊 的場景

3.5 組件生態(tài)

越來越多的第三方組件庫已經(jīng)加入或者被移植進了ZephyrProject中,第三方組件管理與接入流程也日趨成熟這為開發(fā)者節(jié)省了大量常用組件的移植與適配工作。

ebf6fdea-aed6-11ee-8b88-92fbcf53809c.png

4. Zephyr啟動流程

這里我們以cortex_m為例,只講下啟動流程,其他代碼流程分析,參考:https://blog.csdn.net/qq_36115224/category_12279396.html

4.1 程序入口

include/zephyr/arch/arm/cortex_m/scripts/linker.ld中定義了ENTRY程序入口

ENTRY(CONFIG_KERNEL_ENTRY)

這個宏的定義在Kconfig.zephyr中

config KERNEL_ENTRY
string "Kernel entry symbol"
default "__start"
help
  Code entry symbol, to be set at linking phase.

__start是程序的入口,但是這是gcc的規(guī)則,Cortex-M系列處理器是通過中斷向量表來確定程序入口 Cortex-M系列處理器是通過中斷向量表來確定程序入口。

在 Cortex-M 系列 MCU 中,如果設(shè)置為從 flash 啟動,flash 前1K 用于存放中斷向量表,

其中第一個字為程序棧頂指針,用于初始化棧頂

第二個字為復位向量,即 ResetHandler 的地址,作為程序跳轉(zhuǎn)地址,從而跳轉(zhuǎn)到程序中運行

詳細說明可參考異常模型, 該機制為Cortex-M 系列 MCU 中獨有,與此相對的,不同的芯片在系統(tǒng)啟動時對可執(zhí)行程序都有一定的格式要求,需要在程序的頭部添加符合操作規(guī)范的頭。

中斷向量表中,reset的處理地址定義在arch/arm/core/cortex_m/reset.S中

SECTION_SUBSEC_FUNC(TEXT,_reset_section,z_arm_reset)

4.2 匯編初始化

在arch/arm/core/cortex_m/reset.S中

SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)

#if defined(CONFIG_DEBUG_THREAD_INFO)
    /* Clear z_sys_post_kernel flag for RTOS aware debuggers */
    movs.n r0, #0
    ldr r1, =z_sys_post_kernel
    strb r0, [r1]
#endif /* CONFIG_DEBUG_THREAD_INFO */

#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT)
    /* 復位CONTROL寄存器,在特權(quán)模式和非特權(quán)模式均使用MSP,
     * 當切換棧指針之后必須使用ISB指令刷新流水線,
     * 以保證在ISB之后執(zhí)行的指令都使用新的棧
     */
    movs.n r0, #0
    msr CONTROL, r0
    isb
#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM)
    /* 堆棧限制寄存器分別限制 MSP 和 PSP 寄存器可以下降的程度,此處設(shè)置為0 */
    movs.n r0, #0
    msr MSPLIM, r0
    msr PSPLIM, r0
#endif /* CONFIG_CPU_CORTEX_M_HAS_SPLIM */

#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */

#if defined(CONFIG_PM_S2RAM)
    /* 低功耗相關(guān)初始化 */
    bl arch_pm_s2ram_resume
#endif /* CONFIG_PM_S2RAM */

#if defined(CONFIG_PLATFORM_SPECIFIC_INIT)
    /* 針對內(nèi)存,cache,jtag,時鐘,中斷的一些特殊配置  */
    bl z_arm_platform_init
#endif

#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT)
#if defined(CONFIG_CPU_HAS_ARM_MPU)
    /* 操作系統(tǒng)未運行之前使用平坦內(nèi)存模型,所有內(nèi)存均不受保護,
     * 為避免在初始化過程中觸發(fā)讀寫保護進入異常,一定要關(guān)閉MPU
     */
    movs.n r0, #0
    ldr r1, =_SCS_MPU_CTRL
    str r0, [r1]
    dsb
#endif /* CONFIG_CPU_HAS_ARM_MPU */
    /* ARM32使用滿遞減棧,棧頂指針初始時刻指向高地址,
     * 將MSP指向 z_main_stack 的末尾,以便后續(xù)進行函數(shù)調(diào)用
     */
    ldr r0, =z_main_stack + CONFIG_MAIN_STACK_SIZE
    msr msp, r0

    /* 清除MPU配置,關(guān)閉所有中斷,清除被掛起的中斷,重置Cache配置等 */
    bl z_arm_init_arch_hw_at_boot
#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */

    /* 屏蔽中斷 */
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
    cpsid i
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
    movs.n r0, #_EXC_IRQ_DEFAULT_PRIO
    msr BASEPRI, r0
#else
#error Unknown ARM architecture
#endif

#ifdef CONFIG_WDOG_INIT
    /* 開啟看門狗 */
    bl z_arm_watchdog_init
#endif

#ifdef CONFIG_INIT_STACKS
    /* 將棧全部設(shè)置為0xaa,可用于監(jiān)測剩余棧容量 */
    ldr r0, =z_interrupt_stacks
    ldr r1, =0xaa
    ldr r2, =CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE
    bl z_early_memset
#endif

    /* 初始化PSP,將CONTROL的SPSEL位設(shè)置為1(在特權(quán)模式下使用MSP,非特權(quán)模式下使用PSP)
     * 后續(xù)操作將使用 z_interrupt_stacks 作為棧進行初始化
     */
    ldr r0, =z_interrupt_stacks
    ldr r1, =CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE
    adds r0, r0, r1
    msr PSP, r0
    mrs r0, CONTROL
    movs r1, #2
    orrs r0, r1 /* CONTROL_SPSEL_Msk */
    msr CONTROL, r0
    isb

    bl z_prep_c

4.3 C語言初始化

z_prep_c()函數(shù)的定義在arch/arm/core/cortex_m/prep_c.c中

void z_arm_prep_c(void)
{
relocate_vector_table();
#if defined(CONFIG_CPU_HAS_FPU)
z_arm_floating_point_init();
#endif
z_bss_zero();
z_data_copy();
#if ((defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A)) && defined(CONFIG_INIT_STACKS))
z_arm_init_stacks();
#endif
z_arm_interrupt_init();
z_cstart();
CODE_UNREACHABLE;
}

對于不同的平臺還需要增加額外的操作,例如浮點寄存器的初始化,中斷向量表的重定向,在系統(tǒng)啟動之前還運行了一段芯片內(nèi)置程序,這段程序?qū)⒅袛嘞蛄勘淼奈恢迷O(shè)置為 0x00000000,當程序從boot跳轉(zhuǎn)到指定存儲器運行之后,首先需要立即關(guān)閉中斷,避免中斷產(chǎn)生并跳轉(zhuǎn)到錯誤的中斷響應(yīng)函數(shù)中,重設(shè)中斷向量表偏移位置之后,再重新開啟中斷。

初始化內(nèi)核開啟任務(wù)調(diào)度

FUNC_NO_STACK_PROTECTOR
FUNC_NORETURN void z_cstart(void)
{
/* 代碼覆蓋率測試相關(guān) */
gcov_static_init();

/* 調(diào)用初始化級別為 INIT_LEVEL_EARLY 的函數(shù)進行初始化 */
z_sys_init_run_level(INIT_LEVEL_EARLY);

/* z_arm_interrupt_stack_setup 初始化MSP
 * z_arm_exc_setup 初始化PENDSV、SysTick等中斷的優(yōu)先級,其中PENDSV優(yōu)先級為最低
 * z_arm_fault_init 初始化 Fault 中斷。
 * z_arm_cpu_idle_init 初始化 idle 線程
 * z_arm_clear_faults 清除所有故障標志
 * z_arm_mpu_init 初始化MPU
 * z_arm_mmu_init 初始化MMU
 */
arch_kernel_init();

/* 日志初始化 */
LOG_CORE_INIT();

#if defined(CONFIG_MULTITHREADING)
/* Note: The z_ready_thread() call in prepare_multithreading() requires
 * a dummy thread even if CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN=y
 */
struct k_thread dummy_thread;

z_dummy_thread_init(&dummy_thread);
#endif
/* 初始化驅(qū)動中的靜態(tài)節(jié)點 */
z_device_state_init();

/* 其他的硬件初始化 */
z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_1);
z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_2);

#ifdef CONFIG_STACK_CANARIES
/* CONFIG_STACK_CANARIES 用于開啟堆棧金絲雀功能,這是一種安全特性,有助于監(jiān)測堆棧溢出,
 * 當啟動該功能時,系統(tǒng)啟動時會生成一個隨機數(shù)并保存在 __stack_chk_guard 中,
 * 在函數(shù)返回之前會檢查該值確保它沒有被緩沖區(qū)溢出所覆蓋。
 */
uintptr_t stack_guard;

z_early_boot_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard));
__stack_chk_guard = stack_guard;
__stack_chk_guard <<= 8;
#endif/* CONFIG_STACK_CANARIES */

#ifdef CONFIG_TIMING_FUNCTIONS_NEED_AT_BOOT
/* timing_init 函數(shù)用于初始化系統(tǒng)計時器 */
timing_init();
timing_start();
#endif

#ifdef CONFIG_MULTITHREADING
/* CONFIG_MULTITHREADING為y時,使用多線程,否則只會有一個 main 線程,
 * 默認情況下都啟用多線程,通過將 main 線程添加到就緒隊列中然后開啟任務(wù)調(diào)度
 */
switch_to_main_thread(prepare_multithreading());
#else
#ifdef ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING
/* Custom ARCH-specific routine to switch to main()
 * in the case of no multi-threading.
 */
ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING(bg_thread_main,
NULL, NULL, NULL);
#else
bg_thread_main(NULL, NULL, NULL);

/* LCOV_EXCL_START
 * We've already dumped coverage data at this point.
 */
irq_lock();
while (true) {
}
/* LCOV_EXCL_STOP */
#endif
#endif /* CONFIG_MULTITHREADING */

/*
 * Compiler can't tell that the above routines won't return and issues
 * a warning unless we explicitly tell it that control never gets this
 * far.
 */

CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
}

在進入 z_cstart 之后,首先調(diào)用平臺相關(guān)的內(nèi)核初始化函數(shù),然后使用模塊自動初始化機制根據(jù)不同優(yōu)先級調(diào)用相關(guān)初始化函數(shù) 需要注意的是,同一優(yōu)先級的模塊之間不應(yīng)該存在依賴關(guān)系,被依賴的模塊應(yīng)該先初始化。在調(diào)度器啟動之前會調(diào)用優(yōu)先級為 INIT_LEVEL_PRE_KERNEL_1 和 INIT_LEVEL_PRE_KERNEL_2 的初始化函數(shù),此時調(diào)度器還未運行,因此這些函數(shù)中不應(yīng)該使用操作系統(tǒng)提供的功能。在初始化完成之后通過將main線程添加到就緒隊列中并開啟調(diào)度器,main 線程從 bg_thread_main 函數(shù)開始運行。

4.4 main線程

bg_thread_main的定義在kernel/init.c中,

static void bg_thread_main(void *unused1, void *unused2, void *unused3)
{
ARG_UNUSED(unused1);
ARG_UNUSED(unused2);
ARG_UNUSED(unused3);

#ifdef CONFIG_MMU
/* Invoked here such that backing store or eviction algorithms may
 * initialize kernel objects, and that all POST_KERNEL and later tasks
 * may perform memory management tasks (except for z_phys_map() which
 * is allowed at any time)
 */
z_mem_manage_init();
#endif /* CONFIG_MMU */
z_sys_post_kernel = true;

/* 調(diào)用優(yōu)先級為INIT_LEVEL_POST_KERNEL的初始化函數(shù),
 * 此時內(nèi)核已經(jīng)開始運行,可以使用操作系統(tǒng)API
 */
z_sys_init_run_level(INIT_LEVEL_POST_KERNEL);
#if CONFIG_STACK_POINTER_RANDOM
z_stack_adjust_initialized = 1;
#endif
/* 從控制臺輸出系統(tǒng)啟動標識 */
boot_banner();

#if defined(CONFIG_CPP)
/* 初始化CPP運行環(huán)境 */
void z_cpp_init_static(void);
z_cpp_init_static();
#endif

/* 調(diào)用優(yōu)先級為 INIT_LEVEL_APPLICATION 的初始化函數(shù) */
z_sys_init_run_level(INIT_LEVEL_APPLICATION);
/* Zephyr支持靜態(tài)創(chuàng)建線程,線程對應(yīng)的信息在編譯時確定,
 * 隨代碼一起被編譯到程序中,系統(tǒng)啟動之后從對應(yīng)地址將線程的信息從flash中讀出,
 * 創(chuàng)建并初始化線程并將其添加到就緒隊列中等待操作系統(tǒng)調(diào)度。
 */
z_init_static_threads();

#ifdef CONFIG_KERNEL_COHERENCE
__ASSERT_NO_MSG(arch_mem_coherent(&_kernel));
#endif

#ifdef CONFIG_SMP
if (!IS_ENABLED(CONFIG_SMP_BOOT_DELAY)) {
z_smp_init();
}
z_sys_init_run_level(INIT_LEVEL_SMP);
#endif

#ifdef CONFIG_MMU
z_mem_manage_boot_finish();
#endif /* CONFIG_MMU */

#ifdef CONFIG_CPP_MAIN
extern int main(void);
#else
extern void main(void);
#endif

/* 跳轉(zhuǎn)到main函數(shù) */
(void)main();

/* Mark nonessential since main() has no more work to do */
z_main_thread.base.user_options &= ~K_ESSENTIAL;

#ifdef CONFIG_COVERAGE_DUMP
/* Dump coverage data once the main() has exited. */
gcov_coverage_dump();
#endif
}

其中包含幾個系統(tǒng)運行的重要的操作:配置MMU(如果存在) 調(diào)用優(yōu)先級為 INIT_LEVEL_POST_KERNEL 的初始化函數(shù) CPP運行環(huán)境的初始化 調(diào)用優(yōu)先級為 INIT_LEVEL_APPLICATION 的初始化函數(shù) 創(chuàng)建通過宏靜態(tài)創(chuàng)建的線程,并添加到就緒隊列。初始化對稱多核處理(如果存在多個處理器并啟用了多核調(diào)度)。在這些準備工作完成后跳轉(zhuǎn)到用戶編寫的main函數(shù)中,如果main函數(shù)執(zhí)行并返回,最終會返回到 z_thread_entry 被銷毀。

Zephyr RTOS整體上網(wǎng)上資料很多,大家可以自己去搜索學習,也說明這個RTOS是比較流行的,各種硬件也對這個Zephyr進行了支持,里面有很多功能非常的豐富,如果自己項目的RTOS缺失的功能可以去上面進行移植。一個典型就是gcov代碼覆蓋率測試模塊,一般的RTOS是不支持的就可以移植。


對于OS在國內(nèi)可能很神秘,但是在歐美特別是高校里面各種定制版本或者學術(shù)版本的OS層出不窮,已經(jīng)算是人人都能造OS了一樣,這些小眾的OS不一定流行起來,但是也各有特點,特別是一些特定場景下小眾OS也許能獲得更高的效率和效果,開源OS界也是天下文章一大抄。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 微控制器
    +關(guān)注

    關(guān)注

    48

    文章

    7953

    瀏覽量

    155102
  • 單片機
    +關(guān)注

    關(guān)注

    6067

    文章

    44992

    瀏覽量

    650564
  • RTOS
    +關(guān)注

    關(guān)注

    24

    文章

    851

    瀏覽量

    121184
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4900

    瀏覽量

    70756

原文標題:Zephyr RTOS入門-簡介及代碼下載編譯運行

文章出處:【微信號:OS與AUTOSAR研究,微信公眾號:OS與AUTOSAR研究】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    請問Zephyr編譯出來的elf文件無法運行的原因是什么?

    我嘗試使用Zephyr2.6編譯了一個默認的示例程序LED閃爍的代碼,編譯命令如下:west -b build mimxrt1060_evk same/blink 生成的elf文件無法
    發(fā)表于 01-12 07:34

    【泰凌微TLSR9系列開發(fā)套件試用體驗】Zephyr編譯環(huán)境搭建

    /zephyrproject-rtos/zephyr.git2下載交叉編譯工具鏈:http://wiki.telink-semi.cn/tools_and_sdk/Tools/IDE
    發(fā)表于 07-08 10:25

    Zephyr與FreeRTOS實時性測試比較

    1、Zephyr與FreeRTOS實時性測試比較分析用Rhealstone基準程序方法,分別測試Zephyr和FreeRTOS兩個RTOS的六個實時性能指標,發(fā)現(xiàn)Zephyr指標較差。
    發(fā)表于 08-19 16:12

    flash_download_tool燒錄zephyr程序運行后報錯的原因?

    \partitions_singleapp.bin@8000, build\zephyr\zephyr.bin@10000,分別燒錄到@1000, @8000, @10000的地方,運行后報錯。 是否有漏掉其它文件?
    發(fā)表于 03-06 07:25

    small_rtos1.12.1源代碼下載

      small_rtos1.12.1源代碼下載 Small RTOS(51)文件列表 根目錄:list.txt     
    發(fā)表于 02-22 14:53 ?130次下載

    Zephyr v2.6.0下如何搭建esp32的編譯調(diào)試環(huán)境?

    最近在翻看zephyr master的驅(qū)動代碼時,很驚喜的發(fā)現(xiàn)esp32的wifi驅(qū)動和藍牙驅(qū)動都已經(jīng)支持。遙想當年選擇自用的zephyr硬件平臺時,幾次打算用esp32都放棄了,最后選擇了
    的頭像 發(fā)表于 05-24 11:23 ?3798次閱讀

    淺析Zephyr應(yīng)用的代碼結(jié)構(gòu)中的自定義驅(qū)動

    本篇是《《Zephyr應(yīng)用的代碼結(jié)構(gòu)》》系列的終篇和下面兩篇文章一起可以構(gòu)建出一個有app獨立管理的zephyr項目 Zephyr應(yīng)用的代碼
    的頭像 發(fā)表于 08-18 09:08 ?5361次閱讀

    泰凌微電子Zephyr硬件平臺及編譯步驟

    當Telink Zephyr環(huán)境配置成功并且驗證完成之后,便需要明確適用的硬件平臺,選擇想要嘗試的Zephyr例程去進行編譯。接下來,將先簡要介紹適用于Telink Zephyr的TL
    的頭像 發(fā)表于 02-06 15:41 ?3027次閱讀

    泰凌微電子Zephyr固件下載及示例程序

    在了解適用于Telink Zephyr的B91開發(fā)板和如何使用West相關(guān)的命令去編譯Zephyr應(yīng)用之后,讓我們重溫一下將固件下載到開發(fā)板上的方法和步驟,并且了解一些配件的連接和使用
    的頭像 發(fā)表于 02-10 11:29 ?4451次閱讀

    EFR32BG22 Thunderboard擴增支持開源Zephyr RTOS

    Silicon Labs (亦稱“芯科科技”)軟件開發(fā)團隊積極與各種實時操作系統(tǒng) (RTOS) 和項目一起工作,以確保工程師能夠針對 EFR32 無線 SoC 系列產(chǎn)品編寫多任務(wù)應(yīng)用程序代碼。最近
    的頭像 發(fā)表于 05-17 20:30 ?1097次閱讀
    EFR32BG22 Thunderboard擴增支持開源<b class='flag-5'>Zephyr</b> <b class='flag-5'>RTOS</b>

    Linux內(nèi)核的編譯運行

    想讓Linux內(nèi)核代碼跑起來,得先搭建編譯運行代碼的環(huán)境。
    發(fā)表于 06-23 11:56 ?1907次閱讀
    Linux內(nèi)核的<b class='flag-5'>編譯</b>和<b class='flag-5'>運行</b>

    Zephyr RTOS和HC-SR04超聲波傳感器開源

    電子發(fā)燒友網(wǎng)站提供《Zephyr RTOS和HC-SR04超聲波傳感器開源.zip》資料免費下載
    發(fā)表于 06-20 09:44 ?4次下載
    <b class='flag-5'>Zephyr</b> <b class='flag-5'>RTOS</b>和HC-SR04超聲波傳感器開源

    使用Zephyr RTOS的碳漫游者

    電子發(fā)燒友網(wǎng)站提供《使用Zephyr RTOS的碳漫游者.zip》資料免費下載
    發(fā)表于 06-28 14:54 ?3次下載
    使用<b class='flag-5'>Zephyr</b> <b class='flag-5'>RTOS</b>的碳漫游者

    深入解析Zephyr RTOS的技術(shù)細節(jié)

    Zephyr是一個針對資源受限設(shè)備優(yōu)化的小型、可縮放、多體系架構(gòu)實時操作系統(tǒng)(RTOS)。Zephyr由Linux基金會維護[1],是一個以構(gòu)建業(yè)界最佳的RTOS為目標的開源合作項目。
    的頭像 發(fā)表于 10-22 16:47 ?2251次閱讀
    深入解析<b class='flag-5'>Zephyr</b> <b class='flag-5'>RTOS</b>的技術(shù)細節(jié)

    IAR平臺現(xiàn)已提供對Zephyr RTOS的量產(chǎn)級支持

    IAR宣布,其嵌入式開發(fā)平臺正式推出對Zephyr RTOS的量產(chǎn)級支持。該支持自IAR的Arm開發(fā)工具鏈v9.70起全面提供。
    的頭像 發(fā)表于 07-09 15:43 ?104次閱讀