[實戰] Petalinux驅動開發以及代碼框架解讀

目錄

  • Petalinux驅動開發以及代碼框架解讀
    • 一、引言
    • 二、步驟
      • 2.1 創建PetaLinux工程
      • 2.2 配置硬件描述文件
      • 2.3 設備樹配置
      • 2.4 建立驅動框架
      • 2.5 編輯 `.bb` 文件
      • 2.6 編寫驅動文件
      • 2.7 編寫 `Makefile`
      • 2.8 驗證配方配置
      • 2.9 集成驅動到 RootFS
      • 2.10 全系統編譯與部署
      • 2.11 啟動驗證
    • 三、框架解讀
      • 3.1 模塊基本信息
      • 3.2 模塊參數
      • 3.3 數據結構:customGpioExport_local
      • 3.4 中斷處理函數
      • 3.5 Probe函數:設備初始化
        • **功能**:
        • **流程**:
      • 3.5 Remove函數:資源釋放
      • 3.7 設備樹匹配
      • 3.8 平臺驅動結構體
      • 3.9 模塊初始化和退出
      • 3.10 代碼執行流程
      • 3.11 潛在改進點
    • 四、結語

Petalinux驅動開發以及代碼框架解讀

一、引言

Petalinux是Xilinx提供的Linux開發工具鏈。通過Petalinux,可以很輕松的完成Xilinx SOC的Linux系統定制,驅動和應用開發。本文主要從驅動開發角度,基于petalinux2022.2版本,介紹如何同通過Petalinux開發自己的驅動。


二、步驟

安裝Petalinux以及使用Vivado創建SOC工程,這些基礎步驟,網上由太多教程,這里就不累述了。這里假設大家已經安裝好了Vivado,Petalinux,并已經通過Vivado工程導出了硬件描述文件(.xsa文件)。

2.1 創建PetaLinux工程

petalinux-create -t project --name zynq_gpio_demo --template zynq
cd zynq_gpio_demo

2.2 配置硬件描述文件

  1. 將Vivado生成的system.xsa文件復制到工程目錄。
  2. 導入硬件配置:
    petalinux-config --get-hw-description=.
    

2.3 設備樹配置

project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi中添加GPIO節點:

/ {custom_gpios {compatible = "customGpioExport";status = "okay";gpios = <&gpio0 54 GPIO_ACTIVE_HIGH>,  // EMIO GPIO0<&gpio0 55 GPIO_ACTIVE_HIGH>; // EMIO GPIO1};
};
  • 關鍵屬性
    • compatible:驅動匹配標識符。
    • gpios:指定GPIO控制器、引腳號和激活電平。

2.4 建立驅動框架

petalinux為用戶開發自己的驅動建立了完整易用的驅動框架,可以通過petalinux-create -t modules命令創建,如下所示:

petalinux-create -t modules --name customGpioExport --enable

通過上述指令,就會在{petalinux project}/project-spec/meta-user/recipes-modules/目錄下生成custom_gpio_export 目錄,在該目錄下,自動生成了custom_gpio_export .bb文件以及files文件加,在files文件夾下,成了驅動框架文件customGpioExport .c以及Makefile,以下是目錄結構圖:

{petalinux project}/
└── project-spec/└── meta-user/└── recipes-modules/└── customGpioExport/├── customGpioExport.bb└── files/├── customGpioExport.c└── Makefile

2.5 編輯 .bb 文件

打開{petalinux project}/project-spec/meta-user/recipes-modules/customGpioExport下的customGpioExport.bb文件并修改內容如下:

# 配方基礎配置
SUMMARY = "Custom GPIO Export Driver"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"# 定義模塊名稱和源碼路徑
MODULE_NAME = "customGpioExport"
SRC_URI = " \file://${MODULE_NAME}.c \file://Makefile \
"# 指定源碼目錄(默認為當前目錄)
S = "${WORKDIR}"# 繼承內核模塊構建類
inherit module# 定義模塊編譯參數
EXTRA_OEMAKE:append = " \KERNEL_SRC=${STAGING_KERNEL_DIR} \KERNEL_VERSION=${KERNEL_VERSION} \
"# 安裝目標(將模塊復制到 rootfs 的 /lib/modules/ 目錄)
do_install() {install -d ${D}/lib/modules/${KERNEL_VERSION}/extrainstall -m 0644 ${B}/${MODULE_NAME}.ko ${D}/lib/modules/${KERNEL_VERSION}/extra/
}# 定義模塊依賴(可選)
# DEPENDS = "virtual/kernel"

關鍵配置解釋

  • SRC_URI
    指定驅動源碼路徑。此處假設源碼文件為 customGpioExport.cMakefile,位于 files 子目錄。
    若源碼文件名為 customGpioExport.c,需同步修改:

    SRC_URI = " \file://customGpioExport.c \file://Makefile \
    "
    
  • inherit module
    繼承內核模塊構建類,自動處理模塊編譯和簽名(如需 Secure Boot)。

  • EXTRA_OEMAKE
    make 命令傳遞額外參數:

    • KERNEL_SRC:指向內核源碼目錄。
    • KERNEL_VERSION:內核版本號(自動填充)。
  • do_install
    定義模塊安裝邏輯,將生成的 .ko 文件復制到 rootfs 的 /lib/modules/$(uname -r)/extra/ 目錄。


2.6 編寫驅動文件

根據自己需要以customGpioExport.c為基礎框架,增加自己模塊需要的功能實現即可,不在這里累述。

2.7 編寫 Makefile

確保 files/Makefile 內容如下(適配內核模塊編譯):

obj-m := custom_gpio_export.oKERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)all:$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modulesclean:$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
  • 注意
    • obj-m 后的目標名必須與 .c 文件名一致(例如 customGpioExport.ccustomGpioExport.o)。
    • 若源碼文件名為 customGpioExport.c,需修改為:
      obj-m := customGpioExport.o
      customGpioExport-objs := customGpioExport.o
      

2.8 驗證配方配置

執行以下命令檢查語法和路徑:

# 進入 PetaLinux 工程根目錄
cd zynq_gpio_demo# 運行 BitBake 解析配方
petalinux-build -c customGpioExport --force
  • 預期輸出
    若配置正確,將輸出編譯日志并在 build/tmp/work/.../customGpioExport/ 下生成 .ko 文件。

  • 常見錯誤

    • 文件未找到:檢查 SRC_URIfiles/ 目錄中的文件名是否一致。
    • 編譯錯誤:查看 build/tmp/work/.../temp/log.do_compile 中的詳細日志。

2.9 集成驅動到 RootFS

petalinux-config 中啟用模塊自動加載:

petalinux-config -c rootfs

進入菜單:

Filesystem Packages  --->module  --->customGpioExport  --->[*] customGpioExport

2.10 全系統編譯與部署

petalinux-build
petalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga images/linux/system.bit --u-boot

2.11 啟動驗證

系統啟動后檢查模塊加載:

# 查看模塊是否加載
lsmod | grep customGpioExport# 手動加載(若未自動加載)
modprobe customGpioExport# 檢查 GPIO 導出狀態
ls /sys/class/gpio/

三、框架解讀

3.1 模塊基本信息

代碼開頭通過宏定義了模塊的基本信息:

  • MODULE_LICENSE(“GPL”):聲明模塊遵循GPL協議。
  • MODULE_AUTHORMODULE_DESCRIPTION:提供作者和模塊描述。
  • MODULE_DEVICE_TABLE(of, …):用于與設備樹中的節點匹配(后文詳述)。

3.2 模塊參數

通過module_param定義了兩個模塊參數:

unsigned myint = 0xdeadbeef;
char *mystr = "default";
module_param(myint, int, S_IRUGO);  // 整型參數
module_param(mystr, charp, S_IRUGO); // 字符串參數
  • 這些參數可在加載模塊時通過命令行指定,例如:
    insmod customGpioExport.ko myint=1234 mystr="hello"
    
  • 參數權限為S_IRUGO,表示用戶空間可讀但不可寫。

3.3 數據結構:customGpioExport_local

struct customGpioExport_local {int irq;                   // 中斷號unsigned long mem_start;   // 內存起始地址unsigned long mem_end;     // 內存結束地址void __iomem *base_addr;   // 映射后的虛擬地址
};
  • 該結構體保存設備的硬件資源信息,如中斷號、寄存器物理地址及其映射后的虛擬地址。

3.4 中斷處理函數

static irqreturn_t customGpioExport_irq(int irq, void *lp) {printk("customGpioExport interrupt\n");return IRQ_HANDLED;
}
  • 當設備觸發中斷時,此函數被調用。
  • 當前僅打印一條日志,實際應用中需添加具體的中斷處理邏輯(如讀取狀態寄存器、處理數據等)。
  • 注意request_irq的第三個參數(標志位)為0,未指定觸發方式(如上升沿或電平觸發),可能需要根據硬件需求調整。

3.5 Probe函數:設備初始化

static int customGpioExport_probe(struct platform_device *pdev)
功能
  • 在設備樹匹配到驅動時調用,負責初始化設備資源(內存、中斷等)。
流程
  1. 獲取內存資源

    r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    
    • 從設備樹中獲取寄存器內存范圍(mem_startmem_end)。
  2. 分配結構體內存

    lp = kmalloc(sizeof(struct customGpioExport_local), GFP_KERNEL);
    
    • customGpioExport_local分配內存,保存設備信息。
  3. 請求內存區域

    request_mem_region(lp->mem_start, ...);
    
    • 鎖定物理內存區域,防止其他驅動占用。
  4. 內存映射

    lp->base_addr = ioremap(lp->mem_start, ...);
    
    • 將物理地址映射為內核虛擬地址,后續可通過iowrite32/ioread32等函數訪問寄存器。
  5. 獲取中斷資源

    r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    
    • 若設備樹中定義了中斷,注冊中斷處理函數:
      request_irq(lp->irq, &customGpioExport_irq, 0, ...);
      
  6. 錯誤處理

    • 若某步驟失敗,依次釋放已申請的資源(如release_mem_regioniounmapkfree等)。

3.5 Remove函數:資源釋放

static int customGpioExport_remove(struct platform_device *pdev)
  • 在模塊卸載或設備移除時調用。
  • 釋放所有資源:中斷、虛擬地址映射、內存區域及結構體內存。

3.7 設備樹匹配

static struct of_device_id customGpioExport_of_match[] = {{ .compatible = "vendor,customGpioExport", },{ /* end of list */ },
};
  • 通過compatible屬性與設備樹中的節點匹配。例如,設備樹中需包含:
    customGpioExport@0x12340000 {compatible = "vendor,customGpioExport";reg = <0x12340000 0x1000>;interrupts = <0 29 4>;
    };
    

3.8 平臺驅動結構體

static struct platform_driver customGpioExport_driver = {.driver = {.name = DRIVER_NAME,.of_match_table = customGpioExport_of_match,},.probe = customGpioExport_probe,.remove = customGpioExport_remove,
};
  • 定義平臺驅動的名稱、設備樹匹配表、Probe和Remove函數。

3.9 模塊初始化和退出

  • 初始化

    static int __init customGpioExport_init(void) {platform_driver_register(&customGpioExport_driver);printk("Hello module world.\n");
    }
    
    • 注冊平臺驅動,并打印初始化信息。
  • 退出

    static void __exit customGpioExport_exit(void) {platform_driver_unregister(&customGpioExport_driver);printk("Goodbye module world.\n");
    }
    
    • 注銷驅動并清理資源。

3.10 代碼執行流程

  1. 模塊加載

    • 執行customGpioExport_init,注冊平臺驅動。
    • 內核掃描設備樹,若找到匹配的compatible節點,調用customGpioExport_probe初始化設備。
  2. 設備初始化

    • 申請內存、映射地址、注冊中斷(如有)。
  3. 模塊卸載

    • 執行customGpioExport_exit,注銷驅動并調用customGpioExport_remove釋放資源。

3.11 潛在改進點

  1. 中斷標志位request_irq未指定觸發方式(如IRQF_TRIGGER_RISING),需根據硬件配置。
  2. GPIO功能:當前代碼未實現GPIO的導出或操作邏輯,需補充gpio_requestgpio_direction_output等函數。
  3. 模塊參數應用myintmystr未被使用,可擴展為配置參數(如設置GPIO初始狀態)。

總結
此代碼是一個典型的內核模塊框架,實現了設備樹匹配、資源管理、中斷處理等基礎功能,但具體功能(如GPIO操作)需進一步擴展。開發者可根據實際需求,在Probe函數中添加硬件初始化代碼,并在中斷處理函數中實現業務邏輯。


四、結語

在petalinux框架下,完成linux驅動開發門檻大大降低,效率提高不少,希望這篇文章能夠拋磚引玉,對大家有所幫助。


研究學習不易,點贊易。
工作生活不易,收藏易,點收藏不迷茫 :)


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

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

相關文章

[特殊字符] 開發工作高內存占用場景下,Windows 內存壓縮機制是否應該啟用?實測分析與優化建議

在日常開發中&#xff0c;我們往往需要同時運行多個高占用內存的工具&#xff0c;例如&#xff1a; IntelliJ IDEA VMware 虛擬機 多個 Java 后端程序 這些應用程序非常“吃內存”&#xff0c;輕松就能把 16GB、甚至 24GB 的物理內存用滿。那么&#xff0c;Windows 的“內存…

嵌入式學習筆記 - HAL_xxx_MspInit(xxx);函數

使用cubeMX生成的HAL庫函數中&#xff0c;所有外設的初始化函數HAL_xxx_Init(&xxxHandle)中都存在有此調用函數HAL_xxx_MspInit(xxx)&#xff0c;此調用函數其實是對各外設模塊比如UART&#xff0c;I2C等控制器使用的的底層硬件進行初始化&#xff0c;包括時鐘&#xff0c;…

Nginx — http、server、location模塊下配置相同策略優先級問題

一、配置優先級簡述 在 Nginx 中&#xff0c;http、server、location 模塊下配置相同策略時是存在優先級的&#xff0c;一般遵循 “范圍越小&#xff0c;優先級越高” 的原則&#xff0c;下面為你詳細介紹&#xff1a; 1. 配置繼承關系 http 塊&#xff1a;作為全局配置塊&…

WPF之TextBlock控件詳解

文章目錄 1. TextBlock控件介紹2. TextBlock的基本用法2.1 基本語法2.2 在代碼中創建TextBlock 3. TextBlock的常用屬性3.1 文本內容相關屬性3.2 字體相關屬性3.3 外觀相關屬性3.4 布局相關屬性 4. TextBlock文本格式化4.1 使用Run元素進行內聯格式化4.2 其他內聯元素 5. 處理長…

華為云loT物聯網介紹與使用

&#x1f310; 華為云 IoT 物聯網平臺詳解&#xff1a;構建萬物互聯的智能底座 隨著萬物互聯時代的到來&#xff0c;物聯網&#xff08;IoT&#xff09;已成為推動數字化轉型的關鍵技術之一。華為云 IoT 平臺&#xff08;IoT Device Access&#xff09;作為華為云的核心服務之…

AnimateCC教學:形狀補間動畫的代碼實現

核心代碼: var shape; var animationProps = {width: 50,height: 50,cornerRadius: 0,color: "#00FF00" }; function init() { shape = new createjs.Shape();shape.x = 200;shape.y = 150;stage.addChild(shape);// 初始繪制updateShape();// 設置補間動畫createTw…

Android學習總結之Retrofit篇

1. 注解原理概述 在 Java 里&#xff0c;注解是一種元數據&#xff0c;它為代碼提供額外信息但不影響程序的實際邏輯。注解可以在類、方法、字段等元素上使用&#xff0c;并且能在編譯時、運行時通過反射機制被讀取。Retrofit 充分利用了 Java 注解機制&#xff0c;通過自定義…

windows11 編譯 protobuf-3.21.12 c++

下載 protobuf 包&#xff0c;本文使用 3.21.12 版本&#xff0c;Gitub下載鏈接&#xff1a; Github官網 , 網盤下載&#xff1a; 網盤 如果電腦環境沒有安裝 cmake 則需要安裝&#xff0c;本文測試使用 cmake-3.25.1 版本&#xff0c; 下載地址&#xff1a;[camke-3.25.1] (…

Java繼承中super的使用方法

super 關鍵字在 Java 中用于訪問父類的成員&#xff08;包括字段、方法和構造函數&#xff09;。當你在子類中調用父類的方法或訪問父類的成員變量時&#xff0c;super 是必不可少的工具。 &#x1f511; super 的基本用法 1. 調用父類的構造方法 在子類的構造方法中&#x…

網絡安全之淺析Java反序列化題目

前言 這段時間做了幾道Java反序列化題目&#xff0c;發現很多題目都是類似的&#xff0c;并且可以通過一些非預期gadget打進去&#xff0c;就打算總結一下常見的題目類型以及各種解法&#xff0c;并提煉出一般性的思維方法。 正文 分析入口點 拿到題目&#xff0c;有附件最…

動態規劃問題,下降路徑最小和(dp初始化問題,狀態壓縮),單詞拆分(回溯法+剪枝+記憶化),substr函數

下降路徑最小和 題目鏈接&#xff1a; 931. 下降路徑最小和 - 力扣&#xff08;LeetCode&#xff09; 題目描述&#xff1a; 給你一個 n x n 的 方形 整數數組 matrix &#xff0c;請你找出并返回通過 matrix 的下降路徑 的 最小和 。 下降路徑 可以從第一行中的任何元素開…

大數據治理自動化與智能化實踐指南:架構、工具與實戰方案(含代碼)

??個人主頁??:一ge科研小菜雞-CSDN博客 ????期待您的關注 ???? 一、引言:從人治到機治,數據治理正在進化 隨著數據體量持續膨脹、數據場景復雜化,傳統依賴人工規則的大數據治理方式已難以為繼。企業在治理過程中面臨: 數據質量問題激增,人工檢測成本高 元數…

Golang - 實現文件管理服務器

先看效果&#xff1a; 代碼如下&#xff1a; package mainimport ("fmt""html/template""log""net/http""os""path/filepath""strings" )// 配置根目錄&#xff08;根據需求修改&#xff09; //var ba…

Linux-04-用戶管理命令

一、useradd添加新用戶: 基本語法: useradd 用戶名:添加新用戶 useradd -g 組名 用戶:添加新用戶到某個組二、passwd設置用戶密碼: 基本語法: passwd 用戶名:設置用戶名密碼 三、id查看用戶是否存在: 基本語法: id 用戶名 四、su切換用戶: 基本語法: su 用戶名稱:切換用…

Ollama 安裝 QWen3 及配置外網訪問指南

一、Ollama 安裝 QWen3 安裝步驟 首先嘗試運行 QWen3 模型&#xff1a; ollama run qwen3 如果遇到版本不兼容錯誤&#xff08;Error 412&#xff09;&#xff0c;表示需要升級 Ollama&#xff1a; curl -fsSL https://ollama.com/install.sh | sh 驗證版本&#xff1a; o…

高性能架構設計-數據庫(讀寫分離)

一、高性能數據庫簡介 1.高性能數據庫方式 讀寫分離&#xff1a;將訪問壓力分散到集群中的多個節點&#xff0c;沒有分散存儲壓力 分庫分表&#xff1a;既可以分散訪問壓力&#xff0c;又可以分散存儲壓力 2.為啥不用表分區 如果SQL不走分區鍵&#xff0c;很容易出現全表鎖…

【Hive入門】Hive性能優化:執行計劃分析EXPLAIN命令的使用

目錄 1 EXPLAIN命令簡介 1.1 什么是EXPLAIN命令&#xff1f; 1.2 EXPLAIN命令的語法 2 解讀執行計劃中的MapReduce階段 2.1 執行計劃的結構 2.2 Hive查詢執行流程 2.3 MapReduce階段的詳細解讀 3 識別性能瓶頸 3.1 數據傾斜 3.2 Shuffle開銷 3.3 性能瓶頸識別與優化 4 總結 在大…

開源模型應用落地-qwen模型小試-Qwen3-8B-快速體驗(一)

一、前言 阿里云最新推出的 Qwen3-8B 大語言模型,作為國內首個集成“快思考”與“慢思考”能力的混合推理模型,憑借其 80 億參數規模及 128K 超長上下文支持,正在重塑 AI 應用邊界。該模型既可通過輕量化“快思考”實現低算力秒級響應,也能在復雜任務中激活深度推理模式,以…

Kafka Producer的acks參數對消息可靠性有何影響?

1. acks0 可靠性最低生產者發送消息后不等待任何Broker確認可能丟失消息&#xff08;Broker處理失敗/網絡丟失時無法感知&#xff09;吞吐量最高&#xff0c;適用于允許數據丟失的場景&#xff08;如日志收集&#xff09; 2. acks1 (默認值) Leader副本確認模式生產者等待Le…

虛擬機centos7安裝docker

虛擬機CentOS 7上安裝 Docker流程 1. 更新系統軟件包 需要確保系統軟件包是最新的 sudo yum -y update sudo&#xff1a;以超級用戶權限執行命令。 yum&#xff1a;CentOS的包管理器工具。 -y&#xff1a;自動確認所有提示&#xff0c;直接執行。 2. 安裝 Docker 依賴 在安裝 …