Rk3588鲁班猫4点亮led

Rk3588鲁班猫4点亮led

这里只上代码,先执行sudo sh -c 'echo 0 > /sys/class/leds/sys_status_led/brightness'关闭自带一直闪烁的led。

随后编译下面代码得到.ko文件并加载到板卡。Makefile文件可以看我上一篇博客的末尾。

#include <linux/init.h>

#include <linux/module.h>

#include <linux/cdev.h>

#include <linux/fs.h>

#include <linux/uaccess.h>

#include <linux/io.h>



#define DEV_NAME            "led_chrdev"

#define DEV_CNT                 (1)

#define GPIO4_BASE (0xFEC50000)

#define GPIO4_DR_L (GPIO4_BASE + 0x0000)

#define GPIO4_DDR_L (GPIO4_BASE + 0x0008)

static dev_t devno;

struct class *led_chrdev_class;



struct led_chrdev

{

    struct cdev dev;

    unsigned int __iomem *va_dr;    // 数据寄存器,设置输出的电压

    unsigned int __iomem *va_ddr;   // 数据方向寄存器,设置输入或者输出



    unsigned int led_pin; // 偏移

};

static int led_chrdev_open(struct inode *inode, struct file *filp)

{  

    unsigned int val = 0;

    struct led_chrdev *led_cdev = (struct led_chrdev *)container_of(inode->i_cdev, struct led_chrdev,dev);

    filp->private_data = container_of(inode->i_cdev, struct led_chrdev, dev);



    printk("open\n");

    //设置输出模式

    val = ioread32(led_cdev->va_ddr);

    val |= ((unsigned int)0x1 << (led_cdev->led_pin+16));

    val |= ((unsigned int)0X1 << (led_cdev->led_pin));

    iowrite32(val,led_cdev->va_ddr);

   

    //输出高电平

    val = ioread32(led_cdev->va_dr);

    val |= ((unsigned int)0x1 << (led_cdev->led_pin+16));

    val |= ((unsigned int)0x1 << (led_cdev->led_pin));

    iowrite32(val, led_cdev->va_dr);



    return 0;

}



static int led_chrdev_release(struct inode *inode, struct file *filp)

{

    return 0;

}



static ssize_t led_chrdev_write(struct file *filp, const char __user * buf,

                size_t count, loff_t * ppos)

{

    unsigned long val = 0;

    unsigned long copy_ret=0;

    char ret = 0;



    struct led_chrdev *led_cdev = (struct led_chrdev *)filp->private_data;

    printk("write \n");

    copy_ret=copy_from_user(&ret, buf, 1);

    if (copy_ret != 0) {

        printk(KERN_ERR "led_chrdev: copy_from_user failed, uncopied: %lu\n", copy_ret);

        return -EFAULT; // 返回错误码,告知用户空间读取失败

    }

    val = ioread32(led_cdev->va_dr);

    printk("val = %lx\n", val);

    if (ret == '0'){

        val |= ((unsigned int)0x1 << (led_cdev->led_pin+16));

        val &= ~((unsigned int)0x01 << (led_cdev->led_pin));   /*设置GPIO引脚输出低电平*/

    }

    else{

        val |= ((unsigned int)0x1 << (led_cdev->led_pin+16));

        val |= ((unsigned int)0x01 << (led_cdev->led_pin));    /*设置GPIO引脚输出高电平*/

    }

    iowrite32(val, led_cdev->va_dr);

    printk("val = %lx\n", val);

    return count;

}



static struct file_operations led_chrdev_fops = {

    .owner = THIS_MODULE,

    .open = led_chrdev_open,

    .release = led_chrdev_release,

    .write = led_chrdev_write,

};



static struct led_chrdev led_cdev[DEV_CNT] = {

    {.led_pin = 13},    

};



static __init int led_chrdev_init(void)

{

    int i = 0;

    dev_t cur_dev;



    printk("led_chrdev init (lubancat2  GPIO4_B5)\n");

   

    led_cdev[0].va_dr   = ioremap(GPIO4_DR_L, 4);    

    led_cdev[0].va_ddr  = ioremap(GPIO4_DDR_L, 4);    



    alloc_chrdev_region(&devno, 0, DEV_CNT, DEV_NAME);



    led_chrdev_class = class_create(THIS_MODULE, "led_chrdev");



    for (; i < DEV_CNT; i++) {

        cdev_init(&led_cdev[i].dev, &led_chrdev_fops);

        led_cdev[i].dev.owner = THIS_MODULE;



        cur_dev = MKDEV(MAJOR(devno), MINOR(devno) + i);



        cdev_add(&led_cdev[i].dev, cur_dev, 1);



        device_create(led_chrdev_class, NULL, cur_dev, NULL,

                  DEV_NAME "%d", i);

    }



    return 0;

}



module_init(led_chrdev_init);



static __exit void led_chrdev_exit(void)

{

    int i;

    dev_t cur_dev;

    printk("led chrdev exit (lubancat2  GPIO4_B5)\n");

   

    for (i = 0; i < DEV_CNT; i++) {

        iounmap(led_cdev[i].va_dr);         // 释放模式寄存器虚拟地址

        iounmap(led_cdev[i].va_ddr);    // 释放输出类型寄存器虚拟地址

    }



    for (i = 0; i < DEV_CNT; i++) {

        cur_dev = MKDEV(MAJOR(devno), MINOR(devno) + i);



        device_destroy(led_chrdev_class, cur_dev);



        cdev_del(&led_cdev[i].dev);



    }

    class_destroy(led_chrdev_class);

    unregister_chrdev_region(devno, DEV_CNT);

   



}



module_exit(led_chrdev_exit);



MODULE_AUTHOR("embedfire");

MODULE_LICENSE("GPL");

之后执行下面语句就可以看到板卡的led点亮和关闭了。

#绿灯亮

sudo sh -c 'echo 0 >/dev/led_chrdev0'

#绿灯灭

sudo sh -c 'echo 1 >/dev/led_chrdev0'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值