驱动 :3.1内核态控制led

电路原理图:控制LED1,就是控制cpu上的GPIOC12管脚
cpu datasheet:GPIOC12配置输出模式
控制输出高/低电平

GPIOCALTFN0
GPIOCOUTENB
GPIOCOUT

内核态控制GPIO管脚有两种方式:

1)类似裸板中直接通过特殊功能寄存器控制
2)通过GPIO库函数(本质就是将操作特殊功能寄存器的过程封装起来了)

这里我们使用第二种方式
Linux系统中使用GPIO库函数的标准套路(gpio_left.c):

1)申请GPIO管脚

int gpio_request(unsigned gpio,const char *name)
gpio,要申请的GPIO管脚
name,名称
返回值,0 申请成功 1 申请失败

2)使用GPIO管脚

int gpio_direction_output(unsigned gpio,int value)
作用:将指定的管脚设置为输出模式
value,0 默认输出低电平 非0 默认输出高电平
gpio,管脚编号1
void gpio_set_value(unsigned gpio,int value)
作用:将指定的gpio管脚设置为value,0/非0 低/高电平
int gpio_direction_input(unsigned gpio,int value)
作用:将指定的管脚设置为输入模式
int gpio_get_value(unsigned gpio)
作用:获取指定管脚的电平状态
返回值:0/非0 低/高电平

3)释放GPIO管脚

void gpio_free(unsigned gpio)

实验步骤:
vi led_drv.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/gpio.h>
#include <mach/platform.h>
MODULE_LICENSE("GPL");
dev_t dev;   //num
unsigned int major = 0; //main num
unsigned int minor = 5; //ci   num
struct cdev led_cdev;
int led_open(struct inode *inode,struct file *filp){
    gpio_set_value(PAD_GPIO_C+12,0);
    gpio_set_value(PAD_GPIO_C+11,0);
    gpio_set_value(PAD_GPIO_C+7,0);
    gpio_set_value(PAD_GPIO_B+26,0);
    printk("<2>" "OK %s\n",__func__);
    return 0;
}
int led_release(struct inode *inode,struct file *filp){
    gpio_set_value(PAD_GPIO_C+12,1);
    gpio_set_value(PAD_GPIO_C+11,1);
    gpio_set_value(PAD_GPIO_C+7,1);
    gpio_set_value(PAD_GPIO_B+26,1);
    printk("<2>" "OK %s\n",__func__);
    return 0;
}
struct file_operations led_fops={
    .owner = THIS_MODULE,
    .open  = led_open,
    .release = led_release,
};
int __init led_drv_init(void){
    if(major){
        //dev = major<<20|minor;
        dev = MKDEV(major,minor);
        register_chrdev_region(dev,1,"myleds");
    }
    else{
        alloc_chrdev_region(&dev,minor,1,"myleds");
        printk("<2>" "major=%d minor=%d\n",MAJOR(dev),MINOR(dev));
    }
    cdev_init(&led_cdev,&led_fops);
    cdev_add(&led_cdev,dev,1);
    gpio_request(PAD_GPIO_C+12,"myleds");
    gpio_direction_output(PAD_GPIO_C+12,1);
    gpio_request(PAD_GPIO_C+11,"myleds");
    gpio_direction_output(PAD_GPIO_C+11,1);
    gpio_request(PAD_GPIO_C+7,"myleds");
    gpio_direction_output(PAD_GPIO_C+7,1);
    gpio_request(PAD_GPIO_B+26,"myleds");
    gpio_direction_output(PAD_GPIO_B+26,1);
    return 0;
}
void __exit led_drv_exit(void){
    cdev_del(&led_cdev);
    unregister_chrdev_region(dev,1);
    gpio_free(PAD_GPIO_C+12);
    gpio_free(PAD_GPIO_C+11);
    gpio_free(PAD_GPIO_C+7);
    gpio_free(PAD_GPIO_B+26);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
  make
  //最好将内核中自带的LED驱动裁剪掉
  cd /home/tarena/driver/kernel/
  make menuconfig  
     Device Drivers  --->
        -*- LED Support  ---> 
           < >   LED Support for GPIO connected LEDs
           < >   PWM driven LED Support
           [ ]   LED Trigger support  
  make uImage
  cp arch/arm/boot/uImage /tftpboot
  
  在开发板上执行
      insmod led_drv.ko
      mknod /dev/myleds c 244 5
      ./test
      观察LED的变化  

  1. 管脚编号在cfg_××××.c文件好像在common目录下中编辑好了 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值