Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页
    1. Home
    2. allwinner_account
    • Profile
    • Following 0
    • Followers 1
    • my integral 977
    • Topics 4
    • Posts 25
    • Best 2
    • Groups 0

    allwinner_accountLV 4

    @allwinner_account

    977
    integral
    4
    Reputation
    7
    Profile views
    25
    Posts
    1
    Followers
    0
    Following
    Joined Last Online

    allwinner_account Unfollow Follow

    Best posts made by allwinner_account

    • 【萌新入门】D1-H编译运行第一个闪灯驱动

      纯小白, 头铁直接上的荔枝派的板子, 确实是入门比较困难, 结合着b站的一些教程和社区的资料, 倒腾很久终于写出了能用的闪灯驱动
      这里记录和分享下, 欢迎交流指点[社区都是大佬萌新瑟瑟发抖🤣 ]

      驱动程序如下

      #include <linux/init.h>
      #include <linux/module.h>
      #include <linux/fs.h>     //file_operations register_chrdev_region
      #include <linux/kdev_t.h> //MKDEV
      #include <linux/cdev.h>   //cdev_init
      #include <linux/uaccess.h>//copy_from_user
      #include <linux/hrtimer.h>//硬件定时器
      #include <linux/gpio.h>   //gpio
      
      #define DEV_LEDFLASH_TYPE 'k'
      #define DEV_LEDFLASH_GETVALUE  _IOR(DEV_LEDFLASH_TYPE, 0x32, int)
      #define DEV_LEDFLASH_SETVALUE  _IOW(DEV_LEDFLASH_TYPE, 0x33, int)
      
      #define LED_PIN_NUMBER  65  //PC1=32*2+1
      #define LED_FLASH_INTERVAL  500  //1hz
      
      static int major= 222;//主设备号
      static int minor = 0; //子设备号
      static dev_t devno;   //设备号
      struct class *cls;    //设备类
      struct device *class_dev = NULL;  //设备节点
      static struct hrtimer flashTimer; //定时器
      static int interval = LED_FLASH_INTERVAL;  //定时器中断间隔(ms)
      
      /**
       * @description: 定时器回调函数,这里用来闪灯
       * @param {hrtimer} *timer
       * @return {*}
       */
      static enum hrtimer_restart flashTimer_handler(struct hrtimer *timer){
        static int num= 0;
        if(interval!=0){
          __gpio_set_value(LED_PIN_NUMBER, num++%2);
          // 设置下一次中断间隔
          hrtimer_forward_now(&flashTimer, ms_to_ktime(interval));
          return HRTIMER_RESTART;
        }else{
          // 关闭led
          __gpio_set_value(LED_PIN_NUMBER, 0);
          // 关闭定时器
          return HRTIMER_NORESTART;
        }
      }
      
      /**
       * @description: 打开设备文件, 启用LED口和定时器
       * @param {inode} *inode
       * @param {file} *filep
       * @return {*}
       */
      static int ledflash_open(struct inode *inode, struct file *filep){
        int result;
      
      	printk("[DRV] ledflash_open()\n");
        
        /* GPIO初始化 */
        printk("[DRV] _____gpio_init____\n");
        // 获取LED_GPIO访问权
        result= gpio_request(LED_PIN_NUMBER, NULL);
        if(result< 0){
          printk(KERN_ERR "[DRV] gpio_request() failed:%d\n", result);
          gpio_free(LED_PIN_NUMBER);
          return -1;
        }
        // TODO:使用pinctrl还可以配置上下拉,没找到例子还没有测试
        // 设置为输出模式
        result= gpio_direction_output(LED_PIN_NUMBER, 1);
        if(result< 0){
          printk(KERN_ERR "[DRV] gpio_direction_output() failed:%d\n", result);
      		gpio_free(LED_PIN_NUMBER);
          return -1;
        }
      
        /* 定时器初始化 */
        printk("[DRV] _____hrtimer_init____\n");
        // 配置定时器为基于开机时间时钟的相对模式 //模式定义见time.h 和hrtimer.h
        hrtimer_init(&flashTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        // 设置回调函数
        flashTimer.function = &flashTimer_handler;
        // 开启定时器
        hrtimer_start(&flashTimer, ms_to_ktime(LED_FLASH_INTERVAL), HRTIMER_MODE_REL);
      
      	return 0; 
      }
      /**
       * @description: 关闭设备文件, 释放LED口和定时器
       * @param {inode} *inode
       * @param {file} *filep
       * @return {*}
       */
      static int ledflash_release(struct inode *inode, struct file *filep){
        // 取消定时器
        hrtimer_cancel(&flashTimer);
        // 关闭led
        __gpio_set_value(LED_PIN_NUMBER, 0);
        // 释放gpio控制权
      	gpio_free(LED_PIN_NUMBER);
      
        printk("[DRV] ledflash_release()\n");
      	return 0; 
      }
      /**
       * @description: 设备操作函数接口
       * @param {file} *filep
       * @param {unsigned int} cmd
       * @param {unsigned long} arg
       * @return {*}
       */
      long ledflash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg){
      	long ret;
      	void __user *argp= (void __user *)arg;
      	int __user *p= argp; //参数
        int set_val= LED_FLASH_INTERVAL;
      
        // 检测参数合法
      	if(_IOC_TYPE(cmd)!= DEV_LEDFLASH_TYPE){
      		pr_err("[DRV] cmd %u,bad magic 0x%x/0x%x.\n",cmd,_IOC_TYPE(cmd), DEV_LEDFLASH_TYPE);
      		return -ENOTTY;
      	}
      	if(_IOC_DIR(cmd)& _IOC_READ)
      		ret= !access_ok((void __user*)arg, _IOC_SIZE(cmd));
      	else if(_IOC_DIR(cmd)& _IOC_WRITE)
      		ret= !access_ok((void __user*)arg, _IOC_SIZE(cmd));
      	if(ret){
      		pr_err("[DRV] bad access %ld.\n",ret);
      		return -EFAULT;
      	}
      
        // 根据不同操作函数指令指令
      	switch(cmd){
      		case DEV_LEDFLASH_GETVALUE:
      			ret = put_user(interval, p);
      			printk("[DRV] DEV_LEDFLASH_GETVALUE %d\n",interval);
      			break;
      		case DEV_LEDFLASH_SETVALUE:
      			ret = get_user(set_val, p);
            // 设置为0将关闭定时器
            if(interval== 0 && set_val> 0)
              hrtimer_restart(&flashTimer);
            interval= set_val;
            printk("[DRV] DEV_LEDFLASH_SETVALUE %d\n",interval);
      			break;
      		default:
      			return -EINVAL;
      	}
      	return ret;
      }
      
      /**
       * @description: 文件操作接口绑定
       */
      static struct file_operations ledflash_ops = {
      	.open = ledflash_open,
        .release= ledflash_release,
        // .read= ledflash_read,
        // .write= ledflash_write, 
        .unlocked_ioctl= ledflash_ioctl,
      };
      /**
       * @description: 初始化程序
       */
      static int ledflash_init(void){
      	int result;
      	printk("[DRV] _____ledflashdrv_init____\n");
      
        /* 设备初始化 */
        // 注册cdev设备号, 绑定标准文件接口
        // 查看验证cat /proc/devices | grep ledflash
        result = register_chrdev(major, "ledflashCd", &ledflash_ops);
      	if(result <0){
      		printk(KERN_ERR "[DRV] register_chrdev fail\n");
      		goto out_err_0;
      	}
        // 拼接主次设备号
        devno = MKDEV(major, minor);
        // 创建设备类 
        // 查看验证 ls /sys/class/ | grep ledflash
        cls = class_create(THIS_MODULE, "ledflashCls");
      	if (IS_ERR(cls)) {
      		printk(KERN_ERR "[DRV] class_create() failed for cls\n");
      		result = PTR_ERR(cls);
      		goto out_err_1;
      	}
        // 创建设备节点,绑定设备类和设备号
        // 查看验证 ls /dev | grep ledflash
        class_dev = device_create(cls, NULL, devno, NULL, "ledflashDev");
      	if (IS_ERR(class_dev)) {
          printk(KERN_ERR "[DRV] device_create() failed for class_dev\n");
      		result = PTR_ERR(class_dev);
      		goto out_err_2;
      	}
        printk("[DRV] _____ledflashdrv_init_successed____\n");
        
      	return 0;
      out_err_2:
      	class_destroy(cls);
      out_err_1:
      	unregister_chrdev(major,"ledflash");
      out_err_0:  
      	return 	result;
      }
      /**
       * @description: 卸载驱动,依次释放资源
       */
      static void ledflash_exit(void){
        device_destroy(cls, devno);
        class_destroy(cls);
        unregister_chrdev(major, "ledflashCd");
      
        printk("[DRV] _____ledflash_exit_____\n");
      	return;
      }
      
      // 安装驱动时可以设定主设备号
      // 设定参数 insmod led_flash.ko major=333
      module_param(major,  int,  0644);
      // 绑定驱动安装和卸载程序
      module_init(ledflash_init);  //insmod
      module_exit(ledflash_exit);  //rmmod
      // 驱动信息
      // 测试modinfo找不到驱动, depmod找不到指令
      // 需要手动将ko模块放到/lib/modules/5.4.61目录下
      MODULE_LICENSE("GPL");
      MODULE_AUTHOR("G");
      

      makefile如下, 完整编译内核用时太久了, 手动设置三个参数后即可单独编译上传, 调试方便很多

      # 完整内核编译会定义KERNELRELEASE
      ifneq ($(KERNELRELEASE),)
      obj-m := led_flash.o
      
      else
      # 打印一下进到这边直接编译了
      $(warning ____alone_compile____)
      # 配置为riscv架构
      export ARCH=riscv
      # 配置编译器
      export CROSS_COMPILE=/home/ubt/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-
      # 配置内核源码位置
      KDIR = /home/ubt/tina-d1-h/out/d1-h-nezha/compile_dir/target/linux-d1-h-nezha/linux-5.4.61
      # 指定驱动程序源码位置(当前目录)
      PWD = $(shell pwd)
      # 将led_flash.o 编译成led_flash.ko, 而led_flash.o 则由make的自动推导功能编译led_flash.c 文件生成
      obj-m += led_flash.o
      all:
      	make -C $(KDIR) M=$(PWD) modules 
      clean:
      	make -C $(KDIR) M=$(PWD) clean
      
      endif
      

      Kconfig

      config LED_FLASH
        tristate "led_flash driver, gpio out put pulse by timer"
        help
          led_flash help msg.
      

      以上文件放在驱动目录下单独一个文件夹内,注意驱动目录的makefile和Kconfig需要添加该文件夹索引信息
      然后make kernel_menuconfig进入驱动项即可配置
      我尝试了直接上传ko文件安装报错, 还是直接mp更新了板子, 之后就可以直接上传更新驱动模块了
      驱动编写参考教程
      编写一个内核驱动,点亮 LED

      测试的应用程序

      #include <stdio.h>  // printf
      #include <unistd.h> // open file
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      #include <sys/ioctl.h>
      
      #define DEV_LEDFLASH_TYPE 'k'
      #define DEV_LEDFLASH_GETVALUE  _IOR(DEV_LEDFLASH_TYPE, 0x32, int)
      #define DEV_LEDFLASH_SETVALUE  _IOW(DEV_LEDFLASH_TYPE, 0x33, int)
      
      int fd;
      int interval= 500;
      
      int main(void)
      {
        // printf("Hell! O’ world, why won’t my code compile?\n\n");
        printf("[USER] led_flash_begin\n");
      
        fd= open("/dev/ledflashDev", O_RDWR);
        if(fd< 0){
      		perror("[USER] open failed\n");
      		return -1;
      	}
      
        // 读取默认值
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
        }
        printf("[USER] default interval= %d\n", interval);
        sleep(2);
      
        // 关闭
        interval = 0;
      	if(ioctl(fd, DEV_LEDFLASH_SETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_SETVALUE failed\n");
      		return -1;
        }
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
      		perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
      	}
      	printf("[USER] set interval= %d\n", interval);
        sleep(2);
      
        // 设置为2hz
      	interval = 250;
      	if(ioctl(fd, DEV_LEDFLASH_SETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_SETVALUE failed\n");
      		return -1;
        }
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
      		perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
      	}
      	printf("[USER] set interval= %d\n", interval);
        sleep(2);
      
        // 设置为5hz
        interval = 100;
      	if(ioctl(fd, DEV_LEDFLASH_SETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_SETVALUE failed\n");
      		return -1;
        }
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
      		perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
      	}
      	printf("[USER] set interval= %d\n", interval);
        sleep(2);
      
        close(fd);
        printf("[USER] steper_end\n");
      	
      	return 0;
      }
      

      makefile

      #设置编译链路径及工具
      CTOOL := riscv64-unknown-linux-gnu-
      CCL := /home/ubt/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
      CC := ${CCL}/bin/${CTOOL}gcc
      
      # build led_flash executable when user executes “make”
      led_flash: led_flash.o
      	$(CC) $(LDFLAGS) led_flash.o -o led_flash
      
      led_flash.o: led_flash.c
      	$(CC) $(CFLAGS) -c led_flash.c
      
      # remove object files and executable when user executes “make clean”
      clean:
      	rm *.o led_flash
      

      全部编译好后使用adb上传,安装运行效果如下

      root@TinaLinux:/mnt/exUDISK/app# insmod ../mod/led_flash.ko
      [ 2654.707249] led_flash: loading out-of-tree module taints kernel.
      [ 2654.714946] [DRV] _____ledflashdrv_init____
      [ 2654.720524] [DRV] _____ledflashdrv_init_successed____
      root@TinaLinux:/mnt/exUDISK/app# ./led_flash
      [USER] led_flash_begin[ 2664.649231] [DRV] ledflash_open()
      
      [ 2664.654850] [DRV] _____gpio_init____
      [ 2664.659067] [DRV] _____hrtimer_init____
      [ 2664.663458] [DRV] DEV_LEDFLASH_GETVALUE 500
      [USER] default interval= 500
      [ 2666.668404] [DRV] DEV_LEDFLASH_SETVALUE 0
      [ 2666.672975] [DRV] DEV_LEDFLASH_GETVALUE 0
      [USER] set interval= 0
      [ 2668.677738] [DRV] DEV_LEDFLASH_SETVALUE 250
      [ 2668.682480] [DRV] DEV_LEDFLASH_GETVALUE 250
      [USER] set interval= 250
      [ 2670.687414] [DRV] DEV_LEDFLASH_SETVALUE 100
      [ 2670.692243] [DRV] DEV_LEDFLASH_GETVALUE 100
      [USER] set interval= 100
      [ 2672.697095] [DRV] ledflash_release()
      [USER] steper_end
      

      闪灯测试完毕,后面就可以开始正式的深入研究了🤠

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: SD卡启动,如何挂载剩余容量为overlayfs

      试了下不配置downloadfile也是可行的,初始化时可以根据大小自动格式化系统

      formating /dev/by-name/UDISK to ext4
      mke2fs 1.46.4 (18-Aug-2021)
      [    4.827559] random: mkfs.ext4: uninitialized urandom read (16 bytes read)
      [    4.835361] random: mkfs.ext4: uninitialized urandom read (16 bytes read)
      Creating filesystem with 3516935 4k blocks and 879552 inodes
      Filesystem UUID: 84f444b8-02d2-4035-b7b1-ec4f15a8f417
      Superblock backups stored on blocks:
              32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
      
      Allocating group tables: done
      Writing inode tables: done
      Creating journal (16384 blocks): [    6.281300]
      [    6.281300] insmod_device_driver
      [    6.281300]
      [    6.288462] sunxi_usb_udc 4100000.udc-controller: 4100000.udc-controller supply udc not found, using dummy regulator
      [    6.321295] hdmi_hpd_sys_config_release
      done
      Writing superblocks and filesystem accounting information: done
      
      formating /dev/by-name/rootfs_data to ext4
      mke2fs 1.46.4 (18-Aug-2021)
      [   17.598480] random: mkfs.ext4: uninitialized urandom read (16 bytes read)
      [   17.606271] random: mkfs.ext4: uninitialized urandom read (16 bytes read)
      Creating filesystem with 262144 4k blocks and 65536 inodes
      Filesystem UUID: 56bbb4d6-0db1-47ec-a35c-f66492e4fdad
      Superblock backups stored on blocks:
              32768, 98304, 163840, 229376
      
      Allocating group tables: done
      Writing inode tables: done
      Creating journal (8192 blocks): done
      Writing superblocks and filesystem accounting information: done
      

      就是大小还不太对,我再研究下🤤
      总之还是感谢大佬帮助🤠

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account

    Latest posts made by allwinner_account

    • Reply: D1H支持MIPI触摸屏吗

      @whycan 就当商家骗人的话想要使用触摸屏是需要MIPI+I2C这样的配置是嘛, 然后还需要HDMI输出另一个屏的信息, 触摸屏这一块的驱动都需要根据具体硬件自己写吧, 感觉还是挺麻烦的

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: D1H支持MIPI触摸屏吗

      @whycanservice 我淘宝看到一个只用MIPI的触摸屏, 我看手册里也写MIPI的接口支持双向通讯, 之前没用过这种接口的所以不太明白😵

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • D1H支持MIPI触摸屏吗

      小白求教,想采用HDMI输出图像+MIPI做交互屏的解决方案,论坛里似乎没看到有用触摸屏的例子. 淘宝有找到MIPI接口的触摸屏想问问能用不? 有没有什么例程可以参考下呀.🤠
      有翻到这个帖子D1的双屏异显第一弹来啦!,但是似乎只有镜像文件,视频中也看不出来是否有使用触摸屏.

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • 【萌新入门】D1-H编译运行第一个闪灯驱动

      纯小白, 头铁直接上的荔枝派的板子, 确实是入门比较困难, 结合着b站的一些教程和社区的资料, 倒腾很久终于写出了能用的闪灯驱动
      这里记录和分享下, 欢迎交流指点[社区都是大佬萌新瑟瑟发抖🤣 ]

      驱动程序如下

      #include <linux/init.h>
      #include <linux/module.h>
      #include <linux/fs.h>     //file_operations register_chrdev_region
      #include <linux/kdev_t.h> //MKDEV
      #include <linux/cdev.h>   //cdev_init
      #include <linux/uaccess.h>//copy_from_user
      #include <linux/hrtimer.h>//硬件定时器
      #include <linux/gpio.h>   //gpio
      
      #define DEV_LEDFLASH_TYPE 'k'
      #define DEV_LEDFLASH_GETVALUE  _IOR(DEV_LEDFLASH_TYPE, 0x32, int)
      #define DEV_LEDFLASH_SETVALUE  _IOW(DEV_LEDFLASH_TYPE, 0x33, int)
      
      #define LED_PIN_NUMBER  65  //PC1=32*2+1
      #define LED_FLASH_INTERVAL  500  //1hz
      
      static int major= 222;//主设备号
      static int minor = 0; //子设备号
      static dev_t devno;   //设备号
      struct class *cls;    //设备类
      struct device *class_dev = NULL;  //设备节点
      static struct hrtimer flashTimer; //定时器
      static int interval = LED_FLASH_INTERVAL;  //定时器中断间隔(ms)
      
      /**
       * @description: 定时器回调函数,这里用来闪灯
       * @param {hrtimer} *timer
       * @return {*}
       */
      static enum hrtimer_restart flashTimer_handler(struct hrtimer *timer){
        static int num= 0;
        if(interval!=0){
          __gpio_set_value(LED_PIN_NUMBER, num++%2);
          // 设置下一次中断间隔
          hrtimer_forward_now(&flashTimer, ms_to_ktime(interval));
          return HRTIMER_RESTART;
        }else{
          // 关闭led
          __gpio_set_value(LED_PIN_NUMBER, 0);
          // 关闭定时器
          return HRTIMER_NORESTART;
        }
      }
      
      /**
       * @description: 打开设备文件, 启用LED口和定时器
       * @param {inode} *inode
       * @param {file} *filep
       * @return {*}
       */
      static int ledflash_open(struct inode *inode, struct file *filep){
        int result;
      
      	printk("[DRV] ledflash_open()\n");
        
        /* GPIO初始化 */
        printk("[DRV] _____gpio_init____\n");
        // 获取LED_GPIO访问权
        result= gpio_request(LED_PIN_NUMBER, NULL);
        if(result< 0){
          printk(KERN_ERR "[DRV] gpio_request() failed:%d\n", result);
          gpio_free(LED_PIN_NUMBER);
          return -1;
        }
        // TODO:使用pinctrl还可以配置上下拉,没找到例子还没有测试
        // 设置为输出模式
        result= gpio_direction_output(LED_PIN_NUMBER, 1);
        if(result< 0){
          printk(KERN_ERR "[DRV] gpio_direction_output() failed:%d\n", result);
      		gpio_free(LED_PIN_NUMBER);
          return -1;
        }
      
        /* 定时器初始化 */
        printk("[DRV] _____hrtimer_init____\n");
        // 配置定时器为基于开机时间时钟的相对模式 //模式定义见time.h 和hrtimer.h
        hrtimer_init(&flashTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        // 设置回调函数
        flashTimer.function = &flashTimer_handler;
        // 开启定时器
        hrtimer_start(&flashTimer, ms_to_ktime(LED_FLASH_INTERVAL), HRTIMER_MODE_REL);
      
      	return 0; 
      }
      /**
       * @description: 关闭设备文件, 释放LED口和定时器
       * @param {inode} *inode
       * @param {file} *filep
       * @return {*}
       */
      static int ledflash_release(struct inode *inode, struct file *filep){
        // 取消定时器
        hrtimer_cancel(&flashTimer);
        // 关闭led
        __gpio_set_value(LED_PIN_NUMBER, 0);
        // 释放gpio控制权
      	gpio_free(LED_PIN_NUMBER);
      
        printk("[DRV] ledflash_release()\n");
      	return 0; 
      }
      /**
       * @description: 设备操作函数接口
       * @param {file} *filep
       * @param {unsigned int} cmd
       * @param {unsigned long} arg
       * @return {*}
       */
      long ledflash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg){
      	long ret;
      	void __user *argp= (void __user *)arg;
      	int __user *p= argp; //参数
        int set_val= LED_FLASH_INTERVAL;
      
        // 检测参数合法
      	if(_IOC_TYPE(cmd)!= DEV_LEDFLASH_TYPE){
      		pr_err("[DRV] cmd %u,bad magic 0x%x/0x%x.\n",cmd,_IOC_TYPE(cmd), DEV_LEDFLASH_TYPE);
      		return -ENOTTY;
      	}
      	if(_IOC_DIR(cmd)& _IOC_READ)
      		ret= !access_ok((void __user*)arg, _IOC_SIZE(cmd));
      	else if(_IOC_DIR(cmd)& _IOC_WRITE)
      		ret= !access_ok((void __user*)arg, _IOC_SIZE(cmd));
      	if(ret){
      		pr_err("[DRV] bad access %ld.\n",ret);
      		return -EFAULT;
      	}
      
        // 根据不同操作函数指令指令
      	switch(cmd){
      		case DEV_LEDFLASH_GETVALUE:
      			ret = put_user(interval, p);
      			printk("[DRV] DEV_LEDFLASH_GETVALUE %d\n",interval);
      			break;
      		case DEV_LEDFLASH_SETVALUE:
      			ret = get_user(set_val, p);
            // 设置为0将关闭定时器
            if(interval== 0 && set_val> 0)
              hrtimer_restart(&flashTimer);
            interval= set_val;
            printk("[DRV] DEV_LEDFLASH_SETVALUE %d\n",interval);
      			break;
      		default:
      			return -EINVAL;
      	}
      	return ret;
      }
      
      /**
       * @description: 文件操作接口绑定
       */
      static struct file_operations ledflash_ops = {
      	.open = ledflash_open,
        .release= ledflash_release,
        // .read= ledflash_read,
        // .write= ledflash_write, 
        .unlocked_ioctl= ledflash_ioctl,
      };
      /**
       * @description: 初始化程序
       */
      static int ledflash_init(void){
      	int result;
      	printk("[DRV] _____ledflashdrv_init____\n");
      
        /* 设备初始化 */
        // 注册cdev设备号, 绑定标准文件接口
        // 查看验证cat /proc/devices | grep ledflash
        result = register_chrdev(major, "ledflashCd", &ledflash_ops);
      	if(result <0){
      		printk(KERN_ERR "[DRV] register_chrdev fail\n");
      		goto out_err_0;
      	}
        // 拼接主次设备号
        devno = MKDEV(major, minor);
        // 创建设备类 
        // 查看验证 ls /sys/class/ | grep ledflash
        cls = class_create(THIS_MODULE, "ledflashCls");
      	if (IS_ERR(cls)) {
      		printk(KERN_ERR "[DRV] class_create() failed for cls\n");
      		result = PTR_ERR(cls);
      		goto out_err_1;
      	}
        // 创建设备节点,绑定设备类和设备号
        // 查看验证 ls /dev | grep ledflash
        class_dev = device_create(cls, NULL, devno, NULL, "ledflashDev");
      	if (IS_ERR(class_dev)) {
          printk(KERN_ERR "[DRV] device_create() failed for class_dev\n");
      		result = PTR_ERR(class_dev);
      		goto out_err_2;
      	}
        printk("[DRV] _____ledflashdrv_init_successed____\n");
        
      	return 0;
      out_err_2:
      	class_destroy(cls);
      out_err_1:
      	unregister_chrdev(major,"ledflash");
      out_err_0:  
      	return 	result;
      }
      /**
       * @description: 卸载驱动,依次释放资源
       */
      static void ledflash_exit(void){
        device_destroy(cls, devno);
        class_destroy(cls);
        unregister_chrdev(major, "ledflashCd");
      
        printk("[DRV] _____ledflash_exit_____\n");
      	return;
      }
      
      // 安装驱动时可以设定主设备号
      // 设定参数 insmod led_flash.ko major=333
      module_param(major,  int,  0644);
      // 绑定驱动安装和卸载程序
      module_init(ledflash_init);  //insmod
      module_exit(ledflash_exit);  //rmmod
      // 驱动信息
      // 测试modinfo找不到驱动, depmod找不到指令
      // 需要手动将ko模块放到/lib/modules/5.4.61目录下
      MODULE_LICENSE("GPL");
      MODULE_AUTHOR("G");
      

      makefile如下, 完整编译内核用时太久了, 手动设置三个参数后即可单独编译上传, 调试方便很多

      # 完整内核编译会定义KERNELRELEASE
      ifneq ($(KERNELRELEASE),)
      obj-m := led_flash.o
      
      else
      # 打印一下进到这边直接编译了
      $(warning ____alone_compile____)
      # 配置为riscv架构
      export ARCH=riscv
      # 配置编译器
      export CROSS_COMPILE=/home/ubt/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-
      # 配置内核源码位置
      KDIR = /home/ubt/tina-d1-h/out/d1-h-nezha/compile_dir/target/linux-d1-h-nezha/linux-5.4.61
      # 指定驱动程序源码位置(当前目录)
      PWD = $(shell pwd)
      # 将led_flash.o 编译成led_flash.ko, 而led_flash.o 则由make的自动推导功能编译led_flash.c 文件生成
      obj-m += led_flash.o
      all:
      	make -C $(KDIR) M=$(PWD) modules 
      clean:
      	make -C $(KDIR) M=$(PWD) clean
      
      endif
      

      Kconfig

      config LED_FLASH
        tristate "led_flash driver, gpio out put pulse by timer"
        help
          led_flash help msg.
      

      以上文件放在驱动目录下单独一个文件夹内,注意驱动目录的makefile和Kconfig需要添加该文件夹索引信息
      然后make kernel_menuconfig进入驱动项即可配置
      我尝试了直接上传ko文件安装报错, 还是直接mp更新了板子, 之后就可以直接上传更新驱动模块了
      驱动编写参考教程
      编写一个内核驱动,点亮 LED

      测试的应用程序

      #include <stdio.h>  // printf
      #include <unistd.h> // open file
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      #include <sys/ioctl.h>
      
      #define DEV_LEDFLASH_TYPE 'k'
      #define DEV_LEDFLASH_GETVALUE  _IOR(DEV_LEDFLASH_TYPE, 0x32, int)
      #define DEV_LEDFLASH_SETVALUE  _IOW(DEV_LEDFLASH_TYPE, 0x33, int)
      
      int fd;
      int interval= 500;
      
      int main(void)
      {
        // printf("Hell! O’ world, why won’t my code compile?\n\n");
        printf("[USER] led_flash_begin\n");
      
        fd= open("/dev/ledflashDev", O_RDWR);
        if(fd< 0){
      		perror("[USER] open failed\n");
      		return -1;
      	}
      
        // 读取默认值
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
        }
        printf("[USER] default interval= %d\n", interval);
        sleep(2);
      
        // 关闭
        interval = 0;
      	if(ioctl(fd, DEV_LEDFLASH_SETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_SETVALUE failed\n");
      		return -1;
        }
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
      		perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
      	}
      	printf("[USER] set interval= %d\n", interval);
        sleep(2);
      
        // 设置为2hz
      	interval = 250;
      	if(ioctl(fd, DEV_LEDFLASH_SETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_SETVALUE failed\n");
      		return -1;
        }
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
      		perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
      	}
      	printf("[USER] set interval= %d\n", interval);
        sleep(2);
      
        // 设置为5hz
        interval = 100;
      	if(ioctl(fd, DEV_LEDFLASH_SETVALUE, &interval)< 0){
          perror("[USER] DEV_LEDFLASH_SETVALUE failed\n");
      		return -1;
        }
        if(ioctl(fd, DEV_LEDFLASH_GETVALUE, &interval)< 0){
      		perror("[USER] DEV_LEDFLASH_GETVALUE failed\n");
      		return -1;
      	}
      	printf("[USER] set interval= %d\n", interval);
        sleep(2);
      
        close(fd);
        printf("[USER] steper_end\n");
      	
      	return 0;
      }
      

      makefile

      #设置编译链路径及工具
      CTOOL := riscv64-unknown-linux-gnu-
      CCL := /home/ubt/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
      CC := ${CCL}/bin/${CTOOL}gcc
      
      # build led_flash executable when user executes “make”
      led_flash: led_flash.o
      	$(CC) $(LDFLAGS) led_flash.o -o led_flash
      
      led_flash.o: led_flash.c
      	$(CC) $(CFLAGS) -c led_flash.c
      
      # remove object files and executable when user executes “make clean”
      clean:
      	rm *.o led_flash
      

      全部编译好后使用adb上传,安装运行效果如下

      root@TinaLinux:/mnt/exUDISK/app# insmod ../mod/led_flash.ko
      [ 2654.707249] led_flash: loading out-of-tree module taints kernel.
      [ 2654.714946] [DRV] _____ledflashdrv_init____
      [ 2654.720524] [DRV] _____ledflashdrv_init_successed____
      root@TinaLinux:/mnt/exUDISK/app# ./led_flash
      [USER] led_flash_begin[ 2664.649231] [DRV] ledflash_open()
      
      [ 2664.654850] [DRV] _____gpio_init____
      [ 2664.659067] [DRV] _____hrtimer_init____
      [ 2664.663458] [DRV] DEV_LEDFLASH_GETVALUE 500
      [USER] default interval= 500
      [ 2666.668404] [DRV] DEV_LEDFLASH_SETVALUE 0
      [ 2666.672975] [DRV] DEV_LEDFLASH_GETVALUE 0
      [USER] set interval= 0
      [ 2668.677738] [DRV] DEV_LEDFLASH_SETVALUE 250
      [ 2668.682480] [DRV] DEV_LEDFLASH_GETVALUE 250
      [USER] set interval= 250
      [ 2670.687414] [DRV] DEV_LEDFLASH_SETVALUE 100
      [ 2670.692243] [DRV] DEV_LEDFLASH_GETVALUE 100
      [USER] set interval= 100
      [ 2672.697095] [DRV] ledflash_release()
      [USER] steper_end
      

      闪灯测试完毕,后面就可以开始正式的深入研究了🤠

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: 【萌新】D1H如何使用硬件定时器?

      @xiaowenge 25bb2c31-1d45-40f7-977c-b400f46205ed-image.png
      系统配置/应用打包这两个

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: 【萌新】D1H如何使用硬件定时器?

      才发现之前翻了半天论坛和手册才搞明白的SDK基础操作V853的这个网页讲的很清楚,D1H的网页里都没写😢

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: 【萌新】D1H如何使用硬件定时器?

      还是尝试找了下头文件位置,参考linux内核目录介绍和搜索功能,添加了一些路径

      # build pulse executable when user executes “make”
      pulse: pulse.o
      	$(CC) $(LDFLAGS) pulse.o -o pulse
      
      ABS_PATH = /home/ubt/tina-d1-h/lichee/linux-5.4/
      
      # linux/xxx路径	-I/home/ubt/tina-d1-h/lichee/linux-5.4/include/		
      # uapi/xxx路径	-I/home/ubt/tina-d1-h/lichee/linux-5.4/						
      # asm/xxx路径		-I/home/ubt/tina-d1-h/lichee/linux-5.4/arch/riscv/include
      # asm/xxx路径2	-I/home/ubt/tina-d1-h/lichee/linux-5.4/arch/riscv/include/generated
      # linux/xxx路径2-I/home/ubt/tina-d1-h/lichee/linux-5.4/include/uapi/
      INC = -I$(ABS_PATH) -I$(ABS_PATH)include/	 -I$(ABS_PATH)arch/riscv/include/ -I$(ABS_PATH)/arch/riscv/include/generated/ -I$(ABS_PATH)include/uapi/ 
      
      pulse.o: pulse.c
      	$(CC) $(CFLAGS) $(INC) -c pulse.c
      
      # remove object files and executable when user executes “make clean”
      clean:
      	rm *.o pulse
      

      编译出现了大量错误

      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:68:1: warning: empty declaration [enabled by default]
       struct pcpu_group_info {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:75:1: warning: empty declaration [enabled by default]
       struct pcpu_alloc_info {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:87:1: warning: empty declaration [enabled by default]
       enum pcpu_fc {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:94:27: error: storage class specified for parameter ‘pcpu_fc_names’
       extern const char * const pcpu_fc_names[PCPU_FC_NR];
                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:96:21: error: storage class specified for parameter ‘pcpu_chosen_fc’
       extern enum pcpu_fc pcpu_chosen_fc;
                           ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:98:18: error: storage class specified for parameter ‘pcpu_fc_alloc_fn_t’
       typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size,
                        ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:100:16: error: storage class specified for parameter ‘pcpu_fc_free_fn_t’
       typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size);
                      ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:101:16: error: storage class specified for parameter ‘pcpu_fc_populate_pte_fn_t’
       typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr);
                      ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:102:14: error: storage class specified for parameter ‘pcpu_fc_cpu_distance_fn_t’
       typedef int (pcpu_fc_cpu_distance_fn_t)(unsigned int from, unsigned int to);
                    ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/printk.h:6:0,
                       from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/kernel.h:15,
                       from pulse.c:14:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/init.h:50:27: error: expected declaration specifiers or ‘...’ before ‘.’ token
       #define __init  __section(.init.text) __cold  __latent_entropy __noinitretpoline __nocfi
                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:104:33: note: in expansion of macro ‘__init’
       extern struct pcpu_alloc_info * __init pcpu_alloc_alloc_info(int nr_groups,
                                       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/init.h:50:27: error: expected declaration specifiers or ‘...’ before ‘.’ token
       #define __init  __section(.init.text) __cold  __latent_entropy __noinitretpoline __nocfi
                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:106:13: note: in expansion of macro ‘__init’
       extern void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai);
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/init.h:50:27: error: expected declaration specifiers or ‘...’ before ‘.’ token
       #define __init  __section(.init.text) __cold  __latent_entropy __noinitretpoline __nocfi
                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:108:13: note: in expansion of macro ‘__init’
       extern void __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
                   ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:19:0,
                       from pulse.c:16:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:126:23: error: storage class specified for parameter ‘__alloc_reserved_percpu’
       extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align);
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:127:13: error: storage class specified for parameter ‘__is_kernel_percpu_address’
       extern bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr);
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:128:13: error: storage class specified for parameter ‘is_kernel_percpu_address’
       extern bool is_kernel_percpu_address(unsigned long addr);
                   ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/printk.h:6:0,
                       from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/kernel.h:15,
                       from pulse.c:14:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/init.h:50:27: error: expected declaration specifiers or ‘...’ before ‘.’ token
       #define __init  __section(.init.text) __cold  __latent_entropy __noinitretpoline __nocfi
                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:131:13: note: in expansion of macro ‘__init’
       extern void __init setup_per_cpu_areas(void);
                   ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:19:0,
                       from pulse.c:16:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:134:23: error: storage class specified for parameter ‘__alloc_percpu_gfp’
       extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp);
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:135:23: error: storage class specified for parameter ‘__alloc_percpu’
       extern void __percpu *__alloc_percpu(size_t size, size_t align);
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:136:13: error: storage class specified for parameter ‘free_percpu’
       extern void free_percpu(void __percpu *__pdata);
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:137:20: error: storage class specified for parameter ‘per_cpu_ptr_to_phys’
       extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
                          ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:146:22: error: storage class specified for parameter ‘pcpu_nr_pages’
       extern unsigned long pcpu_nr_pages(void);
                            ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:21:0,
                       from pulse.c:16:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:11:2: error: expected specifier-qualifier-list before ‘ktime_t’
        ktime_t expires;
        ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:9:1: warning: empty declaration [enabled by default]
       struct timerqueue_node {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:14:1: warning: empty declaration [enabled by default]
       struct timerqueue_head {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:19:13: error: storage class specified for parameter ‘timerqueue_add’
       extern bool timerqueue_add(struct timerqueue_head *head,
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:21:13: error: storage class specified for parameter ‘timerqueue_del’
       extern bool timerqueue_del(struct timerqueue_head *head,
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:23:32: error: storage class specified for parameter ‘timerqueue_iterate_next’
       extern struct timerqueue_node *timerqueue_iterate_next(
                                      ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:35:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:42:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:47:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:52:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/timerqueue.h:57:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      In file included from pulse.c:16:0:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:24:1: warning: empty declaration [enabled by default]
       struct hrtimer_clock_base;
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:25:1: warning: empty declaration [enabled by default]
       struct hrtimer_cpu_base;
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:39:1: warning: empty declaration [enabled by default]
       enum hrtimer_mode {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:65:1: warning: empty declaration [enabled by default]
       enum hrtimer_restart {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:120:2: error: expected specifier-qualifier-list before ‘ktime_t’
        ktime_t    _softexpires;
        ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:118:1: warning: empty declaration [enabled by default]
       struct hrtimer {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:138:1: warning: empty declaration [enabled by default]
       struct hrtimer_sleeper {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:165:2: error: expected specifier-qualifier-list before ‘seqcount_t’
        seqcount_t  seq;
        ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:161:1: warning: empty declaration [enabled by default]
       struct hrtimer_clock_base {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:172:1: warning: empty declaration [enabled by default]
       enum  hrtimer_base_type {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:217:2: error: expected specifier-qualifier-list before ‘raw_spinlock_t’
        raw_spinlock_t   lock;
        ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:216:1: warning: empty declaration [enabled by default]
       struct hrtimer_cpu_base {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:242:63: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
                                                                     ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:248:69: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta)
                                                                           ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:248:83: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta)
                                                                                         ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:254:72: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta)
                                                                              ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:261:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:266:63: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time)
                                                                     ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:273:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:278:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hrtimer_get_expires’
       static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:283:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hrtimer_get_softexpires’
       static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer)
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:289:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:293:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:298:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:302:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hrtimer_expires_remaining’
       static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:307:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hrtimer_cb_get_time’
       static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer)
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:313:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:331:48: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       static inline void clock_was_set_delayed(void) { }
                                                      ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:336:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__hrtimer_expires_remaining_adjusted’
       __hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:350:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hrtimer_expires_remaining_adjusted’
       hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:356:13: error: storage class specified for parameter ‘clock_was_set’
       extern void clock_was_set(void);
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:360:48: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       static inline void timerfd_clock_was_set(void) { }
                                                      ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:362:13: error: storage class specified for parameter ‘hrtimers_resume’
       extern void hrtimers_resume(void);
                   ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/asm-generic/percpu.h:7:0,
                       from /home/ubt/tina-d1-h/lichee/linux-5.4//arch/riscv/include/generated/asm/percpu.h:1,
                       from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu.h:13,
                       from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:19,
                       from pulse.c:16:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:364:37: error: storage class specified for parameter ‘tick_cpu_device’
       DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
                                           ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu-defs.h:101:44: note: in definition of macro ‘DECLARE_PER_CPU_SECTION’
        extern __PCPU_ATTRS(sec) __typeof__(type) name
                                                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:364:1: note: in expansion of macro ‘DECLARE_PER_CPU’
       DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:364:37: error: section attribute not allowed for ‘tick_cpu_device’
       DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
                                           ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/percpu-defs.h:101:44: note: in definition of macro ‘DECLARE_PER_CPU_SECTION’
        extern __PCPU_ATTRS(sec) __typeof__(type) name
                                                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:364:1: note: in expansion of macro ‘DECLARE_PER_CPU’
       DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
       ^
      In file included from pulse.c:16:0:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:370:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:378:13: error: storage class specified for parameter ‘hrtimer_init’
       extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:380:13: error: storage class specified for parameter ‘hrtimer_init_sleeper’
       extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id,
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:395:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:402:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:406:68: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
                                                                          ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:410:59: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
                                                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:421:57: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim,
                                                               ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:427:12: error: storage class specified for parameter ‘hrtimer_cancel’
       extern int hrtimer_cancel(struct hrtimer *timer);
                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:428:12: error: storage class specified for parameter ‘hrtimer_try_to_cancel’
       extern int hrtimer_try_to_cancel(struct hrtimer *timer);
                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:432:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:445:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:450:16: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__hrtimer_get_remaining’
       extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
                      ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:452:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hrtimer_get_remaining’
       static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
                             ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:457:12: error: storage class specified for parameter ‘hrtimer_get_next_event’
       extern u64 hrtimer_get_next_event(void);
                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:458:12: error: storage class specified for parameter ‘hrtimer_next_event_without’
       extern u64 hrtimer_next_event_without(const struct hrtimer *exclude);
                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:460:13: error: storage class specified for parameter ‘hrtimer_active’
       extern bool hrtimer_active(const struct hrtimer *timer);
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:471:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:481:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:487:40: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
                                              ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:487:53: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
                                                           ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:506:11: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
                 ktime_t interval)
                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:513:12: error: storage class specified for parameter ‘nanosleep_copyout’
       extern int nanosleep_copyout(struct restart_block *, struct timespec64 *);
                  ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:514:13: error: storage class specified for parameter ‘hrtimer_nanosleep’
       extern long hrtimer_nanosleep(const struct timespec64 *rqtp,
                   ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:518:37: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
                                           ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:520:43: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       extern int schedule_hrtimeout_range_clock(ktime_t *expires,
                                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:524:31: error: expected declaration specifiers or ‘...’ before ‘ktime_t’
       extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
                                     ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:527:13: error: storage class specified for parameter ‘hrtimer_run_queues’
       extern void hrtimer_run_queues(void);
                   ^
      In file included from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/printk.h:6:0,
                       from /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/kernel.h:15,
                       from pulse.c:14:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/init.h:50:27: error: expected declaration specifiers or ‘...’ before ‘.’ token
       #define __init  __section(.init.text) __cold  __latent_entropy __noinitretpoline __nocfi
                                 ^
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:530:13: note: in expansion of macro ‘__init’
       extern void __init hrtimers_init(void);
                   ^
      In file included from pulse.c:16:0:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/hrtimer.h:533:13: error: storage class specified for parameter ‘sysrq_timer_list_show’
       extern void sysrq_timer_list_show(void);
                   ^
      pulse.c:19:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
       {
       ^
      In file included from pulse.c:14:0:
      /home/ubt/tina-d1-h/lichee/linux-5.4/include/linux/kernel.h:328:6: error: old-style parameter declarations in prototyped function definition
       void do_exit(long error_code) __noreturn;
            ^
      pulse.c:22:1: error: expected ‘{’ at end of input
       }
       ^
      make: *** [pulse.o] Error 1
      [2]+  Done                    $T/tools/build/buildserver --path $T 2> /dev/null 1>&2
      

      可以确定肯定不是这么搞的,我还是再去学习下怎么添加驱动程序看看

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: 【萌新】D1H如何使用硬件定时器?

      @yuzukitsuru 好的感谢回复,我以为可以不用写驱动来着

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: 【萌新】D1H如何使用硬件定时器?

      想参考下头文件路径该指定哪里
      搜索了package下的文件,都没有调用timer的;
      直接搜索整个SDK太大了,在out目录下找到很多,但这里似乎只是存放各种板型生成文件的地方没啥用
      总之还是没解决😵

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account
    • Reply: 【萌新】D1H如何使用硬件定时器?

      @yuzukitsuru 代码头文件是这样的

      #include <linux/module.h>
      #include <linux/kernel.h>
      #include <linux/hrtimer.h>
      #include <linux/jiffies.h>
      

      makefile没有加-l指定路径

      #设置编译链路径及工具
      CTOOL := riscv64-unknown-linux-gnu-
      CCL := /home/ubt/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
      CC := ${CCL}/bin/${CTOOL}gcc
      
      #设置编译规则
      timer:timer.c
      	${CC} -o timer timer.c
      
      #清理规则
      clean:
      	rm timer
      

      但是编译时没有报错找不到module.h或者kernel.h

      prefix不太清楚我去找一下

      posted in D1系列-RISC-V
      allwinner_account
      allwinner_account