日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

WK2XXX SPI?驅(qū)動:動態(tài)申請設(shè)備號解決雙實例加載失敗

jf_44130326 ? 來源:Linux1024 ? 作者:Linux1024 ? 2026-04-08 08:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

嵌入式Linux驅(qū)動開發(fā)中,基于WK2XXX系列SPI轉(zhuǎn)串口芯片的驅(qū)動開發(fā)是很常見的需求,不少開發(fā)者會遇到兩個WK2XXX SPI驅(qū)動無法同時加載的問題,排查日志后發(fā)現(xiàn)無復(fù)雜的資源爭搶,核心癥結(jié)其實就藏在設(shè)備號的硬編碼里。本文就從問題現(xiàn)象出發(fā),剖析根本原因,并用動態(tài)申請設(shè)備號這一簡單方法徹底解決,同時附上實操步驟和排查修復(fù)流程圖,新手也能快速上手。

一、問題背景:雙驅(qū)動加載失敗,日志無復(fù)雜報錯

在基于WK2XXX系列芯片的項目開發(fā)中,需要同時加載wk2xxx_spi.c和wk2xxx_spi2.c兩個SPI轉(zhuǎn)串口驅(qū)動,實現(xiàn)多串口擴展。但實際操作中,第一個驅(qū)動能正常加載,加載第二個驅(qū)動時直接失敗,查看內(nèi)核日志dmesg僅出現(xiàn)以下關(guān)鍵信息,無其他資源沖突報錯:

[  3.752046]SPI driver wk2xxxspi0 has no spi_device_id for wkmic,wk2xxx_spi[  3.752311]spi0.0: ttysWK0 at I/O0x1 (irq =0, base_baud =691200) is a wk2xxx[  3.752669] wk02xxx_init: SPI driver for spi to Uart chip WK02XXX, etc.[  3.752673] SPI driver wk2xxxspi02 has no spi_device_id for wkmic,wk2xxx_spi02

反復(fù)排查SPI控制器、片選、中斷等資源,均未發(fā)現(xiàn)沖突,最終定位到設(shè)備號的硬編碼是導(dǎo)致該問題的唯一原因。

二、根本原因:Linux主設(shè)備號全局唯一,硬編碼導(dǎo)致沖突

要理解這個問題,首先要掌握Linux字符設(shè)備號的核心機制:

Linux的字符設(shè)備號由主設(shè)備號次設(shè)備號組成,主設(shè)備號是全局唯一的,用于標識驅(qū)動類型,內(nèi)核通過主設(shè)備號匹配對應(yīng)的驅(qū)動程序;次設(shè)備號用于區(qū)分同一驅(qū)動類型下的不同設(shè)備實例。

在WK2XXX SPI驅(qū)動的原始代碼中,開發(fā)人員對主設(shè)備號做了硬編碼定義,且wk2xxx_spi.c和wk2xxx_spi2.c兩個驅(qū)動使用了完全相同的主設(shè)備號宏定義:

// 兩個驅(qū)動均使用該硬編碼,無任何區(qū)分#defineSERIAL_WK2XXX_MAJOR  207 // 串口主設(shè)備號#defineCALLOUT_WK2XXX_MAJOR208// 呼叫主設(shè)備號

當?shù)谝粋€驅(qū)動加載時,會向內(nèi)核申請并占用207、208這兩個主設(shè)備號;第二個驅(qū)動加載時,再次向內(nèi)核申請相同的主設(shè)備號,內(nèi)核檢測到該主設(shè)備號已被占用,會直接拒絕分配,導(dǎo)致驅(qū)動加載失敗。

這也是本次問題的核心:無其他資源沖突,僅因主設(shè)備號硬編碼重復(fù),導(dǎo)致雙驅(qū)動無法同時加載,因此只需修改設(shè)備號的分配方式,即可解決問題。

三、核心解決方法:棄用硬編碼,動態(tài)申請主設(shè)備號

Linux內(nèi)核推薦動態(tài)申請主設(shè)備號,而非硬編碼指定,這也是解決本次問題的唯一方法。

動態(tài)申請設(shè)備號的優(yōu)勢

1.內(nèi)核會自動分配未被占用的主設(shè)備號,從根本上避免全局主設(shè)備號沖突;

2.無需關(guān)注內(nèi)核預(yù)留的主設(shè)備號范圍,適配性更強,跨內(nèi)核版本無需修改設(shè)備號;

3.多驅(qū)動、多實例場景下,無需手動區(qū)分設(shè)備號,開發(fā)更高效。

關(guān)鍵API說明

Linux內(nèi)核提供了專門的字符設(shè)備號動態(tài)申請和釋放API,本次修改僅需用到兩個核心函數(shù),無需引入其他頭文件,原驅(qū)動代碼已包含相關(guān)依賴:

1.動態(tài)申請:alloc_chrdev_region(&dev, minor_start, count, name)

?入?yún)ⅲ篸ev(保存分配到的設(shè)備號)、minor_start(次設(shè)備號起始值)、count(申請的設(shè)備號數(shù)量)、name(驅(qū)動名稱,用于標識);

?出參:成功返回0,失敗返回負的錯誤碼。

2.釋放設(shè)備號:unregister_chrdev_region(dev, count)

?入?yún)ⅲ篸ev(已分配的設(shè)備號)、count(申請的設(shè)備號數(shù)量);

?無返回值,用于驅(qū)動卸載時釋放已申請的設(shè)備號,避免內(nèi)存泄漏。

四、實操步驟:修改兩個驅(qū)動代碼,實現(xiàn)動態(tài)申請

本次修改基于原始的wk2xxx_spi.c和wk2xxx_spi2.c,兩個驅(qū)動的修改邏輯完全一致,僅需保證驅(qū)動名稱標識唯一即可,步驟分4步,新手也能快速完成。

步驟1:新增全局變量,保存動態(tài)分配的主設(shè)備號

在兩個驅(qū)動的宏定義區(qū)下方,新增全局變量用于保存動態(tài)分配的主設(shè)備號,替代原硬編碼的宏:

// 新增:保存動態(tài)分配的主設(shè)備號staticintser_major =0;// 原硬編碼宏保留(無需刪除,后續(xù)賦值為0即可)#defineSERIAL_WK2XXX_MAJOR  207#defineCALLOUT_WK2XXX_MAJOR208#defineMINOR_START      5#defineNR_PORTS         4    

步驟2:修改uart_driver結(jié)構(gòu)體,主設(shè)備號賦值為0

原驅(qū)動中定義了uart_driver結(jié)構(gòu)體,硬編碼指定了major字段,需將其修改為0,告訴內(nèi)核采用動態(tài)分配方式:

// wk2xxx_spi.c的uart_driver修改staticstructuart_driverwk2xxx_uart_driver = {  owner:         THIS_MODULE,  major:         0, // 關(guān)鍵修改:0表示動態(tài)分配主設(shè)備號  driver_name:      "ttySWK",  dev_name:       "ttysWK",  minor:         MINOR_START,  nr:           NR_PORTS,  cons:         NULL};// wk2xxx_spi2.c的uart_driver修改,僅需保證driver_name/dev_name唯一即可staticstructuart_driverwk02xxx_uart_driver = {  owner:         THIS_MODULE,  major:         0, // 關(guān)鍵修改:0表示動態(tài)分配主設(shè)備號  driver_name:      "ttySWK02",  dev_name:       "ttysWK02",  minor:         MINOR_START,  nr:           NR_PORTS,  cons:         NULL};

步驟3:修改驅(qū)動初始化函數(shù),添加動態(tài)申請設(shè)備號邏輯

找到驅(qū)動的__init初始化函數(shù)(wk2xxx_init/wk02xxx_init),在注冊SPI驅(qū)動前添加動態(tài)申請設(shè)備號的代碼,原硬編碼相關(guān)邏輯無需刪除,僅需新增:

// wk2xxx_spi.c的初始化函數(shù)修改staticint__init wk2xxx_init(void){ intret;  dev_t dev;//新增:定義設(shè)備號變量  // 新增:動態(tài)申請主設(shè)備號,次設(shè)備號起始為MINOR_START,共NR_PORTS個  ret = alloc_chrdev_region(&dev, MINOR_START, NR_PORTS,"wk2xxxspi0"); if(ret 

步驟4:修改驅(qū)動退出函數(shù),添加釋放設(shè)備號邏輯

找到驅(qū)動的__exit退出函數(shù)(wk2xxx_exit/wk02xxx_exit),在注銷SPI驅(qū)動后添加釋放設(shè)備號的代碼,保證資源正?;厥眨?/p>

// wk2xxx_spi.c的退出函數(shù)修改staticvoid__exitwk2xxx_exit(void){ printk(KERN_ALERT"%s!!--in--n", __func__); // 原代碼:注銷SPI驅(qū)動 spi_unregister_driver(&wk2xxx_driver); // 新增:釋放動態(tài)分配的設(shè)備號 if(ser_major >0) {   unregister_chrdev_region(MKDEV(ser_major,MINOR_START),NR_PORTS);   printk(KERN_ALERT"%s: 釋放主設(shè)備號:%dn",__func__,ser_major);  }}// wk2xxx_spi2.c的退出函數(shù)修改staticvoid__exitwk02xxx_exit(void){ printk(KERN_ALERT"%s!!--in--n", __func__); // 原代碼 spi_unregister_driver(&wk02xxx_driver); // 新增:釋放設(shè)備號 if(ser_major >0) {   unregister_chrdev_region(MKDEV(ser_major,MINOR_START),NR_PORTS);   printk(KERN_ALERT"%s: 釋放主設(shè)備號:%dn",__func__,ser_major);  }}

關(guān)鍵注意點

兩個驅(qū)動的修改僅需保證動態(tài)申請設(shè)備號的驅(qū)動名稱(alloc_chrdev_region的第四個參數(shù))和uart_driver的driver_name/dev_name唯一即可,其余邏輯完全一致,無需做額外修改。

五、WK2XXX雙驅(qū)動加載失敗排查&修復(fù)流程圖

為了方便大家在實際開發(fā)中快速排查同類問題,整理了專屬流程圖,從問題發(fā)現(xiàn)到功能驗證,一步到位,可直接收藏備用:

wKgZPGnVm6-AZ_jAAANmpxJIX8E417.png

六、驗證:三步確認驅(qū)動加載正常

修改代碼并編譯出.ko驅(qū)動模塊后,依次加載兩個驅(qū)動,通過以下三步驗證是否修復(fù)成功,操作簡單且高效。

步驟1:查看動態(tài)分配的主設(shè)備號

執(zhí)行命令cat /proc/devices,查看字符設(shè)備列表,能看到兩個驅(qū)動被分配了不同的主設(shè)備號,說明設(shè)備號申請成功:

# 示例輸出,實際主設(shè)備號由內(nèi)核分配Characterdevices: ...245ttySWK   # wk2xxx_spi.c的驅(qū)動246ttySWK02  # wk2xxx_spi2.c的驅(qū)動 ...

步驟2:查看/dev下的設(shè)備節(jié)點

執(zhí)行命令ls /dev/ttysWK*,能看到兩個驅(qū)動對應(yīng)的設(shè)備節(jié)點均成功創(chuàng)建,無重復(fù):

/dev/ttysWK0 /dev/ttysWK1 /dev/ttysWK2 /dev/ttysWK3 /dev/ttysWK020 /dev/ttysWK021 /dev/ttysWK022 /dev/ttysWK023

步驟3:串口功能測試

通過minicom/screen等工具分別操作兩個驅(qū)動的串口節(jié)點,向串口發(fā)送/接收數(shù)據(jù),驗證通信正常,說明雙驅(qū)動已實現(xiàn)同時加載且功能正常。

七、拓展知識點:Linux主設(shè)備號的那些事

1.主設(shè)備號范圍:Linux內(nèi)核中主設(shè)備號的取值范圍是1255,其中1127是內(nèi)核預(yù)留的主設(shè)備號,128~255是用戶自定義的主設(shè)備號,硬編碼時建議使用128以后的數(shù)值,但仍有沖突風險;

2.硬編碼的弊端:除了本次的多驅(qū)動沖突,硬編碼主設(shè)備號還會導(dǎo)致跨內(nèi)核版本適配失敗(部分內(nèi)核版本會調(diào)整預(yù)留主設(shè)備號),以及與其他第三方驅(qū)動沖突;

3.動態(tài)申請的適配性:動態(tài)申請主設(shè)備號時,內(nèi)核會從未被占用的數(shù)值中自動分配,無需關(guān)注內(nèi)核版本和其他驅(qū)動,是嵌入式Linux驅(qū)動開發(fā)的最佳實踐。

八、總結(jié)

本次WK2XXX SPI雙驅(qū)動無法同時加載的問題,是嵌入式Linux驅(qū)動開發(fā)中典型的全局資源硬編碼沖突問題,核心僅因主設(shè)備號硬編碼重復(fù),無需排查復(fù)雜的SPI、中斷、IO資源,僅通過動態(tài)申請主設(shè)備號這一招即可徹底解決。

同時也給我們一個開發(fā)提醒:在嵌入式Linux驅(qū)動開發(fā)中,尤其是多驅(qū)動、多實例的場景下,應(yīng)盡量避免硬編碼全局唯一的資源(如主設(shè)備號、IO地址、中斷號),遵循Linux內(nèi)核的動態(tài)分配原則,既能避免資源沖突,又能提升驅(qū)動的適配性和可移植性。

本次的修改方法不僅適用于WK2XXX SPI驅(qū)動,也適用于其他Linux字符設(shè)備驅(qū)動的多實例加載場景,可直接復(fù)用!

審核編輯 黃宇

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

    關(guān)注

    88

    文章

    11822

    瀏覽量

    219600
  • 驅(qū)動開發(fā)
    +關(guān)注

    關(guān)注

    0

    文章

    142

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

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

    RT-Thread 新一代驅(qū)動框架 DM 揭秘:從設(shè)備樹到動態(tài)加載,徹底告別硬編碼 | 技術(shù)集結(jié)

    (DeviceTree)、自動匹配與動態(tài)probe機制,讓驅(qū)動開發(fā)更加現(xiàn)代化、可擴展。本文以qemu-virt64-aarch64平臺為例,帶你從零上手DM框架:設(shè)備樹的
    的頭像 發(fā)表于 04-24 18:05 ?5225次閱讀
    RT-Thread 新一代<b class='flag-5'>驅(qū)動</b>框架 DM 揭秘:從<b class='flag-5'>設(shè)備</b>樹到<b class='flag-5'>動態(tài)</b><b class='flag-5'>加載</b>,徹底告別硬編碼 | 技術(shù)集結(jié)

    PIC18F2XXX/4XXX系列閃存微控制器編程規(guī)范解析

    PIC18F2XXX/4XXX系列閃存微控制器編程規(guī)范解析 一、引言 今天我們來深入探討PIC18F2XXX/4XXX系列閃存微控制器的編程規(guī)范。這個系列包含了眾多型號的
    的頭像 發(fā)表于 04-08 10:05 ?564次閱讀

    SGM42541H橋驅(qū)動IC:自動化設(shè)備的得力助手

    SGM42541H橋驅(qū)動IC:自動化設(shè)備的得力助手 在電子設(shè)備的自動化定位和運動控制領(lǐng)域,電機驅(qū)動IC起著至關(guān)重要的作用。今天,我們就來深
    的頭像 發(fā)表于 03-26 11:15 ?226次閱讀

    Microchip PIC18F2XXX/4XXX 系列閃存微控制器編程指南

    Microchip PIC18F2XXX/4XXX 系列閃存微控制器編程指南 在電子設(shè)計領(lǐng)域,微控制器的編程是一項關(guān)鍵工作。今天,我們就來深入探討一下 Microchip 的 PIC18F2XXX
    的頭像 發(fā)表于 02-09 16:50 ?1184次閱讀

    深入解析Rockchip SFC驅(qū)動SPI Flash傳輸流程與問題排查指南

    、關(guān)鍵機制,并給出實用的問題排查方案,助力開發(fā)者快速定位問題。 一、SFC驅(qū)動核心功能概覽 Rockchip SFC驅(qū)動是Linux內(nèi)核級SPI內(nèi)存設(shè)備
    的頭像 發(fā)表于 02-04 07:13 ?846次閱讀
    深入解析Rockchip SFC<b class='flag-5'>驅(qū)動</b>:<b class='flag-5'>SPI</b> Flash傳輸流程與問題排查指南

    【書籍評測活動NO.67】成為硬核Linux開發(fā)者:《Linux 設(shè)備驅(qū)動開發(fā)(第 2 版)》

    設(shè)備驅(qū)動實例,涵蓋設(shè)備管理、核心數(shù)據(jù)結(jié)構(gòu)填充及用戶與內(nèi)核空間數(shù)據(jù)交互,幫助讀者完成從理論到簡單驅(qū)動
    發(fā)表于 11-17 17:52

    CherryUSB怎樣實現(xiàn)U盤動態(tài)加載?

    USB線時,再動態(tài)地卸載U盤并掛載文件系統(tǒng)。自己償試在CherryUSB的事件回調(diào)usbd_event_handler中完成以上操作,但沒成功,相關(guān)代碼執(zhí)行不到。是CherryUSB不支持動態(tài)加載
    發(fā)表于 10-14 07:31

    基于RT-Thread的EK-RA2E2 設(shè)備驅(qū)動移植與應(yīng)用 | 技術(shù)集結(jié)

    目錄前言環(huán)境配置HelloRT-ThreadGPIO輸入與中斷I2C主機驅(qū)動SPI主機驅(qū)動ADC設(shè)備驅(qū)動
    的頭像 發(fā)表于 10-05 10:06 ?6366次閱讀
    基于RT-Thread的EK-RA<b class='flag-5'>2E2</b> <b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動</b>移植與應(yīng)用 | 技術(shù)集結(jié)

    使用NRF24l01軟件包注冊設(shè)備失敗怎么解決?

    1.根據(jù)軟件包提示第一步先打開了SPI驅(qū)動框架 2.然后軟件包添加了 nrf24l01最新版本以及demo、debug 3.在board.h #define using_spi1 在
    發(fā)表于 09-23 06:51

    RK3588 PCIe設(shè)備識別失敗?一招避坑“非法Class”陷阱

    前言:在RK3588平臺開發(fā)過程中,你是否遇到過這樣的窘境:明明PCIe總線上掛好了網(wǎng)卡模塊,lspci能識別到芯片,可驅(qū)動就是加載失敗,排查半天找不到關(guān)鍵問題?別慌!本文將帶你一步步解決這個棘手
    的頭像 發(fā)表于 08-29 08:32 ?2135次閱讀
    RK3588 PCIe<b class='flag-5'>設(shè)備</b>識別<b class='flag-5'>失敗</b>?一招避坑“非法Class”陷阱

    CX3無法將固件加載SPI閃存如何解決?

    我無法將固件加載SPI 閃存。 步驟如下: 1. 開機,運行 USB 控制中心, 2.點擊boot loader,點擊FX3,然后選擇“SPI flash”。然后USB控制中心顯示
    發(fā)表于 07-16 07:37

    USB設(shè)備設(shè)備ID按照什么邏輯進行分配?

    這樣分配的。 我想要多個USB設(shè)備先插入時,第一個設(shè)備ID應(yīng)該為0,第二個設(shè)備ID應(yīng)該為1,以此類推。 問題1: 請問,是否有什么方法,
    發(fā)表于 07-16 06:29

    請問CCyUSBDevice如何同時實例2個?

    CYAPI編程手冊中的解釋,CCyUSBDevice實例化后是連接到了cyusb driver驅(qū)動上,它能查找實例中的多臺USB設(shè)備?,F(xiàn)在的問題是假如我有
    發(fā)表于 05-19 07:27

    如何使用EZUSB-CX3實現(xiàn)階段引導(dǎo)加載程序?

    我對如何使用 EZUSB-CX3 實現(xiàn)階段引導(dǎo)加載程序有點困惑。我想要的是,當有新的 cx3 映像時,我希望能夠從 cx3 固件引導(dǎo)到第二階段引導(dǎo)加載程序,然后將新映像刷新到 SPI
    發(fā)表于 05-12 08:26

    USB 3.0CX3中的輔助引導(dǎo)加載程序后無法識別怎么解決?

    我正在為CYPRESS? CX3 (FX3) 開發(fā)輔助引導(dǎo)加載程序 (SBL),它從 SPI Flash 加載應(yīng)用程序并執(zhí)行它。 但是,通過 SBL 啟動應(yīng)用程序時,USB 3.0 枚舉失敗
    發(fā)表于 05-06 08:39
    建阳市| 略阳县| 大丰市| 海淀区| 古田县| 长子县| 金堂县| 宣化县| 吴桥县| 灵山县| 定襄县| 广安市| 北流市| 稻城县| 犍为县| 双牌县| 贵港市| 洛宁县| 合肥市| 仁怀市| 盐山县| 科技| 蓝田县| 沙洋县| 惠来县| 靖江市| 江永县| 中方县| 含山县| 芜湖县| 如东县| 虹口区| 五大连池市| 全椒县| 青冈县| 安顺市| 巫溪县| 门源| 津南区| 城市| 盐池县|