全志H3一个灯的驱动(采用write)

灯的驱动,只需要实现open,write,close就可以。

全志H3灯的驱动

test_led.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/device.h> // 内核源码里创建/移除设备,产生热插拔事件的函数class


#define MYMA  1234
#define MYMI  3333
#define COUNT    1

#define LED_IO   GPIOA(2)//注意修改! 对应开发板上的led灯引脚

dev_t devid; //用于存放设备号
struct cdev mycdev; 
static struct class *mycls;



//打开设备文件时开启中断
static int myopen(struct inode *ind,struct file *fl)
{
    int ret;
    ret = gpio_request(LED_IO, "led_0"); //请求gpio口,tldev则是为其取一个名字。
    if(ret<0)
        goto err0;
    gpio_direction_output(LED_IO, 0); //配置gpio口为输出,先输出低电平
    return 0;

err0:
    return ret;
}

static ssize_t mywrite(struct file *fl,const char *__user buf,size_t len,loff_t *off)
{
    char stat;

    copy_from_user(&stat,buf,sizeof(char));
    if(stat)
        gpio_set_value(LED_IO,1);
    else
        gpio_set_value(LED_IO,0);

    return 0;
}

//关闭设备文件时释放中断
static int myclose(struct inode *inode,struct file *fl)
{
    gpio_set_value(LED_IO,0);
    gpio_free(LED_IO);

    return 0;
}

static struct file_operations fops= {
    .owner = THIS_MODULE,
    .open  = myopen,
    .write = mywrite,
    .release= myclose,
};



static int __init test_init(void)
{
    int ret;

    devid = MKDEV(MYMA, MYMI); //生成一个设备号
    ret = register_chrdev_region(devid, COUNT, "tldev"); //name设备名(用于查看用, 长度不能超过64字节   )
    if (ret < 0)
        goto err0;

    cdev_init(&mycdev, &fops);
    mycdev.owner = THIS_MODULE;
    ret = cdev_add(&mycdev, devid, COUNT);
    if (ret < 0)
        goto err1;  
  
    mycls= class_create(THIS_MODULE,"mykeycls");
    if(mycls== NULL)
        goto err2;
    device_create(mycls,NULL,devid,NULL,"tldev");


    return 0;

err2:
    cdev_del(&mycdev);
err1:
    unregister_chrdev_region(devid, COUNT);
err0:
    return ret;
}

static void __exit test_exit(void)
{
    device_destroy(mycls,devid);
    class_destroy(mycls);
    unregister_chrdev_region(devid, COUNT);
    cdev_del(&mycdev);
    gpio_free(LED_IO); //释放gpio
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jmlinux");
MODULE_DESCRIPTION("led");
MODULE_VERSION("v0.0");

 

app.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>


int main(void)
{
    int fd;
    char LED_ON=1,LED_OFF=0,flag=0;

    fd = open("/dev/tldev", O_RDWR);
    if (fd < 0)
    {
        perror("open");
  
    }
   
    while (1)
    {
        write(fd,&LED_ON,1); //led灯亮
        sleep(1);
        write(fd,&LED_OFF,1); //led灯灭
        sleep(1);

    }

    return 0;
}   

 

执行编译好app.c,可实现led灯每隔1s闪烁。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值