字符设备驱动(1)代码分析---之gpio_get_value

在中断处理函数中,调用gpio_get_value/gpio_set_value()函数来获取/设置gpio端口的值,在这里简单分析一下内核的实现流程。

tmp = gpio_get_value(S5PV210_GPH2(0));
#define gpio_get_value    __gpio_get_value
int __gpio_get_value(unsigned gpio)
{
    struct gpio_chip    *chip;
    int value;
    chip = gpio_to_chip(gpio);
    
    
    ##
        {
         .base    = (S5P_VA_GPIO + 0xC40),
         .config    = &gpio_cfg_noint,
         .irq_base = IRQ_EINT(16),
            .chip    = {
            .base    = S5PV210_GPH2(0),
            .ngpio    = S5PV210_GPIO_H2_NR,
            .label    = "GPH2",
            .to_irq = samsung_gpiolib_to_irq,
        },
    ##
    
    
    value = chip->get ? chip->get(chip, gpio - chip->base) : 0;
    //offset = gpio - chip->base
    trace_gpio_value(gpio, 1, value);
    return value;
    
    
    ##
/****************************************************
    chip->get()函数的内核实现
****************************************************/
    //drivers/gpio/gpio-plat-samsung.c
    void __init samsung_gpiolib_add_4bit_chips
            (structs 3c_gpio_chip *chip,int nr_chips)
    {
        for (; nr_chips > 0; nr_chips--, chip++) {
            samsung_gpiolib_add_4bit(chip);
            s3c_gpiolib_add(chip);
        }
    }

    void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
    {
        chip->chip.direction_input = samsung_gpiolib_4bit_input;
        chip->chip.direction_output = samsung_gpi
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,用于在Linux内核中使用ioctl接口控制GPIO输出高低电平和响应中断。该示例使用了GPIO子系统和GPIO键盘驱动程序。 首先,需要定义ioctl命令和相应的结构体: ```c #define GPIO_IOC_MAGIC 'k' #define GPIO_IOC_SET_OUTPUT _IOW(GPIO_IOC_MAGIC, 1, int) #define GPIO_IOC_SET_INPUT _IOW(GPIO_IOC_MAGIC, 2, int) #define GPIO_IOC_SET_VALUE _IOW(GPIO_IOC_MAGIC, 3, int) #define GPIO_IOC_GET_VALUE _IOR(GPIO_IOC_MAGIC, 4, int) #define GPIO_IOC_ENABLE_IRQ _IOW(GPIO_IOC_MAGIC, 5, int) #define GPIO_IOC_DISABLE_IRQ _IOW(GPIO_IOC_MAGIC, 6, int) struct gpio_ioctl_data { int pin; int value; }; ``` 然后,在字符设备驱动程序的ioctl函数中实现这些命令: ```c static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct gpio_chip *chip = filp->private_data; struct gpio_ioctl_data data; int ret; switch (cmd) { case GPIO_IOC_SET_OUTPUT: ret = copy_from_user(&data, (void __user *)arg, sizeof(data)); if (ret) return -EFAULT; gpio_direction_output(chip->base + data.pin, data.value); break; case GPIO_IOC_SET_INPUT: ret = copy_from_user(&data, (void __user *)arg, sizeof(data)); if (ret) return -EFAULT; gpio_direction_input(chip->base + data.pin); break; case GPIO_IOC_SET_VALUE: ret = copy_from_user(&data, (void __user *)arg, sizeof(data)); if (ret) return -EFAULT; gpio_set_value(chip->base + data.pin, data.value); break; case GPIO_IOC_GET_VALUE: ret = copy_from_user(&data, (void __user *)arg, sizeof(data)); if (ret) return -EFAULT; data.value = gpio_get_value(chip->base + data.pin); ret = copy_to_user((void __user *)arg, &data, sizeof(data)); if (ret) return -EFAULT; break; case GPIO_IOC_ENABLE_IRQ: ret = copy_from_user(&data, (void __user *)arg, sizeof(data)); if (ret) return -EFAULT; gpio_direction_input(chip->base + data.pin); ret = request_irq(gpio_to_irq(chip->base + data.pin), gpio_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "gpio_irq_handler", chip); if (ret) return -EINVAL; break; case GPIO_IOC_DISABLE_IRQ: ret = copy_from_user(&data, (void __user *)arg, sizeof(data)); if (ret) return -EFAULT; free_irq(gpio_to_irq(chip->base + data.pin), chip); break; default: return -EINVAL; } return 0; } ``` 最后,需要实现GPIO中断处理程序gpio_irq_handler: ```c static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { struct gpio_chip *chip = dev_id; unsigned long flags; spin_lock_irqsave(&chip->lock, flags); // 处理中断事件 // ... spin_unlock_irqrestore(&chip->lock, flags); return IRQ_HANDLED; } ``` 这样,就可以通过ioctl接口控制GPIO输出高低电平和响应中断了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值