核心内容摘要
立知多模态重排序模型部署案例:边缘AI盒子(RK3588)端侧部署实测
platform_device.c - 平台设备定义#include linux/module.h #include linux/platform_device.h #include linux/io.h #define DRIVER_NAME simple_led // LED资源寄存器地址和大小 #define PMU_GRF_BASE (0xFDC
#define PMU_GRF_GPIO0C_IOMUX_L (PMU_GRF_BASE 0x
#define PMU_GRF_GPIO0C_DS_0 (PMU_GRF_BASE 0x
#define GPIO0_BASE (0xFDD
#define GPIO0_SWPORT_DR_H (GPIO0_BASE 0x
#define GPIO0_SWPORT_DDR_H (GPIO0_BASE 0x000C) // 定义LED设备资源寄存器内存区域 static struct resource led_resources[] { [0] { .start PMU_GRF_GPIO0C_IOMUX_L, .end PMU_GRF_GPIO0C_IOMUX_L 0x3, // 4字节 .flags IORESOURCE_MEM, .name pmu_iomux, }, [1] { .start PMU_GRF_GPIO0C_DS_0, .end PMU_GRF_GPIO0C_DS_0 0x3, .flags IORESOURCE_MEM, .name pmu_ds, }, [2] { .start GPIO0_SWPORT_DR_H, .end GPIO0_SWPORT_DR_H 0x3, .flags IORESOURCE_MEM, .name gpio_dr, }, [3] { .start GPIO0_SWPORT_DDR_H, .end GPIO0_SWPORT_DDR_H 0x3, .flags IORESOURCE_MEM, .name gpio_ddr, }, }; // 平台设备私有数据可选 struct led_platform_data { const char *name; int default_state; // 0off, 1on }; static struct led_platform_data led_pdata { .name rk3568_led, .default_state 0, // 默认关闭 }; // 平台设备定义 static struct platform_device led_platform_device { .name DRIVER_NAME, .id -1, // 只有一个设备 .dev { .platform_data led_pdata, // 传递私有数据 }, .resource led_resources, .num_resources ARRAY_SIZE(led_resources), }; // 模块初始化注册平台设备 static int __init led_device_init(void) { int ret; ret platform_device_register(led_platform_device); if (ret) { printk(KERN_ERR Failed to register LED platform device\n); return ret; } printk(KERN_INFO LED platform device registered successfully\n); return 0; } // 模块退出注销平台设备 static void __exit led_device_exit(void) { platform_device_unregister(led_platform_device); printk(KERN_INFO LED platform device unregistered\n); } module_init(led_device_init); module_exit(led_device_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(Your Name); MODULE_DESCRIPTION(RK3568 LED Platform Device);
platform_driver.c - 平台驱动实现#include linux/module.h #include linux/platform_device.h #include linux/fs.h #include linux/cdev.h #include linux/device.h #include linux/uaccess.h #include linux/io.h #include linux/slab.h #define DRIVER_NAME simple_led #define LED_ON_VAL 0x00010001 #define LED_OFF_VAL 0x00010000 #define DEVICE_NAME simple_led // 设备私有结构体 struct led_private { struct cdev cdev; dev_t dev_num; struct class *class; struct device *device; void __iomem *vir_pmu_iomux; void __iomem *vir_pmu_ds; void __iomem *vir_gpio_dr; void __iomem *vir_gpio_ddr; char kbuf; struct platform_device *pdev; }; // 文件操作函数 static int led_open(struct inode *inode, struct file *filp) { struct led_private *priv container_of(inode-i_cdev, struct led_private, cdev); filp-private_data priv; printk(KERN_INFO LED device opened\n); return 0; } static ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct led_private *priv (struct led_private *)filp-private_data; int ret; if (count !
{ return -EINVAL; } ret copy_from_user(priv-kbuf, buf,
; if (ret) { return -EFAULT; } if (priv-kbuf
{ writel(LED_ON_VAL, priv-vir_gpio_dr); printk(KERN_INFO LED ON (reg: 0x%x)\n, LED_ON_VAL); } else if (priv-kbuf
{ writel(LED_OFF_VAL, priv-vir_gpio_dr); printk(KERN_INFO LED OFF (reg: 0x%x)\n, LED_OFF_VAL); } else { return -EINVAL; } return 1; } static int led_release(struct inode *inode, struct file *filp) { printk(KERN_INFO LED device released\n); return 0; } static struct file_operations led_fops { .owner THIS_MODULE, .open led_open, .write led_write, .release led_release, }; // 平台驱动的probe函数 static int led_probe(struct platform_device *pdev) { struct led_private *priv; struct resource *res; int ret; u32 val; // 分配设备私有结构体 priv devm_kzalloc(pdev-dev, sizeof(struct led_private), GFP_KERNEL); if (!priv) { return -ENOMEM; } priv-pdev pdev; platform_set_drvdata(pdev, priv); // 获取并映射寄存器资源 res platform_get_resource(pdev, IORESOURCE_MEM,
; if (!res) { dev_err(pdev-dev, Failed to get PMU IOMUX resource\n); return -ENODEV; } priv-vir_pmu_iomux devm_ioremap(pdev-dev, res-start, resource_size(res)); res platform_get_resource(pdev, IORESOURCE_MEM,
; priv-vir_pmu_ds devm_ioremap(pdev-dev, res-start, resource_size(res)); res platform_get_resource(pdev, IORESOURCE_MEM,
; priv-vir_gpio_dr devm_ioremap(pdev-dev, res-start, resource_size(res)); res platform_get_resource(pdev, IORESOURCE_MEM,
; priv-vir_gpio_ddr devm_ioremap(pdev-dev, res-start, resource_size(res)); if (!priv-vir_pmu_iomux || !priv-vir_pmu_ds || !priv-vir_gpio_dr || !priv-vir_gpio_ddr) { dev_err(pdev-dev, Failed to ioremap resources\n); return -ENOMEM; } // 初始化硬件 //
配置GPIO0_C0为GPIO功能 val 0x00070000; writel(val, priv-vir_pmu_iomux); //
配置驱动能力 val 0x003F003F; writel(val, priv-vir_pmu_ds); //
配置为输出模式 val 0x00010001; writel(val, priv-vir_gpio_ddr); //
默认关闭LED writel(LED_OFF_VAL, priv-vir_gpio_dr); // 注册字符设备 ret alloc_chrdev_region(priv-dev_num, 0, 1, DEVICE_NAME); if (ret
{ dev_err(pdev-dev, Failed to allocate device number\n); return ret; } cdev_init(priv-cdev, led_fops); priv-cdev.owner THIS_MODULE; ret cdev_add(priv-cdev, priv-dev_num,
; if (ret) { dev_err(pdev-dev, Failed to add cdev\n); goto err_cdev; } // 创建设备节点 priv-class class_create(THIS_MODULE, DEVICE_NAME); if (IS_ERR(priv-class)) { ret PTR_ERR(priv-class); goto err_class; } priv-device device_create(priv-class, NULL, priv-dev_num, NULL, DEVICE_NAME); if (IS_ERR(priv-device)) { ret PTR_ERR(priv-device); goto err_device; } dev_info(pdev-dev, LED driver probed successfully (major: %d)\n, MAJOR(priv-dev_num)); return 0; err_device: class_destroy(priv-class); err_class: cdev_del(priv-cdev); err_cdev: unregister_chrdev_region(priv-dev_num,
; return ret; } // 平台驱动的remove函数 static int led_remove(struct platform_device *pdev) { struct led_private *priv platform_get_drvdata(pdev); if (priv) { // 删除设备节点 device_destroy(priv-class, priv-dev_num); class_destroy(priv-class); // 注销字符设备 cdev_del(priv-cdev); unregister_chrdev_region(priv-dev_num,
; // 注意使用devm_ioremap的资源会自动释放无需手动iounmap dev_info(pdev-dev, LED driver removed\n); } return 0; } // 平台驱动结构体 static struct platform_driver led_platform_driver { .probe led_probe, .remove led_remove, .driver { .name DRIVER_NAME, .owner THIS_MODULE, }, }; // 模块初始化 static int __init led_driver_init(void) { int ret; ret platform_driver_register(led_platform_driver); if (ret) { printk(KERN_ERR Failed to register LED platform driver\n); return ret; } printk(KERN_INFO LED platform driver registered\n); return 0; } // 模块退出 static void __exit led_driver_exit(void) { platform_driver_unregister(led_platform_driver); printk(KERN_INFO LED platform driver unregistered\n); } module_init(led_driver_init); module_exit(led_driver_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(Your Name); MODULE_DESCRIPTION(RK3568 LED Platform Driver); MODULE_ALIAS(platform:simple_led);
test_led.c - 测试应用程序#include stdio.h #include stdlib.h #include unistd.h #include fcntl.h #include string.h int main(int argc, char *argv[]) { int fd; char buf[2]; if (argc !
{ printf(Usage: %s 0|1\n, argv[0]); printf( 0: turn LED off\n); printf( 1: turn LED on\n); return -1; } // 打开设备 fd open(/dev/simple_led, O_WRONLY); if (fd
{ perror(Failed to open device); return -1; } // 写入控制命令 buf[0] argv[1][0]; buf[1] \0; if (write(fd, buf,
1)