您好,登錄后才能下訂單哦!
本篇文章為大家展示了基于OMAPL138的Linux設備驅動程序開發怎么入門,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
開發板LED編號和GPIO對應關系如下:
表 1
開發板型號 | GPIO0[0] | GPIO0[5] | GPIO0[1] | GPIO0[2] |
TL138/1808-EVM | D7 | D6 | D9 | D10 |
TL138/1808-EasyEVM | D7 | D6 | D9 | D10 |
TL138/1808-EthEVM | D7 | D6 | D9 | D10 |
TL138/1808F-EasyEVM | \ | GD1 | GD2 | GD3 |
TL138/1808F-EVM | \ | D1 | D2 | D3 |
開發板資料光盤中有LED設備驅動程序源碼,其路徑為:
led.c:demo\driver\linux-3.3\led\led.c
下面以TL138/1808-EVM開發板為例講解此設備驅動程序。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
/* 因為使用了平臺相關的頭文件,所以編譯時需要ARCH=arm */
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/da8xx.h>
#include <mach/mux.h>
/*定義4個用戶LED對應的GPIO,開發板LED對應編號分別是D7,D6,D9,D10 */
#define DA850_USER_LED0 GPIO_TO_PIN(0, 0)
#define DA850_USER_LED1 GPIO_TO_PIN(0, 5)
#define DA850_USER_LED2 GPIO_TO_PIN(0, 1)
#define DA850_USER_LED3 GPIO_TO_PIN(0, 2)
/* assign the tl som board LED-GPIOs*/
static const short da850_evm_tl_user_led_pins[] = {
/* These pins are definition at <mach/mux.h> file */
DA850_GPIO0_0, DA850_GPIO0_1, DA850_GPIO0_2, DA850_GPIO0_5,
-1
};
/*定義4個LED對應的GPIO號、有效電平(熄燈電平)、名稱、觸發模式等*/
/*使用Linux提供的標準gpio-led框架*/
static struct gpio_led da850_evm_tl_leds[] = {
{
.active_low = 0, /*有效電平(熄燈電平):低電平*/
.gpio = DA850_USER_LED0, /*GPIO號:LED對應gpio管腳*/
.name = "user_led0", /*名稱:對應/sys/class/leds/下的名稱*/
.default_trigger = "default-on", /*觸發模式:默認點亮*/
},
{
.active_low = 0,
.gpio = DA850_USER_LED1,
.name = "user_led1",
.default_trigger = "default-on",
},
{
.active_low = 0,
.gpio = DA850_USER_LED2,
.name = "user_led2",
.default_trigger = "default-on",
},
{
.active_low = 0,
.gpio = DA850_USER_LED3,
.name = "user_led3",
.default_trigger = "default-on",
},
};
static struct gpio_led_platform_data da850_evm_tl_leds_pdata = {
.leds = da850_evm_tl_leds,
.num_leds = ARRAY_SIZE(da850_evm_tl_leds),
};
static void led_dev_release(struct device *dev)
{
};
/*使用Linux提供的標準platform_device 框架*/
static struct platform_device da850_evm_tl_leds_device = {
.name = "leds-gpio",
.id = 1, /*先確定id號是否被使用,此id是platform_device的id,跟LED個數無關*/
.dev = {
.platform_data = &da850_evm_tl_leds_pdata,
.release = led_dev_release,
}
};
static int __init led_platform_init(void)
{
int ret;
#if 0
/*使用davinci pinmux設置接口,把LED對應的管腳配置成gpio模式*/
ret = davinci_cfg_reg_list(da850_evm_tl_user_led_pins);
if (ret)
pr_warning("da850_evm_tl_leds_init : User LED mux failed :"
"%d\n", ret);
#endif
/*注冊LED device設備,系統LED框架將會接收到這個注冊,生成相應LED節點*/
ret = platform_device_register(&da850_evm_tl_leds_device);
if (ret)
pr_warning("Could not register som GPIO expander LEDS");
else
printk(KERN_INFO "LED register sucessful!\n");
return ret;
}
static void __exit led_platform_exit(void)
{
platform_device_unregister(&da850_evm_tl_leds_device);
printk(KERN_INFO "LED unregister!\n");
}
module_init(led_platform_init);
module_exit(led_platform_exit);
MODULE_DESCRIPTION("Led platform driver");
MODULE_AUTHOR("Tronlong");
MODULE_LICENSE("GPL");
以上是LED設備驅動程序解析,對于Linux對LED設備框架,這里稍微說明一下:
Linux的LED設備類在內核"Documentation/leds/leds-class.txt"文件有詳細說明。
注冊一個LED設備成功后,會"/sys/class/leds/"生成相應的設備節點。
用戶可以通過讀寫節點目錄下的brightness文件控制LED亮滅。
對于GPIO口的操作,有以下幾點步驟:
查看開發板的原理圖,找到與LED連接的GPIO。TL138/1808-EVM開發板與LED連接的GPIO分別是GPIO0[5]、GPIO0[0]、GPIO0[1]、GPIO0[2]。
查看OMAP-L138的數據手冊,查找對應PINMUX寄存器的地址,將對應的管腳的寄存器中相應位設置為GPIO的工作模式。本例中使用的是PINMUX1。
設置GPIO的方向寄存器。本例程中將GPIO口配置為輸出。
配置GPIO的數據寄存器,寫"1"表示輸出高電平,寫"0"表示輸出低電平。
此處使用Makefile編譯LED設備驅動程序。工程中源文件有時候很多,其按類型、功能、模塊分別放在若干個目錄中,Makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進行更復雜的功能操作,因為Makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。
開發板資料光盤中有LED設備驅動程序Makefile文件,其路徑為:
Makefile: demo\driver\linux-3.3\led\Makefile
以下為LED設備驅動程序Makefile文件的解析:
ifneq ($(KERNELRELEASE),)
obj-m := led.o /*定義了要編譯的驅動文件為led.c,生成的模塊名字為led.ko*/
else
/*以下定義運行編譯命令時使用的內核源碼、驅動源碼路徑、平臺、使用的交叉編譯工具鏈等參數*/
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
/*定義運行"make clean"時清除的文件*/
clean:
rm -rf *.ko *.o *.mod.o *.mod.c *.symvers modul* .button.* .tmp_versions
#help: make KDIR=<you kernel path>
endif
圖 1
將光盤"demo\driver\linux-3.3\led"的led.c和Makefile文件復制到開發系統Ubuntu任意路徑,并在led.c和Makefile目錄運行以下命令編譯LED設備驅動程序:
Host# make KDIR=/home/tl/omapl138/linux-3.3
圖 3
將光盤"demo\driver\linux-3.3\button"中的button.c和Makefile文件復制到Ubuntu任意路徑,在button.c和Makefile文件所在目錄運行如下命令編譯按鍵設備驅動程序:
Host# make KDIR=/home/tl/omapl138/linux-3.3 CROSS_COMPILE=arm-none-linux-gnueabi-
圖 5
可以看到在當前目錄生成了測試程序鏡像文件button_test。具體按鍵測試步驟請看用戶手冊快速體驗相關小節。
假如需要將設備驅動程序模塊靜態編譯進內核,請按照如下步驟操作。
以LED設備驅動程序為例,將光盤"demo\driver\linux-3.3\led"目錄下的設備驅動程序源代碼led.c放到內核源碼"drivers/char"目錄下,修改內核源碼"drivers/char"目錄下Kconfig菜單配置文件,在"menu "Character devices""行下面添加如下內容:
圖 6
config USER_LED:USER_LED是驅動程序的配置名稱。
tristate "user led":在使用"make menuconfig"配置內核時菜單欄出現的驅動名字。
depends on ARM:注明是ARM平臺下的驅動程序。
default y:默認是靜態編譯到內核鏡像的。
---help---:驅動程序的補充信息,讓用戶進一步了解此驅動程序的作用。
修改內核源碼"drivers/char"目錄下的Makefile編譯文件,在最后添加如下內容:
obj-$(CONFIG_USER_LED) += led.o
圖7
obj-$(CONFIG_USER_LED):"USER_LED"此內容必須和前面步驟Kconfig文件中添加的內容一致。
+= led.o:這個前綴必須是"led",編譯驅動程序時,系統會去找"driver/char"目錄下的led.c文件。
在內核源碼頂層目錄執行以下命令查看設備內核配置情況:
Host# make menuconfig ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
可在"device drivers->character devices"下有"user led"的驅動配置選項,如下圖:
圖 8
前面的"*"符號代表將設備驅動模塊靜態編譯進內核。保存退出,并重新編譯內核,然后使用編譯得到的內核鏡像啟動開發板,可發現在不用安裝led.ko的情況下,可以直接運行led_loop.sh來實現LED的循環點亮。
若需要將設備驅動模塊編譯成內核模塊的形式,按空格鍵將"*"變為"M",變為空表示不編譯。
上述內容就是基于OMAPL138的Linux設備驅動程序開發怎么入門,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。