Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页
    1. Home
    2. qianhao
    Q
    • Profile
    • Following 0
    • Followers 0
    • my integral 637
    • Topics 2
    • Posts 18
    • Best 3
    • Groups 0

    qianhaoLV 4

    @qianhao

    637
    integral
    3
    Reputation
    17
    Profile views
    18
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    qianhao Unfollow Follow

    Best posts made by qianhao

    • Reply: ubuntu16.04编译D1源码通过,在ubuntu21.04编译不通过

      @spring 建议就16 或者 18 使用吧 高版本很多坑要填。。。

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: 设备上面的有线网卡无法使用

      正确答案:
      试试:
      ifconfig br-lan 你的IP
      route add default gw 你的网关
      或者
      udhcpc -i br-lan

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: 【DIY教程】用D1实现提醒器

      大致效果视频

      posted in D1系列-RISC-V
      Q
      qianhao

    Latest posts made by qianhao

    • Reply: D1 fastboot烧写rootfs分区有问题

      啊 这 得加速解决啊

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: D1 JTag 调试

      @chenlinfei 智慧的是我~~~

      posted in D1系列-RISC-V
      Q
      qianhao
    • 基于全志H5搭建主线开发环境

      搭建A53调试环境
      本文介绍如何A53的调试环境,调试最新的内核。
      本实验调试基于全志H5芯片,使用nanopi-neo2开发板。
      编译ATF
      直接使用官方仓库,使用最新的ATF2.6代码。注意编译器百度自行安装, aarch64-linux-gnu- 推荐工具链使用最新的,下不赘述。
      仓库:https://github.com/ARM-software/arm-trusted-firmware.git
      make PLAT=sun50i_a64 DEBUG=1 bl31 CROSS_COMPILE=aarch64- linux-gnu-
      编译完成后,将绝对路径导出,编译u-boot的时候需要使用。
      export BL31=/path/to/bl31.bin
      编译CRUST(全志协处理器的固件代码)
      H5里面有一个openrisc 架构的协处理器,编译该代码,还需要安装改架构的交叉编译工具。
      仓库地址:https://github.com/crust-firmware/crust
      交叉编译工具下载地址:https://openrisc.io/software
      make pine64_plus_defconfig && make -j5 scp CROSS_COMPILE=or1k-linux-musl-
      export SCP=/src/crust/build/scp/scp.bin
      编译u-boot:
      u-boot 代码,我选择的是:u-boot-2021.10.tar.bz2 官方下载。
      注意在编译U-BOOT前,请将ATF 和 CRUST的成果,路径导出。
      ARCH=arm64 CROSS_COMPILE=aarch64 -linux-gnu- make nanopi_neo2_defconfig
      ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j16
      烧录u-boot到SD卡:
      U盘接入linux主机,dd进去。
      dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1

      编译文件系统:
      我使用buildroot 搭建文件系统。版本:buildroot-2021.08.2.tar.gz
      主要将以下配置选对。

      1.png
      选择生成CPIO镜像, 这样子跑RAMFS 调试比较方便。
      2.png
      编译后 将rootfs.cpio.gz 复制到你的 kernel/usr目录下。
      编译内核:
      内核源码:https://www.kernel.org/
      下载自己感兴趣的版本。
      make ARCH=arm64 CROSS_COMPILE=aarch64 -linux-gnu- defconfig
      修改内核配置:
      make ARCH=arm64 CROSS_COMPILE=aarch64 -linux-gnu- menuconfig

      1. 支持ramfs
        3.png
      2. 打开网络驱动
        4.png

      开始编译内核
      make ARCH=arm64 CROSS_COMPILE=aarch64 -linux-gnu- Image -j16
      make ARCH=arm64 CROSS_COMPILE=aarch64 -linux-gnu- dtbs -j16

      tftp启动内核:
      setenv ipaddr 192.168.31.222
      setenv serverip 192.168.31.3
      tftp 0x40080000 Image
      tftp 0x4FA00000 sun50i-h5-nanopi-neo2.dtb
      booti 0x40080000 - 0x4FA00000

      到此,A53的开发环境搭建完毕。

      dmesg
      [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
      [ 0.000000] Linux version 5.16.1 (qianhao@qianhao-server) (aarch64-seev200-linux-gnu-gcc (crosstool-NG 1.24.0.489_25f6dae) 11.2.0, GNU ld (crosstool-NG 1.24.0.489_25f6dae) 2.37) #3 SMP PREEMPT Mon Jan 17 13:34:46 UTC 2022
      [ 0.000000] Machine model: FriendlyARM NanoPi NEO 2
      [ 0.000000] efi: UEFI not found.
      [ 0.000000] NUMA: No NUMA configuration found
      [ 0.000000] NUMA: Faking a node at [mem 0x0000000040000000-0x000000005fffffff]
      [ 0.000000] NUMA: NODE_DATA [mem 0x5feddb40-0x5fedffff]
      [ 0.000000] Zone ranges:
      [ 0.000000] DMA [mem 0x0000000040000000-0x000000005fffffff]
      [ 0.000000] DMA32 empty
      [ 0.000000] Normal empty
      [ 0.000000] Movable zone start for each node
      [ 0.000000] Early memory node ranges
      [ 0.000000] node 0: [mem 0x0000000040000000-0x000000005fffffff]
      [ 0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000005fffffff]
      [ 0.000000] cma: Reserved 32 MiB at 0x000000005d400000
      [ 0.000000] psci: probing for conduit method from DT.
      [ 0.000000] psci: PSCIv1.1 detected in firmware.
      [ 0.000000] psci: Using standard PSCI v0.2 function IDs
      [ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
      [ 0.000000] psci: SMC Calling Convention v1.2
      [ 0.000000] percpu: Embedded 20 pages/cpu s41304 r8192 d32424 u81920

      posted in Linux
      Q
      qianhao
    • Reply: D1s全志公版uart驱动是否支持485?

      建议不要使用公版485驱动,貌似我有遇到过问题,问题就是拉发送引脚的前 数据已经发了,那不完犊子了

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: D1s的SPI1通信卡死问题

      请大佬及时分享解决问题的经验,小弟感激不尽

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: 海鲜市场淘了一块35元二手香橙派H3开发板,看看会不会翻车

      致敬,有手艺 有功底 才敢捡漏!

      posted in 其它全志芯片讨论区
      Q
      qianhao
    • Reply: PLIC在写入complete寄存器后立马会触发下一次中断

      @ytf4425 我就知道 硬件肯定没有问题 😊

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: 基于D1s的WhycanPI-0A,aw-ol满100分免费送

      我几分了????

      posted in D1系列-RISC-V
      Q
      qianhao
    • Reply: 【DIY教程】用D1实现提醒器

      大致效果视频

      posted in D1系列-RISC-V
      Q
      qianhao
    • 【DIY教程】用D1实现提醒器

      人体红外传感器坏了,那便手动设置GPIO吧,原理一样,硬件换上去就好了。
      先看看效果图(没有UI)。。。
      图片3.png
      图片2.png
      图片1.jpg
      程序的大概组成:

      BOA实现web服务器,实现对提醒内容的配置。
      LVGL程序实现UI,实现逻辑,蜂鸣器的,红外传感器的控制与读取。

      内核增加NFS支持

      为了调试程序方便,打开NFS功能,方便板卡和服务器交换文件。

      在tina-d1-open/device/config/chips/d1/configs/nezha/linux-5.4目录中,备份原始配置。

      cp config-5.4 config-5.4.bk
      

      在tina-d1-open/out/d1-nezha/compile_dir/target/linux-d1-nezha/linux-5.4.61目录下

      make ARCH=riscv menuconfig
      #把如下选项打开
      File systems  ---> 
                 [*] Network File Systems  --->  
                         <*>   NFS client support
                          [*]         NFS client support for NFS version 3
                          [*]               NFS client support for the NFSv3 ACL protocol extension
                          [*]         NFS client support for NFS version 4 (EXPERIMENTAL) 
                          [*]               NFS client support for NFSv4.1 (DEVELOPER ONLY) 
      

      修改完成后,将该目录下的.config复制为tina-d1-open/device/config/chips/d1/configs/nezha/linux-5.4/config-5.4

      mboot;mkernel #重新编译uboot以及内核
      make -j4
      pack
      

      增加NTP--网络对时

      在tina-d1-open下执行如下:

      source build/envsetup.sh
      lunch d1_nezha-tina
      make menuconfig
      

      使用 / 可以在目录中进行查找,找到ntpd,打开后保存退出。

      make -j4
      pack
      

      LVGL支持

      采用坛友的工程,在这个工程上进行修改。

      链接:https://bbs.aw-ol.com/topic/303/哪吒d1开发板-lvgl7-源码下载-带git仓库/4

      网页服务器

      采用BOA作为网页服务器。

      下载 boa-0.94.13.tar.gz

      解压后进入src目录执行:

      ./configure --prefix=../../riscv-boa/ --host=riscv-linux
      

      修改生成的Makefile

      CC = riscv64-unknown-linux-gnu-gcc
      CPP = riscv64-unknown-linux-gnu-gcc -E
      

      修改源码:

      vi compat.h +120

      #define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
      

      编译后,生成的boa,复制到D1的/bin目录下,在D1根目录下新建

      /WWW (这个目录下,放index.html)

      /www/cgi-bin (这个目录下放运行cgi的bin文件)

      /etc/boa/boa.conf //附件提供

      运行时 可能会产生缺少mime.types的错误,直接将ubuntu的/etc/mime.types复制到D1的ETC目录。

      HDMI的开关

      //找到驱动定义
      enum disp_output_type {
          DISP_OUTPUT_TYPE_NONE = 0,
          DISP_OUTPUT_TYPE_LCD  = 1,
          DISP_OUTPUT_TYPE_TV   = 2,
          DISP_OUTPUT_TYPE_HDMI = 4,
          DISP_OUTPUT_TYPE_VGA  = 8,
          DISP_OUTPUT_TYPE_EDP  = 32, /*16 for vdpo*/
      };
      

      打开HDMI

      cd /sys/kernel/debug/dispdbg
      echo disp0 > name; echo switch1 > command; echo 4 10 0 0 0x4 0x101 0 0 0 8 > param; echo 1 > start;
      

      关闭HDMI

      cd /sys/kernel/debug/dispdbg
      echo disp0 > name; echo switch1 > command; echo 0 10 0 0 0x4 0x101 0 0 0 8 > param; echo 1 > start;
      

      注意:echo 1 4 0 0 0x4 0x101 0 0 0 8 > param;——此处的第一个参数 1 代表MIPI-DSI输出,如果是要切换为HDMI输出,则改为 4,关闭则改为0

      GPIO 操作

      echo 65 > /sys/class/gpio/export
      echo out > /sys/class/gpio/gpio65/direction
      echo 1 > /sys/class/gpio/gpio65/value
      

      web源码:

      <!DOCTYPE html>
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>简易个人信息提醒器配置页面</title>
      </head>
      <body>
      <h1>简易个人信息提醒器配置页面</h1>
      <form name="form1" action="/cgi-bin/pass.cgi" method="POST">
      <table>
         <tr>
            <td>提醒时间段0:</td>
         </tr>
         <tr>
             <td><input type="text" name="hour0"></td>
             <td>时</td>
             <td><input type="text" name="min0"></td>
             <td>分至</td>
             <td><input type="text" name="hour1"></td>
             <td>时</td>
             <td><input type="text" name="min1"></td>
             <td>分</td>
         </tr>
         <tr>
            <td>提醒内容:</td>
         </tr>
         <tr>
            <td><input type="text" name="data0"></td>
         </tr>
      
         <tr>
            <td>提醒时间段1:</td>
         </tr>
         <tr>
             <td><input type="text" name="hour2"></td>
             <td>时</td>
             <td><input type="text" name="min2"></td>
             <td>分至</td>
             <td><input type="text" name="hour3"></td>
             <td>时</td>
             <td><input type="text" name="min3"></td>
             <td>分</td>
         </tr>
         <tr>
            <td>提醒内容:</td>
         </tr>
         <tr>
            <td><input type="text" name="data1"></td>
         </tr>
         <tr>
            <td><input type="submit" value="提交"></td>
         </tr>
      </table>
      </form>
      </body>
      </html>
      

      cgi程序源码:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      char* getcgidata(FILE* fp, char* requestmethod);
      
      char ToChar(char a, char b)
      {
          char c = 0;
       
          if(a >= '0' && a <= '9')
          {
              c = a - '0';
          }
          else if(a >= 'a' && a <= 'z')
          {
              c = a - 'a' + 10;
          }
          else if(a >= 'A' && a <= 'Z')
          {
              c = a - 'A' + 10;
          }
       
          if(b >= '0' && b <= '9')
          {
              c = c * 16 + b - '0';
          }
          else if(b >= 'a' && b <= 'z')
          {
              c = c * 16 + b - 'a' + 10;
          }
          else if(b >= 'A' && b <= 'Z')
          {
              c = c * 16 + b - 'A' + 10;
          }
       
          return c;
      }
       
      int AToI(const char *src, char *des)
      {
          if(NULL == src || NULL == des)
          {
              return -1;
          }
       
          int i, j;
          int strLen = strlen(src);
       
          for(i = 0, j = 0; i < strLen; )
          {
              if(src[i] == '%')
              {
                  des[j++] = ToChar(src[i + 1], src[i + 2]);
                  i += 3;
              }
              else
              {
                  des[j++] = src[i++];
              }
          }
       
          return 0;
      }
      
      int main()
      {
             char *input;
             char *req_method;
             int hour0,min0,hour1,min1,hour2,min2,hour3,min3;
             char data0[128] = {0};
             char data1[128] = {0};
             char utf8_data0[128] = {0};
             char utf8_data1[128] = {0};
             time_t *timep;
             printf("Content-type: text/html;charset=utf-8\n\n");
             timep = malloc(sizeof(*timep));
             time(timep);
             char *s = ctime(timep);
             printf("<br>当前时间:%s</br>", s);
             printf("<br>配置成功!</br>");
             req_method = getenv("REQUEST_METHOD");
             input = getcgidata(stdin, req_method);
             sscanf(input,"hour0=%d&min0=%d&hour1=%d&min1=%d&data0=%[^&]&hour2=%d&min2=%d&hour3=%d&min3=%d&data1=%s",&hour0, &min0, &hour1, &min1, data0, &hour2, &min2, &hour3, &min3, data1);
      
             AToI(data0, utf8_data0);
             AToI(data1, utf8_data1);
             printf("<br>从%d:%d到%d点%d提醒内容为:%s</br>", hour0, min0, hour1, min1, utf8_data0);
             printf("<br>从%d:%d到%d点%d提醒内容为:%s</br>", hour2, min2, hour3, min3, utf8_data1); 
             free(input);
             return 0;
      }
      char* getcgidata(FILE* fp, char* requestmethod)
      {
             char* input;
             int len;
             int size = 1024;
             int i = 0;
            
             if (!strcmp(requestmethod, "GET"))
             {
                    input = getenv("QUERY_STRING");
                    return input;
             }
             else if (!strcmp(requestmethod, "POST"))
             {
                    len = atoi(getenv("CONTENT_LENGTH"));
                    input = (char*)malloc(sizeof(char)*(size + 1));
                   
                    if (len == 0)
                    {
                           input[0] = '\0';
                           return input;
                    }
                   
                    while(1)
                    {
                           input[i] = (char)fgetc(fp);
                           if (i == size)
                           {
                                  input[i+1] = '\0';
                                  return input;
                           }
                          
                           --len;
                           if (feof(fp) || (!(len)))
                           {
                                  i++;
                                  input[i] = '\0';
                                  return input;
                           }
                           i++;         
                    }
             }
             return NULL;
      }
      

      lvgl 主要代码:

      #include "lvgl/lvgl.h"
      #include "lv_drivers/display/fbdev.h"
      #include "lv_drivers/indev/evdev.h"
      #include "lv_examples/lv_examples.h"
      #include <unistd.h>
      #include <pthread.h>
      #include <time.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <sys/time.h>
      #include <fcntl.h>
      #include <errno.h> 
      #include <unistd.h>
      #include <time.h>
      
      #define DISP_DEVICE_SWITCH 0x0F
      
      enum disp_output_type {
          DISP_OUTPUT_TYPE_NONE = 0,
          DISP_OUTPUT_TYPE_LCD  = 1,
          DISP_OUTPUT_TYPE_TV   = 2,
          DISP_OUTPUT_TYPE_HDMI = 4,
          DISP_OUTPUT_TYPE_VGA  = 8,
          DISP_OUTPUT_TYPE_EDP  = 32, /*16 for vdpo*/
      };
      
      
      #define DISP_BUF_SIZE (80 * LV_HOR_RES_MAX)
      LV_FONT_DECLARE(myFont1);
      char read_data[512];
      
      void IR_init(void)
      {
          system("echo 118 > /sys/class/gpio/export");
      	system("echo in > /sys/class/gpio/gpio118/direction");
      }
      
      int getGpioValue(int n)  
      {  
          char path[64];  
          char value_str[3];  
          int fd;  
        
          snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);  
          fd = open(path, O_RDONLY);  
          if (fd < 0) {  
              perror("Failed to open gpio value for reading!");  
              return -1;  
          }  
        
          if (read(fd, value_str, 3) < 0) {  
              perror("Failed to read value!");  
              return -1;  
          }  
        
          close(fd);  
          return (atoi(value_str));  
      }  
      
      void buzzer_on(void)
      {
          system("echo 65 > /sys/class/gpio/export");
      	system("echo out > /sys/class/gpio/gpio65/direction");
      	system("echo 1 > /sys/class/gpio/gpio65/value");
      }
      
      void buzzer_off(void)
      {
          system("echo 65 > /sys/class/gpio/export");
      	system("echo out > /sys/class/gpio/gpio65/direction");
      	system("echo 0 > /sys/class/gpio/gpio65/value");
      }
      
      int main(void)
      {     
      
          IR_init();
          /*LittlevGL init*/
          lv_init();
      
          /*Linux frame buffer device init*/
          fbdev_init();
      
          /*A small buffer for LittlevGL to draw the screen's content*/
          static lv_color_t buf[DISP_BUF_SIZE];
      
          /*Initialize a descriptor for the buffer*/
          static lv_disp_buf_t disp_buf;
          lv_disp_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
      
          /*Initialize and register a display driver*/
          lv_disp_drv_t disp_drv;
          lv_disp_drv_init(&disp_drv);
          disp_drv.buffer   = &disp_buf;
          disp_drv.flush_cb = fbdev_flush;
          lv_disp_drv_register(&disp_drv);
      
          static lv_style_t style1;
          lv_style_init(&style1);
          lv_style_set_bg_color(&style1, LV_STATE_DEFAULT, LV_COLOR_GRAY);
          lv_style_set_bg_opa(&style1, LV_STATE_DEFAULT, LV_OPA_50);
          lv_style_set_text_color(&style1, LV_STATE_DEFAULT, LV_COLOR_BLUE);
          lv_style_set_text_font(&style1,  LV_STATE_DEFAULT, &myFont1);
      
          lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
          lv_obj_align(label, NULL, LV_ALIGN_CENTER, -650, -100);
          lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLUE);
          lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &myFont1);
      
      
          lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
          lv_obj_align(label1, NULL, LV_ALIGN_CENTER, -300, 200);
          lv_obj_set_style_local_text_color(label1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
          lv_obj_set_style_local_text_font(label1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &myFont1);
      
          int fd = open("/www/cgi-bin/web.log", O_RDONLY);
          if(fd < 0) {
              printf("error\n:%d\n", fd);
          }
          read(fd, read_data, sizeof(read_data));
          printf("data:%s\n", read_data);
          close(fd);
          
          
          char time_now_data [256];
          time_t *timep;
          struct tm *p;
          timep = malloc(sizeof(*timep));
          time(timep);
          char *s = ctime(timep);
          p = localtime(timep);
          sprintf(time_now_data, "%s", s);
          lv_label_set_text(label1, time_now_data);
      
          int hour0, min0, hour1, min1;
          int hour2, min2, hour3, min3;
          char data0[256] = {};
          char data1[256] = {};
          sscanf(read_data,"%d:%d:%d:%d:%[^:]:%d:%d:%d:%d:%s",&hour0, &min0, &hour1, &min1, data0, &hour2, &min2, &hour3, &min3, data1);
         
          lv_label_set_text(label, data0);
      
          lv_task_handler();
          
          int buzzer_status = 0;
          while(1)
          {
              sleep(1);
              int ir_status = getGpioValue(118);
              printf("check ir:%d\n", ir_status);
              if(ir_status == 1)
              {
                  system("echo disp0 > /sys/kernel/debug/dispdbg/name");
                  system("echo switch1 > /sys/kernel/debug/dispdbg/command");
                  system("echo 4 10 0 0 0x4 0x101 0 0 0 8 > /sys/kernel/debug/dispdbg/param");
                  system("echo 1 > /sys/kernel/debug/dispdbg/start");
                  if(buzzer_status == 0) {
                      buzzer_on();
                      buzzer_status = 1;
                      sleep(2);
                      buzzer_off();
                  }
                  sleep(1);
                  if(((p->tm_hour + 12) > hour0) && ((p->tm_hour + 12) < hour1))
                  {
                      lv_label_set_text(label, data0);
                  }
                  if(((p->tm_hour + 12) > hour2) && ((p->tm_hour + 12) < hour3))
                  {
                      lv_label_set_text(label, data1);
                  }
      
                  lv_task_handler();
                  sleep(10);
              } else if(ir_status == 0) {
                  system("echo disp0 > /sys/kernel/debug/dispdbg/name");
                  system("echo switch1 > /sys/kernel/debug/dispdbg/command");
                  system("echo 0 10 0 0 0x4 0x101 0 0 0 8 > /sys/kernel/debug/dispdbg/param");
                  system("echo 1 > /sys/kernel/debug/dispdbg/start");
                  sleep(3);
                  buzzer_status = 0;
              }
          }
          return 0;
      }
      
      /*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
      uint32_t custom_tick_get(void)
      {
          static uint64_t start_ms = 0;
          if(start_ms == 0) {
              struct timeval tv_start;
              gettimeofday(&tv_start, NULL);
              start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
          }
      
          struct timeval tv_now;
          gettimeofday(&tv_now, NULL);
          uint64_t now_ms;
          now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;
      
          uint32_t time_ms = now_ms - start_ms;
          return time_ms;
      }
      

      新手上路。。。。。有待完善。。。。。

      posted in D1系列-RISC-V
      Q
      qianhao