用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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...