点亮一个灯的过程:

1.首先写出字符设备驱动的框架

2. 在open 函数中初始化各个引脚的内容

3. 在write函数中点亮灯

 

 

我们首先先写出字符设备的框架:如下面程序所示:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>


static struct class *forthdrv_class;
static struct class_device    *forthdrv_class_dev;

volatile unsigned long *gpfcon;
volatile unsigned long *gpfdat;

volatile unsigned long *gpgcon;
volatile unsigned long *gpgdat;






static int forth_drv_open(struct inode *inode, struct file *file)
{
   printk("this is the open function\r\n");
   return 0;
}

ssize_t forth_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{

    printk("this is the read function\r\n");
    return 0;
}







static struct file_operations sencod_drv_fops = {
    .owner   =  THIS_MODULE,    /* ����һ���꣬�������ģ��ʱ�Զ�������__this_module���� */
    .open    =  forth_drv_open,     
    .read     =    forth_drv_read,       
    
    
};


int major;
static int forth_drv_init(void)
{
    major = register_chrdev(0, "forth_drv", &sencod_drv_fops);

    forthdrv_class = class_create(THIS_MODULE, "forth_drv");

    forthdrv_class_dev = class_device_create(forthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */


    return 0;
}

static void forth_drv_exit(void)
{
    unregister_chrdev(major, "forth_drv");

    return 0;
}


module_init(forth_drv_init);

module_exit(forth_drv_exit);

MODULE_LICENSE("GPL");

 

 

然后我们添加硬件的设置:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>


static struct class *forthdrv_class;
static struct class_device    *forthdrv_class_dev;

volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;







static int forth_drv_open(struct inode *inode, struct file *file)
{
   printk("this is the open function\r\n");
 
   *gpfcon |= (1<<8);
   *gpfcon &= ~(1<<9);

   
   return 0;
}

ssize_t  forth_drv_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
   int val;
   copy_from_user(&val, buf, count);

   if(val == 1)
       {
      *gpfdat &= ~((1<<4) | (1<<5) | (1<<6));

    }
   else
       {
        *gpfdat |= (1<<4) | (1<<5) | (1<<6);

    }
  return 0;
}


ssize_t forth_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{

    printk("this is the read function\r\n");
    return 0;
}







static struct file_operations sencod_drv_fops = {
    .owner   =  THIS_MODULE,    /* ����һ���꣬�������ģ��ʱ�Զ�������__this_module���� */
    .open    =  forth_drv_open,     
    .read     =    forth_drv_read,       
    .write   =  forth_drv_write,
    
};


int major;
static int forth_drv_init(void)
{
    major = register_chrdev(0, "forth_drv", &sencod_drv_fops);

    forthdrv_class = class_create(THIS_MODULE, "forth_drv");

    forthdrv_class_dev = class_device_create(forthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

    
    gpfcon = ioremap(0x56000050, 16);    //remap the IO address to virsual linux address
    gpfdat = gpfcon + 1;
    return 0;
}

static void forth_drv_exit(void)
{
    unregister_chrdev(major, "forth_drv");
    iounmap(gpfcon);
    class_destroy(forthdrv_class);
    
}


module_init(forth_drv_init);

module_exit(forth_drv_exit);

MODULE_LICENSE("GPL");

这个代码很简单 慢慢看就行了。

posted on 2020-12-20 17:51  闲云潭影  阅读(102)  评论(0编辑  收藏  举报