一、 led驅(qū)動的實現(xiàn)原理:
通過GPC0_3和GPC0_4引腳的高低電平來控制三極管的導通性,從而控制LED燈亮滅。
盡管 Linux 驅(qū)動直接與硬件打交道,但并不是 Linux 驅(qū)動直接向硬件中的內(nèi)存寫數(shù)據(jù), 而是與本機的I0內(nèi)存(I/O Memory,位于內(nèi)核空間〉進行交互。所謂 1/0 內(nèi)存是通過各種接口( PCI、 USB、藍牙、以太網(wǎng)口等〉連接到主機( PC、手機〉的硬件〈網(wǎng)卡、聲卡、攝像頭等〉在主機內(nèi)存中的映射。
二、 編寫led驅(qū)動
1>首先我們需要感受一下led驅(qū)動的結(jié)果:
測試 LED 驅(qū)動之前需要用 USB 數(shù)據(jù)線連接 S3C 開發(fā)板,然后打開 S3C 開發(fā)板的電源開關(guān)。成功啟動后,執(zhí)行 build.sh腳本文件編譯和安裝 LED 驅(qū)動。如果一切順利,build. sh腳本文件會自動將 s3c6410_leds.ko 文件上傳到 S3C 開發(fā)板并安裝.
可以用下面的命令控制開發(fā)板上的 LED:
adb shell ”echo ‘1’ > /dev/s3c6.410_leds' #打開第 1 個 LEO,其他的 LED 都關(guān)閉
adb shell ” echo’ 1010 ’> /dev/s3c6410_leds' #第 1 個和第 3 個 LED 打開,第2個和 第 4 個 LED 關(guān)閉
2>其次:創(chuàng)建 LED 驅(qū)動的設備文件,步驟如下:
第1步:使用 cdev_init 函數(shù)初始化 cdev:
描述設備文件需要一個 cdev 結(jié)構(gòu)體.cdev 的大多數(shù)成員變量并不需要我們自己去初始化, 只要調(diào)用 cdev init 函數(shù)就可以初始化大 部分 cdev 的成員變量。
第 2 步:指定設備號
Linux 設備文件的設備號分為主設備號和次設備號。用 1 個 int類型(devt)表示。其中前 12 位表示主設備號,后 20 位表示次設備號。設備號有如下兩種指定方法:
1、直接在代碼中指定(硬編碼〉
2、動態(tài)分配。
i.nt alloc_c hrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name) 其中,dev 表示設備號指針〈就是個int 指針), .alloc_chrdev_region函數(shù)會隨機分配-個未使用的主設備號,并根據(jù)baseminor參數(shù)值分配次設備號。
如果直接指定設備號,需要使用register_chrdev_region函數(shù)注冊字符設備區(qū)域。
一般采用分別指定主設備號和次設備號的方式指定設備號,因此需要 MKDEV宏將主設備號和次設備號組合成設備號,代碼如下:
// major 表示主設備號, minor表示次設備號
int dev_number =MKDEV(m:ajor, minor) ;
可以分別使用 MAJOR和 MiNOR宏從設備號中獲取主設備號和次設備號,代碼如下:
// 獲取主設備號
int major=MAJOR(dev_number);
// 獲取次設備號
int minor= MAJOR(dev number);
第 3步:使用 cdev_add函數(shù)將字符設備添加到內(nèi)核中的字符設備數(shù)組中
cdev_add函數(shù)用于將字符設備添加到 probes數(shù)組〈保存己建立的字符設備〉中。
第 4 步: 使用 class_create宏創(chuàng)建 struct class
struct class 包含了一些與設備文件有關(guān)的變量以及一些回調(diào)函數(shù)指針變量。
第 5 步:使用 device_create 函數(shù)創(chuàng)建設備文件
使用下面的代碼調(diào)甩device_create 函數(shù)創(chuàng)建設備文件。
device create(leds class, NULL, dev number, NULL, DEVICE NAME);
其中 leds class 表示 struct class, dev number表示設備號,DEVICE NAME 表示設備文件的名稱。
3>卸載 LED 驅(qū)動的設備文件
卸載 Linux 驅(qū)動的設備文件稍微簡單-些,需要依次調(diào)用 device_destroy、class_destroy 和 unregister_chrdev_region 方法。
4>設置寄存器與初始化 LED 驅(qū)動
ARM 處理器有多個寄存器,通過設置不同寄存器的值。可以設置 LED 引腳的狀態(tài)、打開或禁止上拉(pull-up)電路以及控制 LED 的亮和滅。
注意:
LED 有兩個引腳: GPBO 和 GPBI 。其中一個引腳連接到了 ARM 處理器的 GPIO 端口,另 一個引腳經(jīng)過一個限流電阻連接到電源: VCC3 上。。當 GPIO 端口為低電平時, LED 兩端產(chǎn)生電壓差,這時 LED 有電流通過并發(fā)光;反之當 GPIO 端口為高電平時, LED 中沒有電流通過, LED 將 熄滅。
控制 LED 需要通過 3個寄存器來完成。這 3個寄存器是GPMCON (端口配置寄存器〉、 GPMDAT (端口數(shù)據(jù)寄存器)和 GPMPUD (端口上拉電路寄存器〉。
每一個寄存器可以使用 4個字節(jié),也就是一個int型類型數(shù)據(jù)占用的空間。
使用 GPMCON 寄存器的低 16 位將 LED 的兩個端口( GPBO 和 GPB l )的屬性,設為 Output。
使用 GPMDAT 寄存器的低 4 位控制 4 個 LED 的亮、滅。
使用 GPMPUD 寄存糕的低 8 位分別打開 4 個 LED 的上拉( pull-up)電路。
一般需要在LED驅(qū)動加載時初始化以上3個寄存器。先編寫一個初始化函數(shù)--à在 leds_init 函數(shù)中調(diào)用leds_init_gpm 函數(shù)就可以完成寄存器的初始化。
5>控制 LED
LED 驅(qū)動可以使用如下兩種方式控制 LED:1、通過字符串控制 LE D; 2、通過 l/0命令控制 LED ;
其次:LED 驅(qū)動必須要接收相應的數(shù)據(jù)。 如果通過字符串控制 LED。需要使用. fif.e_operations.write函數(shù)。如果通過 I/0命令控制 LED, 需要使用 file__operations.iocdl函數(shù)。
6> LED 驅(qū)動的模塊參數(shù)
使用一個模塊參數(shù):Linux 驅(qū)動指定一個模塊參數(shù)需要使用 module_param Cname, type, perm)宏。其中 name 表示參數(shù)名, type 表示參數(shù)類型, perm表示讀/寫權(quán)限。
module_param 支持的參數(shù)類型包括 byte、 short、 ushort (無符號 short)、 int、 uint (無符號 int〕、 long、 ulong (無符號 long)、 charp (字符指針)、 bool 和 invbool (布爾的反)。
因此:修改 LED 驅(qū)動的代碼,為 LED 驅(qū)動添加一個模塊參數(shù):
首先要定義一個保存模塊參數(shù)值的變量(leds_state),--àmodule_param 宏指定模塊參數(shù)的相關(guān)信息--à修改 leds_init 函數(shù)的代碼;將leds_init_gpm 函數(shù)的參數(shù)值改成leds_state (因為模塊參數(shù)值和LED 驅(qū)動控制lED的規(guī)則正好相反)。
擴展:
使用下面的命令可以測試 LED 驅(qū)動的模塊參數(shù):
# adb shell insmod /data/1ocal/s3c6410_leds.ko leds_state=3 點亮靠近電池的兩個 LED
使用下面的命令可以看到leds_state文件的內(nèi)容為3 :
# adb shell cat /sys/module/s3c6410_leds/parameters/leds_state
使用下面的命令可以將 leds_state文件的內(nèi)容改為 5
# adb shel l ’echo 5 > /sys/module/s3c6410_leds/parameters/leds_ state’修改 leds_state文件的內(nèi)容后。在LED驅(qū)動代碼中的leds_state值會變成5.
使用模塊參數(shù)我們需要注意:
1. 通過module_param_array宏的第3個參數(shù)指定數(shù)組長度時使用指針類型的數(shù)據(jù);
2. 如果linux驅(qū)動含有多個模塊參數(shù),需要將這些參數(shù)用單引號或雙引號括起來;
3. 指定數(shù)組類型的參數(shù)值,逗號前后不能空格。
7>led燈完整代碼的編寫。
三、 測試led驅(qū)動
在本章學習過程中,前面已經(jīng)提到過測試方法,此處為更復雜的方法:可以向 LED 設備文件發(fā)送字符串,還可以發(fā)送 I/0 控制命令。其測試方式包括可執(zhí)行程序測試、 NDK 測試和 Java 測試。
1> 編寫測試 I/O 控制命令的通用程序
LED 驅(qū)動有兩種與設備文件交互的方式:
分別為:直接寫入字符串數(shù)據(jù)和I/O控制命令。
其中直接向設備文件寫入數(shù)據(jù)可以使用命令行方式來完成,也可以通過 write 函數(shù)來完成。但 I/0 控制命令只能通過 iocll 函數(shù)發(fā)出。
注意:編譯android源代碼有很多方法,例如:使用獨立的交叉編譯器、AndroidADK等。如果利用android源代碼編譯,要保證本機上有Android源代碼,并且在<Android混代碼>/development目錄為ioctl 目錄建立一個符號鏈接,符號鏈接名必須是ioctl。
1.在ioctl 目錄有一個 build_android.sh腳本文件,讀者可以直接運行這個腳本文件利用Adroid 源代碼編譯 ioctl【前提:按照build_android.sh文件中的路徑確定android源代碼的位置,或者修改build_android.sh文件中的Android源代碼路徑】-----à先編譯 test_ioctl文件----à將生成的ioctl文件上傳到開發(fā)板的“/data/local”目錄,最后執(zhí)行ioctl命令。
注意:ioctl 的命令行參數(shù)必須至少有3 個 (多余的被忽略〉,如果命令行參數(shù)小于 3 個,會輸出ioctl 命令的用法提示。
2.在開發(fā)板上運行的可執(zhí)行文件同樣可以在 eclipse集成環(huán)境中開發(fā)。由于ioctl是通用的,因此,應該為每一個需要測試的程序單獨建立1個 Eclipse 工程,當我們測試一個程序時,例如:led。我們需要建立一個eclipse目錄,用于存放eclipse工程的相關(guān)內(nèi)容。另外,還需要為每一個測試程序單獨建立1個腳本文件,其最后一條命令為 ioctl命令傳遞了3個參數(shù),該條命令如下:
adb shell ‘/data/loctal/ioctl /dev/s3c6410_leds 1 .2'//將第三個led點亮。
2> 使用 NDK 測試 LED 驅(qū)動
NDK 程序測試和可執(zhí)行程序測試差不多。只不過 NDK Library 可以被 Java 程序調(diào)用,而在 Android 系統(tǒng)中的可執(zhí)行程序在非 root 狀態(tài)下是無法直接被調(diào)用的。所以如果想在 Android 應用程序中測試 Linux 驅(qū)動, 最直接的方法就是使用 NDK。
3> 使用 Java 測試 LED 驅(qū)動
由于 JDK 未提供發(fā)送I/O命令的 API,因此使用 Java 只能通過發(fā)送控制字符串測試 LED 驅(qū)動。
四、 Led驅(qū)動移植
Android 系統(tǒng)能否正常運行,在很大程度上 取決于 Android 能否識別當前設備的硬件,例如,顯示屏、 Wi-Fi、 GPS、 GSM、藍牙、各種傳感器等,識別這些設備的工作主要由 Linux 驅(qū)動完成。而 Linux 驅(qū)動必須要在當前使用的 Linux 內(nèi)核下編譯才可以安裝在當前的 Linux 或 Android 系統(tǒng)中。LED 驅(qū)動最簡單的移植就是將其在不同 Linux內(nèi)核版本下進行編譯。
例如:以led驅(qū)動為例:
LED 驅(qū)動是通過設置 GPMDAT 寄存器來控制 LED 的亮滅的。 GPMDAT 寄存器的低 4位分別控制 4個 LED 。 0 表示打開 LED, 1 表示關(guān)閉 LED。這是在 OK64 1 0 開發(fā)板上的設置。如果要將 LED 驅(qū)動移植到另外基于 S3C6410 的開發(fā)版上,而這個目標開發(fā)板上恰好與 OK6410 開發(fā)板的 GPMDA1、寄存器的低 4 位表示的含義相反,也就是說, 1 表示打開 LED,0 表示關(guān)閉 LED, 那么 LED 驅(qū)動的代碼就要做相應的改變。首先要改變的就是 leds_init 函數(shù)。在 LED 驅(qū)動裝載后,會 用 OxE 設置 4個 LED 的默認狀態(tài). 而在新的開發(fā)板上,就要將 OxE 變成 Oxl.
我們還需要修改控制 LED 的代碼,例如,下面的代碼用于發(fā)送控制字符串。需要將生成開關(guān) LED 的代碼互換位置。
注意:移植linux有一條非常重要,就是在修改Liunx驅(qū)動的源代碼時應盡量不修改linux驅(qū)動接口。
上一篇:Android JNI用于驅(qū)動測試
下一篇:android休眠喚醒驅(qū)動流程分析
推薦閱讀最新更新時間:2025-04-08 08:04





設計資源 培訓 開發(fā)板 精華推薦
- 迅為IMX6ULL開發(fā)板交叉編譯器的安裝和使用
- 迅為-i.MX6ULL 開發(fā)板-移植OpenCv3.4.1-搭建編譯環(huán)境
- 嵌入式學習篇丨迅為4412開發(fā)板Android4.4系統(tǒng)編譯
- Linux系統(tǒng)編程篇丨迅為IMX6ULL-對應視頻講解
- 嵌入式學習丨4412開發(fā)板-uboot源碼-匯編-源碼分析(一)嵌入式學習丨4412開發(fā)板-uboot源碼-匯
- 迅為IMX6ULL開發(fā)板-主頻和時鐘配置例程(二)
- 迅為IMX6ULL開發(fā)板-主頻和時鐘配置例程
- 迅為IMX6ULL開發(fā)板安裝VMware Tool工具
- i.MX6ULL終結(jié)者Debian文件系統(tǒng)的構(gòu)建i.MX6ULL 移植Debian文件系統(tǒng)
- DC2564A,基于 LT8606EMSE 同步降壓的演示板,5.5V = VIN = 42V,VOUT = 5V @ 350mA,fSW = 2MHz
- 使用 ON Semiconductor 的 FAN2510S 的參考設計
- 65W,交流轉(zhuǎn)直流單輸出筆記本電源
- Wireless_light
- FEBFL7701_L34U018A,基于 FL7701 通用線電壓 LED 鎮(zhèn)流器的評估板
- 使用具有 B 類 EMI 濾波(單輸出)的 RP10-1205DA DC/DC 轉(zhuǎn)換器的典型應用
- 毫米波雷達無線警報系統(tǒng)-(4通道)
- ZIGBEESLK: AP13192USLK ZigBee-ready RF Transceiver Student Learning Kit
- 使用 Analog Devices 的 LT1498 的參考設計
- EVAL-AD7664CB,用于 AD7664、16 位、571 Ksps PulSAR 模數(shù)轉(zhuǎn)換器的評估板
- 中國發(fā)布HDMI和DisplayPort替代方案:GPMI接口來了
- 三星進軍 AI 機器人領(lǐng)域,Ballie 本周公開亮相
- 消息稱美光即日起針對存儲模組產(chǎn)品向美國客戶征收“關(guān)稅附加費”
- 迅為IMX6ULL開發(fā)板交叉編譯器的安裝和使用
- 迅為-i.MX6ULL 開發(fā)板-移植OpenCv3.4.1-搭建編譯環(huán)境
- BOE(京東方)董事長提議回購公司股份 堅定看好資本市場長期價值
- 英飛凌宣布收購Marvell的汽車以太網(wǎng)業(yè)務
- 強強聯(lián)合!兆易創(chuàng)新與納微半導體達成戰(zhàn)略合作
- 德州儀器模擬設計 | 運算放大器基本穩(wěn)定性概述
- 人形機器人新王者崛起:Figure估值直逼2900億,中國軍團能否迎頭趕上?
- 【已結(jié)束】直播|Microchip MPU解決方案及典型應用
- 羅德與施瓦茨-車載以太網(wǎng)及其一致性測試方案 回饋您的需求 看視頻贏好禮
- 直播已結(jié)束|Molex 和 TTI 更小型、高速、可靠的連接器推動物聯(lián)網(wǎng)應用的新發(fā)展
- 有獎直播:TI DLP® 產(chǎn)品賦能工業(yè)光控領(lǐng)域與創(chuàng)新
- 更好的供電方式:使用更小、更輕的電源模塊加速車輛電氣化
- 2025玄鐵RISC-V生態(tài)大會 火熱報名中,參會贏好禮
- 5G來襲 TE Connectivity 助你搶占消費電子市場先機
- 有獎直播:超小型封裝 TI MSPM0 MCU 可優(yōu)化設計空間,實現(xiàn)更多可能
- 2023 DigiKey KOL 系列——將TinyML融入IoT物聯(lián)網(wǎng)應用中