导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    MQ_Pro Tina GPIO驱动

    MR Series
    3
    12
    5191
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • A
      a614547915 LV 5 最后由 YuzukiTsuru 编辑

      设备树根目录添加

      led: gpioled{
      		device_type = "gpioled";
      		compatible = "gpio-led";
      		gpios = <&pio PD 18 GPIO_ACTIVE_HIGH>;
      		status	= "okay";
      	};
      
      1 条回复 最后回复 回复 引用 分享 1
      • A
        a614547915 LV 5 最后由 编辑

        linxu系统操作
        编译 Lina :

        1. 首先执行 source build/envsetup.sh 提示 Setup env done! Please run lunch next.
        2. 输入 lunch d1-h_nezha-tina
        3. make -j32
        4. 执行 pack打包
          MQ_pro操作
          1.下载至SD卡启动
          2.通过ls /proc/device-tree/ 命令查看是否有 “gpioled”节点
        1 条回复 最后回复 回复 引用 分享 0
        • A
          a614547915 LV 5 最后由 YuzukiTsuru 编辑

          gpioled.c 如下 该文件直接复制 正点原子历程

          #include <linux/types.h>
          
          #include <linux/kernel.h>
          
          #include <linux/delay.h>
          
          #include <linux/ide.h>
          
          #include <linux/init.h>
          
          #include <linux/module.h>
          
          #include <linux/errno.h>
          
          #include <linux/gpio.h>
          
          #include <linux/cdev.h>
          #include <linux/device.h>
          #include <linux/of.h>
          #include <linux/of_address.h>
          #include <linux/of_gpio.h>
          /***************************************************************
          Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
          文件名		: gpioled.c
          作者	  	: 左忠凯
          版本	   	: V1.0
          描述	   	: 采用pinctrl和gpio子系统驱动LED灯。
          其他	   	: 无
          论坛 	   	: www.openedv.com
          日志	   	: 初版V1.0 2019/7/13 左忠凯创建
          ***************************************************************/
          #define GPIOLED_CNT			1		  	/* 设备号个数 */
          #define GPIOLED_NAME		"gpioled"	/* 名字 */
          #define LEDOFF 				0			/* 关灯 */
          #define LEDON 				1			/* 开灯 */
          
          /* gpioled设备结构体 */
          struct gpioled_dev{
          	dev_t devid;			/* 设备号 	 */
          	struct cdev cdev;		/* cdev 	*/
          	struct class *class;	/* 类 		*/
          	struct device *device;	/* 设备 	 */
          	int major;				/* 主设备号	  */
          	int minor;				/* 次设备号   */
          	struct device_node	*nd; /* 设备节点 */
          	int led_gpio;			/* led所使用的GPIO编号		*/
          };
          struct gpioled_dev gpioled;	/* led设备 */
          /*
           * @description		: 打开设备
           * @param - inode 	: 传递给驱动的inode
           * @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量
           * 					  一般在open的时候将private_data指向设备结构体。
           * @return 			: 0 成功;其他 失败
           */
          static int led_open(struct inode *inode, struct file *filp)
          {
          	filp->private_data = &gpioled; /* 设置私有数据 */
          	return 0;
          }
          /*
           * @description		: 从设备读取数据 
           * @param - filp 	: 要打开的设备文件(文件描述符)
           * @param - buf 	: 返回给用户空间的数据缓冲区
           * @param - cnt 	: 要读取的数据长度
           * @param - offt 	: 相对于文件首地址的偏移
           * @return 			: 读取的字节数,如果为负值,表示读取失败
           */
          static ssize_t led_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
          {
          	return 0;
          }
          /*
           * @description		: 向设备写数据 
           * @param - filp 	: 设备文件,表示打开的文件描述符
           * @param - buf 	: 要写给设备写入的数据
           * @param - cnt 	: 要写入的数据长度
           * @param - offt 	: 相对于文件首地址的偏移
           * @return 			: 写入的字节数,如果为负值,表示写入失败
           */
          static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
          {
          	int retvalue;
          	unsigned char databuf[1];
          	unsigned char ledstat;
          	struct gpioled_dev *dev = filp->private_data;
          	retvalue = copy_from_user(databuf, buf, cnt);
          	if(retvalue < 0) {
          		printk("kernel write failed!\r\n");
          		return -EFAULT;
          	}
          	ledstat = databuf[0];		/* 获取状态值 */
          	if(ledstat == LEDON) {	
          		gpio_set_value(dev->led_gpio, 0);	/* 打开LED灯 */
          	} else if(ledstat == LEDOFF) {
          
          		gpio_set_value(dev->led_gpio, 1);	/* 关闭LED灯 */
          	}
          	return 0; 
          }
          /*
           * @description		: 关闭/释放设备
           * @param - filp 	: 要关闭的设备文件(文件描述符)
           * @return 			: 0 成功;其他 失败
           */
          static int led_release(struct inode *inode, struct file *filp)
          {
          	return 0;
          }
          /* 设备操作函数 */
          static struct file_operations gpioled_fops = {
          	.owner = THIS_MODULE,
          	.open = led_open,
          	.read = led_read,
          	.write = led_write,
          	.release = 	led_release,
          };
          /*
           * @description	: 驱动出口函数
           * @param 		: 无
           * @return 		: 无
           */
          static int __init led_init(void)
          {
          	int ret = 0;
          	ret = ret;
          	/* 设置LED所使用的GPIO */
          	/* 1、获取设备节点:gpioled */
          	gpioled.nd = of_find_node_by_path("/gpioled");
          	if(gpioled.nd == NULL) {
          		printk("gpioled node not find!\r\n");
          		return -EINVAL;
          	} else {
          		printk("gpioled node find!\r\n");
          	} 
          	/* 2、 获取设备树中的gpio属性,得到LED所使用的LED编号 */
          	gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "gpios", 0);
          	if(gpioled.led_gpio < 0) {
          		printk("can't get led-gpio");
          		return -EINVAL;
          	}
          	printk("led-gpio num = %d\r\n", gpioled.led_gpio);
          	/* 3、设置GPIO1_IO03为输出,并且输出高电平,默认关闭LED灯 */
          	ret = gpio_direction_output(gpioled.led_gpio, 0);
          	if(ret < 0) {
          		printk("can't set gpio!\r\n");
          	} 
          	/* 注册字符设备驱动 */
          	/* 1、创建设备号 */
          	if (gpioled.major) {		/*  定义了设备号 */
          		gpioled.devid = MKDEV(gpioled.major, 0);
          		register_chrdev_region(gpioled.devid, GPIOLED_CNT, GPIOLED_NAME);
          	} else {						/* 没有定义设备号 */
          		alloc_chrdev_region(&gpioled.devid, 0, GPIOLED_CNT, GPIOLED_NAME);	/* 申请设备号 */
          		gpioled.major = MAJOR(gpioled.devid);	/* 获取分配号的主设备号 */
          		gpioled.minor = MINOR(gpioled.devid);	/* 获取分配号的次设备号 */
          	}
          	printk("gpioled major=%d,minor=%d\r\n",gpioled.major, gpioled.minor);	
          	/* 2、初始化cdev */
          	gpioled.cdev.owner = THIS_MODULE;
          	cdev_init(&gpioled.cdev, &gpioled_fops);
          	/* 3、添加一个cdev */
          	cdev_add(&gpioled.cdev, gpioled.devid, GPIOLED_CNT);
          	/* 4、创建类 */
          	gpioled.class = class_create(THIS_MODULE, GPIOLED_NAME);
          	if (IS_ERR(gpioled.class)) {
          		return PTR_ERR(gpioled.class);
          	}
          	/* 5、创建设备 */
          	gpioled.device = device_create(gpioled.class, NULL, gpioled.devid, NULL, GPIOLED_NAME);
          	if (IS_ERR(gpioled.device)) {
          		return PTR_ERR(gpioled.device);
          	}
          	return 0;
          }
          
          static void __exit led_exit(void)
          {
          	/* 注销字符设备驱动 */
          	cdev_del(&gpioled.cdev);/*  删除cdev */
          	unregister_chrdev_region(gpioled.devid, GPIOLED_CNT); /* 注销设备号 */
          	device_destroy(gpioled.class, gpioled.devid);
          	class_destroy(gpioled.class);
          }
          module_init(led_init);
          module_exit(led_exit);
          MODULE_LICENSE("GPL");
          MODULE_AUTHOR("zuozhongkai");
          
          1 条回复 最后回复 回复 引用 分享 0
          • A
            a614547915 LV 5 最后由 YuzukiTsuru 编辑

            Makefile 文件编写 如下:

            KERNELDIR := /home/tina-d1-h/lichee/linux-5.4/
            CURRENT_PATH := $(shell pwd)
            
            CFLAGS= ARCH=riscv CROSS_COMPILE=/home/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-
            obj-m := gpioled.o
            
            build: kernel_modules
            
            kernel_modules:
            	$(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(CURRENT_PATH) modules 
            clean:
            	$(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(CURRENT_PATH) cleanmake
            

            KERNELDIR CFLAGS 路径需要根据自己的路径设置

            1 条回复 最后回复 回复 引用 分享 0
            • A
              a614547915 LV 5 最后由 YuzukiTsuru 编辑

              ledAPP.c 正点原子原封不动的历程

              #include "stdio.h"
              #include "unistd.h"
              #include "sys/types.h"
              #include "sys/stat.h"
              #include "fcntl.h"
              #include "stdlib.h"
              #include "string.h"
              
              /***************************************************************
              Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
              文件名		: ledApp.c
              作者	  	: 左忠凯
              版本	   	: V1.0
              描述	   	: chrdevbase驱测试APP。
              其他	   	: 无
              使用方法	 :./ledtest /dev/led  0 关闭LED
              		     ./ledtest /dev/led  1 打开LED		
              论坛 	   	: www.openedv.com
              日志	   	: 初版V1.0 2019/1/30 左忠凯创建
              ***************************************************************/
              
              #define LEDOFF 	0
              #define LEDON 	1
              /*
               * @description		: main主程序
               * @param - argc 	: argv数组元素个数
               * @param - argv 	: 具体参数
               * @return 			: 0 成功;其他 失败
               */
              
              int main(int argc, char *argv[])
              {
              	int fd, retvalue;
              	char *filename;
              	unsigned char databuf[1];
              	if(argc != 3){
              		printf("Error Usage!\r\n");
              		return -1;
              	}
              	filename = argv[1];
              	/* 打开led驱动 */
              	fd = open(filename, O_RDWR);
              	if(fd < 0){
              		printf("file %s open failed!\r\n", argv[1]);
              		return -1;
              	}
              	databuf[0] = atoi(argv[2]);	/* 要执行的操作:打开或关闭 */
              	/* 向/dev/led文件写入数据 */
              	retvalue = write(fd, databuf, sizeof(databuf));
              	if(retvalue < 0){
              		printf("LED Control Failed!\r\n");
              		close(fd);
              		return -1;
              	}
              	retvalue = close(fd); /* 关闭文件 */
              	if(retvalue < 0){
              		printf("file %s close failed!\r\n", argv[1]);
              		return -1;
              	}
              	return 0;
              }
              
              1 条回复 最后回复 回复 引用 分享 0
              • A
                a614547915 LV 5 最后由 编辑

                linux系统操作:
                1.通过make 编译出gpioled.ko文件
                2.通过 /home/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-
                thead_20200702/bin/riscv64-unknown-linux-gnu-gcc -o ledapp ledApp.c 编译出ledgpio 软件
                MQpro:
                1.通过insmod gpioled.ko加载gpioled驱动,通过ls /dev 查看是否有gpioled
                2.通过 chmod 777 ledapp 添加权限
                3.通过 ./ledapp /dev/gpioled 0 点亮LED
                4.通过 ./ledapp /dev/gpioled 1 熄灭LED
                注:以上命令没有跟LED高低电平相对应可以通过修改 gpioled.c led_write函数进行修改就好了

                J 2 条回复 最后回复 回复 引用 分享 3
                • J
                  Justyu666 LV 5 @a614547915 最后由 编辑

                  @a614547915
                  哈喽,MQpro 的操作可以截图看下详细步骤吗?

                  1 条回复 最后回复 回复 引用 分享 0
                  • J
                    Justyu666 LV 5 @a614547915 最后由 编辑

                    @a614547915 在 MQ_Pro Tina GPIO驱动 中说:

                    linux系统操作:
                    1.通过make 编译出gpioled.ko文件
                    2.通过 /home/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-
                    thead_20200702/bin/riscv64-unknown-linux-gnu-gcc -o ledapp ledApp.c 编译出ledgpio 软件
                    MQpro:
                    1.通过insmod gpioled.ko加载gpioled驱动,通过ls /dev 查看是否有gpioled
                    2.通过 chmod 777 ledapp 添加权限
                    3.通过 ./ledapp /dev/gpioled 0 点亮LED
                    4.通过 ./ledapp /dev/gpioled 1 熄灭LED
                    注:以上命令没有跟LED高低电平相对应可以通过修改 gpioled.c led_write函数进行修改就好了

                    哈喽,请教一下,我按此步骤操作,打包下载到板子上的操作未能通过,是没把 gpioled.ko 等与 led 相关的文件打包进去吗?
                    有具体详细步骤吗?

                    A 1 条回复 最后回复 回复 引用 分享 0
                    • A
                      y_uu LV 5 @Justyu666 最后由 编辑

                      @justyu666
                      先编译得到gpioled.ko
                      用adb push到板子tmp目录:adb push gpioled.ko /tmp
                      串口控制台操作:
                      cd /tmp
                      insmod gpioled.ko
                      看打印是否能安装成功或到/dev下看有没有gpioled设备。成功后再单独编译ledapp,同样方法将ledapp push到/tmp目录,然后

                      2.通过 chmod 777 ledapp 添加权限
                      3.通过 ./ledapp /dev/gpioled 0 点亮LED
                      4.通过 ./ledapp /dev/gpioled 1 熄灭LED

                      J 3 条回复 最后回复 回复 引用 分享 0
                      • J
                        Justyu666 LV 5 @afu120 最后由 编辑

                        @afu120 好的谢谢,再请教一下,不能在ubuntu里面执行pack的时候直接打包后烧录到板子里面吗?

                        1 条回复 最后回复 回复 引用 分享 0
                        • J
                          Justyu666 LV 5 @afu120 最后由 编辑

                          @afu120 执行不了 ledapp 呢?

                          1 条回复 最后回复 回复 引用 分享 0
                          • J
                            Justyu666 LV 5 @afu120 最后由 编辑

                            @afu120
                            我按照您的步骤操作,还是无法执行 ledapp
                            67b93c11-41d5-4dd4-b5b3-7f8ec9309712-e170be7561b7df33b5103aaca3ff8ec.png
                            会是什么问题呢?

                            1 条回复 最后回复 回复 引用 分享 0
                            • Referenced by  D dazb3 
                            • 1 / 1
                            • First post
                              Last post

                            Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

                            行为准则 | 用户协议 | 隐私权政策