字符设备驱动-LED实验

发布者:静逸心境最新更新时间:2016-04-05 来源: eefocus关键字:字符设备驱动  LED实验 手机看文章 扫描二维码
随时随地手机看文章
驱动源码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
 
int major;
static struct class *leddrv_class;
static struct class_device *leddrv_class_dev;
 
volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;
 
static int led_drv_open(struct inode *inode, struct file *file)
{
    //printk("first_drv_open\n");
    *gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
    *gpfcon |=  ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
    return 0;
}
 
static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
    char val = 0;
 
    copy_from_user(&val,buf,count);
    if(val == 1)
        *gpfdat &= ~((1<<4) | (1<<5) | (1<<6));
    else if(val == 0)
        *gpfdat |= ((1<<4) | (1<<5) | (1<<6));
    //printk("first_drv_write\n");
    return 0;
}
 
static struct file_operations led_drv_fops = {
    .owner  =   THIS_MODULE,    
    .open   =   led_drv_open,     
    .write = led_drv_write,   
};
 
static int led_drv_init(void)
{
    major = register_chrdev(0, "led_drv", &led_drv_fops); // 注册, 告诉内核
 
    leddrv_class = class_create(THIS_MODULE, "leddrv");
 
    leddrv_class_dev = class_device_create(leddrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
 
    gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
    gpfdat = gpfcon + 1;
        
    return 0;
}
 
static void led_drv_exit(void)
{
    unregister_chrdev(major, "led_drv"); // 卸载
    class_device_unregister(leddrv_class_dev);
    class_destroy(leddrv_class);
    iounmap(gpfcon);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
==================================================================================================
测试程序:
#include
#include
#include
#include
 
int main(int argc, char **argv)
{
    int fd;
    int val = 1;  
 
    fd = open("/dev/xxx",O_RDWR);
    if(fd < 0)
    {
        printf("can't open!\n");
    }
    if(argc != 2)
    {
        printf("Usage:\n");
        printf("%s ",argv[0]);
        return 0;
    }
    if(strcmp(argv[1],"on") == 0)
        val = 1;
    else
        val = 0;
    write(fd,&val,4);
    return 0;
}
==================================================================================================
 
注:在调用write(fd,&val,4);时根据不同的val值在调用驱动程序时做出判断:关闭、打开led灯
         copy_from_user(&val,buf,count);   //从用户空间buf拷贝count长度的数据到内核空间val中
         copy_to_user(buf,&val,,count);   //从内核空间val拷贝count长度的数据到用户空间buf中
    内核空间不能直接访问物理地址,故要映射:
         gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
 
关键字:字符设备驱动  LED实验 引用地址:字符设备驱动-LED实验

上一篇:字符设备驱动-利用次设备号实现多路LED控制
下一篇:arm中的PLL,MPLL,UPLL,FCLK,HCLK,PCLK的作用概述

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved