编写LED驱动-传统

写LED驱动 

首先,我们要建立一个file_operator结构体:

/* 定义自己的file_operations结构体                                              */
static struct file_operations led_drv = {
    .owner     = THIS_MODULE,       //主设备号
    .open    = led_drv_open,     // driver function
    .read    = led_drv_read,
    .write   = led_drv_write,
    .release = led_drv_close,
};

 

 接下来要配置GPIO的地址:

复制代码
/*指定引脚的基地址 */
static unsigned int gpio_base[] = {
       0x56000000;      /*GPIOA*/
       0x56000010;      /*GPIOB*/
       .........;
}

// 这里是确定GPIOE的第n个引脚
#define IMX6ULL_GPE(n)    (5<<16 | n)

//查找GPIO基地址:
复制代码

 

 

 

编写相应的四个driver function:

复制代码
static volatile unsigned int *gpio_con;          // 将引脚配置为输出引脚
static volatile unsigned int *gpio_dat;          // 设置高低电平
static int led_pin = IMX6ULL_GPE(5);
/* 3. 实现对应的open/read/write等函数,填入file_operations结构体                   */
static ssize_t led_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

/* write(fd, &val, 1); */
static ssize_t led_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
    int err;
    usigned char status;
  int pin = pin_bin * 0xffff; printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); err = copy_from_user(&status, buf, 1); // 将用户空间传入到值传入到kernel   if(err){
    return -1;
  }
  if(status){
    /*点灯*/
    *gpio_data &= ~(1<<pin);
  }else{
    /*灭灯*/
    *gpio_data |= (1<<pin);
   }
return 1; } static int led_drv_open (struct inode *node, struct file *file) {
  
  int bank =
led_pin >> 16;
  int bass = gpio_bas[bank]; // 这里不太清楚宏定义的意思
  int pin = led_pin & 0xFFFF;
  gpio_con = ioremap(bass, 8);       // 在bass基地址映射8(1024),size只映射空间的大小,这里是以page为单位,8<1024,也是一个page的大小
  gpio_dat = gpio_con + 1;
  *gpio_con |= (1<<pin*2); // 这里是相关寄存器配置,因为要配置GPIO5--[11:10]为output---01
    return 0;
}

static int led_drv_close (struct inode *node, struct file *file)
{
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  ioumap(gpio_con) return 0; }
复制代码

 

注册filer_operator: 告诉CPU

复制代码
static int myled_init(void)
{
       major = register_chrdev(0, "myled", &myled_oprs);
       return 0;  
}

static void myled_exit(void)
{
        unregister_chrdev(major, "myled");
}
module_init(myled_init); //这里是为了告诉内核,入口函数是什么
module_exit(myled_exit);
复制代码

 

 

 
« 上一篇: 编写LED驱动-设备树
» 下一篇: linux设备节点
posted @ 2023-05-21 13:55  嵌入式小白—  阅读(46
 
 
posted @   嵌入式小白—  阅读(46)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示