Zephyr的設備驅動模型

默認配置

默認配置
boards/arm/nucleo_f401re/
├── nucleo_f401re.dts          ← 板卡設備樹主入口
├── nucleo_f401re_defconfig    ← 默認 Kconfig 配置
├── board.cmake                ← CMake 構建入口

overlay

1.新增加驅動需要修改對應板的設備樹文件,通常選擇以 .overlay 的形式增加或修改設備樹節點Overlay的路徑:
———boards/<架構>/<板級名稱>/
———或者sample/xxx/boards

2.Overlay加載優先級(從高到低)
———顯式指定文件最高優先級?
通過CMake變量 DTC_OVERLAY_FILE 顯式指定的文件(如 -DDTC_OVERLAY_FILE="file1.overlay;file2.overlay"),按聲明順序加載,后聲明者覆蓋先聲明者

———自動掃描路徑優先級?(未顯式指定時)
構建系統按順序加載以下路徑的文件,?后加載者覆蓋先加載者?:

———第一級?:socs/<SOC型號>.overlay(如 socs/nrf52840.overlay)
———第二級?:boards/<板卡名>.overlay(如 boards/nrf52840dk.overlay)
———第三級?:應用根目錄的 app.overlay
———示例:boards/nrf52840dk.overlay 可覆蓋 socs/nrf52840.overlay 的配置。


3.?硬件修訂版覆蓋?
若存在板卡修訂版(如 nrf52840dk_v2),則 boards/<板卡名>_<修訂版>.overlay 會覆蓋基礎板級文件(boards/<板卡名>.overlay

4.示例

&i2c1 {status = "okay";fake_eeprom: eeprom@77 {compatible = "fake-eeprom";reg = <0x77>;size = <1024>;pagesize = <16>;address-width = <8>;timeout = <5>;buffer_size = <4096>;/* read-only; */};
};

yaml

1.對于 .yaml 文件,其他內容主要是指定該設備樹節點下的所有屬性的約束條件,如指定類型,是否必須定義等
YAML綁定文件?必須?位于名為 dts/bindings/ 的目錄中,但該目錄的具體父路徑可以是:
———Zephyr基礎目錄(zephyr/dts/bindings/)
———應用層目錄(如 sample/xxx/dts/bindings/)
———自定義模塊目錄(${ZEPHYR_MODULE_DIR}/dts/bindings/)

2.覆蓋情況:
構建系統會自動掃描所有匹配 dts/bindings/ 的路徑?;當應用層綁定文件與基礎或模塊路徑文件同名時,僅使用應用層文件進行節點驗證與宏生成

3.示例

# Copyright (c) 2021 BrainCo Inc.
# SPDX-License-Identifier: Apache-2.0description: nucleo-g474re, fake-eepromcompatible: "fake-eeprom"include: [base.yaml, i2c-device.yaml]properties:size:type: intrequired: truedescription: Total EEPROM size in bytespagesize:type: intrequired: truedescription: EEPROM page size in bytesaddress-width:type: intrequired: truedescription: EEPROM address width in bitstimeout:type: intrequired: truedescription: EEPROM write cycle timeout in millisecondsread-only:type: booleanrequired: falsedescription: Disable writes to the EEPROMbuffer_size:type: intrequired: truedescription: EEPROM BUFFER

dts設備匹配驅動

獲取設備

static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(temp_sensor)); //設備樹節點的label屬性
const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(eeprom0)); //設備樹節點的別名,如果有的話可以用這個

驅動匹配設備樹節點

#define DT_DRV_COMPAT vendor_temp_sensor //需與設備樹compatible中的逗號等非字母的特殊字符,替換為下劃線

driver通過dts創建設備對象

#define INST_DT_FAKE_EEPROM(inst) DT_INST(inst, fake_eeprom)
#define FAKE_EEPROM_DEVICE(inst) static const struct eeprom_config eeprom_config_##inst = { .i2c = I2C_DT_SPEC_INST_GET(inst), .addr_width = DT_PROP(INST_DT_FAKE_EEPROM(inst), address_width), .readonly = DT_PROP(INST_DT_FAKE_EEPROM(inst), read_only), .timeout = DT_PROP(INST_DT_FAKE_EEPROM(inst), timeout), .size = DT_PROP(INST_DT_FAKE_EEPROM(inst), size), }; static uint8_t eeprom_buffer_##inst[DT_PROP(INST_DT_FAKE_EEPROM(inst), buffer_size)]; static struct eeprom_data eeprom_data_##inst = { .buffer = eeprom_buffer_##inst, .state = false, }; DEVICE_DT_INST_DEFINE(inst, &eeprom_init, NULL, &eeprom_data_##inst, &eeprom_config_##inst, POST_KERNEL, 10, &eeprom_api);
DT_INST_FOREACH_STATUS_OKAY(FAKE_EEPROM_DEVICE)

非dts匹配

driver創建設備對象

DEVICE_DEFINE(my_driver_0, "my_driver", my_driver_init, NULL, NULL, NULL, POST_KERNEL, 0, &api);

app獲取設備

const struct device *dev = device_get_binding("my_driver");

設備驅動讀寫函數流程

通過I2C_DT_SPEC_INST_GET從設備樹解析出i2c_dt_spec,并且也填充了i2c_dt_spec的bus成員,也即i2c總線,調用總線的api就可以操作i2c控制器的寄存器們,來完成讀寫工作;spi_dt_spec,gpio_dt_spec同理

struct s11059_dev_config {struct i2c_dt_spec bus;uint8_t gain;int64_t integration_time; /* integration period (unit: us) */
};#define S11059_INST(inst)                                                                          \static struct s11059_data s11059_data_##inst;                                              \static const struct s11059_dev_config s11059_config_##inst = {                             \.bus = I2C_DT_SPEC_INST_GET(inst),                                                 \.gain = DT_INST_PROP(inst, high_gain),                                             \.integration_time = DT_INST_PROP(inst, integration_time)};                         \SENSOR_DEVICE_DT_INST_DEFINE(inst, s11059_init, NULL, &s11059_data_##inst,                 \&s11059_config_##inst, POST_KERNEL,                           \CONFIG_SENSOR_INIT_PRIORITY, &s11059_driver_api);DT_INST_FOREACH_STATUS_OKAY(S11059_INST)static int s11059_control_write(const struct device *dev, uint8_t control)
{const struct s11059_dev_config *cfg = dev->config;const uint8_t opcode[] = {S11059_REG_ADDR_CONTROL, control};return i2c_write_dt(&cfg->bus, opcode, sizeof(opcode));
}static inline int i2c_write_dt(const struct i2c_dt_spec *spec,const uint8_t *buf, uint32_t num_bytes)
{return i2c_write(spec->bus, buf, num_bytes, spec->addr);
}static inline int i2c_write(const struct device *dev, const uint8_t *buf,uint32_t num_bytes, uint16_t addr)
{struct i2c_msg msg;msg.buf = (uint8_t *)buf;msg.len = num_bytes;msg.flags = I2C_MSG_WRITE | I2C_MSG_STOP;return i2c_transfer(dev, &msg, 1, addr);
}__syscall int i2c_transfer(const struct device *dev,struct i2c_msg *msgs, uint8_t num_msgs,uint16_t addr);static inline int z_impl_i2c_transfer(const struct device *dev,struct i2c_msg *msgs, uint8_t num_msgs,uint16_t addr)
{const struct i2c_driver_api *api =(const struct i2c_driver_api *)dev->api;if (!num_msgs) {return 0;}if (!IS_ENABLED(CONFIG_I2C_ALLOW_NO_STOP_TRANSACTIONS)) {msgs[num_msgs - 1].flags |= I2C_MSG_STOP;}int res =  api->transfer(dev, msgs, num_msgs, addr);i2c_xfer_stats(dev, msgs, num_msgs);if (IS_ENABLED(CONFIG_I2C_DUMP_MESSAGES)) {i2c_dump_msgs_rw(dev, msgs, num_msgs, addr, true);}return res;
}

主機驅動讀寫api

static DEVICE_API(i2c, nxp_ii2c_driver_api) = {.configure = nxp_ii2c_configure,.transfer = nxp_ii2c_transfer,
#ifdef CONFIG_I2C_CALLBACK.transfer_cb = nxp_ii2c_transfer_cb,
#endif
#ifdef CONFIG_I2C_RTIO.iodev_submit = i2c_iodev_submit_fallback,
#endif
};

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88442.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88442.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88442.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mysql字段沒有索引,通過where x = 3 for update是使用什么級別的鎖

沒有索引時&#xff0c;FOR UPDATE 會鎖住整個表 現在&#xff0c;你正在一本一本地翻看所有書&#xff0c;尋找“維修中”的書&#xff0c;并且你對管理員說&#xff1a;“在我清點和修改完之前&#xff0c;別人不能動這些書&#xff0c;也不能往這個范圍里加新書&#xff01;…

TCP-與-UDP-協議詳解:原理、區別與應用場景全解析

TCP 與 UDP 協議詳解&#xff1a;原理、區別與應用場景全解析 在日常使用網絡的過程中&#xff0c;我們經常聽到 TCP 和 UDP 這兩個詞。你打開網頁、發送消息、觀看視頻&#xff0c;背后都在使用 TCP 或 UDP 進行數據傳輸。那么這兩個協議到底是怎么工作的&#xff1f;它們之間…

GitHub信息收集

目錄 簡介 一、入門搜索技巧 1. 基本關鍵詞搜索 2. 文件類型限定搜索 3. 用戶/組織定向搜索 二、精準定位技巧 1. 組合搜索條件 2. 排除干擾結果 3. 路徑限定搜索 三、防御建議 四、法律與道德提醒 簡介 GitHub作為全球最大的代碼托管平臺&#xff0c;存儲著數十億…

由 DB_FILES 參數導致的 dg 服務器無法同步問題

由 DB_FILES 參數導致的 dg 服務器無法同步問題 用戶反映&#xff0c;dg 服務器數據從昨晚&#xff08;7月8日&#xff09;開始停止同步。 連接服務器發現沒有 mrp 進程&#xff0c;并且 OPEN_MODE 參數也不正確。具體情況如下所示&#xff1a; SQL> select process, status…

Go語言泛型-泛型對代碼結構的優化

在Go語言中,Go泛型-泛型對代碼結構的優化部分主要探討了泛型如何幫助我們優化代碼結構、減少重復代碼,并提高代碼的可維護性、可讀性和復用性。以下是詳細內容: 一、引言 Go 1.18 引入了泛型,極大地提高了語言的靈活性。泛型使得我們可以編寫更加通用、可復用且類型安全的…

【1-快速上手】

文章目錄前言簡介什么是 Konva&#xff1f;安裝 Konva概述它是如何工作的&#xff1f;基本形狀樣式事件拖放濾鏡動畫選擇器序列化與反序列化性能前言 結合項目實際業務需求&#xff0c;在 Fabric、Konva 等圖形化框架中&#xff0c;我選擇了性能表現好的 Konva。首先去學習官方…

【LeetCode】209. 長度最小的子數組(前綴和 + 二分)

【LeetCode】209. 長度最小的子數組&#xff08;前綴和 二分&#xff09;題目描述前綴和二分優化前綴和總結二分總結題目描述 題目鏈接&#xff1a;【LeetCode】209. 長度最小的子數組&#xff08;前綴和 二分&#xff09; 給定一個含有 n 個整數的數組和一個整數 target。…

文件系統----底層架構

當我們談到文件系統的時候&#xff0c;最重要的點在于&#xff1a;文件的內容與屬性是如何存儲在磁盤中的&#xff1f;以及操作系統是如何精準定位到這些文件內容的&#xff1f;在談及文件的內核前&#xff0c;我們先來了解一下儲存文件的硬件-----硬盤一.理解硬件首先我們來看…

小程序開發平臺,自主開發小程序源碼系統,多端適配,帶完整的部署教程

溫馨提示&#xff1a;文末有資源獲取方式全開源與自主開發源碼完全開放&#xff1a;開發者可自由修改前端界面、后端邏輯及數據庫結構&#xff0c;支持深度定制&#xff08;如調整用戶端交互流程、商家端管理功能等&#xff09;。技術棧透明&#xff1a;基于主流技術&#xff0…

stp拓撲變化分類

Max Age 20sHellotime 2sForward delay 153、拓撲改變需要多長時間1&#xff09;根橋故障&#xff1a;需要50秒&#xff08;Max age2個forwarding delay&#xff09;2&#xff09;非直連鏈路&#xff1a;非直連故障在穩定的STP網絡&#xff0c;非根橋會定期收到來自根橋的BPDU報…

一、深度學習——神經網絡

一、神經網絡 1.神經網絡定義&#xff1a;人工神經網絡&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;也簡稱為神經網絡&#xff08;NN&#xff09;&#xff0c;是一種模仿生物神經網絡結構和功能的計算模型。人腦可以看作是一個生物神經網絡&#xff0c;由…

【牛客算法】 小紅的奇偶抽取

文章目錄 一、題目介紹1.1 題目描述1.2 輸入描述1.3 輸出描述1.4 示例二、解題思路2.1 核心算法設計2.2 性能優化關鍵2.3 算法流程圖三、解法實現3.1 解法一:字符串分離法3.1.1 初級版本分析3.2 解法二:數學逐位構建法(推薦)3.2.1 優化版本分析四、總結與拓展4.1 關鍵優化技…

Maven 繼承:構建高效項目結構的利器

一、引言 Maven 是一個強大的項目管理工具&#xff0c;它通過標準化的項目結構和依賴管理極大地簡化了 Java 項目的開發流程。在 Maven 中&#xff0c;繼承是一種非常有用的功能&#xff0c;它允許我們創建一個父項目&#xff0c;其他子項目可以繼承這個父項目的配置信息&#…

Mysql組合索引的update在多種情況下的間隙鎖的范圍(簡單來說)

簡單來說&#xff0c;當 UPDATE 語句的 WHERE 條件使用了組合索引&#xff0c;并且需要鎖定不存在的“間隙”來防止幻讀時&#xff0c;就會產生間隙鎖。間隙鎖的范圍取決于 WHERE 條件如何利用組合索引&#xff0c;以及數據庫的隔離級別。 我們用圖書館的例子。比如&#xff1a…

什么是Apache Ignite的affinity(親和性)

在 Apache Ignite 中&#xff0c; affinity&#xff08;親和性&#xff09; 是一種用于控制數據分布和查詢性能的重要機制。它允許開發者指定數據如何在集群中的節點之間分布&#xff0c;從而優化數據訪問和查詢效率。以下是關于 affinity 的詳細解釋&#xff1a;數據親和性&a…

youtube圖論

dfs排序lifo & fifo存儲方式鄰接矩陣dijstra處理過的保存/更新&#xff0c;意味著一個節點避免了重復訪問bfs dfs

借助ssh實現web服務的安全驗證

背景 公有云服務器 http 服務 80端口&#xff0c;想做到安全訪問無須HTTPS 客戶端證書方便、快捷、安全 SSH 隧道 本地代理 使用 SSH 隧道將 HTTP 服務“隱藏”在 SSH 之后&#xff1a; # 客戶端建立隧道&#xff08;將本地 8080 轉發到服務器的 80 端口&#xff09; ssh…

狀態機在前端開發中的藝術:從理論到框架級實踐

文章目錄一 狀態機&#xff1a;復雜邏輯的終結者1.1 什么是狀態機&#xff1f;1.2 為何前端需要狀態機&#xff1f;二 狀態機核心概念深度解析2.1 有限狀態機&#xff08;FSM&#xff09;與分層狀態機&#xff08;HSM&#xff09;2.2 狀態機的數學表示三 前端開發中的狀態機實戰…

把word中表格轉成excle文件

把word中表格轉成excle文件 from docx import Document from openpyxl import Workbook from pathlib import Path# 打開 Word 文檔 document Document(./weather_report.docx) tables document.tables# 輸出文件路徑 output_file Path(./weather_report.xlsx)# 如果文件已存…

運維打鐵: 阿里云 ECS 實例的高效運維與管理

文章目錄思維導圖正文內容一、實例基礎管理1. 實例創建2. 實例配置調整3. 實例停止與啟動二、性能監控與優化1. 系統性能指標監控2. 磁盤 I/O 優化3. 網絡優化三、安全防護1. 防火墻設置2. 賬號安全管理3. 數據備份與恢復四、自動化運維1. 腳本自動化2. 使用云助手五、成本優化…