91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

驅(qū)動之路#04:LCD 驅(qū)動程序分析(基于RK3576)

BSP調(diào)試從0到1 ? 來源:嵌入式分享 ? 作者:嵌入式分享 ? 2026-02-17 08:20 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

題圖:河北太行山脈,山頭密密麻麻都被太陽能板覆蓋了。

歡迎關(guān)注,每周更新!?

本合集分享的是,我當初學習Linux驅(qū)動的來時路——《《驅(qū)動之路》開篇:自序&前言》。

正文

在實際工作中,雖然并不需要我們從零編寫 LCD 驅(qū)動程序,但必須掌握 LCD 驅(qū)動框架 —— 這是分析現(xiàn)有驅(qū)動、定位問題,以及在必要時修改驅(qū)動以適配硬件或需求的必修課。

分析之前,首先需要掌握字符設(shè)備驅(qū)動的基本框架,看前面文章《驅(qū)動之路#01:Hello World!》。LCD 驅(qū)動本質(zhì)上也是字符設(shè)備驅(qū)動,理解了字符設(shè)備驅(qū)動的框架,有助于分析 LCD 驅(qū)動程序。

下面我們就運用前面掌握的字符設(shè)備驅(qū)動基本框架,以 RK3576 平臺的 panel-simple.c 為例,淺淺分析 LCD 驅(qū)動。

驅(qū)動位置:kernel-6.1/drivers/gpu/drm/panel/panel-simple.c

如何閱讀驅(qū)動程序,準確說是如何閱讀字符設(shè)備驅(qū)動程序?閱讀一個字符設(shè)備驅(qū)動程序,應(yīng)該從它的入口函數(shù)開始看。

看到 panel-simple.c 的入口函數(shù)*register() 注冊了 3 個驅(qū)動,說明該驅(qū)動程序同時兼容DPI、DSI和SPI接口連接的 panel。

wKgZO2mTtV6ABC1gAADoM4XiIH8808.png

拿 panel_simple_dsi_driver 舉例分析,繼續(xù)往下看。當 driver 與 device(即 dts) 的 compatible 屬性匹配就會調(diào)用 panel_simple_dsi_probe 函數(shù)。

wKgZO2mTtV6AV8ayAAHNHHsufxM945.png

只有我們弄清楚panel_simple_dsi_probe函數(shù)的具體操作就基本了解了panel_simple_dsi_driver驅(qū)動,這就是分析字符設(shè)備驅(qū)動程序的大致流程。

接下來,分析 panel_simple_dsi_probe 函數(shù),直接看代碼注釋。

/** MIPI-DSI 面板探測函數(shù)* 負責初始化DSI接口的面板設(shè)備*/staticintpanel_simple_dsi_probe(structmipi_dsi_device *dsi){ /* 局部變量定義 */ structpanel_simple *panel;   // 通用面板數(shù)據(jù)結(jié)構(gòu) structdevice *dev = &dsi->dev; // 獲取設(shè)備指針,簡化后續(xù)訪問 conststructpanel_desc_dsi *desc;// DSI面板描述符(預(yù)定義或動態(tài)) structpanel_desc_dsi *d;    // 動態(tài)分配的描述符指針 conststructof_device_id *id; // 設(shè)備樹匹配結(jié)果 interr;            // 錯誤碼 /* 1. 設(shè)備樹匹配 - 檢查設(shè)備是否在驅(qū)動支持列表中 */  id = of_match_node(dsi_of_match, dsi->dev.of_node); if(!id)   return-ENODEV; // 設(shè)備不在支持列表中,返回設(shè)備不存在錯誤 /* 2. 面板描述符處理 */ if(!id->data) {   /* 情況A: 設(shè)備樹中定義了自定義面板,沒有預(yù)定義描述符 */   // 動態(tài)分配DSI面板描述符內(nèi)存    d = devm_kzalloc(dev,sizeof(*d), GFP_KERNEL);   if(!d)     return-ENOMEM; // 內(nèi)存分配失敗   /* 從設(shè)備樹節(jié)點解析面板參數(shù) */    err = panel_simple_dsi_of_get_desc_data(dev, d);   if(err) {      dev_err(dev,"failed to get desc data: %dn", err);     returnerr; // 參數(shù)解析失敗    }  } /* 注意: 如果 id->data 不為空,表示使用預(yù)定義的描述符,跳過動態(tài)分配 */ /* 3. 選擇最終使用的描述符 */  desc = id->data ? id->data : d; // 優(yōu)先使用預(yù)定義,否則使用動態(tài)解析的描述符 /* 4. 調(diào)用通用面板探測函數(shù)進行基礎(chǔ)初始化 */  err = panel_simple_probe(&dsi->dev, &desc->desc); if(err dsi = dsi;       // 將DSI設(shè)備指針保存到面板結(jié)構(gòu)中,建立雙向關(guān)聯(lián) /* 6. 背光設(shè)備處理 */ if(!panel->base.backlight) {   /* 如果面板沒有背光設(shè)備,注冊一個DCS背光設(shè)備 */   structbacklight_properties props; // 背光屬性結(jié)構(gòu)   /* 初始化背光屬性 */    memset(&props,0,sizeof(props));    props.type = BACKLIGHT_RAW;   // 背光類型:原始模式    props.brightness =255;     // 初始亮度:最大值    props.max_brightness =255;   // 最大亮度:255級   /* 注冊背光設(shè)備 */    panel->base.backlight =        devm_backlight_device_register(dev, dev_name(dev),                       dev, panel, &dcs_bl_ops,                       &props);   /* 錯誤處理 */   if(IS_ERR(panel->base.backlight)) {      err = PTR_ERR(panel->base.backlight);      dev_err(dev,"failed to register dcs backlight: %dn", err);     returnerr; // 背光設(shè)備注冊失敗    }  } /* 注意: 如果面板已有背光設(shè)備(如通過設(shè)備樹引用),則跳過此步驟 */ /* 7. 配置DSI主機控制器參數(shù) */  dsi->mode_flags = desc->flags; // 設(shè)置DSI工作模式標志  dsi->format = desc->format;   // 設(shè)置像素數(shù)據(jù)格式  dsi->lanes = desc->lanes;    // 設(shè)置數(shù)據(jù)通道數(shù)量 /* 8. 將面板附加到DSI主機 */  err = mipi_dsi_attach(dsi); if(err) {   /* 附件失敗時的清理工作 */   structpanel_simple *panel = mipi_dsi_get_drvdata(dsi);    drm_panel_remove(&panel->base); // 從DRM子系統(tǒng)移除面板  } /* 9. 返回執(zhí)行結(jié)果 */ returnerr; // 成功返回0,失敗返回錯誤碼}

我們在設(shè)備樹中定義的屏參以及mipi 屏幕相關(guān)初始化代碼。

wKgZO2mTtV6AH792AAK8_dj-zhw331.png

最終是通過函數(shù) panel_simple_dsi_of_get_desc_data()和 panel_simple_of_get_desc_data()獲取到的。

wKgZO2mTtV6ACTP8AARQ5GMJv50168.png

至此,mipi-dsi 屏幕驅(qū)動分析完畢!能分析閱讀整體驅(qū)動框架和函數(shù)調(diào)用流程就行,不需要花大量時間和精力去解讀每行代碼解讀,AI時代沒多大意義。

最后附上兩個比較重要的函數(shù),供閱讀參考。

附錄:static int panel_simple_dsi_of_get_desc_data(struct device *dev,          struct panel_desc_dsi *desc){  struct device_node *np = dev->of_node;  u32val;  int err; // 1. 首先解析通用面板參數(shù)  err = panel_simple_of_get_desc_data(dev, &desc->desc); if(err)   returnerr; // 2. 設(shè)置連接器類型為DSI  desc->desc.connector_type = DRM_MODE_CONNECTOR_DSI; // 3. 從dts解析DSI特有參數(shù) if(!of_property_read_u32(np,"dsi,flags", &val))    desc->flags =val; if(!of_property_read_u32(np,"dsi,format", &val))    desc->format =val; if(!of_property_read_u32(np,"dsi,lanes", &val))    desc->lanes =val; return0;}函數(shù) panel_simple_dsi_of_get_desc_data( )中調(diào)用 panel_simple_dsi_of_get_desc_data( )獲取面板 desc_data。static int panel_simple_of_get_desc_data(struct device *dev,          struct panel_desc *desc){  struct device_node *np = dev->of_node;  u32 bus_flags; constvoid *data;  int len;  int err; // 1. 解析顯示時序 if(of_child_node_is_present(np,"display-timings")) {    struct drm_display_mode *mode;    mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);   if(!mode)     return-ENOMEM;   // 從設(shè)備樹解析DRM顯示模式   if(!of_get_drm_display_mode(np, mode, &bus_flags,            OF_USE_NATIVE_MODE)) {      desc->modes = mode;      desc->num_modes =1;      desc->bus_flags = bus_flags;    }  }elseif(of_child_node_is_present(np,"panel-timing")) {    struct display_timing *timing;    struct videomode vm;    timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL);   if(!timing)     return-ENOMEM;   // 從設(shè)備樹解析顯示時序   if(!of_get_display_timing(np,"panel-timing", timing)) {      desc->timings = timing;      desc->num_timings =1;     // 轉(zhuǎn)換時序標志為總線標志      bus_flags =0;      vm.flags = timing->flags;      drm_bus_flags_from_videomode(&vm, &bus_flags);      desc->bus_flags = bus_flags;    }  } // 2. 解析基本面板屬性 if(desc->num_modes || desc->num_timings) {    of_property_read_u32(np,"bpc", &desc->bpc);     // 每顏色位數(shù)    of_property_read_u32(np,"connector-type", &desc->connector_type);    of_property_read_u32(np,"bus-format", &desc->bus_format);// 總線格式    of_property_read_u32(np,"width-mm", &desc->size.width); // 物理寬度    of_property_read_u32(np,"height-mm", &desc->size.height);// 物理高度  } // 3. 解析時序延遲參數(shù)  of_property_read_u32(np,"prepare-delay-ms", &desc->delay.prepare);  of_property_read_u32(np,"enable-delay-ms", &desc->delay.enable);  of_property_read_u32(np,"disable-delay-ms", &desc->delay.disable);  of_property_read_u32(np,"unprepare-delay-ms", &desc->delay.unprepare);  of_property_read_u32(np,"reset-delay-ms", &desc->delay.reset);  of_property_read_u32(np,"init-delay-ms", &desc->delay.init); // 4. 解析初始化序列 data= of_get_property(np,"panel-init-sequence", &len); if(data) {    desc->init_seq = devm_kzalloc(dev, sizeof(*desc->init_seq), GFP_KERNEL);   if(!desc->init_seq)     return-ENOMEM;   // 解析初始化命令序列    err = panel_simple_parse_cmd_seq(dev,data, len, desc->init_seq);   if(err) {      dev_err(dev,"failed to parse init sequencen");     returnerr;    }  } // 5. 解析退出序列 data= of_get_property(np,"panel-exit-sequence", &len); if(data) {    desc->exit_seq = devm_kzalloc(dev, sizeof(*desc->exit_seq), GFP_KERNEL);   if(!desc->exit_seq)     return-ENOMEM;   // 解析退出命令序列    err = panel_simple_parse_cmd_seq(dev,data, len, desc->exit_seq);   if(err) {      dev_err(dev,"failed to parse exit sequencen");     returnerr;    }  } return0;}

(完)

審核編輯 黃宇

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

    關(guān)注

    36

    文章

    4615

    瀏覽量

    177204
  • 驅(qū)動程序
    +關(guān)注

    關(guān)注

    19

    文章

    869

    瀏覽量

    50456
  • rk3576
    +關(guān)注

    關(guān)注

    1

    文章

    265

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

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

    硬核進階:RK3576 Android15?驅(qū)動與系統(tǒng)開發(fā)實戰(zhàn)指南

    RK3576 探索之旅】系列文章導航及功能全景介紹(基于android14) 之前有出過系列的文章,但這是自己公司定制項目,暫時沒有相關(guān)硬件,有需求可以私信我,這個系列主要還是驅(qū)動的開發(fā),接下來
    的頭像 發(fā)表于 01-26 22:29 ?627次閱讀
    硬核進階:<b class='flag-5'>RK3576</b> Android15?<b class='flag-5'>驅(qū)動</b>與系統(tǒng)開發(fā)實戰(zhàn)指南

    迅為RK3576對比RK3568:AI算力與接口的全面躍遷

    迅為RK3576對比RK3568:AI算力與接口的全面躍遷
    的頭像 發(fā)表于 12-22 15:24 ?1590次閱讀
    迅為<b class='flag-5'>RK3576</b>對比<b class='flag-5'>RK</b>3568:AI算力與接口的全面躍遷

    迅為如何在RK3576上部署YOLOv5;基于RK3576構(gòu)建智能門禁系統(tǒng)

    迅為如何在RK3576開發(fā)板上部署YOLOv5;基于RK3576構(gòu)建智能門禁系統(tǒng)
    的頭像 發(fā)表于 11-25 14:06 ?1796次閱讀
    迅為如何在<b class='flag-5'>RK3576</b>上部署YOLOv5;基于<b class='flag-5'>RK3576</b>構(gòu)建智能門禁系統(tǒng)

    RK3576驅(qū)動高端顯控系統(tǒng)升級:多屏拼控與AI視覺融合解決方案

    下達任務(wù)指令,副屏監(jiān)測 AI 分析結(jié)果,大屏實時展示各區(qū)域畫面與運行狀態(tài),真正實現(xiàn) “一屏決策,多屏聯(lián)動”。 八路攝像頭輸入:實現(xiàn)多源視頻融合與 AI 識別RK3576 原生支持八路攝像頭輸入
    發(fā)表于 11-21 17:51

    【作品合集】米爾RK3576開發(fā)板測評

    米爾RK3576開發(fā)板測評作品合集 產(chǎn)品介紹: RK3576 是瑞芯微一款面向AI市場推出的高性能處理器,它配備了四核Cortex-A72和四 核Cortex-A53 的 CPU,集成了6TOPS
    發(fā)表于 09-11 10:19

    【作品合集】靈眸科技EASY EAI Orin Nano(RK3576)開發(fā)板測評

    【EASY EAI Orin Nano(RK3576)開發(fā)板試用體驗】01-開箱報告及開發(fā)環(huán)境準備 【EASY EAI Orin Nano(RK3576)開發(fā)板試用體驗】02-拓展空間及內(nèi)核分析
    發(fā)表于 09-09 09:59

    瑞芯微RK3576RK3576S有什么區(qū)別,性能參數(shù)配置與型號差異解析

    瑞芯微第二代8nm高性能AIOT平臺RK3576家族再添新成員-RK3576S,先說結(jié)論:相較主型號的RK3576/RK3576J,性能略有縮減,而功耗有所降低。主要應(yīng)用于商顯終端、智
    的頭像 發(fā)表于 08-14 23:57 ?2367次閱讀
    瑞芯微<b class='flag-5'>RK3576</b>與<b class='flag-5'>RK3576</b>S有什么區(qū)別,性能參數(shù)配置與型號差異解析

    RK這2款旗艦芯片RK3588 PK RK3576,誰是最優(yōu)選

    在 AI 邊緣計算領(lǐng)域,瑞芯微的 RK3588 和 RK3576 都是備受矚目的處理器。在中國半導體產(chǎn)業(yè)的版圖中,瑞芯微作為國內(nèi) SoC 芯片領(lǐng)跑者,憑借其在處理器芯片設(shè)計領(lǐng)域的深厚積累和持續(xù)創(chuàng)新
    發(fā)表于 07-10 18:24

    Mpp支持RK3576

    想問下,https://github.com/rockchip-linux/mpp這里面支持RK3576么,看介紹沒有提到說支持RK3576 目前是買了個rk3576的機頂盒,搭載了安卓14,想做安卓視頻硬解。
    發(fā)表于 06-13 15:35

    RK3576 vs RK3588:為何越來越多的開發(fā)者轉(zhuǎn)向RK3576?

    (圖形性能更強) 分析RK3576 的 A72+A53+M0 組合 在能效比上更優(yōu),適合需要長時間運行的設(shè)備(如 IoT、平板)。 RK3588 的 A76 架構(gòu) 單核性能更強,適合高性能計算場景(如
    發(fā)表于 05-30 08:46

    適配多種系統(tǒng),米爾瑞芯微RK3576核心板解鎖多樣化應(yīng)用

    米爾電子發(fā)布的基于瑞芯微 RK3576 核心板和開發(fā)板,具備高性能數(shù)據(jù)處理能力、領(lǐng)先的AI智能分析功能、多樣化的顯示與操作體驗以及強大的擴展性與兼容性,適用于多種應(yīng)用場景。目前米爾電子為
    發(fā)表于 05-23 16:07

    基于RK3576開發(fā)板的人臉識別算法

    RK3576開發(fā)板展示人臉識別算法例程和API說明
    的頭像 發(fā)表于 05-07 16:48 ?2734次閱讀
    基于<b class='flag-5'>RK3576</b>開發(fā)板的人臉識別算法

    基于RK3576開發(fā)板的RTC使用說明

    文章主要展示RK3576開發(fā)板的RTC信息和快速上手例程
    的頭像 發(fā)表于 05-07 15:04 ?2227次閱讀
    基于<b class='flag-5'>RK3576</b>開發(fā)板的RTC使用說明

    基于RK3576開發(fā)板的PWN使用說明

    RK3576開發(fā)板使用PWN教程及Demo
    的頭像 發(fā)表于 05-07 14:07 ?2257次閱讀
    基于<b class='flag-5'>RK3576</b>開發(fā)板的PWN使用說明

    基于RK3576開發(fā)板的TF卡槽使用說明

    RK3576開發(fā)板使用TF卡槽
    的頭像 發(fā)表于 05-07 09:24 ?1942次閱讀
    基于<b class='flag-5'>RK3576</b>開發(fā)板的TF卡槽使用說明