[OK210開發(fā)板體驗]功能篇(1)Linux字符驅(qū)動之LED燈驅(qū)動
【OK210開發(fā)板體驗】的第一篇:開箱驗板
【OK210開發(fā)板體驗】的第二篇:板載資源
【OK210開發(fā)板體驗】的第三篇:開發(fā)環(huán)境(軟件安裝,開發(fā)環(huán)境,燒寫系統(tǒng))
【OK210開發(fā)板體驗】的第四篇:編程入門(NFS登錄,驅(qū)動入門)
雖然在【OK210試用體驗】問題篇(1)速求飛凌技術(shù)支持或大神解答中,也集中問了幾個問題,但仍然rmmod這個命令不能用,飛凌的技術(shù)支持也沒有給出正確的使用方法,看來只能自己慢慢摸索了。也希望有知道的,不吝賜教!
申請到板子有一段時間了,看著大家每天的試用報告,多數(shù)還停留在環(huán)境搭建上,而且有些人一個簡單的功能,都能寫一篇試用報告,我真是服了。接下來,將開啟我的試用體驗第二階段:功能篇,主要圍繞智能家居的一些應(yīng)用模塊進行功能的測試檢驗,以硬件分析+軟件基礎(chǔ)的形式引入,以驅(qū)動程序+應(yīng)用源碼的形式呈現(xiàn)。
今天是功能篇的第一篇,字符驅(qū)動之LED燈的控制,主要分3部分:硬件分析,軟件基礎(chǔ),驅(qū)動編程。
一、硬件分析
在【OK210試用體驗】的第二篇:板載資源中,簡單分析了LED功能和作用。其實對LED的操作,就是對GPIO的最基本操作,也是入門操作。
首先查看S5Pv210的用戶手冊,對其GPIO口有一個整體了解,在用戶手冊的92頁,對S5PV210的GPIO進行了概要的說明,總的來說,S5PV210有237個多功能輸入輸出端口,142個存儲器端口引腳,控制146個GPIO中斷,控制32個外部中斷。
接著從OK210的底板原理圖中可知,
OK210開發(fā)板將LED接到了XM0ADDR4-7引腳上,而這些引腳通過插座接到了核心板上,
從用戶手冊中,如下圖得知,這些引腳是由EBI(External Bus Interface)來管理,詳見用戶手冊的第六章。
所以,要對4個LED控制,就是對XM0ADDR4-7這4個引腳進行操作。
二、軟件基礎(chǔ)
1 Linux中的GPIO引腳定義
在Linux中,GPIO分成若干個group,每個group包含幾個io port,訪問某個port時要指明哪個group哪個port。kernel處理方法是把所有io port整理成一個線性的空間,即一組線性的數(shù)值,每個io port對應(yīng)于一個數(shù)值。S5PV210引腳的具體定義,位于linux/arch/arm/mach-s5pv210/include/mach/gpio.h。
在該頭文件中,首先進行分組及每組包含的端口數(shù),如下所示
#define S5PV210_GPIO_A0_NR (8)
表示GPIO的A0口,含有8個引腳(端口)
接著定義每組GPIO的起始號碼,其中S5PV210_GPIO_NEXT定義為如下形式
#defineS5PV210_GPIO_NEXT(__gpio) ((__gpio##_START) +(__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
ps:用##粘貼符號來運算的,以A組的0起始,依次加每組的GPIO個數(shù)。
如:S5PV210_GPIO_A1_START=S5PV210_GPIO_NEXT(S5PV210_GPIO_A0)=
S5PV210_GPIO_A0_START+S5PV210_GPIO_A0_NR+CONFIG_S3C_GPIO_SPACE+ 1
全部的GPIO的起始號在s5p_gpio_number枚舉中定義:
enum s5p_gpio_number {
S5PV210_GPIO_A0_START =0,
S5PV210_GPIO_A1_START =S5PV210_GPIO_NEXT(S5PV210_GPIO_A0),/*0+8+1 = 9*/
S5PV210_GPIO_B_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_A1),/*9+4+1 = 14*/
......
S5PV210_GPIO_ETC2_START =S5PV210_GPIO_NEXT(S5PV210_GPIO_ETC1),/*438+8+1 = 447*/
S5PV210_GPIO_ETC4_START =S5PV210_GPIO_NEXT(S5PV210_GPIO_ETC2),/*447+8+1 = 456*/
/*總數(shù)是456+6+1 = 463*/
};
最后定義了單個GPIO腳的起始號
#define S5PV210_GPA0(_nr) (S5PV210_GPIO_A0_START + (_nr))
#define S5PV210_GPA1(_nr) (S5PV210_GPIO_A1_START + (_nr))
#define S5PV210_GPB(_nr) (S5PV210_GPIO_B_START + (_nr))
......
#define S5PV210_ETC2(_nr) (S5PV210_GPIO_ETC2_START + (_nr))
#define S5PV210_ETC4(_nr) (S5PV210_GPIO_ETC4_START + (_nr))
2 Linux中GPIO函數(shù)定義
Linux使用Struct gpio_chip結(jié)構(gòu)體來描述各種不同體系結(jié)構(gòu)和電路板的抽象接口,也說是各種電路板都要提供自己接口實現(xiàn),三星公司的芯片都使用自己的接口實現(xiàn)。主要在include/asm-generic/gpio.h中聲明。而Linux將系統(tǒng)中所有的IO口都統(tǒng)一指定編號,一般情況是組名+編號。Linux將所有的IO稱為資源,系統(tǒng)的任何模塊使用資源,都要先申請,用完歸還資源,
int gpio_request(unsigned gpio, const char*label)
void gpio_free(unsigned gpio)
所有的gpio都可以指定方向,
int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio,int value)
所有的gpio都提供讀寫數(shù)據(jù)
int gpio_get_value(unsigned gpio)
void gpio_set_value(unsigned gpio, int on)
以上幾個關(guān)鍵函數(shù),在linux/gpio.h聲明,在drivers/gpio/gpiolib.c定義
同時三星公司還封裝了自己的gpio接口,定義位于arch/arm/plat-s3c/gpio-config.c,主要有
int s3c_gpio_cfgpin(unsigned int pin,unsigned int config)
int s3c_gpio_setpull(unsigned int pin,s3c_gpio_pull_t pull)
int s3c_gpio_setpin(unsigned int pin,s3c_gpio_pull_t level)
三、驅(qū)動編程
驅(qū)動代碼由飛凌提供的驅(qū)動改編而來,只要根據(jù)硬件,設(shè)置對應(yīng)的GPIO口,使其更方便移植;應(yīng)用程序?qū)崿F(xiàn)簡單的流程燈功能;Makefile配置成可編譯驅(qū)動程序和應(yīng)用程序的形式。
具體的代碼如下,具體的使用見上一篇【OK210試用體驗】的第四篇:編程入門(NFS登錄,驅(qū)動入門):
1
驅(qū)動程序:
1.
2. #include <linux/miscdevice.h>
3. #include <linux/input.h>
4. #include <linux/clk.h>
5. #include <linux/delay.h>
6. #include <asm/io.h>
7. #include <asm/uaccess.h>
8. #include <mach/map.h>
9. #include <mach/gpio.h>
10. #include <mach/regs-gpio.h>
11. #include <plat/gpio-core.h>
12. #include <plat/gpio-cfg.h>
13. #include <plat/gpio-cfg-helpers.h>
14.
15. #define DEVICE_NAME "leds"
16. /* 應(yīng)用程序執(zhí)行ioctl(fd, cmd, arg)時的第2個參數(shù) */
17. /*the second parameter that application program execute*/
18. #define IOCTL_GPIO_ON 1
19. #define IOCTL_GPIO_OFF 0
20. /* 用來指定LED所用的GPIO引腳 */
21. /*appoint the pin the LED will use*/
22. static unsigned long leds_table [] =
23. {
24. S5PV210_MP04(4),
25. S5PV210_MP04(5),
26. S5PV210_MP04(6),
27. S5PV210_MP04(7),
28. //arch\arm\mach-s5pv210\include\mach\gpio.h
29. };
30. static char leds_name[][4]={{"LED1"},{"LED2"},{"LED2"},{"LED3"}};
31. #define LED_NUM ARRAY_SIZE(leds_table)
32. /**
33. *函數(shù)功能:打開/dev/led設(shè)備
34. *fuction:open /dev/leds device
35. *設(shè)備名是:/dev/leds
36. *devce name: /dev/leds
37. **/
38. static int my_gpio_open(struct inode *inode, struct file *file)
39. {
40. int i;
41. int err;
42.
43. for (i = 0; i < LED_NUM; i++)
44. {
45. err = gpio_request(leds_table[i], leds_name[i]);
46. //drivers/gpio/gpiolib.c
47. if(err)
48. {
49. printk(KERN_ERR "failed to request S5PV210_GPH2(%d) for LED%d \n",i-1,i);
50. return err;
51. }
52. }
53.
54. for (i = 0; i < LED_NUM; i++)
55. {
56. // s3c_gpio_cfgpin(leds_table[i], gpio_cfg_table[i]);//Configuration pin function:input output multiplex
57. // s3c_gpio_setpin(leds_table[i], 0);//Set the pin level
58. //arch\arm\plat-samsung\gpio-config.c
59. gpio_direction_output(leds_table[i], 0);//write a value to GPIO port ,also set the port to output mode
60. gpio_set_value(leds_table[i], 0);
61. //drivers/gpio/gpiolib.c
62.
63. }
64. printk(KERN_INFO "LEDs driver successfully close\n");
65. return 0;
66. }
67. /**
68. *函數(shù)功能:用于控制led的亮滅
69. *fuction:control the led /turn on & turn off
70. *控制字為cmd,arg為控制哪個燈的亮滅取值范圍為0-1:cmd為IOCTL_GPIO_ON時亮,cmd為IOCTL_GPIO_OFF為滅
71. *control byte is cmd; arg appointed which led wile be turn on or off,it can be 0 and 1;IOCTL_GPIO_ON:turn on,IOCTL_GPIO_OFF:turn off.
72. **/
73. static int my_gpio_ioctl(
74. struct inode *inode,
75. struct file *file,
76. unsigned int cmd,
77. unsigned long arg)
78. {
79. arg -= 1;
80. if (arg > LED_NUM)
81. {
82. return -EINVAL;
83. }
84. switch(cmd)
85. {
86. case IOCTL_GPIO_ON:
87. {
88. // 設(shè)置指定引腳的輸出電平為1
89. gpio_direction_output(leds_table[arg], 1);
90. //s3c_gpio_setpin(leds_table[arg], 1);
91. return 0;
相關(guān)產(chǎn)品 >
-
OKMX6UL-C開發(fā)板
飛凌嵌入式專注imx6系列imx6ul開發(fā)板、飛思卡爾imx6ul核心板等ARM嵌入式核心控制系統(tǒng)研發(fā)、設(shè)計和生產(chǎn),i.mx6UL系列產(chǎn)品現(xiàn)已暢銷全國,作為恩智浦imx6ul,imx6ul開發(fā)板,i.mx6提供者,飛凌嵌入式提供基于iMX6 iMX6UL解決方案定制。
了解詳情 -
OKMX6ULL-C開發(fā)板
40*29mm,雙網(wǎng)雙CAN,8路串口| i.MX6ULL開發(fā)板是基于NXP i.MX6ULL設(shè)計開發(fā)的的一款Linux開發(fā)板 ,主頻800MHz,體積小,其核心板僅40*29mm,采用板對板連接器,適應(yīng)場景豐富。 了解詳情