3.4 gpio linux
2013-01-10 17:56:49 kevinx_xu 阅读数 468

GPIO的驱动主要就是读取GPIO口的状态,或者设置GPIO口的状态。就是这么简单,但是为了能够写好的这个驱动,在LINUX上作了一些软件上的分层。

为了让其它驱动可以方便的操作到GPIO,在LINUX里实现了对GPIO操作的统一接口,这个接口实则上就是GPIO驱动的框架,具体的实现文件为gpiolib.c

在配置内核的时候,我们必须使用CONFIG_GENERIC_GPIO这个宏来支持GPIO驱动。

这里我们把目光放到gpiolib.c上,主要对外提供的接口函数,在其头文件gpio.h里可以看到:

具体的GPIO描述符:

structgpio_chip {

… ...

int (*request)(struct gpio_chip *chip, unsigned offset);

void (*free)(struct gpio_chip *chip, unsigned offset);

int (*direction_input)(struct gpio_chip *chip, unsignedoffset);

int (*get)(struct gpio_chip *chip, unsigned offset);

int (*direction_output)(struct gpio_chip *chip, unsignedoffset, int value);

int (*set_debounce)(struct gpio_chip *chip, unsigned offset,

unsigneddebounce);

void (*set)(struct gpio_chip *chip, unsigned offset, int value);

int (*to_irq)(struct gpio_chip *chip, unsigned offset);

void (*dbg_show)(struct seq_file *s, struct gpio_chip *chip);

int base;

u16 ngpio;

… ...

};

 


申请和释放GPIO资源:

externint gpio_request(unsigned gpio, const char *label);

 


externvoid gpio_free(unsigned gpio);

 


设置GPIO口方向的操作www.linuxidc.com

externint gpio_direction_input(unsigned gpio);

externint gpio_direction_output(unsigned gpio, int value);

 


设置GPIO口高低电平值操作:

externint gpio_get_value_cansleep(unsigned gpio);

externvoid gpio_set_value_cansleep(unsigned gpio, int value);

 


externint __gpio_get_value(unsigned gpio);

externvoid __gpio_set_value(unsigned gpio, int value);

 


GPIO驱动的关系图:

 

 

如上图所示,右上方部分为GPIO驱动对其它驱动提供的GPIO操作接口,其对应的右下方部分为GPIO硬件操作接口,也就是说对外提供的接口最终会一一对应的对硬件GPIO进行操作。

再来看左边部分,左上方部分为一全局数组,记录各个GPIO的描述符,即对应左下方的gpio_desc结构体,其中gpio_chip指向硬件层的GPIO,flags为一标志位,用来指示当前GPIO是否已经占用,当用gpio_request申请GPIO资源时,flags位就会置位,当调用gpio_free释放GPIO资源时,flags就会清零。label是一个字符串指针,用来作说明。

在软件上,我们首先通过函数gpiochip_add注册一个gpio_chip对应的gpio_desc到全局数组gpio描述符中。其中,一个描述符对应一个GPIO,所以如果我们要使用多个GPIO,那么就在gpio_chip结构体的ngpio指定个数,base为起始的GPIO号。

如果你想使用GPIO驱动,那么在配置内核的时候请把该驱动选上,即定义宏CONFIG_GENERIC_GPIO,然后在你的驱动里加入头文件linux/gpio.h,这样就可以用那些操作函数了。


本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-07/39523.htm

 

2017-03-16 10:40:40 owhfg 阅读数 198
  1. 查看原理图,我的JZ2440开发板连接图是
    LED1: nLED_1 –> GPF4
    LED2: nLED_2 –> GPF5
    LED3: nLED_4 –> GPF6

S1: EINT0–> GPF0
S2: EINT2 –> GPF2
S3: EINT11 –> GPG3
2. 查看S3C2440手册
控制GPF口的寄存器如下:

GPFCOND寄存器控制I/O口的功能(输入/输出/中断)。
GPFDAT寄存器存放I/O口的状态(高电平/低电平)
GPFUP寄存器控制I/O口是否使能上拉
电路图里LED和Key都接有上拉电阻,不用内部上拉。
控制GPG口的寄存器也类似。
3. 编写代码
@************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@************************************************************

.text
.global _start                    @代码开始地址定义个标记
_start:
    ldr     r0, =0x53000000     @ WATCHDOG寄存器地址
    mov    r1, #0x0           @给r1 赋值0x0
    str     r1, [r0]             @ 写入0,禁止WATCHDOG,否则CPU会不断重启

    ldr  sp, =1024*4      @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
                      @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
                      @调用C函数前要先设置堆栈
    bl   main            @调用C程序中的main函数,并将下一条指令地址定义为返回地址
halt_loop:
    b   halt_loop                @死循环

/*************************************************************
File:key_led.c
功能:实现按键控制LED灯的亮灭
*************************************************************/

 #define GPFCON      (*(volatile unsigned long *)0x56000050)    //设置GPFCON地址
 #define GPFDAT      (*(volatile unsigned long *)0x56000054)       //设置GFPDAT地址
 #define GPGCON      (*(volatile unsigned long *)0x56000060)   //设置GPGCON地址
 #define GPGDAT      (*(volatile unsigned long *)0x56000064)   //设置GPFDAT地址
 #define    GPF4_out    (1<<(4*2))       //  0000 0001 0000 0000     
 #define    GPF5_out    (1<<(5*2))     //  0000 0100 0000 0000
 #define    GPF6_out    (1<<(6*2))       //  0001 0000 0000 0000

 #define    GPF4_msk    (3<<(4*2))       //  0000 0011 0000 0000
 #define    GPF5_msk    (3<<(5*2))     //  0000 1100 0000 0000
 #define    GPF6_msk    (3<<(6*2))     //  0011 0000 0000 0000

 #define  GPF0_in     (0<<(0*2))
 #define  GPF2_in     (0<<(2*2))
 #define  GPG3_in     (0<<(3*2))

 #define  GPF0_msk    (3<<(0*2))
 #define  GPF2_msk    (3<<(2*2))
 #define  GPG3_msk    (3<<(3*2))

int main()  
{
    unsigned long dwDat;         // LED1,LED2,LED4对应的3根引脚设为输出
    GPFCON & = ~(GPF4_msk | GPF5_msk | GPF6_msk) ;     //将GPF4-6设置为输入
                        //0011 1111 0000 0000 取反 1100 0000 1111 1111 
    GPFCON |= GPF4_out | GPF5_out | GPF6_out ;        //将GPF4-6设置为输出
                        //0001 0101 0000 0000
    // S2,S3对应的2根引脚设为输入
    GPFCON &= ~(GPF0_msk | GPF2_msk);
    GPFCON |= GPF0_in | GPF2_in;

    // S4对应的引脚设为输入
    GPGCON &= ~GPG3_msk;
    GPGCON |= GPG3_in;

    while(1)
    {
            //若Kn为0(表示按下),则令LEDn为0(表示点亮)
            dwDat = GPFDAT;             // 读取GPF管脚电平状态

            if (dwDat & (1<<0))        // S2没有按下
                GPFDAT |= (1<<4);       // LED1熄灭
            else    
                GPFDAT &= ~(1<<4);      // LED1点亮

            if (dwDat & (1<<2))         // S3没有按下
                GPFDAT |= (1<<5);       // LED2熄灭
            else    
                GPFDAT &= ~(1<<5);      // LED2点亮

            dwDat = GPGDAT;             // 读取GPG管脚电平状态

            if (dwDat & (1<<3))         // S4没有按下
                GPFDAT |= (1<<6);       // LED3熄灭
            else    
                GPFDAT &= ~(1<<6);      // LED3点亮
    }

    return 0;
}

之后编写makefile文件,即可生成可执行文件烧录到开发板。
编译和烧录过程http://blog.csdn.net/owhfg/article/details/62226849

2017-03-10 09:27:08 sunlei0625 阅读数 306
 
/**
 * Convert a GPIO descriptor to the integer namespace.
 * This should disappear in the future but is needed since we still
 * use GPIO numbers for error messages and sysfs nodes
 */
int desc_to_gpio(const struct gpio_desc *desc)
{
 return desc->gdev->base + (desc - &desc->gdev->descs[0]);
}
EXPORT_SYMBOL_GPL(desc_to_gpio);
 
 
 
 
2017-03-10 09:28:13 sunlei0625 阅读数 266
 
/**
 * gpiod_to_chip - Return the GPIO chip to which a GPIO descriptor belongs
 * @desc: descriptor to return the chip of
 */
struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
{
 if (!desc || !desc->gdev || !desc->gdev->chip)
  return NULL;
 return desc->gdev->chip;
}
EXPORT_SYMBOL_GPL(gpiod_to_chip);
 
 
 
 
 
 
 
 
 
 
 

Linux GPIO驱动

阅读数 343

linux gpio接口

阅读数 281

linux之GPIO的使用

阅读数 895

linux之GPIO的使用

阅读数 511

没有更多推荐了,返回首页