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'

### 设备树配置概述 LubanCat 4 基于 Rockchip RK3588 芯片,支持高性能计算和多媒体处理。要实现 8K 显示支持,需要对设备树(Device Tree)进行适当修改和配置,以启用 HDMI 2.1 接口并正确设置显示时序参数。 ### 核心配置步骤 RK3588 支持通过 HDMI 2.1 输出 8K 分辨率(7680x4320),通常刷新率为 30Hz 或更高(如 60Hz 需要 DSC 压缩技术)。在设备树中,需要关注以下几个关键部分: - **HDMI 控制器节点**:确保 `dw_hdmi` 节点存在并启用。 - **显示时序定义**:添加或修改 `display-timings` 子节点以支持 8K 分辨率。 - **DSC 支持(可选)**:如果需要 8K@60Hz,必须启用 Display Stream Compression (DSC) 技术[^1]。 ### 示例设备树片段 以下是一个典型的 RK3588 设备树片段,用于配置 HDMI 2.1 支持 8K 显示: ```dts &hdmi { status = "okay"; ddc-i2c-bus = <&i2c8>; hdmi_8k_mode: mode_7680x4320 { clock-frequency = <594000000>; hactive = <7680>; vactive = <4320>; hfront-porch = <200>; hback-porch = <200>; hsync-len = <100>; vfront-porch = <8>; vback-porch = <8>; vsync-len = <20>; hsync-active = <1>; vsync-active = <1>; de-active = <1>; pixelclk-active = <0>; dsc-enable; dsc-config = "dsc0_config_data"; }; }; &dsc0 { status = "okay"; fragment@0 { target-path = "/reserved-memory"; __overlay__ { dsc0_config_data: dsc-config-data { compatible = "rockchip,dsc-config"; reg = <0x0 0x100>; data = [ /* DSC 编码配置数据 */ 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f ]; }; }; }; }; ``` ### 注意事项 - **硬件兼容性**:确保连接的显示器支持 HDMI 2.1 和 8K 分辨率,并使用高质量的 HDMI 线缆。 - **固件与驱动支持**:更新至最新版 Rockchip DRM 驱动和内核版本,以获得最佳兼容性和性能[^1]。 - **调试与验证**:使用 `modetest` 工具检查显示模式是否被正确识别,同时查看内核日志以排查潜在问题。 ### 内核编译与部署 完成设备树修改后,需重新编译内核及设备树镜像: ```bash make -C kernel O=../out/target/product/rk3588/obj/KERNEL_OBJ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rk3588-linux_defconfig make -C kernel O=../out/target/product/rk3588/obj/KERNEL_OBJ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs Image ``` 将生成的 `.dtb` 文件替换到目标系统的 `/boot/dtb` 目录,并更新引导配置。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值