用OLED屏幕播放視頻(2): 為OLED屏幕開發I2C驅動

来源:https://www.cnblogs.com/kfggww/archive/2023/09/10/17672942.html
-Advertisement-
Play Games

下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放: 項目介紹 為OLED屏幕開發I2C驅動 使用cuda編程加速視頻處理 這是此系列文章的第2篇, 主要總結和記錄一個I2C從設備的驅動, 在linux內核中如何實現, 如何給用戶態的程式暴露合適的介面, 讓用戶態有機會 ...


下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放:

  1. 項目介紹
  2. 為OLED屏幕開發I2C驅動
  3. 使用cuda編程加速視頻處理

這是此系列文章的第2篇, 主要總結和記錄一個I2C從設備的驅動, 在linux內核中如何實現, 如何給用戶態的程式暴露合適的介面, 讓用戶態有機會操作真實的硬體設備. 可以通過下麵的視頻快速瞭解最終達到的效果和實現的總體思路.

跳轉到6:48, 直接觀看演示

1). I2C驅動架構

I2C匯流排是一種主從, 同步, 半雙工的低速通信匯流排, 硬體標準可以參考這裡. 這篇文章只討論I2C匯流排上從設備的驅動在linux平臺下如何實現, 下圖是linux中I2C匯流排相關的軟體模塊, 其中i2c core提供給驅動開發人員重要的數據結構和介面函數:

image

  • i2c_adapter: 表示匯流排上的主設備, 或者說匯流排控制器
  • i2c_algorithm: 當主設備想要通信時, 它負責具體硬體時序的實現, 比如, 在匯流排上產生開始/結束條件, 發送/接收數據
  • i2c_client: 表示匯流排上的從設備
  • i2c_driver: 表示從設備對應的驅動, 需要實現其中的介面函數之後, 把驅動註冊到i2c core之中
  • i2c_add_driver: 註冊i2c_driver到i2c core, 一般在模塊初始化函數中調用
  • i2c_del_driver: 刪除i2c_driver, 一般在模塊退出函數中調用
  • i2c_master_send/recv: 主設備發送/接收數據, 實際上為了驅動從設備, 需要讓主設備向從設備發送合適的命令, 或者讀取從設備的狀態, 具體發送或者接收什麼, 參考從設備的datasheet即可

2). 實現ssd1306屏幕的I2C驅動

  1. 註冊i2c_driver
    使用module_i2c_driver巨集, 並傳遞我們實現的i2c_driver, 該巨集能夠為我們生成模塊的init和exit函數, 在函數中自動註冊和刪除傳遞進來的i2c_driver. 如果需要在init和exit中做一些其他工作, 則需要自己實現, 不能使用這個巨集.
module_i2c_driver(ssd130x_driver);
  1. 實現i2c_driver中的介面
static struct i2c_driver ssd130x_driver = {
    .driver = {
        .owner = THIS_MODULE,
        .name = "ssd130x_driver",
    },
    .probe = ssd130x_probe,
    .remove = ssd130x_remove,
    .id_table = ssd130x_id_table,
};

這裡只實現了i2c_driver中的probe和remove. 當驅動和設備匹配成功時, probe函數被調用, 在probe函數中, 完成了字元設備的相關的操作, 包括:

  • 分配設備號
  • 初始化字元設備結構體
  • 添加字元設備到內核
  • 創建設備文件
  1. 實現字元設備介面, 暴露給用戶態程式
static struct file_operations ssd130x_fops = {
	.owner = THIS_MODULE,
	.open = ssd130x_open,
	.release = ssd130x_close,
	.write = ssd130x_write,
};

用戶態程式可以對設備文件進行打開, 關閉, 寫入3種操作. 當打開設備文件時, ssd130x_open被調用, 完成OLED屏幕的初始化; 關閉設備文件時, ssd130x_close被調用, 屏幕被關閉; 當向設備文件寫入數據時, ssd130x_write被調用, 一幀數據被髮送到ssd1306的RAM上, 屏幕顯示的內容被更新. 以上3種操作, 底層都是通過i2c_master_send向從設備發送特定的命令或者數據實現的.

2.1). 閱讀數據手冊

ssd1306的數據手冊參考這裡, 手冊內容較多, 不宜通讀, 主要關註以下幾點:

  • 基本硬體參數: 屏幕解析度, 支持的通信介面, 支持哪些顯示相關的功能(比如滾動, 反轉等) ...
  • 基本工作原理: 通過向RAM中寫入數據, 控制屏幕像素點的亮滅
  • 基本使用方法: 支持哪些命令? 分別能控制它的什麼功能?
  • Application Note: 典型硬體電路, 示例代碼

2.2). 設備的初始化

在數據手冊的Application Note中包含使用ssd1306時的初始化流程, 如下圖所示. 在此基礎上, 可以做一些調整, 比如我在驅動中關閉了屏幕滾動.

image

2.3). 調整I2C的頻率

我在beaglebone black板子上刷入的debian系統, 其設備樹中的i2c時鐘頻率是100kbits/s, 內核中的i2c_algorithm會根據這個頻率計算在i2c匯流排上發送數據時使用的延時. 實際測試之後發現按照這個頻率播放視頻存在一些卡頓, 因此需要對i2c時鐘頻率做修改, 有兩種方式:

  • 在uboot啟動時, 進入uboot的shell, 使用fdt相關的命令修改始終頻率
  • 備份原來的設備樹文件, 使用dtc編譯器從dtb得到dts, 在dts中修改始終頻率, 再編譯得到新的dtb, 替換原來的設備樹文件

我這裡採用的是dtc的方式, 這樣就不需要每次系統啟動都手動修改了, 修改之後的時鐘頻率為400kbits/s, 播放視頻流暢很多.

3). 測試驅動功能

驅動代碼編寫完成之後, 需要實際測試一下功能, 下麵代碼首先打開OLED屏幕的設備文件, 寫入一幀數據, 每個位元組都填充為0x88, 這樣屏幕上會顯示出預期的條紋, sleep兩秒之後, 關閉設備文件, 屏幕熄滅.

#define FRAME_SIZE (128 * 8)

int main(int argc, char **argv)
{
	int device_fd = open("/dev/ssd130x0", O_WRONLY);
	if (device_fd < 0) {
		return -1;
	}

	char *frame = malloc(FRAME_SIZE);
	memset(frame, 0x88, FRAME_SIZE);
	write(device_fd, frame, FRAME_SIZE);
	sleep(2);

	free(frame);
	close(device_fd);
	return 0;
}

4). 文末推廣

歡迎關註我的B站賬號, 或者加入QQ群838923389, 一起研究電腦底層技術, 一起搞事情:P

其實還有很多實現的細節沒有在博客中寫出來, 只有自己在做的時候遇到了才能夠體會的到, 需要完整代碼的老鐵直接在qq群中問一下.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Relocation(重定位)是一種將程式中的一些地址修正為運行時可用的實際地址的機制。在程式編譯過程中,由於程式中使用了各種全局變數和函數,這些變數和函數的地址還沒有確定,因此它們的地址只能暫時使用一個相對地址。當程式被載入到記憶體中運行時,這些相對地址需要被修正為實際的絕對地址,這個過程就是重定位... ...
  • 方案 markdown+Typora + picGo + jsdelivr + github倉庫 + bloghelper Typora: 本地 Markdown 編輯器,用於本地編寫文檔 PicGo:一個用於快速上傳圖片並獲取圖片 URL 鏈接的工具,可以與 Typora 集成,實現黏貼圖片後自動 ...
  • 方案 markdown+Typora + picGo + jsdelivr + github倉庫 + bloghelper Typora: 本地 Markdown 編輯器,用於本地編寫文檔 PicGo:一個用於快速上傳圖片並獲取圖片 URL 鏈接的工具,可以與 Typora 集成,實現黏貼圖片後自動 ...
  • 本文介紹在Anaconda環境下,創建、使用與刪除Python虛擬環境的方法。 在Python的使用過程中,我們常常由於不同Python版本以及不同第三方庫版本的支持情況與相互之間的衝突情況,而需要創建不同的Python虛擬環境;在Anaconda的幫助下,這一步驟就變得十分方便。 首先,我們需要打 ...
  • LeetCode的hard題都很難嗎?不一定,297就非常簡單,隨本文一起,用最基礎的知識寫代碼,執行用時能擊敗98.46%,與此同時,記憶體消耗擊敗99.73% ...
  • 淺聊一下SpringMVC的核心組件以及通過源碼瞭解其執行流程 MVC作為WEB項目開發的核心環節,正如三個單詞的分解那樣,Controller(控制器)將View(視圖、用戶客戶端)與Model(javaBean:封裝數據)分開構成了MVC,今天我們淺聊一下SpringMVC的相關組件以及通過源碼... ...
  • 下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放: 項目介紹 為OLED屏幕開發I2C驅動 使用cuda編程加速視頻處理 這篇文章主要對項目的實現做整體的介紹, 包括硬體的需求, 最終實現的視頻播放效果, 以及軟體的實現思路. 1). 硬體需求 beaglebone ...
  • 對於有科班背景的讀者,可以跳過本系列文章。這些文章的主要目的是通過簡單易懂的彙總,幫助非科班出身的讀者理解底層知識,進一步瞭解為什麼在面試中會涉及這些底層問題。否則,某些概念將始終無法理解。這些電腦基礎文章將為你打通知識的任督二脈,祝你在編程領域中取得成功! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...