字符设备驱动点灯

驱动程序

#include <linux/module.h>

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

static struct class *firstdrv_class;
static struct class_device  *firstdrv_class_dev;


volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;
/*
volatile的作用是: 作为指令关键字,确保本条指令不会因编译>器的优化而省略,且要求每次直接读值.
如果不加入volatile,基本上会导致这样的结果:要么无法编写多
线程程序,要么编译器失去大量优化的机会。
*/
static int firstdrv_open(struct inode *inode,struct file *file)
{
         *gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
        *gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
        return 0;

}
//ssize_t 有符号整型 size_t 无符号整型
//32位机 ssize_t = int  64位 ssize_t = long int
static ssize_t firstdrv_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;

static struct file_operations firstdrv_fops =
{
        .owner = THIS_MODULE,
        .open  = firstdrv_open,
        .write = firstdrv_write,
};

int major;
static int firstdrv_init(void)
{
        major = register_chrdev(0,"firstdrv",&firstdrv_fops);     //注册设备,返回设备号
        firstdrv_class = class_create(THIS_MODULE,"firstdrv");
        firstdrv_class_dev = class_device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"firstdrv");

        gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
        gpfdat = gpfcon + 1; //指针+1

        return 0;
}

static void firstdrv_exit(void)
{
        unregister_chrdev(major,"firstdrv");
        class_device_unregister(firstdrv_class_dev);
        class_destroy(firstdrv_class);

        iounmap(gpfcon);
        iounmap(gpfdat);
}

module_init(firstdrv_init);
module_exit(firstdrv_exit);

MODULE_LICENSE("GPL");

大笑大笑



测试程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
        int fd;
        int val = 1;
        fd = open("/dev/firstdrv", O_RDWR);
        if (fd < 0)
        {
                printf("can't open!\n");
        }
        if (argc != 2)
        {
                printf("Usage :\n");
                printf("%s <on|off>\n", argv[0]);
                return 0;
        }

        if (strcmp(argv[1], "on") == 0)
        {
                val  = 1;
        }
        else
        {
                val = 0;
        }

        write(fd, &val, 4);
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值