色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

【i.MX6ULL】驅動開發6——GPIO子系統點亮LED

碼農愛學習 ? 來源:碼農愛學習 ? 作者:碼農愛學習 ? 2022-05-21 21:50 ? 次閱讀

前面的兩篇文章(寄存器配置點亮LED與設備樹版的點亮LED),其本質都是通過寄存器配置,來控制LED的亮滅。

使用直接操作寄存器的方式,是將與LED有關的寄存器信息,直接寫到了LED的驅動代碼中,這也是一種比較常規的控制方式。但當芯片的寄存器發了變動,就要對底層的驅動進行重寫。

使用設備樹的方式,是將與LED有關的寄存器信息,寫到了設備樹文件中,這樣,當設備的信息修改了,還可以通過設備樹的接口函數,來獲取設備信息,提高了驅動代碼的復用能力。

本篇介紹的Pinctrl子系統與GPIO子系統的方式,不需要再直接操作寄存器了,因為這兩個子系統已經替我們實現了對寄存器的操作,我們只需要操作這兩個子系統提供的API函數即可。

1 Pinctrl子系統

Pintrl子系統,顧名思義,就是管理pin引腳的一個系統,比如要點亮LED,即要控制LED對應引腳的高低電平,就要先通過Pintrl子系統將LED對應的引腳復用為GPIO功能(這一點是不是和之前寄存器配置時使用的MUX寄存器的功能有點像)。

1.1 設備樹中iomuxc節點

如何使用Pintrl子系統呢?其實它也是要依賴設備樹的,先來了解一下設備樹里的iomuxc節點,這個節點是IOMUXC外設對應的節點,負責IO功能的復用。

打開自己開發板對應的設備樹文件(我的是imx6ull-myboard.dts),然后找到iomuxc節點,先來看一下其基本結構:

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_hog_1>;
	imx6ul-evk {
		pinctrl_hog_1: hoggrp-1 {
			fsl,pins = <
				MX6UL_PAD_UART1_RTS_B__GPIO1_IO19	    0x17059 /* SD1 CD */
				MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT	0x17059 /* SD1 VSELECT */
				MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */
			>;
		};
        
		pinctrl_csi1: csi1grp {
			fsl,pins = <
				MX6UL_PAD_CSI_MCLK__CSI_MCLK		0x1b088
				MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK	0x1b088
				MX6UL_PAD_CSI_VSYNC__CSI_VSYNC		0x1b088
				MX6UL_PAD_CSI_HSYNC__CSI_HSYNC		0x1b088
				MX6UL_PAD_CSI_DATA00__CSI_DATA02	0x1b088
				MX6UL_PAD_CSI_DATA01__CSI_DATA03	0x1b088
				MX6UL_PAD_CSI_DATA02__CSI_DATA04	0x1b088
				MX6UL_PAD_CSI_DATA03__CSI_DATA05	0x1b088
				MX6UL_PAD_CSI_DATA04__CSI_DATA06	0x1b088
				MX6UL_PAD_CSI_DATA05__CSI_DATA07	0x1b088
				MX6UL_PAD_CSI_DATA06__CSI_DATA08	0x1b088
				MX6UL_PAD_CSI_DATA07__CSI_DATA09	0x1b088
			>;
		};
        //省略...

這里以pinctrl_hog_1插拔子節點為例進行分析,它是和熱插拔有關的Pin集合,比如USB OTG的ID引腳,pinctrl_csi1子節點是csi外設所使用的PIN,本篇需要控制LED的亮滅,就需要新建一個對應的節點,然后將這個自定義外設的所有Pin配置信息都放到這個子節點中。

1.2 宏定義的含義解析

對于pinctrl_hog_1這個字節點,注意其中的:

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19	    0x17059 /* SD1 CD */

這就是對Pin引腳的配置,配置包括兩方面:一是設置Pin的復用功能,二是設置Pin的電氣特性

前面的MX6UL_PAD_UART1_RTS_B__GPIO1_IO19這個宏定義, 定義在arch/arm/boot/dts/imx6ul-pinfunc.h中(注意imx6ull.dtsi會引用imx6ull-pinfunc.h,而imx6ull-pinfunc.h又會引用imx6ul-pinfunc.h

pYYBAGKI7KCAX6zqAAJnWJhOezU948.png

這里一共有8 個以MX6UL_PAD_UART1_RTS_B開頭的宏定義,分別代表這個IO的8種不同的功能。

另外,這個宏定義的值,被分為了5段,每段的值都有具體的含義:

0x0090 mux_reg寄存器偏移地址

pYYBAGKI7KiAfUv1AAF6aSF6lvg586.png

0x031C conf_reg寄存器偏移地址

pYYBAGKI7K6AXIfiAAGNVxBLOL0527.png

0x0000 input_reg寄存器偏移地址(這里無效)

0x5 mux_reg寄存器的值

poYBAGKI7LWAYSWXAANuxScJUAM153.png

0x0 input_reg寄存器值(這里無效)

2 GPIO子系統

GPIO子系統,顧名思義,就是管理GPIO功能的一個系統,其作用是初始化配置GPIO(這一點是不是和之前寄存器配置時使用的PAD寄存器的功能有點像),并提供對外的API接口。使用GPIO子系統后,就不需要自己操作寄存器,通過調用GPIO子系統提供的API函數即可實現對GPIO的控制。

2.1 設備樹中gpio信息

仍以熱插拔節點為例:

poYBAGKI7LuAQ-JjAADyIuPUmdQ560.png

UART1_RTS_B復用為GPIO1_IO19,通過讀取其高低電平來判斷SD卡有沒有插入。

那SD卡驅動程序怎么知道CD引腳連接的GPIO1_IO19呢?還是需要設備樹告訴驅動,在設備樹中SD卡節點下添加一個屬性來描述SD卡的 CD 引腳就行了:

poYBAGKI7MKAbYQ6AAEsBfUxedI148.png

cd-gpios描述了SD卡的CD引腳使用的哪個IO,屬性值一共有三個:

&gpio1 表示CD引腳所使用的IO屬于GPIO1組

19 表示GPIO1組的第19號IO

GPIO_ACTIVE_LOW 表示低電平有效

根據上面這些信息,SD卡驅動程序就可以使用GPIO1_IO19來檢測SD卡的CD信號

2.2 gpio子系統API函數

2.2.1 gpio_request/free

gpio_request

用于申請一個GPIO管腳

/**
 * gpio: 要申請的gpio標號(使用of_get_named_gpio函數從設備樹獲取指定GPIO屬性信息時返回的標號)
 * label: 給gpio設置個名字
 * return: 0-申請成功 其他值-申請失敗
 */
int gpio_request(unsigned gpio,  const char *label)

gpio_free

用于釋放一個GPIO管腳

/**
 * gpio: 要釋放的gpio標號
 * return
 */
void gpio_free(unsigned gpio) 

2.2.2 gpio_direction_input/output

gpio_direction_input

用于設置某個GPIO為輸入

/**
 * gpio: 要設置為輸入的GPIO標號
 * return: 0-設置成功 負值-設置失敗
 */
int gpio_direction_input(unsigned gpio)

gpio_direction_output

此函數用于設置某個GPIO為輸出,并且設置默認輸出值

/**
 * gpio: 要設置為輸出的GPIO標號
 * value: GPIO默認輸出值
 * return 0-設置成功 負值-設置失敗
 */
int gpio_direction_output(unsigned gpio, int value) 

2.2.3 gpio_get_value/set_value

gpio_get_value

此函數用于獲取某個GPIO的值(0 或 1)

#define gpio_get_value  __gpio_get_value
/**
 * gpio: 要獲取的gpio標號
 * return: 非負值-得到的gpio值 負值-獲取失敗
 */
int __gpio_get_value(unsigned gpio)

gpio_set_value

用于設置某個GPIO的值

#define gpio_set_value  __gpio_set_value 
/**
 * gpio: 要設置的gpio標號
 * value: 要設置的值
 * return
 */
void __gpio_set_value(unsigned gpio, int value)

2.3 與gpio相關的OF函數

2.3.1 of_gpio_named_count

用于獲取設備樹某個屬性里面定義了幾個GPIO信息

/**
 * np: 設備節點
 * propname: 要統計的gpio屬性
 * return: 正值-統計到的gpio數量 負值-失敗
 */
int of_gpio_named_count(struct device_node *np, const char  *propname) 

2.3.2 of_gpio_count

統計“gpios”這個屬性的gpio數量

/**
 * np: 設備節點
 * return: 正值-統計到的gpio數量 負值-失敗
 */
int of_gpio_count(struct device_node *np) 

2.3.3 of_get_named_gpio

獲取GPIO編號

/**
 * np: 設備節點
 * propname: 包含要獲取gpio信息的屬性名
 * index: gpio索引(一個屬性里面可能包含多個gpio)
 * return: 正值-獲取到的gpio編號 負值-失敗
 */
int of_get_named_gpio(struct device_node *np, 
                              const char *propname,   
                                     int index) 

3 Pinctr版LED驅動程序

上面介紹了Pinctrl子系統與GPIO子系統的基本情況,下面就來使用它們來實現LED的亮滅控制。

3.1 修改設備樹文件

修改imx6ull-myboard.dts,在iomuxc節點的imx6ull-evk字節點下創建一個名為pinctrl_led的子節點,節點內容如下:

pinctrl_gpioled: ledgrp{
    fsl,pins = <
        MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03    0x10b0
        >;
};

MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 表示將該io復用為GPIO

0x10b0 表示對PAD寄存器的配置值,具體含義為如下,之前的文章(驅動開發4--點亮LED(寄存器版))介紹過。

/*寄存器SW_PAD_SNVS_TAMPER3設置IO屬性
     *bit 16:0 HYS關閉
     *bit [15:14]: 00 默認下拉
     *bit [13]: 0 kepper功能
     *bit [12]: 1 pull/keeper使能
     *bit [11]: 0 關閉開路輸出
     *bit [7:6]: 10 速度100Mhz
     *bit [5:3]: 110 R0/6驅動能力
     *bit [0]: 0 低轉換率
     */
poYBAGKI7M-ACpQxAAE0T6VcuZ4075.png

在根節點下創建名為gpioled的LED節點,內容如下:

/*pinctrl led*/
gpioled {
    compatible = "myboard,gpioled";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_gpioled>;
    led-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
    status = "okay";
};

pinctrl-0 設置 LED所使用的PIN對應的pinctrl節點

led-gpio 指定了LED所使用的GPIO,這里是GPIO5的IO03,低電平有效

pYYBAGKI7NaARIqgAAGYrHgGx_w745.png

3.2 檢查引腳是否使用沖突

因為我的開發板使用的設備樹文件(imx6ull-myboard.dts)是從NXP官方提供的設備樹文件(imx6ull-14x14-evk.dts)上修改而來的,可能某些引腳的配置與自己的開發板不一樣,需要檢查一下是否有使用沖突。

本次添加的這個MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03與文件中的其它引腳沒有出現沖突,因此無需修改。

3.3 修改LED驅動文件

在上一篇的設備樹版的驅動文件上進行修改,主要修改內容如下。

頭文件需要添加一個:

#include 

設備結構體改為gpio_led:

/* gpioled設備結構體 */
struct gpioled_dev{
    dev_t         devid;    /* 設備號   */
    struct cdev   cdev;     /* cdev     */
    struct class  *class;   /* 類       */
    struct device *device;  /* 設備     */
    int           major;    /* 主設備號 */
    int           minor;    /* 次設備號 */
    struct device_node *nd; /* 設備節點 */
    int           led_gpio; /* led使用的GPIO編號*/
};

struct gpioled_dev gpioled;    /* led設備 */

硬件初始化部分是主要修改的內容,這次就不需要從設備樹讀取寄存器操作了,也不需要自己再進行I/O內存映射了,而實使用gpio子系統的API函數來對LED的GPIO進行配置:

static int gpioled_hardware_init(void)
{
    int ret;

    /* 獲取設備樹中的屬性數據 */
    /* 1、獲取設備節點:gpioled */
    gpioled.nd = of_find_node_by_path("/gpioled");
    if(gpioled.nd == NULL) 
    {
        printk("gpioled node not find!\r\n");
        return -EINVAL;
    } 
    else 
    {
        printk("gpioled node find!\r\n");
    }

    /* 2、獲取gpio屬性, 得到LED編號 */
    gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpio", 0);
    if(gpioled.led_gpio < 0) 
    {
        printk("can't get led-gpio!\r\n");
        return -EINVAL;
    } 
    else 
    {
        printk("led-gpio num = %d\r\n", gpioled.led_gpio);
    }

    /* 3、設置GPIO為輸出, 并默認關閉LED */
    ret = gpio_direction_output(gpioled.led_gpio, 1);
    if(ret < 0)
    {
        printk("can't set led-gpio!\r\n");
    }
    
    return 0;
}

開關LED時,也不需要再直接操作寄存器了,也是使用API函數來操作:

static ssize_t gpioled_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
	//省略...

    if(ledstat == LEDON) 
    {    
        gpio_set_value(dev->led_gpio, 0);         /* 打開LED燈 */
        printk("led on!\n");
    } 
    else if(ledstat == LEDOFF) 
    {
        gpio_set_value(dev->led_gpio, 1);        /* 關閉LED燈 */
        printk("led off!\n");
    }
    
    return 0;
}

4 實驗測試

4.1 編譯程序

編譯設備樹文件(.dtb),和上篇設備樹點亮LED的實驗一樣,先將設備樹文件復制到nfs文件系統位置,再從網絡啟動開發板,串口中查看設備樹中是否有添加的gpioled節點:

pYYBAGKI7OKAaZFuAABvQHK0vHw773.png

編譯LED驅動文件(.ko),復制到rootfs/lib/modules/4.1.15目錄中:

pYYBAGKI7OyAIPOwAACPQEKA2AU916.png

LED應用程序不需要改,仍使用之前寄存器版點亮LED實驗時使用的程序即可。

4.2 測試

測試方式與之前的一樣,都是先加載驅動文件,然后調用應用程序來控制LED的亮滅:

pYYBAGKI7PSAbdXZAADcDOZLJgU848.png

效果和之前的寄存器版點亮LED設備樹版點亮LED的效果一樣

pYYBAGKI60aAYOiNAAC-QqGhKlk901.png

5 總結

本篇介紹了使用Pinctrl子系統與GPIO子系統的方式來點亮LED,與之前的寄存器版點亮LED設備樹版點亮LED的最大區別在于不需要直接操作寄存器了,而是使用API函數來配置GPIO,具體操作寄存器在過程在API函數內部實現,我們無需在進行繁瑣的寄存器操作。

本篇與上一篇的設備樹版點亮LED的程序編寫流程基本一致,因為都是要使用設備樹,與上一篇的主要區別就在于,不需要將寄存器信息寫入設備樹,再從設備樹獲取出來手動配置寄存器了。

審核編輯:符乾江

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5090

    文章

    19173

    瀏覽量

    306844
  • 驅動
    +關注

    關注

    12

    文章

    1851

    瀏覽量

    85480
  • Linux
    +關注

    關注

    87

    文章

    11339

    瀏覽量

    210119
收藏 人收藏

    評論

    相關推薦

    i.MX6ULL 驅動開發7—按鍵輸入捕獲與GPIO輸入配置與高低電平讀取

    本篇主要介紹了i.MX6ULL的按鍵檢測的使用,主要的知識點是設備樹的修改,以及GPIO的輸入配置與高低電平的讀取。
    的頭像 發表于 05-24 09:11 ?6320次閱讀
    <b class='flag-5'>i.MX6ULL</b> <b class='flag-5'>驅動</b><b class='flag-5'>開發</b>7—按鍵輸入捕獲與<b class='flag-5'>GPIO</b>輸入配置與高低電平讀取

    使用i.MX6ULL開發板進行Linux根文件系統的完善

    上一篇推文講了怎么移植根文件系統,并在i.MX6ULL開發板中運行起來,但是會出現一些提示,現在來進行根文件的完善。
    發表于 10-17 11:13 ?820次閱讀

    移植NXP官方linux 5.4內核到i.MX6ULL開發

    本文描述移植NXP官方 linux 5.4 內核到i.MX6ULL開發板。
    發表于 12-19 11:10 ?2101次閱讀

    I.MX6ULL終結者開發板裸機仿真jlink調試

    I.MX6ULL‘終結者’開發板預留了JTAG仿真接口,并給出了開發文檔,可以實現在JLINK仿真器條件下的單步跟蹤、斷點調試等功能,使得開發研究i
    發表于 07-07 10:56

    i.MX6ULL開發板硬件資源

    迅為i.MX6ULL 終結者開發板硬件資源非常豐富,幾乎將 i.MX6ULL 芯片的所有資源都擴展引出到底板上了,底板提供了豐富的外設接口,開發板的尺寸是 190mm*125mm,充分
    發表于 12-29 06:18

    初識 i.MX6ULL 寄存器

    裸機開發_L1_匯編LED實驗0. 本節目標1. 硬件層電路2. 初識 i.MX6ULL 寄存器2.1 i.MX6ULL 時鐘控制寄存器2.2 i.
    發表于 12-20 07:13

    關于i.MX6ULL配置GPIO

    正如學習C語言時寫的第一段代碼都是“HelloWorld!”,接觸一款新的處理器時往往是從點亮一個LED開始;而點亮一個LED,則需要操作這款芯片的
    發表于 08-05 10:37

    飛凌i.MX6ULL開發板的評測,再次進階擁有更高的性價比

    處理器MCIMX6Y2開發設計,采用先進的ARMCortex-A7內核,運行速度高達800MHz。i.MX6ULL應用處理器包括一個集成的電源管理模塊,降低了外接電源的復雜性,并簡化了上電時序。
    發表于 10-27 11:55 ?1503次閱讀
    飛凌<b class='flag-5'>i.MX6ULL</b><b class='flag-5'>開發</b>板的評測,再次進階擁有更高的性價比

    基于NXP i.MX6ULL處理器的FETMX6ULL-C核心板

    合作伙伴,飛凌不負美譽,基于i.MX6ULL匠心打造的FETMX6ULL-S核心板一經問世便好評不斷,且已有數百家來自工業、醫療、電力、物聯網等行業的用戶采用此款核心板快速完成了整機產品的開發上市。
    發表于 04-11 15:05 ?1167次閱讀
    基于NXP <b class='flag-5'>i.MX6ULL</b>處理器的FETMX<b class='flag-5'>6ULL</b>-C核心板

    i.MX6ULL驅動開發4——點亮LED(寄存器版)

    本篇主要介紹了如何通過操作寄存器來點亮i.MX6ULL開發板上的led,通過編寫LED對應的驅動
    的頭像 發表于 05-21 21:26 ?3014次閱讀
    【<b class='flag-5'>i.MX6ULL</b>】<b class='flag-5'>驅動</b><b class='flag-5'>開發</b>4——<b class='flag-5'>點亮</b><b class='flag-5'>LED</b>(寄存器版)

    基于i.MX6ULL點亮LED

    都說入門一款芯片的第一步是點亮LED,但是i.MX6ULL入門門檻比較高,特別是通過自學入門的,這個系列已經寫了好久了,最近打算在項目不急的時候加快一下學習進度,現在就開始學習一下怎么點亮
    的頭像 發表于 03-06 09:09 ?873次閱讀

    使用pinctrl和gpio子系統實現LED驅動

    前邊已經學了兩種點燈,本質依然還是通過配置寄存器;在學習STM32的時候除了學習配置一下寄存器,基本都是使用庫來開發,那么在i.MX6ULL還使用寄存器開發明顯是不太適合,那么i.MX6ULL
    的頭像 發表于 04-03 10:17 ?1421次閱讀

    【北京迅為】i.MX6ULL開發板移植 Debian 文件系統

    【北京迅為】i.MX6ULL開發板移植 Debian 文件系統
    的頭像 發表于 02-10 15:34 ?1198次閱讀
    【北京迅為】<b class='flag-5'>i.MX6ULL</b><b class='flag-5'>開發</b>板移植 Debian 文件<b class='flag-5'>系統</b>

    基于i.MX6ULL的掉電檢測設計與軟件測試

    基于i.MX6ULL的掉電檢測設計與軟件測試基于i.MX6ULL平臺設計實現掉電檢測功能,首先選擇一路IO,利用IO電平變化觸發中斷,在編寫驅動時捕獲該路GPIO的中斷,然后在中斷響應
    的頭像 發表于 11-09 10:40 ?892次閱讀
    基于<b class='flag-5'>i.MX6ULL</b>的掉電檢測設計與軟件測試

    【迅為電子】i.MX6UL和i.MX6ULL芯片區別與開發板對比

    【迅為電子】i.MX6UL和i.MX6ULL芯片區別與開發板對比
    的頭像 發表于 11-28 14:31 ?537次閱讀
    【迅為電子】<b class='flag-5'>i.MX6</b>UL和<b class='flag-5'>i.MX6ULL</b>芯片區別與<b class='flag-5'>開發</b>板對比
    主站蜘蛛池模板: 免费无码国产欧美久久18| 国产午夜久久影院| 午夜视频在线瓜伦| 免费视频xxx| 国产午夜在线观看视频| JIZJIZJIZ 日本老师水多| 亚洲一区在线观看视频| 色欲狠狠躁天天躁无码中文字幕| 久青草国产97香蕉在线视频| 国产成人综合视频| china chinese中国人玩| 亚洲狠狠97婷婷综合久久久久| 日韩精品一卡二卡三卡四卡2021 | 国产产一区二区三区久久毛片国语 | 最新中文字幕在线视频| 亚洲AV永久无码精品老司机蜜桃| 欧亚一卡二卡日本一卡二卡| 久久偷拍国2017| 精品国产国产精2020久久日| 国产精品99久久久久久人韩国 | 久草在线草a免费线看| 国产精品免费观看视频| 成人国产精品玖玖热色欲| 97国产视频| 中文字幕在线观看网站| 一本久道视频无线视频| 亚洲欧美中文字幕高清在线| 武侠古典久久亚洲精品| 偷拍自偷拍亚洲精品| 日本九九热在线观看官网| 欧式午夜理伦三级在线观看| 欧美gay老头互吃| 男女全黄h全肉细节文| 恋夜秀场支持安卓版全部视频国产 | 亚洲中文 字幕 国产 综合| 亚州综合网| 先锋资源久久| 午夜影院一区二区三区| 无码乱人伦一区二区亚洲一| 色多多涩涩屋下载软件| 色尼玛亚洲综合|