导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. q1215200171
    3. 帖子
    • 资料
    • 关注 0
    • 粉丝 36
    • 我的积分 27597
    • 主题 319
    • 帖子 512
    • 最佳 159
    • 群组 1

    q1215200171 发布的帖子

    • 【FAQ】全志R329Tina下无法选中libcedarx如何解决?

      问题背景

      Tina SDK用户反馈,对于特定方案(v833),在make menuconfig时,可以搜索到PACKAGE_libcedarx,但无法选择。

      0c8beadd51f34b74ab5d0e8c53f32629.jfif

      如上图所示,可以搜索到PACKAGE_libcedarx,但是没有显示其目录路径,同时也没有显示是否选中。

      问题分析

      在Tina中, 使用 make 编译 tina 下的任何目标,都会通过 build/scan.mk 生成必要的临时文件,scan.mk 会扫描tina package、target等目录下的文件信息,并将对应的扫描结果保存在 tmp 目录,这是tina下所有目标生成的前提。

      对于本例来说,PACKAGE_libcedarx对应目录package/allwinner/tina_multimedia,经过扫描之后,会生成临时文件tmp/info/.packageinfo-allwinner_tina_multimedia,此时,该文件的内容如下:

      $ cat tmp/info/.packageinfo-allwinner_tina_multimedia
      Source-Makefile: package/allwinner/tina_multimedia/Makefile
      

      现在,我们打开一个menuconfig可以选中的pacakge,比如tplayerdemo,其对应的临时文件tmp/info/.packageinfo-allwinner_tina_multimedia_demo_tplayerdemo的内容如下:

      $ cat tmp/info/.packageinfo-allwinner_tina_multimedia_demo_tplayerdemo
      Source-Makefile: package/allwinner/tina_multimedia_demo/tplayerdemo/Makefile
      Package: tplayerdemo
      Submenu: tina_multimedia_demo
      Version: 1-1
      Depends: +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread @TPLAYER libcedarx libstdcpp
      Conflicts:
      Menu-Depends:
      Provides:
      Build-Depends: libcedarx
      Section: utils
      Category: Allwinner
      Title: use tplayer interface in tina_multimedia
      Maintainer:
      Source:
      Type: ipkg
      Description:    CedarX2.8 tplayerdemo
      
      @@
      

      对比两者,可发现libcedarx的临时文件只有一行,缺少很多信息,如Package、Submenu、Depends等,而Package、Submenu、Depends信息都是对应package下的Makefile定义。

      对package/allwinner/tina_multimedia/Makefile进行检查,发现上述定义都被下列条件语句所限制。

      feq ($(TARGET_BOARD_PLATFORM),$(filter $(TARGET_BOARD_PLATFORM),r16 r58 r40 r18 r6 c200s g102 r11 r7 r30 r311 r333 r331 r7s t7 r332 v306 dolphin h3 h6 mr133 r328s2 r328s3 mr813 r329 r818 a33i r528 r528rv d1 f133 t113))
      

      显然,这里表示的意思是,只有这些方案,才会定义libcedarx所需的目标。

      问题解决

      对于本例(v833)来说,补丁如下。

      diff --git a/allwinner/tina_multimedia/Makefile b/allwinner/tina_multimedia/Makefile
      index 8f3f263af..28cc01eb2 100755
      --- a/allwinner/tina_multimedia/Makefile
      +++ b/allwinner/tina_multimedia/Makefile
      @@ -435,7 +435,7 @@ ifeq ($(CONFIG_ONLY_DISABLE_AUDIO),y)
              CONF_ONLY_DISABLE_AUDIO = -DONLY_DISABLE_AUDIO
       endif
      
      -ifeq ($(TARGET_BOARD_PLATFORM),$(filter $(TARGET_BOARD_PLATFORM),r16 r58 r40 r18 r6 c200s g102 r11 r7 r30 r311 r333 r331 r7s t7 r332 v306 dolphin h3 h6 mr133 r328s2 r328s3 mr813 r329 r818 a33i r528 r528rv d1 f133 t113))
      +ifeq ($(TARGET_BOARD_PLATFORM),$(filter $(TARGET_BOARD_PLATFORM),r16 r58 r40 r18 r6 c200s g102 r11 r7 r30 r311 r333 r331 r7s t7 r332 v306 dolphin h3 h6 mr133 r328s2 r328s3 mr813 r329 r818 a33i r528 r528rv d1 f133 t113 v833))
      
       define Package/$(PKG_NAME)/config
       source "$(SOURCE)/Config.in"
      @@ -765,6 +765,6 @@ endef
      
       endif
      
      -ifeq ($(TARGET_BOARD_PLATFORM),$(filter $(TARGET_BOARD_PLATFORM),r16 r58 r40 r18 r6 c200s g102 r11 r7 r30 r311 r333 r331 r7s t7 r332 v306 dolphin h3 h6 mr133 r328s2 r328s3 mr813 r329 r818 a33i r528 r528rv d1 f133 t113))
      +ifeq ($(TARGET_BOARD_PLATFORM),$(filter $(TARGET_BOARD_PLATFORM),r16 r58 r40 r18 r6 c200s g102 r11 r7 r30 r311 r333 r331 r7s t7 r332 v306 dolphin h3 h6 mr133 r328s2 r328s3 mr813 r329 r818 a33i r528 r528rv d1 f133 t113 v833))
       $(eval $(call BuildPackage,$(PKG_NAME)))
       endif
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329Tina中TA下有哪些加解密接口?

      问题背景

      客户希望在安全OS端实现如下功能:

      • RSA私钥的生成与存储;
      • 公钥的提取(指定私钥,提取对应的公钥)
      • 指定信息的签名;对非安全OS传入的信息进行签名后,返回签名结果;
      • 信息的加密、解密;对传入的信息进行加密、解密等操作,并返回结果;

      想咨询一下当前Tina optee是否支持openssl库,如果不支持openssl库,如何实现上述功能。

      问题分析

      首先optee不支持openssl库,但是有其他替代方案。

      GlobalPlatform API

      OPTEE实现了《GPD_TEE_Internal_Core_API_Specification》这一套API,提供了对称加密、非对称加密、签名、提取密钥等操作。

      mbedtls库

      mbedtls是为嵌入式设备而开发的一个TLS协议的轻量级实现,虽然是为嵌入式设备而开发,但它也能被用于其他各种平台,因此也常常被用作OpenSSL的一个轻量级替代。Tina SDK中optee-3.7.0中已经支持。

      解决办法

      GlobalPlatform API

      密钥生成API:
      TEE_GenerateKey

      密钥提取API:
      TEE_GetObjectBufferAttribute

      签名验证API:
      TEE_AsymmetricSignDigest
      TEE_AsymmetricVerifyDigest

      加解密API:
      TEE_CipherInit
      TEE_CipherUpdate
      TEE_CipherDoFinal
      TEE_AsymmetricEncrypt
      TEE_AsymmetricDecrypt

      可参考Linaro Security Working Group提供的例子,https://github.com/linaro-swg/optee_examples

      mbedtls库
      mbedtls算是比较常用的库,可参考官方API文档:https://tls.mbed.org/api/

      本文提供了一个rsa例子,如附件0003-optee-add-optee-mbedtls-rsa-demo.patch
      0003-optee-add-optee-mbedtls-rsa-demo.patch

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 Tina下为何有些optee的demo只有NA源码没有TA源码?

      问题描述

      客户发现Tina SDK下有些optee demo 没有TA,提出问题:

      为什么有的sample只有 NA的源码,比如 optee-keybox 和 optee-getdmkey,对应 TA的程序在哪里?

      问题分析

      高版本optee(对Tina,optee-3.7.0支持)新增了PTA(Pseudo Trusted Application)的支持。

      PTA作用与TA类似,但是PTA不是一个TA,是一个接口,可以被TA与NA调用。

      PTA直接在optee os中源码实现,直接编译到optee.bin中,运行也与optee_os是同一个特权等级。

      简单来说,就是把原本在安全世界应用层实现的功能放到了操作系统层。

      解决办法

      一般来说TA是由客户自行开发,但是全志基于optee实现一些特有功能,这部分以PTA的形式集成到optee.bin中,暂未开源。

      目前仅有optee-keybox与optee-getdmkey两个包是这样。

      客户如需开发与keybox与dm-crypt相关的NA,可以参考上述两个包,直接调用相关命令,与正常的NA开发没有什么不同,TA则不用开发。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329Tina下几种安全存储实现有何区别

      问题描述

      客户在《TinaLinux_安全开发指南》上看到有多种安全储存实现,想详细了解他们的区别,进行选择。

      问题解答

      Tina上目前支持三种安全存储,分别是keybox、optee secure storage与dm-crypt。

      keybox

      keybox是全志实现的一种安全存储方法,keybox使用flash区域是特意预留的,该区域未映射到逻辑扇区,通常的数据操作无法访问,具有量产不擦除特性。

      keybox上保存的数据都是通过optee中进行加解密的。

      注:

      • 只有使用nand与emmc介质的方案才支持keybox,nor介质的方案不支持。
      • keybox最多支持31个key烧写,每个key最大支持3KB数据。设计之初主要目的是存放密钥、证书等小数据对象。
      • 可以通过DragonSN与控制台命令方式,烧写数据到keybox上。

      optee secure storage

      OPTEE Secure Storage是optee提供的根据GP TEE Internal API规范实现的一种安全存储技术。它将数据发送到Secure OS进行加密,然后保存到Linux端的文件系统(/data/tee)或者RPMB中。

      注:

      • 保存的数据大小没有限制,最大可以为optee os的堆大小。optee官方提到设计的目的主要是用于存放密钥、hash值以及计数器等小数据对象。
      • 客户需要开发相关的NA与TA来使用optee secure storage功能,全志有提供一个参考demo,位于package/security/optee-secure-storage目录。

      dm-crypt

      dm-crypt 是Linux内核提供的一种基于加密API框架和设备映射器(device mapper)子系统的安全存储技术。dm-crypt是对整个文件系统进行加密,在初始化好后,可以直接读写该文件系统,内核自动对数据进行加解密。

      注:

      • dm-crypt的密钥需要保存在安全域,在初始化时,从安全域读取,配置给Linux内核。
      • 从flash上看,该分区数据是经过加密的,但是Linux端可以直接明文访问。
      • 由于是一个文件系统,所以这种方式可以保存大数据对象,用户数据分区常采用这种安全机制。
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329Tina安全启动校验linux/rootfs失败直接重启如何解决?

      问题描述

      客户发现在安全启动时,如果uboot中校验linux、rootfs失败,会进入uboot控制台,不符合他们的安全要求。

      他们希望校验失败重启或停止运行。

      问题分析

      默认情况下,Tina安全启动中:

      • 如果brom校验toc0(sboot)失败,会跳fel烧写;
      • 如果sboot校验toc1(bl31/optee/uboot等)失败,会跳fel烧写;
      • 如果uboot校验linux、rootfs失败,会进入uboot控制台。

      可以根据不同客户的安全需求进行定制。

      解决办法

      参考下面补丁修改tina/lichee/brandy-2.0/u-boot-2018/cmd/bootm.c文件

      diff --git a/cmd/bootm.c b/cmd/bootm.c
      index 0a267b4251..887c1f0a79 100644
      --- a/cmd/bootm.c
      +++ b/cmd/bootm.c
      @@ -248,13 +248,17 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                              full = 0;
                      }
                      if (sunxi_verify_partion(&verify_pattern, rootfs_name, "rootfs", full) != 0) {
      -                       return -1;
      +                       gd->debug_mode = 8;
      +                       printf("sunxi verify rootfs fail, reboot\n");
      +                       reset_cpu(0);
                      }
       #endif /*CONFIG_SUNXI_PART_VERIFY*/
      
                      if (sunxi_verify_os(os_load_addr,
                                          env_get("boot_from_partion")) != 0) {
      -                       return -1;
      +                       gd->debug_mode = 8;
      +                       printf("sunxi verify linux kernel fail, reboot\n");
      +                       reset_cpu(0);
                      }
              }
       #endif /*CONFIG_SUNXI_SECURE_BOOT*/
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何判断Tina安全启动boot分区证书与boot分区数据是匹配与否?

      问题描述

      客户自己移植Tina打包流程,反馈使用安全启动后,boot分区校验失败,导致启动不了,关键log如下:

      [06.319]partinfo: name boot1, start 0xe00, size 0xb400
      [06.895]kernel len:10350592, part len:23592960
      **++hash compare is not correct++**
      **>>>>>>>hash of file<<<<<<<<<<**
      5bed1d5c: 98590b3b 3b1116da 174ab29e 30a13e78    ;.Y....;..J.x>.0
      5bed1d6c: 60efaf5c 567b8961 38d000dd a2da3783    \..`a.{V...8.7..
      **>>>>>>>hash in certif<<<<<<<<<<**
      5c3e2218: dd7f2b61 2343e66f cb2f648c 03c76a71    a+..o.C#.d/.qj..
      5c2e2228: 6a2ee78b f03c1694 43da3873 8474b958    ...j..<.s8.CX.t.
      bootm - boot application image from memory
      
      Usage:
      bootm [addr [arg ...]]
      

      问题分析

      log中hash in file是对boot分区payload部分计算sha256的值;hash in certify表示证书中的记录的sha256值,两个值必须相等。

      本例中,log提示这两个值不等。可能的原因有很多:有可能是分区数据本身就有问题,也有可能计算sha256时内存中boot.img数据被修改等等。

      但是,第一步要澄清分区中数据是否存在问题,即判断boot分区中证书与boot.img是否是匹配的。

      本例中客户自己移植打包过程,容易造成上述问题。

      解决办法

      Tina安全启动中,boot分区包含boot.img与boot.img的证书。

      在打包过程中,先将out/<platform>/boot.img复制到out/<platform>/image/boot.fex

      然后通过dragonsecboot -toc1 dragon_toc.cfg xxx命令对out/<platform>/boot.fex进行签名,生成证书out/<platform>/image/toc1/cert/boot.der

      dragonsecboot -toc1 dragon_toc.cfg ${ROOT_DIR}/keys ${CNF_BASE_FILE} ${ROOT_DIR}/image/version_base.mk
      

      最后通过sigbootimg 命令将证书boot.der附在boot.fex文件后。此时boot.fex中包含了boot.img与其证书。

      sigbootimg --image boot.fex --cert toc1/cert/boot.der --output boot_sig.fex
      

      boot.fex与证书boot.der要匹配,如果不匹配就会导致校验不过。

      可以进行如下验证:

      ① 执行sha256sum out/<platform>/boot.img,得到boot.img的sha256值。
      ② 将①运算的sha256值与out/<platform>/image/toc1/cnf/boot.cnf中的usr_cert块进行对比。看是否一样,如果不一样,则表明boot.img与证书不一致,打包流程出现问题,检查下是否有严格按照上述打包流程走。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 MiniGUI如何获取和设置BITMAP像素点?

      问题描述

      在MiniGUI中使用FillBoxWithBitmap加载一张图片后,需要获取到每一个像素点并重新设置像素点,实时更新内存中图像数据,做一些特效,比如旋转

      问题分析

      通过FillBoxWithBitmap加载图片后,返回的是BITMAP结构体,里面包含指向图像内存的指针bmBits,因此访问和修改该指针里的内容即可修改

      解决方案

      需要一个结构体来存RGBA数据

      typedef struct tagRGBQUAD {
          BYTE rgbBlue;
          BYTE rgbGreen;
          BYTE rgbRed;
          BYTE rgbReserved;
      } RGBQUAD;
      

      下面是获取像素的方法

      static void getPixel(PBITMAP src) {
          RGBQUAD srcdib[src->bmWidth * src->bmHeight];
          int x, y, point = 0;
          Uint8 *srcrow;
          Uint32 pixel;
      
          /* 循环获取像素点 */
          for (y = 0; y < src->bmHeight; y++) {
              for (x = 0; x < src->bmWidth; x++) {
                  /* 得到像素点的地址 */
                  srcrow = (Uint8 *) src->bmBits + y * src->bmPitch
                          + x * src->bmBytesPerPixel;
                  pixel = *((Uint32 *) (srcrow));
                  /* 这是MiniGUI中根据Pixel转成RGBA的函数 */
                  Pixel2RGBA(HDC_SCREEN, pixel, &srcdib[point].rgbRed,
                          &srcdib[point].rgbGreen, &srcdib[point].rgbBlue,
                          &srcdib[point].rgbReserved);
                  /* 打印看看对不对 */
                  printf("%d %d %d %d\n", srcdib[point].rgbReserved,
                          srcdib[point].rgbRed, srcdib[point].rgbGreen,
                          srcdib[point].rgbBlue);
                  /* 记录点的位置 */
                  point++;
              }
          }
      }
      

      下面是设置像素的方法

      static void setPixel(PBITMAP src, PBITMAP dstbmp) {
          /* 这里根据源图片重新构造一个PBITMAP对象 */
          dstbmp->bmType = src->bmType;
          dstbmp->bmBitsPerPixel = src->bmBitsPerPixel;
          dstbmp->bmBytesPerPixel = src->bmBytesPerPixel;
          dstbmp->bmAlpha = src->bmAlpha;
          dstbmp->bmColorKey = src->bmColorKey;
      #ifdef _FOR_MONOBITMAP
          dstbmp->bmColorRep = src->bmColorRep;
      #endif
          dstbmp->bmAlphaMask = src->bmAlphaMask;
          dstbmp->bmAlphaPitch = src->bmAlphaPitch;
          dstbmp->bmWidth = src->bmWidth;
          dstbmp->bmHeight = src->bmHeight;
          dstbmp->bmPitch = src->bmPitch;
          dstbmp->bmBits = malloc(src->bmWidth * src->bmHeight * src->bmBytesPerPixel);
      
          /* dstdib存的是自己需要的每个像素点的值,根据需要自己赋值 */
          RGBQUAD dstdib[src->bmWidth * src->bmHeight];
          int x, y, point = 0;
          Uint32 pixel;
          
          /* 设置每一个像素点的值 */
          for (y = 0; y < src->bmHeight; y++) {
              for (x = 0; x < src->bmWidth; x++) {
                  pixel = RGBA2Pixel(HDC_SCREEN, dstdib[point].rgbRed,
                          dstdib[point].rgbGreen, dstdib[point].rgbBlue,
                          dstdib[point].rgbReserved);
                  /* 打印看看像素是否正常 */
                  printf("%d %d %d %d\n", dstdib[point].rgbReserved,
                   dstdib[point].rgbRed, dstdib[point].rgbGreen,
                   dstdib[point].rgbBlue);
                  printf("pixel=%x\n", pixel);
      
                  /* MiniGUI根据pixel设置像素点的函数 */
                  SetPixelInBitmap(dstbmp, x, y, pixel);
                  /* 记录点的位置 */
                  point++;
              }
          }
      }
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何在Tina在不烧写secure bit下开发OPTEE安全应用?

      问题描述

      正常情况下,需要在安全环境下开发安全相关功能。但是一旦开启安全功能就烧写掉efuse中的secure bit,以后芯片就只能启动安全固件。

      客户处于功能开发阶段,如果把很多芯片烧写成安全,会造成一定的浪费,客户希望在不开启安全的情况下,也能正常的开发OPTEE的TA/NA。

      问题分析

      处理之前,我们简单了解下TrustZone与Secure bit之间的关系。

      TrustZone的作用范围是CPU(处理器、gic、cache、总线等)。Secure bit是一个开关,开启后,TZMA/SMC/SPC/EFUSE/CE等模块,其作用范围是外设。

      正常使用时,需要TrustZone与Secure bit一起协同工作,才能保障整个系统的安全。

      这里需要说明的是,在Secure bit没有烧写时,TrustZone依旧是起作用的,CPU依旧有安全态与非安全态,但是外设、存储等是没有安全属性的,所以CPU在非安全态也可以访问所有的外设、内存。

      回到客户问题,OPTEE的安全应用TA与非安全应用NA交互是基于TrustZone硬件基础,所以是可以在Secure bit没有烧写时进行OPTEE TA/NA的开发。

      解决办法

      arm方案

      对于arm32方案来说,非安全固件中默认就包含了OPTEE,可以直接参考《TinaLinux_安全开发指南》进行开发。

      aarch64方案

      对于aarch64方案来说,非安全固件中默认没有包含OPTEE,在tina/device/config/chips/<chip>目录加入如下补丁后,非安全固件中就会包含OPTEE。

      diff --git a/configs/default/boot_package.cfg b/configs/default/boot_package.cfg
      index 5b38539..2152e6e 100644
      --- a/configs/default/boot_package.cfg
      +++ b/configs/default/boot_package.cfg
      @@ -2,6 +2,7 @@
       ;item=Item_TOC_name,         Item_filename,
       item=u-boot,                 u-boot.fex
       item=monitor,                monitor.fex
      +item=optee,                  optee.fex
       ;item=logo,                   bootlogo.bmp.lzma
       ;item=shutdowncharge,         bempty.bmp.lzma
       ;item=androidcharge,          battery_charge.bmp.lzma
      

      打包脚本修改

      在tina/scripts加入如下补丁,其作用是在非安全情况下也对OPTEE中的公钥进行更新。如不更新,运行TA时对TA的校验将会失败,导致TA运行不了。

      diff --git a/pack_img.sh b/pack_img.sh
      index f8b11fa..78ced4f 100755
      --- a/pack_img.sh
      +++ b/pack_img.sh
      @@ -1749,19 +1749,6 @@ function do_signature()
                      fi
              fi
      
      -       # update optee pubkey
      -       if [ -f ${ROOT_DIR}/staging_dir/target/usr/dev_kit/arm-plat-${PACK_CHIP}/export-ta_arm32/keys/default_ta.pem ]; then
      -               ${PACK_TOPDIR}/scripts/update_optee_pubkey.py \
      -                       --in_file optee.fex --out_file optee-new.fex \
      -                       --key ${ROOT_DIR}/staging_dir/target/usr/dev_kit/arm-plat-${PACK_CHIP}/export-ta_arm32/keys/default_ta.pem
      -               if [ $? -eq 0 ]; then
      -                       mv optee-new.fex optee.fex
      -               else
      -                       pack_error "update optee pubkey error!"
      -                       exit 1
      -               fi
      -       fi
      -
              if [ -f ${LONGAN_COMMON_DIR}/sign_config/cnf_base.cnf ] ; then
                      CNF_BASE_FILE=${LONGAN_COMMON_DIR}/sign_config/cnf_base.cnf
              else
      @@ -1907,6 +1894,18 @@ function do_pack_tina()
                      fi
              fi
      
      +       if [ -f ${ROOT_DIR}/staging_dir/target/usr/dev_kit/arm-plat-${PACK_CHIP}/export-ta_arm32/keys/default_ta.pem ]; then
      +               ${PACK_TOPDIR}/scripts/update_optee_pubkey.py \
      +                       --in_file optee.fex --out_file optee-new.fex \
      +                       --key ${ROOT_DIR}/staging_dir/target/usr/dev_kit/arm-plat-${PACK_CHIP}/export-ta_arm32/keys/default_ta.pem
      +               if [ $? -eq 0 ]; then
      +                       mv optee-new.fex optee.fex
      +               else
      +                       pack_error "update optee pubkey error!"
      +                       exit 1
      +               fi
      +       fi
      +
              if [ "x${PACK_SIG}" = "xsecure" ] ; then
                      echo "secure"
                      do_signature
      

      注意事项

      按照上述办法可以进行在不烧写seucre bit情况下开发OPTEE的安全应用,但是由于外设、内存等资源的安全属性没有进行设置,因此务必在烧写secure bit的芯片上进行功能验证与测试。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列 Tina 如何查看通过 procd init 脚本启动的应用输出到 stdout/stderr 的打印信息?

      问题描述

      当我们使用 procd init 脚本让某个应用程序实现开机自启时,会发现应用程序中原本通过 printf/fprintf 等输出到 stdout/stderr 的打印信息都无法从串口或 adb shell 中看到了。

      这些打印默认是输出到什么地方?我们可以如何看到这些打印?

      原因

      一般情况下,当用户在终端中执行命令来运行某个应用程序时,stdin/stdout/stderr 就确定下来是在当前终端,因此应用程序的打印信息自然能从当前终端中显示出来。

      而如果该应用程序是通过 procd init 脚本进行开机自启,它会被认为是一个守护进程(daemon)。守护进程是随系统自启的,它们有可能在用户登录终端之前就已经开始运行了,也无法得知用户是从哪个终端登录,因此也就无法将打印信息输出到用户所在的终端。

      解决方法

      一般来说,要获取守护进程的打印,需要通过 syslog 之类记录系统整体日志的方法。procd init 脚本也提供了方法将应用程序的打印重定向到 syslog 中。

      下面是一个简单的 procd init 脚本例子,它会启动应用程序 /usr/bin/foobar,但我们默认没法看到 foobar 输出到 stdout/stderr 的打印:

      #!/bin/sh /etc/rc.common
      
      START=50
      
      USE_PROCD=1
      
      start_service() {
          procd_open_instance
          procd_set_param command /usr/bin/foobar
          procd_close_instance
      }
      

      通过增加“procd_set_param stdout 1”和“procd_set_param stderr 1”两个参数,可将其输出到 stdout/stderr 的内容重定向到 syslog:

      #!/bin/sh /etc/rc.common
      
      START=50
      
      USE_PROCD=1
      
      start_service() {
          procd_open_instance
          procd_set_param command /usr/bin/foobar
          procd_set_param stdout 1    # 将其 stdout 的内容重定向到 syslog
          procd_set_param stderr 1    # 将其 stderr 的内容重定向到 syslog
          procd_close_instance
      }
      

      如此设置后,就可以从 syslog 中看到 foobar 应用程序输出的打印。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何设置蓝牙自动重连时间或关闭自动重连?

      问题背景

      通常情况下,蓝牙设备因距离远或信号不好会发生断开连接,但环境恢复后蓝牙设备会自动重新连接。

      问题描述

      部分客户想设置这个自动重新连接的时间,或者因某种原因想直接关闭自动重连。

      问题分析

      (1)蓝牙自动重连的实现。
      在bluez里面,bluez/plugins/policy.c文件,负责解析配置文件和实现蓝牙重连的策略。
      bluez/src/main.conf是蓝牙可配置文件,[Policy]部分就是重连配置。用户也可以在etc/bluetooth/目录下找到main.conf文件修改配置。
      aef9211c6cc24df68309de1ba3636e68.jfif

      (2)配置参数
      ReconnectUUIDs:设置重新连接的services
      ReconnectAttempts:设置重新连接的次数
      ReconnectIntervals:设置连接间隔,和连接次数对应
      AutoEnable:发现adapters时自动使能它

      解决办法

      在main.conf修改配置参数,如关闭自动重连就将连接次数设置为0即可。
      不适用main.conf配置参数,直接在policy.c文件里修改默认配置。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 LRADC电压设置、识别精度、识别误差、应用等相关知识

      问题背景

      不少朋友在使用LRADC可能会有以下几种疑问:

      • LRADC允许输入电压是多少?
      • 支持检测最大/小的电压是多少?
      • LRADC最小能检测多大的电压变化?
      • LRADC的误差有多少?
      • LRADC应该如何设计按键的分压值?最多能接入多少个按键。

      本文主要讲述以上几个点。

      设备环境

      • 软件系统:Tina系统
      • 硬件芯片:带LRADC的soc

      LRADC详解

      1、LRADC正常工作需要输入的电压是1.8V。但是,最大不能超过1.8V。

      2、LRADC最大能检测的电压值是1.35V。所以即使输入的是1.8V,LRADC读出来的还是1.35V。最小能检测的电压是0V,即直接下拉接地。
      (LRADC最大能检测的电压值每款芯片可能不一样,有的芯片是1.2V,详情查看user manual)

      3、LRADC的分辨率为6bit,即64个数。当最大检测电压为1.35V时,每一档电压为1350/64=21.1mV,即为LRADC最小能检测电压变化范围。

      4、分辨率为6bit,精度是为4bit,理论误差为±84mV。但是经过硬件中的误差纠正后,精度可为5bit,即理论误差为±42mV(这个是理论误差,实际误差要比理论的要小,经过测试最大为±30mV左右的误差)。

      5、由于这个误差的存在,在将LRADC用作按键的时候需要注意,尽量把两个按键之间的电压间隔设计大一点,这里推荐最小间隔为**“120mV”**,并且不超过1.2V。(因为当电压超过1.266V后,可认为1.266V~1.35V之间的电压是不准确的。)因此,最大可以设计120mV/240mV/…1200mV等10个档位。

      不过,一般在公版上都是设置5个按键档位,硬件设计可参考下图:

      4126e6455e304318b038a26fda051ba8.jfif image.png

      LRADC拓展

      LRADC精度比较低,一般不推荐用其作为普通ADC使用的。那么,除了作为按键使用的话,还可以用作什么用途呢?

      这里还推荐一种使用方式,许多客户可能需要在同个板子上使用多种方案,不同方案只有可能有些模块是不一样的,但是固件又只能出一种。这时候,就可以使用LRADC达到区分方案,从而加载不同dts适配各个方案的目的。

      首先,可以在硬件中,不同的方案设置不同电阻上/下拉连接到LRADC,使得不同方案输入到LRADC的电压值不一样。比如说,方案A直接10k电阻上拉到1.8V,方案B通过10k电阻下拉到0V。那么,只需要在uboot里调用lradc读电压接口,再稍做判断即可知道当前硬件是属于什么方案,然后再加载不同dts。
      lradc读电压接口代码,在uboot里的路径为:u-boot-2018/board/sunxi/sunxi_lradc_vol.c

      3185a00d67194bbe82c9b4ee610f6f81.jfif image.png

      首先是调用lradc_data_init()对LRADC进行一个初始化,然后再调用lradc_read_data(u32 reg_base)读取实际的电压值,详情使用方法可以参考下方的sunxi_read_lradc_vol(void)函数。

      需要注意的是:
      LRADC默认的采样频率要500Hz,即2ms采样一样,而电压data寄存器需要采样8次才能更新一次电压,所以一共需要至少16ms才能准确读取真实的电压。
      因此,在调用LRADC初始化后至少30ms后,才能调用用lradc_read_data去读取电压。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329在dtbo中如何配置gpio?

      问题背景

      客户同一款产品,一供模拟功放和二供模拟功放使用不同的PIN脚来使能PA,客户想在dtbo中根据硬件版本类型配置不同的pin脚。但是在dtbo中根据dts的方法配置的时候会报syntax error。如当时按以下方法配置成PM8的情况,会提示syntax error

      &codec_ex {
        gpio-spk = <&r_pio PM 8 1 1 1 1>;
      };
      

      问题分析

      在dts中,如果要使用gpio.h中定义的pin脚,那么可以直接用#include <dt-bindings/gpio/gpio.h>这句话把gpio.h头文件包含之后就可以使用里面定义的宏了。但dtbo的语法不支持这种include的方式,也不支持直接在dtbo中定义宏的方式,因此要配置PM8这个pin时,不能写PM这个符号,只能写PM实际定义的数字。所有pin定义的数字定义在lichee/linux-4.9/include/dt-bindings/gpio/gpio.h,如下所示:

      /* sunxi gpio arg */
      #define  PA  0
      #define  PB  1
      #define  PC  2
      #define  PD  3
      #define  PE  4
      #define  PF  5
      #define  PG  6
      #define  PH  7
      #define  PI  8
      #define  PJ  9
      #define  PK  10
      #define  PL  11
      #define  PM  12
      #define  PN  13
      #define  PO  14
      #define  PP  15
      #define  default 0xffffffff
      

      解决方法

      在device/config/chips/r329/configs/xxx/dtbo/xxx.dts中根据实际要配置的pin脚加入以下代码,如配置使能脚为PM8,则根据lichee/linux-4.9/include/dt-bindings/gpio/gpio.h中的宏定义把PM改成12,改动如下:

      &codec_ex {
        gpio-spk = <&r_pio 12 8 1 1 1 1>;
      };
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何在Tina安全应用程序调试?

      问题描述

      客户将Tina上的安全应用移植到自己的SDK,编译完成后,执行时出现如下问题:

      printf(“NA:open session\n”);
      teecErr = TEEC_OpenSession(&ctx, &teecSession, &ta_UUID,
      TEEC_LOGIN_PUBLIC, NULL, NULL, NULL);

      在打印了NA:open session后,卡在了TEEC_OpenSession后面就没走了。

      问题分析

      TEEC_OpenSession函数作用是建立一个指定NA(非安全程序)与指定TA(可信程序)之间的通信通道。

      在此处出错,表明NA与TA建立不了联系,可能原因有多种。

      首先要对NA与TA通信过程要有整体了解,才确认在哪个节点出现问题。

      解决办法

      了解NA与TA通信流程。如下图所示:
      e6b1627fa5d34830808e902acf8c4034.jfif

      整个通信设计5个模块: NA <-> optee_client <-> linux驱动(driver/tee/optee)<-> optee(闭源)-> TA。

      在上述每个过程中都可能出现问题。下一步,检查每个模块是否工作正常。

      optee_client。 optee_client提供NA使用的libteec库,以及tee-supplicant后台应用程序。
      确保rootfs中有包含该库与应用程序,同时tee-supplicant有在后台运行。

      linux驱动。 检查内核配置有没有开CONFIG_TEE与CONFIG_OPTEE。启动后,检查是否存在tee的设备节点/dev/tee0与/dev/teepriv0。

      由于optee为闭源,可以先从NA查到linux驱动,比如TEEC_OpenSession这个最终会调用到内核driver/tee/tee_core.c中的tee_ioctl_open_session函数。检查上述流程是否存在问题。

      TA。TA也是客户自己开发。NA与TA交互接口如下图所示。比如本例NA调用TEEC_OpenSession,会与TA中的TA_CreateEntryPoint与TA_OpenSessionEntryPoint接口交互,可以在这两个接口中加入打印,看是否有到达TA。

      acdd492da0ea49149433ab0a44848724.jfif

      如果最终确认是optee中的问题,可以找AW内部安全负责人进行处理。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决Tina双系统uboot校验rootfs失败的问题?

      问题描述

      内核双备份系统安全固件启动失败,有如下log:

      Hit any key to stop autoboot: 0
      [06.393]partinfo: name boot1, start 0xe00, size 0x7800
      [06.989]begin to verify rootfs
      get part: rootfs info failed
      bootm - boot application image from memory
      Usage:
      bootm [addr [arg …]]

      boot application image stored in memory

      问题分析

      从log中看,提示没有找到名字为rootfs的分区信息。

      此问题原因:由于Tina默认当前是但系统,uboot校验rootfs时直接指定的rootfs的分区名“rootfs”。但是客户是双系统,rootfs有两个分区,分区名为rootfs1与rootfs2,而这里直接指定rootfs,会造成找不到对应的分区信息。

      解决办法

      不直接指定,从evn环境变量中获取当前要启动的rootfs分区。在tina/lichee/brandy-2.0/u-boot-2018/加入如下补丁:

      diff --git a/cmd/bootm.c b/cmd/bootm.c
      index f4071e026e..0a267b4251 100644
      --- a/cmd/bootm.c
      +++ b/cmd/bootm.c
      @@ -231,6 +231,7 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                      struct sunxi_image_verify_pattern_st verify_pattern = {
                              0x1000, 0x100000, -1
                      };
      +               char *rootfs_name = env_get("root_partition");
                      char *s = env_get("rootfs_per_MB");
                      if (strcmp(s, "full") == 0) {
                              full = 1;
      @@ -246,7 +247,7 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
      
                              full = 0;
                      }
      -               if (sunxi_verify_partion(&verify_pattern, "rootfs", "rootfs", full) != 0) {
      +               if (sunxi_verify_partion(&verify_pattern, rootfs_name, "rootfs", full) != 0) {
                              return -1;
                      }
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何使用DMIC的高通滤波寄存器滤掉低频噪声?

      开发环境

      硬件:R328
      软件:Tina
      内核: Linux-4.9

      问题描述

      客户使用DMIC录音,想通过配置高通滤波寄存器,滤掉800hz的噪声
      与高通滤波相关的寄存器:
      HPF_EN_CTR: 0x38
      HPF_COEF_REG: 0x3c
      HPF_GAIN_REG: 0x40

      解决方案

      只需要更改HPF_COEF_REG中的值即可,假如效果没有达到预期,还请找出噪声来源,从源头上解决。

      0fb00923076b4479831efda9fdc9170b.jfif

      coef值与截止频率的关系是Fc=fs*(1-coef)/2π,其中fs是采样频率。

      coef的值是3.24格式,也就是有效位是27bit,3个整数位,24个小数位,默认值为0x00FFAA45,换算成10进制就是0.99869,当采样频率是48k时,默认设置的截止频率Fc=48k *(1-0.99869)/2π = 10Hz。

      下面演示如何通过配置HPF_COEF_REG寄存器滤掉100hz的正弦波。

      使用audiocodec播放100hz正弦波。

      7265e6a7c7704ec58ed51ee264f43505.jfif

      HPF_COEF_REG使用默认值,DMIC使用采样频率16k录音,保存文件为100hz_default.wav。

      ec38e94145c84940a8aaff687277b513.jfif

      截止频率为100Hz的话,经计算得出coef值为0.96075,因此HPF_COEF_REG修改为0x00f5f1db,DMIC使用采样频率16k录音,保存文件为100hz_setHPF.wav。

      c89499539f2c40138a153c2c6e77747c.jfif

      两者的音频波形如下,可见100hz_setHPF的波形中,录回正弦波的db值比100hz_default更小。

      16516f7172914f53a20b29dfe092e833.jfif

      因为驱动中并没有对该寄存器进行操作,所以目前只有硬改寄存器的方式进行配置,之后会考虑在dts中添加截止频率的配置项。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决Tina中package下新增软件包目录很深导致检测不到问题

      问题描述

      在Tina/package下新增软件包配置,如果新增软件包的目录太深,将会导致tina检测不到。

      比如tina/package/dir1/dir2/dir3/dir4/Makefile可以检测到,但是tina/package/dir1/dir2/dir3/dir4/dir5/Makefile将检测不到。

      问题分析
      Tina构建时,将根据一定的规则扫描各个目录下的Makefile文件,这些规则定义在tina/build目录下。

      tina/build目录下有一个scan.mk文件,打开后可以看到有一个$(FILELIST)的编译目标,语句比较简单。

      主要操作是删除一个临时文件,然后在(SCAN_DIR)下查找目录深度为1到(SCAN_DEPTH)的Makefile文件,找到之后进行一些处理,并写入到(FILELIST),我们可以打开FILELIST文件看看,里面记录了package下目录深度为1到(SCAN_DEPTH)的包目录。

      FILELIST:=$(TMP_DIR)/info/.files-$(SCAN_TARGET)-$(SCAN_COOKIE)
      $(FILELIST): $(OVERRIDELIST)
              rm -f $(TMP_DIR)/info/.files-$(SCAN_TARGET)-*
              $(call FIND_L, $(SCAN_DIR)) $(SCAN_EXTRA) -mindepth 1 $(if $(SCAN_DEPTH),-maxdepth $(SCAN_DEPTH)) -name Makefile | xargs grep -aHE 'call $(GREP_STRING)' | sed -e 's#^$(SCAN_DIR)/##' -e 's#/Makefile:.*##' | uniq | awk -v of=$(OVERRIDELIST) -f build/scan.awk > $@
      

      所以,差不多知晓其中$(SCAN_DEPTH)就是扫描的深度,在tina/build下查找改SCAN_DEPTH关键字,发现在tina/build/toplevel.mk下有相关设置。

      prepare-tmpinfo: FORCE
              @+$(MAKE) -r -s out/host/.prereq-build $(PREP_MK)
              mkdir -p tmp/info
              $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f build/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/build/package*.mk $(TOPDIR)/overlay/*/*.mk" SCAN_DEPTH=5 SCAN_EXTRA=""
              $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f build/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/allwinner" SCAN_NAME="target" SCAN_DEPS="*.mk $(TOPDIR)/build/kernel*.mk $(TOPDIR)/build/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
      

      可以看到上述prepare-tmpinfo目标中的部分内容中,会对两个目录进行扫描,一个是tina/package目录,最大扫描深度为5; 一个是tina/target/allwinner目录,最大扫描深度为2。

      到现在,问题点已经找到。

      解决办法

      将toplevel.mk中package目录扫描深度SCAN_DEPTH改大就可以了。

      这里也需要注意一点,SCAN_DEPTH改大之后,扫描内容变多,会导致编译前的准备工作变慢,因此最好还是不要将软件包放那么深。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 多台设备的adb device id相同,无法指定设备,如何指定设备的adb device id?

      问题背景

      系统平台:R329 + Tina

      问题描述

      多块R329开发板连接电脑后的adb device id相同,均为一串0,同时连接时无法通过adb -s [device id] shell指定设备连接,需要给每个设备指定不同的device id。

      问题分析

      一串0的长度与chip id的长度相似,猜测默认是将chip id 作为device id,但是这几块开发板没有烧码导致device id相同;

      cat /sys/class/sunxi_info/sys_info查看sunxi_serial确实是一串0。

      解决方法

      Tina_Linux_USB_开发指南.pdf中有配置USB序列号的介绍,其中是在uboot将chip id作为androidboot.serialno,由adbd脚本读取该值,写入节点/sys/kernel/config/usb_gadget/g1/strings/0x409/serialnumber

      f3fb23c385b34775b60d2bf4579dcf09.jfif

      读取serialnumber的代码如下:

      get_serialnumber() {
      	str=`cat /proc/cmdline |tr ' ' '\n' | grep 'androidboot.serialno' | awk -F "=" '{print $2}'`
      	[ -z $str ] || SERIALNUMBER=$str
      }
      

      这里我直接修改脚本而不去修改dts:

      修改/etc/rc.d/K99adbd中的get_serialnumber函数为:

      get_serialnumber(){
      	SERIALNUMBER="12345678"
      }
      

      其中的12345678即为指定的device id。

      也可以读取将指定文件内容作为serialnumber,文件不存在时随机生成并保存为文件:

      ADB_SERIAL_CONF="/etc/adb_serial.conf"
      
      get_serialnumber() {
              if [ ! -f $ADB_SERIAL_CONF ];then
                      rand_var=$(head -200 /dev/urandom | cksum | cut -f1 -d " ")
                      if [ -n "$rand_var" ];then
                              SERIALNUMBER=$(printf %010d $rand_var)
                              echo $SERIALNUMBER > $ADB_SERIAL_CONF
                      fi
              else
                      SERIALNUMBER=$(cat $ADB_SERIAL_CONF)
              fi
      }
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决蓝牙播放无声(snd_pcm_open error: Out of memory)?

      问题背景
      客户使用蓝牙a2dp source功能,连接蓝牙耳机播放音乐高概率出现播放无声的现象。
      但在客户使用相同btmanager版本的其他机型上并没有遇到这个问题。

      问题描述
      在出现播放无声问题时,btmanager会一直出现如下的打印:

      BTMG[aw_pcm_open:400]:  --->Couldn't open PCM:bluealsa:DEV=28:37:13:3B:DA:78
      BTMG[_a2dp_src_pcm_write:150]:  a2dp source open pcm error: Out of memory;
      

      从log来看,播放时没有成功打开蓝牙虚拟声卡,所以播放没有声音是必然的。其中打开蓝牙声卡是使用标准函数snd_pcm_open,
      而错误信息是 Out of memory。显然从日志来看,此问题与系统内存有关系。客户机器是512M内存。

      问题分析

      既然与内存有关系,便从内存方向去分析此问题:

      1)查看当前内存信息
      cat /proc/meminfo

      3b1f6a9b0776482496a80e6fa06090e5.jfif
      但是看内存信息,在声卡一直打不开的时候,MemFree也有 10M左右,所以就觉得有点奇怪了,为什么内存这么多,还是申请不到内存打开声卡呢?
      难道是脏内存太多了?

      2)尝试线程的栈调大

      • 把btmanager里面相关的线程栈调高至20K,还是无效。
      • 修改C库把默认线程的栈修改为1M,依然无效。

      3)清理缓存

      是不是脏内存太多,内存不连续?
      使用echo 3 > /proc/sys/vm/drop_caches 清理一下,发现就可以正常申请了。
      但是让内存的同事看了下连续内存还是足够的,所以这还不是根本原因。

      4)跟踪代码
      通过在alsa-lib 里面增加打印,最终发现是在snd_user_file函数里面调用wordexp(file, &we, WRDE_NOCMD);
      返回了WRDE_NOSPACE,而打开的file /usr/share/alsa/alsa.conf也只有10K左右。再继续跟踪C库里面的wordexp函数,发现是在fork的时候有问题。
      接着又做了个实验,同时在出问题的时候,我们在非打开声卡的地方调用fork函数,也是会申请不到内存。
      所以本质上是fork函数导致的,打开声卡的过程刚好触发了这个问题。

      解决办法

      对于fork函数,有如下的行为:

      fork函数会创建带有独立虚拟地址空间的新进程,内核会把当前进程的虚拟内存中数据结构复制一份给新进程。

      看了下客户应用的出问题时的内存情况:
      c258bb1c9e9849a2a5c991468981f992.jpg

      异常时,应用的VmPeak和VmSize偏高,这个说明此时应用申请的虚拟内存是非常高了。
      此时如果有打开声卡,触发fork的操作,子进程也需要申请那么大的虚拟内存。
      问题就在此,突然申请那么大的虚拟内存,被内核限制了。

      解决方案:

      1、客户出问题的方案,由于跑特殊的算法导致使用了比较大的虚拟内存。
      可以通过优化应用内存解决。

      2、取消内核的限制
      在系统启动脚本加上 echo > 1 /proc/sys/vm/overcommit_memory 这个命令操作。
      内核就不会限制应用申请比较大的虚拟内存了。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何修改bluez缓存保存路径

      问题背景

      系统改为只读之后,蓝牙的扫描/配对等信息无法保存。

      问题描述

      客户的系统在开发前期所有的分区都是可读可写的,此时蓝牙功能还是正常的。
      到了项目后期,可能会把系统改为只读了,只有data分区可写。
      这时会发现本来已经配对连接过的蓝牙设备,在开关蓝牙之后就丢失了。

      问题分析

      bluez默认的缓存路径为:/etc/lib/bluetooth/
      由于修改了分区权限,会导致相关信息无法写入。

      解决办法

      修改缓存路径到可写的分区,修改Makefile即可。
      路径:package/utils/bluez/Makefile
      假如data分区可写,就迁移到data:
      把 --localstatedir=/etc 修改为 --localstatedir=/data,重新编译bluez。
      修改后保存路径变为:/data/lib/bluetooth/

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何在WiFi Softap模式添加自定义Vendor IE?

      问题背景

      对于某些应用场景,需要在Probe Response帧和Beacon帧中添加指定的Vendor IE信息,以满足特定需求

      问题分析

      对于802.11管理帧,IE是可变的,因此可以在其Payload末尾添加IE信息,IE由ID、Length(有效载荷长度,单位为字节)和Payload构成

      实现方法

      在在hostapd.conf配置文件中增加vendor_elements选项,格式为 id + len + payload十六进制形式,举例如下:

      vendor_elements=23020600      //id=0x23=35, length=0x02=2, payload=0600
      

      测试验证
      通过抓包确定IE是否添加成功

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 XRADIO如何查看发射功率和频偏?

      问题背景

      硬件:R328+ Wi-Fi模组(XRADIO)
      软件:Tina3.0及以上
      说明:该FAQ旨在记录XRADIO驱动常见的调试Tips。与具体驱动相关,具有一般性。

      问题简述

      客户在做吞吐性能优化过程中问到:如何查看和修改xr829的发射功率和频偏?

      问题分析

      发射功率和频偏都是性能优化过程中比较重要的参数,不支持驱动直接修改。
      都是在firmware文件中设置的,都是经过大量测试才定的。所以一般不建议客户自己修改,以避免引起性能问题。

      解决方法

      可以通过sdd工具查看,如下:
      借用sdd工具导入firmware(package/firmware/linux-firmware/xr829/sdd_xr829_40M.bin)文件即可。
      注意:区分不同晶振的sdd文件不一样。

      562a989ce7b44ca6b279a7b8e195fd8a.jfif

      注:sdd工具获取
      可以从一号通获取:https://one.allwinnertech.com/#/devtool?menuID=37

      517d424271c24137be9369706abf9d79.jfif

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何关闭HT40?

      问题背景

      硬件:R328+ Wi-Fi模组(XRADIO)
      软件:Tina3.0及以上
      说明:该FAQ旨在记录XRADIO驱动常见的调试Tips。与具体驱动相关,具有一般性。

      问题简述

      客户在做吞吐性能优化过程中问到:xr829的HT40如何关闭?

      问题分析

      1.XR829如何关闭HT40?

      HT40 怎么关闭,如果在Makefile里面加入 ccflags-y += -DSUPPORT_HT40去掉,wifi无法连接热点.
      直接在Makefile中注释#ccflags-y += -DSUPPORT_HT40

      • 直接编译不过,发现就是一个头文件的函数:*wsm_get_80211_frame(),没有其他任何地方用,只在/wlan/wsm.h中定义了。
      • 强行注释掉函数:*wsm_get_80211_frame()后,编译通过,系统起来无法扫描,也无法联网。

      解决方法

      正确做法:

      在wlan/main.c中:

      #ifndef SUPPORT_NON_HT40_CHIP
      -                       | IEEE80211_HT_CAP_SUP_WIDTH_20_40
      +                       //| IEEE80211_HT_CAP_SUP_WIDTH_20_40
                              | IEEE80211_HT_CAP_SGI_20
      -                       | IEEE80211_HT_CAP_SGI_40
      +                       //| IEEE80211_HT_CAP_SGI_40
       #endif'''
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329一些正常的I2C报错

      问题背景

      在使用I2C通信的时候,经常会出现一些I2C通信失败的报错,但是呢,有一些报错是正常的,并不会影响到系统或者模块正常工作的。下面就讲述一些常见的I2C正常报错。

      问题分析

      1、当在dts中配置了一些i2c设备,并且在kernel_menuconfig中也选上对应的驱动,但是实际硬件中并没有连接真实的硬件,这就会导致在系统启动时,会有不少的I2C报错打印出来。
      这里以一款触摸屏为例:

      2e6204efa5bd43a2bfb00f2fb46fec22.jfif

      系统启动时触摸屏驱动会多次地使用I2C向触摸屏模块进行通信,但是由于实际硬件没有连接触摸屏,通信是一定会失败的,因此就会打印一大堆通信失败的字眼。这些其实都是正常的,并不会影响到系统正常加载。

      解决办法:

      如果不想要看到这么多错误的打印的话,可以尝试以下几种办法:

      (1)可以修改系统启动时的打印等级,通过命令“cconfigs”跳转到方案的配置目录,然后找到文件env*.cfg(这里*指的是内核版本,若是4.9内核,则配置文件名为env-4.9.cfg,在4.9以前版本的内核中都是这样命名的。只有在5.4内核中,是直接命名为env.cfg)。然后修改参数loglevel,将其值改为0,那么就可以减少很多内核打印了。

      c47f124e26ab4d33b62294eeab79f26e.jfif

      (2)在触摸屏代码中,在probe函数中初始化一些资源后,尽快地调用I2C去读取触摸屏的一些ID号或者是版本号,若读取失败后,就立即退出驱动加载。没必要继续进行其他设置相关的I2C通信。

      2、使用i2c-detect工具检索某个I2C总线哪些地址存在设备时,出现很多错误通信的log信息,可能会令人误以为该I2C总线是有问题的。如下图所示:

      766a08a7151744c5b41eea37c323b396.jfif

      上图命令i2cdetect -y 2的作用是:检索I2C2总线上所有的I2C设备。这里的打印其实都是正常的,检索是通过cpu主动向全部I2C地址读写数据来检测的。可能硬件上一根I2C总线就连接了一个I2C设备,只会占用一个I2C设备地址,那么其他地址都是为空的。自然而然地,与这些空的设备地址通信肯定是失败的,因此也一定会有错误的打印打出来。

      解决办法:

      (1)减少系统内核打印等级,进入内核打印等级修改节点“printk”的目录:

      cd /proc/sys/kernel
      ls
      cat printk
      echo 2 > printk
      一般内核打印等级为4,当输入到printk的值小于4时,即可把大于等于4的打印等级全部关闭。

      (2)使用adb去调试:
      内核打印是通过串口打印出来的,若通过usb连接开发板,通过adb调试进入系统调试界面,adb是不能接收串口打印的,因此自然地看不到内核错误打印。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329蓝牙设备类型分类与过滤方法

      问题背景

      在蓝牙扫描时,有的客户想对扫描到的蓝牙设备类型进行分类,并过滤出想要的设备。

      问题描述

      蓝牙设备类型是怎么分类的?
      用C代码怎么实现蓝牙设备分类的函数?

      问题分析

      蓝牙设备类型也可以称为cod(class of device)。

      93af23f1d70848458147c044a8d803dc.jfif

      Cod的结构如上图,一共有3个byte,其中一共分为4个部分。

      主要分为:

      (1)Service class(服务类型)
      描述此设备有什么功能?Networking?Audio?Telephony?

      (2)Major device class(设备的主类型)
      这个是我们解析需要关注的重要部分,它是用来说描述蓝牙设备的一个大分类。
      比如:Computer、Phone 、Audio/Video、Peripheral等等。
      如果只是想了解到这个蓝牙设备的大致类型,解析到Major device class就可以了。

      (3)Minor device class(设备的子类型)
      对应于每种Major类型下面的子类,从这里更能清楚了解到这个设备。
      比如 Audio/Video这个主类型,它还可以分为Wearable Headset Device、Hands-free Device、Headphones、Loudspeaker。

      对于COD,蓝牙官方网站有更详细的介绍:

      https://www.bluetooth.com/specifications/assigned-numbers/baseband/

      解决办法

      那么用代码应该怎么解析呢?

      在Tina 平台上扫描到设备时是带有class信息的。比如bt_test扫描的结果如下:

      [bt]#scan 1
      [bt]#63.778892: [bt_test_discovery_status_cb:80]:  bt start scanning.
      63.778957: [btmg_gap_bluez_callback:1204]:  Discovery started
      63.951689: [bt_test_dev_add_cb:104]:  address:7C:2A:DB:F9:67:B7,name:Redmi 9,class:5898764,icon:phone,address type:public,rssi:-60
      64.552549: [bt_test_dev_add_cb:104]:  address:E0:DC:FF:E9:34:1E,name:flyBT,class:5898764,icon:phone,address type:public,rssi:-56
      66.288756: [bt_test_dev_add_cb:104]:  address:90:F0:52:69:2F:86,name:houxiaoni,class:5898764,icon:phone,address type:public,rssi:-76
      66.303184: [bt_test_dev_add_cb:104]:  address:00:19:86:00:03:C9,name:PCJIJIANJUN2,class:260,icon:computer,address type:public,rssi:-78
      

      其实icon信息也能看出设备的主类型,这是bluez协议栈处理好的。
      我们直接对class的值按照cod的规则进行解析即可,参考代码:

      只解析主要设备类

      const char *get_device_class_info(uint32_t device_class)
      {
          switch ((device_class & 0x1f00) >> 8) {
          case 0x01:
              return "computer";
          case 0x02:
              return "phone";
          case 0x03:
              return "network-wireless";
          case 0x04:
              return "audio";
          case 0x05:
              return "input-mouse";
          case 0x06:
              return "printer";
      
              break;
          }
      
          return NULL;
      }
      

      解析到次要设备类

      const char *get_device_class_info(uint32_t device_class)
      {
          switch ((device_class & 0x1f00) >> 8) {
          case 0x01:
              return "computer";
          case 0x02:
              switch ((device_class & 0xfc) >> 2) {
              case 0x01:
              case 0x02:
              case 0x03:
              case 0x05:
                  return "phone";
              case 0x04:
                  return "modem";
              }
              break;
          case 0x03:
              return "network-wireless";
          case 0x04:
              switch ((device_class & 0xfc) >> 2) {
              case 0x01:
              case 0x02:
                  return "audio-Headset";    /* Headset */
              case 0x06:
                  return "audio-Headphone";    /* Headphone */
              case 0x0b: /* VCR */
              case 0x0c: /* Video Camera */
              case 0x0d: /* Camcorder */
                  return "camera-video";
              default:
                  return "audio";    /* Other audio device */
              }
              break;
          case 0x05:
              switch ((device_class & 0xc0) >> 6) {
              case 0x00:
                  switch ((device_class & 0x1e) >> 2) {
                  case 0x01:
                  case 0x02:
                      return "input-gaming";
                  }
                  break;
              case 0x01:
                  return "input-keyboard";
              case 0x02:
                  switch ((device_class & 0x1e) >> 2) {
                  case 0x05:
                      return "input-tablet";
                  default:
                      return "input-mouse";
                  }
              }
              break;
          case 0x06:
              if (device_class & 0x80)
                  return "printer";
              if (device_class & 0x20)
                  return "camera-photo";
              break;
          }
      
          return NULL;
      }
      

      代码中没有对所有子设备进行解析,如果以上没有涉及到,请参考蓝牙COD进行解析。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决调用Bluez mainloop_add_fd函数失败的问题?

      问题背景

      Tina系统使用的蓝牙协议栈为开源bluez协议栈,在上层应用开发的时候会常常使用mainloop_add_fd函数,尤其是btmanager中也有很多模块是调用了该函数。

      问题描述

      在使用Tina btmanager ble模块时,启动异常,提示打印"Failed to add listen socket(11),error(-38)",详细如下:

      1607334876.975885: [gatt_run:355]:  ++
      1607334876.976066: [l2cap_le_att_listen:263]:  ++
      1607334876.976208: [l2cap_le_att_listen:296]:  Started listening on ATT channel
      1607334876.976311: [gatt_run:371]:  sockfds 12 13
      1607334876.976820: [gatt_set_bta_mainloop_id:27]:  tid: 3047021836
      1607334876.977276: [gatt_run:373]:  tid 3047021836
      1607334876.977541: [gatt_set_bta_cmd_fd:39]:  gatt_commfds 12 13
      1607334876.977884: [gatt_bta_register_handler:44]:  ++
      1607334876.979351: [gatt_run:383]:  Failed to add listen socket(11),error(-38)
      

      问题分析
      "[gatt_run:383]: Failed to add listen socket(11),error(-38)"该行错误打印,提示的源代码如下:

      ```
      

      ret = mainloop_add_fd(fd, EPOLLIN, server_listen_cb, server, NULL);
      if (ret < 0) {
      BTMG_ERROR("Failed to add listen socket(%d),error(%d)\n",fd,ret);
      close(fd);
      netcfg_state = 0;
      return NULL;
      }

      从上可以判断是调用了mainloop_add_fd函数异常,该函数是链接的开源bluez协议栈中的库,于是搜索了bluez中关于mainloop_add_fd的实现,发现实现该函数有有三处地方,分别是
      
      (1)src/shared/mainloop-ell.c:编入到src/.libs/libshared-ell.a库中。
      
      

      int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
      void *user_data, mainloop_destroy_func destroy)
      {
      return -ENOSYS;
      }

      (2)src/shared/mainloop-glib.c:编入到src/.libs/libshared-glib.a库中。
      
      

      int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
      void *user_data, mainloop_destroy_func destroy)
      {
      return -ENOSYS;
      }

      (3) src/shared/mainloop.c:编入到src/.libs/libshared-mainloop.a库中。
      
      

      int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
      void *user_data, mainloop_destroy_func destroy)
      {
      struct mainloop_data *data;
      struct epoll_event ev;
      int err;
      if (fd < 0 || fd > MAX_MAINLOOP_ENTRIES - 1 || !callback)
      return -EINVAL;
      data = malloc(sizeof(*data));
      if (!data)
      return -ENOMEM;
      memset(data, 0, sizeof(*data));
      data->fd = fd;
      data->events = events;
      data->callback = callback;
      data->destroy = destroy;
      data->user_data = user_data;
      memset(&ev, 0, sizeof(ev));
      ev.events = events;
      ev.data.ptr = data;
      err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, data->fd, &ev);
      if (err < 0) {
      free(data);
      return err;
      }
      mainloop_list[fd] = data;
      return 0;
      }

      而 Failed to add listen socket(11),error(-38)提示-38正好是"-ENOSYS", 在errno.h中有定义
      
      

      #define ENOSYS 38 /* Function not implemented */

      所以排查到是链接的函数不对,应用程序中同时链接了libshared-glib.a和libshared-mainloop.a,最后取用的是libshared-glib.a,应该使用的是libshared-mainloop.a。
      
      **解决办法**
      
      在使用mainloop_add_fd函数的时候,要尤其注意,要链接使用正确的库。使用libshared-mainloop.a而不是libshared-glib.a和libshared-ell.a。
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何正确查看XRADIO相关版本信息?

      问题背景

      硬件:R328+ Wi-Fi模组(XRADIO)
      软件:Tina3.0及以上
      说明:该FAQ旨在记录XRADIO驱动常见的调试Tips。与具体驱动相关,具有一般性。

      问题简述

      在解决客户问题的过程中,多数问题都是因为版本没有对齐导致的,从驱动到firmware再到etf测试工具。

      问题分析

      正确的查看版本信息,客户提交case时减少沟通,有助于问题及时解决。

      解决方法

      1.如何查看驱动版本信息?

      1)启动log查看:

      ======== XRADIO WIFI OPEN ========
      [XRADIO] Driver Label:XR_V02.16.91 _HT40_01.35  Nov 10 2020 07:57:47
      

      2)节点读取:

      cat /sys/kernel/debug/ieee80211/phy0/xradio/version 
      Driver Label:XR_V02.16.91 _HT40_01.35  Nov 10 2020 07:57:47
      

      2.如何查看firmware版本信息?

      1)启动log查看:

      [SBUS] XRadio Device:sdio clk=50000000
      [XRADIO] XRADIO_HW_REV 1.0 detected.
      [XRADIO] Bootloader complete
      [XRADIO] Firmware completed.
      [WSM] Firmware Label:XR_C09.08.52.64_DBG_02.100 2GHZ HT40 Jan  3 2020 13:14:37
      

      2)节点读取:

      cat /sys/kernel/debug/ieee80211/phy0/xradio/version 
      Firmware Label:XR_C09.08.52.64_DBG_02.100 2GHZ HT40 Jan  3 2020 13:14:37
      

      3.如何查看etf的版本信息?

      ETF工具版本:
      系统执行etf命令
      不带参数ETF version: 1.4.1

      etf fw版本:
      系统执行etf connect命令
      [WSM] Firmware Label:ETF_FW_A09.01.0102-HIF; Mar 6 2020, 11:29:47

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何在Linux Device Tree中配置预留内存?

      前言

      有时我们需要在 Linux 内核中预留一部分内存空间用作特殊用途(给安全模块使用,给其它处理器使用,或是给特定的驱动程序使用等),在 Device Tree 中有提供两种方法对预留内存进行配置:memreserve 和 reserved-memory。

      memreserve

      memreserve 的使用方法比较简单,如下所示,会将从地址 0x40000000 开始共 1MB 的内存空间预留出来:

      /memreserve/ 0x40000000 0x00100000;
      

      使用 memreserve 预留出来的内存一般无法再被 Linux 系统使用(当然,也可以通过特殊方法让代码固定访问该地址,但这种并非标准用法,在此不展开描述)。

      reserved-memory

      reserved-memory 框架提供了更多样的使用方法,并且与内核的 DMA API 和 CMA 框架紧密联系。

      推荐先阅读一下内核自带的文档 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt,里面有其详细的语法说明和注意事项(例如 reserved-memory 节点中的 #address-cells 和 #size-cells 的值需要与根节点的保持一致)。

      下面对几种常见的使用方法进行举例说明:

      通过 memremap/ioremap 来使用
      在 Device Tree 配置如下,然后通过“memory-region”参数可将该预留内存分配给特定的设备驱动使用:

      reserved-memory {
         #address-cells = <2>;
         #size-cells = <2>;
         ranges;
       
         foobar_reserved: foobar@70000000 {
            no-map;
            reg = <0x0 0x70000000 0x0 0x10000000>;
         };
      };
       
      foobar_driver: foobar_driver@0 {
         memory-region = <&foobar_reserved>;
      };
      

      在设备驱动程序中,可解析 Device Tree 节点获得预留内存的物理地址和大小,然后通过 memremap/ioremap 映射这片内存空间来使用:

      /* Get reserved memory region from Device-tree */
      np = of_parse_phandle(dev->of_node, "memory-region", 0);
      if (!np) {
        dev_err(dev, "No %s specified\n", "memory-region");
        goto error1;
      }
        
      rc = of_address_to_resource(np, 0, &r);
      if (rc) {
        dev_err(dev, "No memory address assigned to the region\n");
        goto error1;
      }
        
      lp->paddr = r.start;
      lp->vaddr = memremap(r.start, resource_size(&r), MEMREMAP_WB);
      dev_info(dev, "Allocated reserved memory, vaddr: 0x%0llX, paddr: 0x%0llX\n", (u64)lp->vaddr, lp->paddr);
      

      通过 DMA API 来使用

      设置“shared-dma-pool”属性后,可让设备驱动通过 DMA API 来使用预留内存:

      reserved-memory {
         #address-cells = <2>;
         #size-cells = <2>;
         ranges;
       
         foobar_reserved: foobar@70000000 {
            compatible = "shared-dma-pool";
            no-map;
            reg = <0x0 0x70000000 0x0 0x10000000>;
         };
      };
       
      foobar_driver: foobar_driver@0 {
         memory-region = <&foobar_reserved>;
      };
      

      设备驱动程序中可类似常规地使用 DMA API,它申请的内存不是来源于默认的 CMA 内存池,而是来源于该预留内存:

      /* Initialize reserved memory resources */
        rc = of_reserved_mem_device_init(dev);
        if(rc) {
          dev_err(dev, "Could not get reserved memory\n");
          goto error1;
        }
        
        /* Allocate memory */
        dma_set_coherent_mask(dev, 0xFFFFFFFF);
        lp->vaddr = dma_alloc_coherent(dev, ALLOC_SIZE, &lp->paddr, GFP_KERNEL);
        dev_info(dev, "Allocated coherent memory, vaddr: 0x%0llX, paddr: 0x%0llX\n", (u64)lp->vaddr, lp->paddr);
      

      给 CMA 预留内存

      有时我们不需要将预留内存分配给特定的设备驱动,而只是想给默认 CMA 内存池分配一片固定的内存区域,这时我们可配置上“reusable”和“linux,cma-default”:

      reserved-memory {
            #address-cells = <2>;
            #size-cells = <2>;
            ranges;
        
            linux,cma {
               compatible = "shared-dma-pool";
               reusable;
               reg = <0x0 0x70000000 0x0 0x10000000>;
               linux,cma-default;
            };
         };
      

      由此可见,不同于 memreserve,通过 reserved-memory 预留的内存有可能进入系统 CMA,这需要满足以下几个条件:

      • compatible 需要为“shared-dma-pool”
      • 没有定义“no-map”属性
      • 定义了“reusable”属性
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329以太网常用调试说明

      需求背景

      硬件:R329+ RTL8211F
      软件:Tina3.0及以上

      需求说明

      对于单phy的平台以太网技术已经很成熟,这里提供一些以太网常用的调试方法。帮助客户快速定位常见问题。

      常用命令

      ifconfig eth0 up        打开eth0 网卡
      ifconfig eth0 down      关闭eth0 网卡
      ifconfig eth0 promisc   设置网卡eth0为混杂模式
      ifconfig eth0 -promisc  取消网卡eth0的混杂模式
      ifconfig eth0 192.168.1.100   设置ip地址
      ifconfig eth0 hw ether 4A:13:E4:F9:79:74   设置mac地址
      ifconfig eth0 192.168.1.100  设置静态ip地址
      udhcpc -i eth0         动态获取ip地址
      

      代码路径

      内核代码

      gmac代码:
      drivers/net/ethernet/allwinner/
      sunxi-gmac.c  sunxi_gmac_ops.c
      phy代码:(一般用内核generic的代码)
      linux-4.9/drivers/net/phy
      phy.c phy_device.c mdio_bus.c ...
      

      配置代码

      linux-4.9的适配
      board.dts
       730                 gmac0: eth@05020000 {
       731                         phy-rst = <&r_pio PH 19 1 1 1 0>;
       732                         use_ephy25m = <1>;
       733                         phy-mode = "rgmii";
       734                         tx-delay = <7>;
       735                         rx-delay = <0>;
       736                         status   = "okay";
       737                 };
      

      调试工具

      1.ethtool

      ethtool -s eth0 speed 1000 duplex full autoneg on  //设置1000M全双工自适应
      

      2.brctl

      root@TinaLinux:/# brctl --help
      BusyBox v1.27.2 () multi-call binary.
      
      Usage: brctl COMMAND [BRIDGE [INTERFACE]]
      
      Manage ethernet bridges
      
      Commands:
              show                    Show a list of bridges
              addbr BRIDGE            Create BRIDGE
              delbr BRIDGE            Delete BRIDGE
              addif BRIDGE IFACE      Add IFACE to BRIDGE
              delif BRIDGE IFACE      Delete IFACE from BRIDGE
              setageing BRIDGE TIME           Set ageing time
              setfd BRIDGE TIME               Set bridge forward delay
              sethello BRIDGE TIME            Set hello time
              setmaxage BRIDGE TIME           Set max message age
              setpathcost BRIDGE COST         Set path cost
              setportprio BRIDGE PRIO         Set port priority
              setbridgeprio BRIDGE PRIO       Set bridge priority
              stp BRIDGE [1/yes/on|0/no/off]  STP on/off
      root@TinaLinux:/# brctl addif br-lan eth0
      [ 4312.718522] br-lan: port 1(eth0) entered blocking state
      [ 4312.724433] br-lan: port 1(eth0) entered disabled state
      [ 4312.730790] device eth0 entered promiscuous mode
      
      root@TinaLinux:/# brctl delif br-lan eth0
      [ 4270.518067] device eth0 left promiscuous mode
      [ 4270.523335] br-lan: port 1(eth0) entered disabled state
      

      eth0加入和移除网桥时都会有混杂模式的打印
      br-lan网桥的配置

      > Networking support > Networking options
      		<*> 802.1d Ethernet Bridging    //CONFIG_BRIDGE=y
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列如何解决gpio-keys驱动在系统启动上报两次input事件?

      问题背景

      硬件:R系列板子
      软件:Tina3.5

      问题简述

      在Tina全部版本中,选用gpio-keys驱动,在系统上电时从log信息发现gpio-keys驱动自动上报了两次按键弹起的input事件。

      问题分析

      上报两次input事件的原因一共有两个,分别如下所示:

      1.由中断状态机误报一次中断。在gpio-keys驱动在初始化时,设置了软件上拉GPIO(或者是在硬件中上拉),对于中断状态机来说,外部GPIO已经是属于高电平了。在request_irq时,中断检测电路开始初始化,当前中断状态机的移位寄存器为0000(PS:中断检测电路用4bit来表示当前的中断触发方式,比如说0000认为外部是低电平,触发低电平中断)。

      当GPIO的功能寄存器设置为中断功能,中断状态机开始移位检测。因为当前GPIO为高电平,两个CLK时钟周期后,中断状态机的移位寄存器会出现0011的情况,这时候,即使未出现上升沿,也会认为触发了一次上升沿中断。

      这是中断误报属于硬件寄存器的问题,无法取消,只能规避。不过这个只会误报一次,后续驱动正常工作下不会再次误报的。除非设置改GPIO的复用功能为非中断功能,然后再设置GPIO为中断功能,这时候中断状态机又会重新初始化和误报一次中断。

      解决方法:

      • 在配置GPIO复用功能之后,等待一段时间,清一遍pending,去除第一次误触发中断。另外,在使用过程中,不要动态切换GPIO的复用功能。
      • 在gpio-keys驱动中,定义一些变量,强行让中断处理函数不去处理第一次中断事件。

      2.由gpio-keys的gpio_keys_open()函数上报的:

      static int gpio_keys_open(struct input_dev *input)
      {
              struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
              const struct gpio_keys_platform_data *pdata = ddata->pdata;
              int error;
      
              if (pdata->enable) {
                      error = pdata->enable(input->dev.parent);
                      if (error)
                              return error;
              }
      
              /* Report current state of buttons that are connected to GPIOs */
              gpio_keys_report_state(ddata);
      
              return 0;
      }
      

      gpio_keys_open()函数最终调用gpio_keys_report_state()函数来上报按键当前状态。在驱动probe函数和resume函数都会运行该函数。

      这个函数是否需要运行主要取决于应用层的工作逻辑,不想在probe或者resume上报当前按键状态的话,也可以在代码中注释掉该函数。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决在Audiocodec使用S24_LE格式进行录音时产生的软件分析波形异常问题?

      问题背景

      硬件:R329
      软件:Tina
      内核:Linux-4.9

      问题描述

      使用Audiocodec进行录音,格式S24_LE,录制的.wav波形在某些软件中异常

      arecord -D hw:audiocodec -f S24_LE -r 16000 -c 2 -d10 /tmp/test3_S24_LE.wav
      

      d65d357edb0842cb9d54148ed1c5e0b3.jpg
      需要放大很多倍才能看到声音波形

      3cddc50a8f214d7380305433df378993.jfif

      问题分析

      1.R329的Audiocodec用于录音的ADC只支持16bit和20bit的采样精度。采样后的数字信号会存放到RX_FIFO中,RX_FIFO的大小为256*20-bit,其他平台可以在User Manual确认支持的采样精度,从而判断是否会有这个问题产生

      4570bdb36f594591b6ec4c71310e5fe7.jfif

      2.RX_DATA是一个32位的寄存器,保存的是从RX_FIFO获取的一个channel的样本数据,当使用arecord进行录音时,RX_DATA中的值会经DMA搬至内存,最后保存到.wav中

      5c2c17d228f944fd8a4a6e8d1924e778.jfif

      其中RX_DATA有四种模式去获取RX_FIFO的数据,S24_LE和S32_LE均采用20-bit mode0

      6972b81f741b4bf9829ecb814f5dbb7a.jfif

      当设置了20bit采样精度时,对应的两种模式如下图所示:

      8b502f06666046368fafccf0d13eee46.jfif

      3.先说明一下S24_LE和S32_LE这两种格式的区别

      S24_LE指有符号整型,范围是-2^23 ~ ((2^23) - 1),有效数据在低24位
      S32_LE指有符号整型,范围是-2^31 ~ ((2^31) - 1),有效数据在高24位

      LSB                           MSB
               1st byte  2nd byte  3rd byte  4th byte   alignment
      S32_LE:   00000000  xxxxxxxx  xxxxxxxx  xxxxxxxx   32 bits
      S24_LE:   xxxxxxxx  xxxxxxxx  xxxxxxxx  00000000   32 bits
      S24_3LE:  xxxxxxxx  xxxxxxxx  xxxxxxxx             24 bits
      

      4.在驱动程序中,S24_LE和S32_LE虽然都支持,但他们两者都是使用20-bit的mode0,这导致这两种格式保存到文件中的数据排布是一致的,但生成的wav头信息中的采样位数则不一样,从下图可以看出两者的差异

      S32_LE的wav文件信息:

      b782fd998a1a42bfafb6a46a3362d79b.jfif

      若软件以S32_LE进行解析,以上红框的数据变为0x0f80f0,依然可以保留全部有效数据

      5de38b0c26a346a2bd0cc517b1cb6485.jfif

      S24_LE的wav文件信息:

      561fc954670c4a7e8f5c122acd788689.jfif

      若软件以S24_LE进行解析,以上红框的数据变为0x55f000,便会丢失一部分数据

      a185f006bee4483ebb53b3835c4053dc.jfif

      解决方案

      总结原因就是audiocodec的采样精度只支持16和20bit,因此PCM格式中S24_LE虽然也支持,但硬件的特性使驱动并不能做到很好的适配,若软件以标准S24_LE格式进行分析,则会丢失高位的有效数据,这取决于软件如何对数据进行分析,解决方法有以下三种

      • 使用audiocodec时,使用-f S32_LE,修改wav头信息中的采样位数位32,这对大部分软件都有效
      arecord -D hw:-f S32_LE -r 16000 -c 2 -d10 /tmp/test32.wav
      
      • 如果必须使用S24_LE格式进行录音,可以选择其他支持24bit采样的音频接口,如I2S等
      • 假如必须使用audiocodec声卡,S24_LE格式进行录音,可以自行调整RX_DATA寄存器的模式,结合RX_DATA寄存器中实际的有效数据分布,自己开发软件进行数据分析
        如果有分析和处理音频数据的需求,可以参考以上思路,结合RX_DATA寄存器去调整
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329Tina网络adb的使用

      问题背景

      硬件:R328+ Wi-Fi模组(RTL8723ds)
      软件:Tina3.0及以上
      说明:该FAQ旨在记录网络adb的使用

      问题简述

      客户整机已经封板,没法使用usb的adb和串口,客户提出是否有其他方式可以和板子交互。

      问题分析

      usb的adb和串口都没法使用,即有线方式无法使用了,那就只能是无线方式了,所以就想到了网络adb。

      使用网络adb还有一个好处就是多台设备压测时,省去了布线的操作。

      解决方法

      1.系统配置adb。

      46bc94b70413405d975d632d1cef157b.jfif

      2.将如下命令添加到自启动脚本中,一般选择/etc/init.d/local
      临时使用也可以直接在板卡执行。(一般串口只有一个时又要测试多台可以这样操作)

      killall adbd    //杀死adbd进程。
      export ADB_TRANSPORT_PORT=5555   //重新设置adbd的端口
      ./bin/adbd -D > /dev/null &   //重启adbd进程
      

      3.系统起来后联网并产看ip地址。

      4.pc执行:

      1.adb disconnect //断开所有连接
      2.adb connect ip  //和板子建立连接,ip为板子联网的之后获取的ip地址
      3.adb shell  //进入板子shell
      

      此时进入的shell就跟usb使用的adb shell一样。

      下面是我整理的一个常用网络adb做测试的简单脚本,也供大家参考

      for %%i in (110,111,112,113,167,168)   //使用自己测试板卡的ip地址
      do
          adb disconncect
          adb connect 192.168.1.%%i
          adb shell dmesg
          adb shell ...  //添加任何自己想做的操作
      done
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何利用wpa_cli设置地区代码?

      问题背景

      硬件:R328+ Wi-Fi模组(XRADIO)
      软件:Tina3.0及以上
      说明:该FAQ旨在记录XRADIO驱动常见的调试Tips。与具体驱动相关,具有一般性。

      问题简述

      客户需求,如何获取和设置地区代码?

      问题分析

      地区码:表示现有的国家、独立机构或特殊地理政治区域的名称代码。

      区别于

      移动网络代码:是与移动设备国家代码(Mobile Country Code,MCC)(也称为“MCC / MNC”)相结合,以用来表示唯一一个的移动设备的网络运营商。这些运营商可以是使用的GSM/LTE、CDMA、iDEN、TETRA和通用移动通讯系统的公共陆基移动网亦或是卫星网络。

      当前xr829驱动并没有透出接口用来获取和设置地区代码。

      解决方法

      借用wpa_cli工具来获取和设置:

      root@TinaLinux:/# wpa_cli -i wlan0 -p /etc/wifi/sockets set country US
      OK
      root@TinaLinux:/# wpa_cli -i wlan0 -p /etc/wifi/sockets get country
      US
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决蓝牙设备断开慢的问题?

      问题背景

      蓝牙设备主动断开连接,主控端20s后才收到断开消息,时间过长。

      问题描述

      • 已连接的蓝牙耳机设备关机了,没及时收到断开的回调,无法播放音乐。
      • 已连接的蓝牙打印机关机了,没收到断开的消息,继续打印,数据发送失败。

      问题分析

      此问题涉及到一个概念:Link supervision timeout。
      每个物理链路都有一个timer用于链接监测,link supervision timeout就是timer的超时时间。
      蓝牙Controller使用link supervision timeout监测连接是否丢失了。一般以下的这种情况link supervision timeout会发挥作用:

      • 设备连接超出范围或者被干扰导致物理链接丢失。
      • 设备掉电引起的物理链接丢失。

      link supervision timeout 一般是双方设备协商的,一般默认为20s。
      如果觉得20s时间太长,可以主动去调整link supervision timeout。

      解决办法

      当蓝牙为master设备时,可以修改link supervision timeout。
      Tina平台,可以调用btmanager的API去调整:

      int bt_manager_set_link_supervision_timeout(const char *addr, int slots) ;
      其中addr是对端蓝牙设备的mac地址,slots为超时时间,单位为0.625ms,实际的超时时间为: slots * 0.625ms。
      

      需要注意,需要在设备已连接的状态去设置,否则无效,同时设备断开连接之后也会失效。
      所以如果要设置,则每次连接成功之后需要设置一次。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决无法将wlan0加到br-lan这个网桥上面的问题?

      问题背景

      硬件:R329+ Wi-Fi模组(RTL8723ds)
      软件:Tina3.0及以上
      操作:无线wlan0桥接到有线eth0

      问题简述

      将wlan0添加到br-lan这个网桥里面,但是加不进去,提示brctl: bridge br-lan: Operation not supported。

      root@TinaLinux:/# brctl addif br-lan wlan0
      brctl: bridge br-lan: Operation not supported
      root@TinaLinux:/# brctl show
      bridge name bridge id STP enabled interfaces
      br-lan 7fff.fe2bf4a14158 no eth0
      usb0
      

      问题分析

      需求:usb dongle盒子, 该盒子只有一个hdmi口和usb口(无电源线、无网口),usb口兼具供电和上网的功能。r329这边配置usb网口,将usb dongle盒子的usb口插到r329上面,r329生成usb0网卡,此时只要能将usb0和wlan0添加到一个网桥下,那么usb dongle盒子就能直接通过r329连接的wifi获取到ip并上网了。

      分析:当设备为client或者adhoc以及wds时,对应的无线接口是无法加入到桥接中去的。
      执行root@TinaLinux:/# brctl addif br-lan wlan0
      brctl: bridge br-lan: Operation not supported

      通过报错信息目前跟踪到:

      tina-r329/lichee/linux-4.9/net/bridge/br_if.c +513
      511 /* No bridging devices that dislike that (e.g. wireless) */
      512 if (dev->priv_flags & IFF_DONT_BRIDGE)
      513 return -EOPNOTSUPP;
      

      可以发现是不支持桥接的标志导致的。

      解决办法

      直接把 tina-r329/lichee/linux-4.9/net/bridge/br_if.c +513

      @511 /* No bridging devices that dislike that (e.g. wireless) */
      512 if (dev->priv_flags & IFF_DONT_BRIDGE)
      513 return -EOPNOTSUPP;@
      

      这个判断取消掉后可以执行桥接的命令
      在kernel下打上附件的patch后,按照如下流程测试正常。

      1.R329_V1 wifi无线连接到ap route1.(可以不获取ip地址)

      2.R329_v1 上执行桥接:

      brctl addbr br-lan //添加一个br-lan网桥
      brctl addif br-lan wlan0 //把wlan0添加到br-lan网桥
      brctl addif br-lan eth0 //把eth0添加到br-lan网桥
      

      3.R329_V1和R329_v2通过有线连接RGMI(吉比特接口)接口.

      4.R329_V1获取ip地址: udhcpc -i br-lan

      验证:R329_V2能正常上网。ping www.baidu.com

      注:具体模组之间可能存在差异,请咨询wifi原厂协助。

      桥接命令正常.png

      附件: 0001-network-bridge-test.patch

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决RTL驱动hostap启动失败的问题?

      问题背景

      硬件:R328系列公板+ Wi-Fi模组(RTL8723ds)
      软件:Tina3.0及以上

      问题简述

      执行hostapd报错提示:wlan0: IEEE 802.11 Configured channel (13) not found from the channel list of current mode (1) IEEE 802.11g
      操作log:
      
      Configuration file: /etc/wifi/hostapd.conf
      wlan0: IEEE 802.11 Configured channel (13) not found from the channel list of current mode (1) IEEE 802.11g
      wlan0: IEEE 802.11 Hardware does not support configured channel
      Could not select hw_mode and channel. (-3)
      wlan0: interface state UNINITIALIZED->DISABLED
      wlan0: AP-DISABLED 
      wlan0: Unable to setup interface.
      wlan0: interface state DISABLED->DISABLED
      wlan0: AP-DISABLED 
      hostapd_free_hapd_data: Interface wlan0 wasn't started
      nl80211: deinit ifname=wlan0 disabled_11b_rates=0
      

      问题分析

      hostapd启动失败,第一反应是配置文件配的不对,从hostapd的启动日志或许能看出点猫腻。从log看很明显,不支持channel 13。

      1.第一反应是网卡国家码不对

      iw reg get查看国家码是US,确实不支持13信道。重新配置网卡国家码为CN:iw reg set CN,配置失败,设置后会重新变回US,看来网卡驱动的配置是以环境的AP来配置国家码的。

      重新设置网卡的WCNSS_qcom_cfg.ini文件以支持手动配置国家码,并强制关闭环境AP的配置:

      gStaCountryCode=CN    //默认sta的国家码为CN
      gAPCntryCode=CN       //默认AP的国家码为CN
      g11dSupportEnabled=0  //关闭国家码从环境获取
      

      好了,国家码能正常设置了,但是启动hostapd还是直接退出了,报错还是不支持13信道。

      2.没办法,就去看了一下hostapd报错的位置的代码

      static int hostapd_is_usable_chans(struct hostapd_iface *iface)
      {
             if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1)) 
                    return 0;
      
             if (!iface->conf->secondary_channel)
                    return 1;
      
             return hostapd_is_usable_chan(iface, iface->conf->channel +
                                        iface->conf->secondary_channel * 4, 0); 
      }
      

      原来,配置文件中指定的启动HT40[即信道带宽是40MHz]时,要求辅信道也必须在支持的信道内。HT40+是指辅信道是主信道+4,17信道是不支持的,因此配置失败了。

      同样,5G信道也有一些配置是不允许的,于是使用RTL8821cs测试

      5G时设置hostapd失败打印:

      I/hostapd (  661): wlan0: interface state UNINITIALIZED->HT_SCAN
      E/hostapd (  661): HT40 channel pair (153, 1) not allowed
      I/hostapd (  661): Fallback to 20 MHz
      E/hostapd (  661): Interface initialization failed
      I/hostapd (  661): wlan0: interface state HT_SCAN->DISABLED
      I/hostapd (  661): wlan0: AP-DISABLED 
      E/hostapd (  661): hostapd_free_hapd_data: Interface wlan0 wasn't started
      

      而代码中指定要求5G时hostapd的信道只能有以下几个:

      int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
                        149, 157, 184, 192 };
      

      解决办法

      修改驱动配置即可:

      drivers/net/wireless/rtl8723ds/Makefile
      CONFIG_RTW_CHPLAN=0x23
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何通过uboot修改设备树属性?

      问题背景

      硬件:R328+ Wi-Fi模组(XRADIO)
      软件:Tina3.0及以上

      问题简述

      有时候经常需要临时调整部份设备树的属性配置,例如sdc的频率,以太网的delay参数。如果每次都源码修改后编译烧写,比较费时,所以uboot提供了临时修改的方法。
      注:uboot修改都是单次启动有效,重启无效。

      问题分析

      1.修改sdc的属性

      产看当前sdc的配置

      => fdt print /soc/sdmmc@4021000
      sdmmc@4021000 {
              compatible = "allwinner,sunxi-mmc-v5p3x";
              device_type = "sdc1";
              reg = <0x00000000 0x04021000 0x00000000 0x00001000>;
              interrupts = <0x00000000 0x00000029 0x00000004>;
              clocks = <0x0000000c 0x00000002 0x00000005 0x00000002 0x0000003a 0x00000002 0x0000003d>;
              clock-names = "osc24m", "pll_periph", "mmc", "ahb";
              resets = <0x00000002 0x00000010>;
              reset-names = "rst";
              pinctrl-names = "default", "sleep";
              pinctrl-0 = <0x00000022>;
              pinctrl-1 = <0x00000023>;
              max-frequency = <0x08f0d180>;
              bus-width = <0x00000004>;
              cap-sd-highspeed;
              no-mmc;
              keep-power-in-suspend;
              sunxi-dly-52M-ddr4 = <0x00000001 0x00000000 0x00000000 0x00000000 0x00000002>;
              sunxi-dly-104M = <0x00000001 0x00000000 0x00000000 0x00000000 0x00000001>;
              sunxi-dly-208M = <0x00000001 0x00000000 0x00000000 0x00000000 0x00000001>;
              status = "okay";
              no-sd;
              cap-sdio-irq;
              ignore-pm-notify;
              ctl-spec-caps = <0x00000008>;
      };
      

      修改sdc的最大支持频率

      25M
      fdt set /soc/sdmmc@04021000 max-frequency <0x017d7840>
      50M
      fdt set /soc/sdmmc@04021000 max-frequency <0x02faf080>
      100M
      fdt set /soc/sdmmc@04021000 max-frequency <0x05f5e100>
      120M
      fdt set /soc/sdmmc@04021000 max-frequency <0x07270e00>
      150M
      fdt set /soc/sdmmc@04021000 max-frequency <0x08f0d180>
      

      修改相位

      fdt set /soc/sdmmc@04021000 sunxi-dly-208M <0x00000001 0x00000000 0x00000000 0x00000000 0x00000000 0x00000001>
      

      2.修改以太网的属性

      打印当前以太网的配置

      => fdt print /soc/eth@4500000
      eth@4500000 {
              compatible = "allwinner,sunxi-gmac";
              reg = <0x00000000 0x04500000 0x00000000 0x00010000 0x00000000 0x03000030 0x00000000 0x00000004>;
              interrupts = <0x00000000 0x0000002e 0x00000004>;
              interrupt-names = "gmacirq";
              clocks = <0x00000002 0x00000050 0x00000002 0x0000004f>;
              clock-names = "gmac", "ephy";
              resets = <0x00000002 0x00000020>;
              device_type = "gmac0";
              gmac-power0;
              gmac-power1;
              gmac-power2;
              status = "okay";
              phy-mode = "rgmii";
              use_ephy25m = <0x00000001>;
              pinctrl-0 = <0x00000019>;
              pinctrl-1 = <0x0000001a>;
              pinctrl-names = "default", "sleep";
              tx-delay = <0x00000003>;
              rx-delay = <0x00000005>;
      };
      

      修改delay 参数

      fdt set /soc/eth@4500000 rx-delay  <0x0000000a>
      

      注:这里只是简单介绍uboot的命令,具体设备属性的解释就不展开说明了。

      解决办法

      uboot常用命令
      fdt

      => fdt -h
      fdt - flattened device tree utility commands
      
      Usage:
      fdt addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>
      fdt apply <addr>                    - Apply overlay to the DT
      fdt boardsetup                      - Do board-specific set up
      fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active
      fdt resize [<extrasize>]            - Resize fdt to size + padding to 4k addr + some optional <extrasize> if needed
      fdt print  <path> [<prop>]          - Recursive print starting at <path>
      fdt list   <path> [<prop>]          - Print one level starting at <path>
      fdt get value <var> <path> <prop>   - Get <property> and store in <var>
      fdt get name <var> <path> <index>   - Get name of node <index> and store in <var>
      fdt get addr <var> <path> <prop>    - Get start address of <property> and store in <var>
      fdt get size <var> <path> [<prop>]  - Get size of [<property>] or num nodes and store in <var>
      fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]
      fdt mknode <path> <node>            - Create a new node after <path>
      fdt rm     <path> [<prop>]          - Delete the node or <property>
      fdt header                          - Display header info
      fdt bootcpu <id>                    - Set boot cpuid
      fdt memory <addr> <size>            - Add/Update memory node
      fdt rsvmem print                    - Show current mem reserves
      fdt rsvmem add <addr> <size>        - Add a mem reserve
      fdt rsvmem delete <index>           - Delete a mem reserves
      fdt chosen [<start> <end>]          - Add/update the /chosen branch in the tree
                                            <start>/<end> - initrd start/end addr
      
      printenv:打印环境变量
      setenv:设置环境变量
      saveenv:保存设置的环境变量
      md:显示内存区的内容
      mm:修改内存
      cmp:比较两块内存
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列如何在Tina下使用bootchartd来分析rootfs启动时间?

      问题背景

      硬件: R818
      软件: Tina2.5及以上
      操作: bootchart工具打开后无法开机。
      说明: 客户程序较复杂,系统应用起来时间有25秒,需要优化。bootchart无使用说明。

      问题简述

      Tina整体启动时间中rootfs占用的比重很大,但是rootfs启动过程中log很多,在自启动脚本中也添加不了打印,造成启动时间统计非常不便。

      Tina SDK有集成busybox bootchart工具,可使用该工具分析rootfs启动过程各个进程的启动时刻以及耗费时间等信息,可以让用户分析启动过程并进行针对性优化。

      解决办法

      该方法支持Tina所有方案。

      Tina上开启bootchartd方法:
      ① make menuconfig,打开CONFIG_BUSYBOX_CONFIG_BOOTCHARTD
      ② 修改文件env-x.x.cfg,将“init=/sbin/init”修改为“init=/sbin/bootchartd”
      ③ 编译,烧写固件,设备启动后,等待一段时间(1min左右),直到出现/var/log/bootlog.tgz,使用adb pull将该文件拉到PC端。
      ④ 在PC端解压附件工具bootchart.tar.xz,运行命令“./bootchart/pybootchartgui.py bootlog.tgz”,生成bootchart.png图片,打开可得系统各进程的启动时间。

      bootchart.png图片分析

      bootchart.png效果如下图所示,图中横坐标是时间,纵坐标是各进程信息。图上方两条是CPU和I/O的使用情况;下方是各个进程的运行状态,包含各个进程开始执行时间与结束时间,进程条上有颜色信息,表示对CPU、I/O的占用情况。

      e076818e05064a89b48968ee2e674996.jfif

      优化思路:

      • 将主应用程序一起主应用依赖的程序提前执行,其他程序延后执行。
      • 调整进程启动顺序,使CPU、I/O不要太高,避免竞争产生等待。

      附件:bootchart.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 「免费申请」基于安谋科技STAR-C1的全志XR806 IoT开发板试用活动

      基于安谋科技STAR-C1的全志XR806 IoT开发板免费试用

      111111111.png

      为了让极术社区开发者体验搭载安谋科技STAR-MC1处理器的面向IoT领域的全志XR806开发板,极术社区联合全志在线开发者社区共同推出XR806开发板免费试用活动。

      XR806开发板支持WiFi和BLE,集成度高,硬件设计简单、BOM成本低、安全可靠等,同时它也支持鸿蒙L0系统,适合很多领域内的无线连接需求。同时它开放了硬件设计资料。更多产品介绍,教程等可以查看 全志XR806开发板产品介绍/资料下载/教程/应用等汇总或查看全志XR806在线文档了解。

      如何申请XR806开发板?

      1.直接点击报名参与按钮,提交申请表,申请会在一周内审核。
      2.提交申请通过后会邮件发送注意事项给到开发者,同时邮寄开发板。
      3.收到开发板一个月内,需要在极术社区和全志在线开发者社区发布基于XR806的应用文章(不包含开箱体验及基础烧录,点灯类体验文章),完成发文任务的极术社区会邮寄相应礼品。
      4.未按规定完成任务的会收回开发板。

      活动时间:2021-11-29 周一 12:00 ~ 2021-12-29 周三 08:00
      活动报名链接:https://aijishu.com/e/1120000000256667

      开发过程中,遇到任何问题,欢迎访问全志在线开发者社区发帖咨询及加入XR806活动交流群,有任何问题也可以直接在微信群里咨询。

      如想直接购买XR806开发板,请关注
      https://item.taobao.com/item.htm?spm=a230r.1.14.18.3b4d27e1qyZGnT&id=655130156742&ns=1&abbucket=10#detail

      发布在 Wireless & Analog Series
      q1215200171
      budbool
    • 回复: 【单板仅需99】D1哪吒计算条上线!为智能家居提供高性价比的RISC-V算力

      @jordonwu 86盒据说要等到12初,多留意论坛消息😁

      发布在 MR Series
      q1215200171
      budbool
    • 回复: 【单板仅需99】D1哪吒计算条上线!为智能家居提供高性价比的RISC-V算力

      @molin2050 你看最后一个他像不像已经成型的产品😀

      发布在 MR Series
      q1215200171
      budbool
    • 【单板仅需99】D1哪吒计算条上线!为智能家居提供高性价比的RISC-V算力

      喜加一!喜加一!D1哪吒大家庭成员数量喜加一!

      此前预告的三款新品当中的第一款产品今日正式发布!

      预告3.png
      (剩下两款新品也会在近期陆续发布)

      为了进一步展现哪吒D1的优秀RISC-V算力和丰富的功能,矽速科技(Sipeed)与全志在线推出了搭载D1芯片的全新产品:D1哪吒计算条

      1.png

      D1哪吒计算条(D1 Nezha Compute Modul)是矽速科技(Sipeed)基于全志D1芯片定制的AIoT计算模块,通过插卡式模块化的设计将全志D1芯片的优秀RISC-V算力和丰富的功能赋能到底板/设备上。可以应用于模块化AIoT产品开发生产。

      D1哪吒计算条将以普及型价格推广RISC-V生态,目标是让RISC-V开发不再困难。

      购买链接:淘宝D1哪吒计算条直通车

      参数特性

      D1哪吒计算条搭载全志D1主控芯片(基于平头哥玄铁C906处理器),512MB DDR3内存,可选启动介质为TF卡或者SD NAND芯片,并使用两组M.2B-KEY 67 Pin金手指引出所有IO,方便量产使用,也方便维修替换。
      2.png

      规格参数

      • 主控芯片:全志D1 C906 RISC-V 1.0GHz+
      • DRAM:512MB DDR3
      • 存储介质:TF卡或者SD NAND芯片
      • 外扩显示:支持1.14寸磁吸SPI显示屏(选配)
      • USB接口:板载Type-C OTG*1
      • 调试接口:系统串口,4 Pin 2.54插针
      • 连接器接口:两组M.2B - KEY 67Pin金手指
      • 系统支持:Tina Linux
      • 电源输入:5V±0.5V@500mA
      • 尺寸:46.2mm*25.0mm
      • 外设接口:HDMI输出,MIPI-DSI,RGB/MCU屏,RGMI,AUDIO,SDIO,GPIO等

      同时D1哪吒计算条本身提供了OTG USB调试口和UART调试串口,可选配SPI LCD作为初级显示设备,计算条可独立运行,开发者可以无需底板单独使用该核心模块进行基础RISC-V系统开发,也可以通过底板将D1哪吒计算条的算力赋能到自己的设计的产品上。

      Lichee RV - 86

      为了使得D1哪吒计算条可以更好的满足智能家居-86盒开发等产品项目预等需求,Sipeed为D1哪吒计算条配备了Lichee RV - 86模组。

      小文哥科普:

      86盒,即我们家居中常常看到的墙上照明灯开关和插座,根据国家行业标准的规定,其尺寸为86mm*86mm,所以被称之为86盒。

      在装修时,装修公司墙上的槽位会按照8686mm的尺寸来预留,而电气设备公司在设计开关座和插孔座的时候,也按照8686mm的尺寸来设计,这样我们在市面上任意买到的开关盒就都能装到家中预留的槽位上。

      640.webp

      因其广泛性和普适性,86盒的智能化升级,被认为是智能家居的下一个机会点:通过可以联网的触摸屏,可以可视化控制全屋家电,进行开关灯、温度调节等操作;通过麦克风阵列,可以对家电进行语音控制;通过摄像头,可以远程监控家中的情况 ……

      智能86盒或将成为和智能音箱一样的智能家居重要控制入口。

      62E9EF6D-C485-4dd8-A9F3-AB3D42D9F018.png
      常见智能家居86盒

      Lichee RV - 86是与Lichee RV - NeZha CM配套的智能家居中控开发套件,支持WAFT(WebAssembly Framework for Things)开发环境。WAFT是一个面向AIoT的高性能应用研发框架,WAFT基于WebAssembly和自研的渲染引擎技术打造,适用于智能终端的软件应用研发场景,支持动态化AOT运行模式,能接近原生应用体验,可在非常低配的IoT设备上运行。可以帮助快速进行智能86盒产品的开发和量产。

      3.png
      规格参数

      • 计算模块:Lichee RV - NeZha CM
      • 屏幕:480*480 RGB接口IPS屏+FT 6336G 电容触摸屏
      • 无线连接:XR829模块(2.4G WIFI+蓝牙)
      • 有线连接:预留百兆网口(使用1.25mm端子的RJ45尾线)
      • 音频:板载双路MEMS数字硅麦克风,音频功放电路(最大支持3W喇叭)
      • USB端口:USB HOST1,USB TO UART1
      • RTC:专用RTC芯片+纽扣电池座
      • GPIO拓展:FPC座子和2.54mm排针焊盘引出GPIO
      • 电源电路:支持12V/5V输入
      • 尺寸:86*86mm,完美适配标准86盒尺寸
      • 开发框架:支持WAFT环境

      应用领域

      智能家居、智能楼宇、工业控制、智能机器人......

      淘宝购买链接:https://item.taobao.com/item.htm?spm=a2126o.success.result.1.1c2d48315NRnH3&id=660478137105

      发布在 MR Series
      q1215200171
      budbool
    • 【FAQ】全志R329如何将I2C时钟频率变成800kHz?

      问题背景

      硬件:R329
      软件:Tina
      注:I2C在全志平台称为TWI,这是同一个模块来的。

      问题简述

      修改了uart的时钟源为50M,twi也会被修改为50M。dts中给某一条twi总线设置的时钟频率为400k,但是实际测得该twi的时钟频率为833kHz。

      问题分析

      twi的工作频率会根据时钟源自动计算最佳分频系数,从而分频而来的。可是为什么会分出800KHz的频率呢?

      1、在R329中,uart和twi公用同一个时钟源——apb2。当用户想要修改uart的波特率为3M时,需要将apb2的时钟源修改成50MHz(原来apb2的时钟源为24MHz),这样twi的时钟源也会同时被修改成50MHz。

      uart驱动的初始化级别为:module_init(sunxi_uart_init); 等级为6
      twi驱动的初始化级别为:fs_initcall(sunxi_i2c_adap_init); 等级为5
      当选用了i2c相关的regulator时,twi驱动的初始化级别则是更早:subsys_initcall(sunxi_i2c_adap_init); 等级为4

      由此看出,uart初始化顺序比twi的要迟。

      2、然后,因为要适配波特率才去修改apb2的时钟源,修改时钟源的代码是在uart中实现的。那么就是说,当uart初始化之后,apb2的时钟源才会更改成50MHz。在uart初始化之前apb2一直保持24MHz。

      所以,在twi初始化的时候,是以24MHz这个频率去计算分频系数的。当twi分频系数已经写入寄存器后,这时候时钟源改变。所以就导致以24MHz的分频系数去分频50MHz,从而分出了833KHz的频率。

      解决方法

      在系统没有选上依赖I2C的PMU时,提前uart驱动初始化顺序即可解决该问题。

      ---
       drivers/tty/serial/sunxi-uart.c | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/drivers/tty/serial/sunxi-uart.c b/drivers/tty/serial/sunxi-uart.c
      index 224646f..87d1135 100644
      --- a/drivers/tty/serial/sunxi-uart.c
      +++ b/drivers/tty/serial/sunxi-uart.c
      @@ -2260,7 +2260,7 @@ static void __exit sunxi_uart_exit(void)
       	uart_unregister_driver(&sw_uart_driver);
       }
       
      -module_init(sunxi_uart_init);
      +subsys_initcall(sunxi_uart_init);
       module_exit(sunxi_uart_exit);
       
       MODULE_AUTHOR("Aaron<leafy.myeh@allwinnertech.com>");
      -- 
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329Tina下如何判断是安全固件?

      问题描述

      客户希望在用户空间判断如何获取设备的安全状态。

      问题简述

      Tina下越来越多的方案开始支持安全功能,客户经常会问起如何判断当前板子中的固件是否是安全。

      问题分析

      安全与非安全有较大区别,有多种方法可以进行判断,现汇总如下:

      • 查看SoC是否支持安全。
        在datasheet查找SoC是否包含安全系统,如果有TrustZone、Secure Boot等关键字,表明该SoC支持安全。

      • 确认Tina SDK是否支持安全固件。
        查看tina/scripts/createkeys文件中的PLATFORM_LIST变量,如果SoC代号在该变量中,表明该Tina SDK支持安全启动。

      • 查看烧写的固件名。
        Tina安全固件名与非安全固件名有区别,安全固件名格式为tina_{BOARD}_<uart0/card0>_secure_v[NUM].img,带有_secure_关键字,非安全则没有该关键字。

      • 查看启动log
        安全启动过程中有一些特有的打印,如

      “SBOOT is starting!”、“sboot commit...”、“OLD version:...”、“NEW version: ...”、“OP-TEE version: ...”、“secure enable bit: 1”
      
      • 用户空间获取
        执行命令,如果输出的结果中sunxi_secure为secure,表明当前系统是安全系统。
      cat /sys/class/sunxi_info/sys_info
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何在平台修改uboot阶段CPU频率?

      在启动优化过程,有一个优化项是提高uboot阶段CPU运行频率,CPU默认配置启动频率为1G,提高CPU频率确实可以提升开机速度,但是在提升CPU频率的时候,需要同步提升 VDD-CPU 的电压,该电压配置需要与芯片的 VF 表一致。

      下面以 R818 evb2 方案为例,介绍如何在uboot节点提升 CPU 频率。

      • 查看平台的 vf 表,R818当前的 vf 表在内核的dts中有配置,详细的配置参考内核dts的 cpu_opp_l_table 配置即可。R818 1.5G时,VDD-CPU需要配置为1.18V,得到该信息之后,uboot中将配置为该频率启动。

      • 方案的 sys_config.fex 中,boot_clock 为uboot阶段CPU频率,当前我们需要以1.5G频率启动,则修改为 boot_clock = 1512。

      • 同步修改 VDD-CPU 电压,R818 evb2 方案中,DCDCA输出连接到VDD-CPU,所以需要在uboot阶段,将DCDCA的电压修改为1.18V。配置为 dcdca_vol = 1001180。

      • 由于evb2方案没有BMU,uboot中的方案配置需要去掉BMU的配置,将需要修改uboot中,平台defconfig中的配置。

      上述总的修改如下:

      fc0883e8aba945c28a4554e6d5461216.jfif

      32e61aa8493b44179f2c1ba39964b1b5.jfif

      补丁如下:

      // 方案sys_config.fex 中的修改
      diff --git a/configs/evb2/sys_config.fex b/configs/evb2/sys_config.fex
      index 8c99868..f86464e 100644
      --- a/configs/evb2/sys_config.fex
      +++ b/configs/evb2/sys_config.fex
      @@ -20,7 +20,7 @@ debug_mode  = 8
       ;power_mode    = axp_type,   0:axp81X, 1:dummy, 2:axp806, 3:axp2202, 4:axp858
       ;----------------------------------------------------------------------------------
       [target]
      -boot_clock     = 1008
      +boot_clock     = 1512
       storage_type    = 2
       advert_enable   = 0
       burn_key        = 1
      @@ -38,6 +38,7 @@ power_mode            = 2
       ;dldo1_vol                                                     ---set dldo1 voltage,mV,500-3500,100mV/step
       ;----------------------------------------------------------------------------------
       [power_sply]
      +dcdca_vol = 1001180
      
       [card_boot]
       logical_start   = 40960
      
      // uboot 中,平台defconfig的修改
      diff --git a/configs/sun50iw10p1_tina_defconfig b/configs/sun50iw10p1_tina_defconfig
      index 581e4b84a6..bc42673f67 100644
      --- a/configs/sun50iw10p1_tina_defconfig
      +++ b/configs/sun50iw10p1_tina_defconfig
      @@ -39,7 +39,7 @@ CONFIG_R_I2C0_ENABLE=y
       CONFIG_SUNXI_POWER=y
      
       CONFIG_SUNXI_PMU=y
      -CONFIG_SUNXI_BMU=y
      +#CONFIG_SUNXI_BMU=y
       CONFIG_AXP81X_POWER=y
       CONFIG_AXP81X_SUNXI_I2C_SLAVE=0x34
       CONFIG_AXP858_POWER=y
      

      在修改完成之后,uboot的启动log将可以看到下面的信息:

      [00.794]dcdca_vol = 1180, onoff=1
      [00.802]CPU=1512 MHz,PLL6=600 Mhz,AHB=200 Mhz, APB1=100Mhz  MBus=400Mhz
      

      启动log中有上述信息则修改成功。

      其他的平台、方案、频率如何修改?

      其他的平台、方案、频率修改都是类似的,只要确定期望uboot启动的CPU频率之后,确认在该频点下,VDD-CPU需要的电压,然后通过原理图确认VDD-CPU是由哪一路DCDC供电的,而后修改sys_config.fex中的boot_clock和power_sply的配置即可。而uboot中的修改,根据实际使用方案,配置PMU和BMU即可,如果发现uboot中的电压没有配置正确,则在uboot中搜索”power_sply“字段信息,查看代码解析"/soc/power_sply"逻辑后修改即可。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列Tina 如何使用 NFS?

      NFS(Network File System,网络文件系统)可用于客户端访问服务器端的文件,并且从上层看其过程与访问本地文件相同。

      以下介绍如何将 Tina 作为客户端、Ubuntu 电脑作为服务器端使用。

      配置

      客户端

      在 Tina 的 kernel_menuconfig 中选上以下内容:

      File systems --->
          [*] Network File Systems --->
              <*> NFS client support
      

      服务器端
      ( 下面以 Ubuntu 14.04 为例,新一些版本的 Ubuntu 可能使用 systemd 管理系统服务,用到的命令会有所不同 )

      安装 nfs 服务器端软件包:

      sudo apt-get install nfs-kernel-server
      

      打开 /etc/exports 文件,添加需要共享的目录:

      /path/to/share *(rw,sync,no_root_squash,no_subtree_check)
      
      • /path/to/share 是共享的目录
      • 表示允许所有网段访问
      • rw 表示允许读写

      更多的配置说明可用 man 5 exports 查看 exports 的手册。

      接着重启 NFS 服务:

      sudo /etc/init.d/rpcbind restart
      sudo /etc/init.d/nfs-kernel-server restart
      

      使用

      客户端和服务器端连接到 同一个网段,接着在客户端执行挂载命令:

      mount -t nfs -o nolock <server_address>:/path/to/share /local/mnt/dir
      <server_address> 为服务器端的地址,一般使用 IP 地址
      /path/to/share 为服务器端共享的目录
      /local/mnt/dir 为客户端挂载的目录
      

      此处若不加 -o nolock 在某些情况下可能会挂载失败,尚不清楚原因。如果加上后无法挂载成功可以尝试去掉看看。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列wpa_supplicant和wpa_cli简介

      问题背景

      硬件:R系列芯片
      软件:Tina

      问题简述

      说明:该FAQ旨在记录wpa_supplicant和wpa_cli的一些基础知识,方便在Tina系统上做网络联通性的排查。

      问题分析

      wpa_supplicant是一个连接、配置WiFi的工具,它主要包含wpa_supplicant与wpa_cli两个程序。 可以通过wpa_cli来进行WiFi的配置与连接,前提要保证wpa_supplicant正常启动。
      相当于wpa_supplicant 是服务端,wpa_cli 是客户端。

      1.wpa_supplicant

      启动wpa_supplicant应用
      wpa_supplicant -i wlan0 -Dnl80211 -c/etc/wifi/wpa_supplicant.conf -O /etc/wifi/sockets -B
      wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wifi/wpa_supplicant.conf -B
      wpa_supplicant -B -iwlan0 -c/etc/wifi/wpa_supplicant.conf -Dwext
      -D 驱动程序名称(可以是多个驱动程序:nl80211,wext)
      -i 接口名称
      -c 配置文件
      -B 在后台运行守护进程

      配置文件 /etc/wpa_supplicant.conf文件里,添加下面代码:
      ctrl_interface=/var/run/wpa_supplicant //
      update_config=1 // 强制更新覆盖配置 
      ctrl_interface指向的是一个目录,在这个目录中默认会生成一个文件/var/run/wpa_supplicant/wlan0,这是local socket address,相当于UNIX Domain Socket,程序和后台程序wpa_supplicant进行通信(其实是wpa_supplicant作为后台服务程序是通过本地socket和客户端进行通信的)
      update_config = 1时会在(客户端发送SAVE_CONFIG命令)更新这个配置文件。

      Tina上wpa_supplicant的启动是放在/etc/init.d/wpa_supplicant自启动脚本中的。

      2.wpa_cli

      wpa_cli 是客户端,用来进行WiFi的配置与连接。

      启动wpa_cli应用

      wpa_cli 有命令和交互的方式进行操作
      wpa_cli -i wlan0 scan   //搜索附件wifi热点
      wpa_cli -i wlan0 scan_result   //显示搜索wifi热点
      wpa_cli -i wlan0 status //当前WPA/EAPOL/EAP通讯状态
      wpa_cli -i wlan0 ping //pings wpa_supplicant
      

      添加新的连接

      wpa_cli -i wlan0 add_network //添加一个网络连接,会返回
      wpa_cli set_network ssid ‘“name”’ //ssid名称
      wpa_cli set_network psk ‘“psk”’  //密码
      wpa_cli set_network scan_ssid 1
      wpa_cli set_network priority 1 //优先级
      

      保存连接

      wpa_cli -i wlan0 save_config //信息保存到默认的配置文件中,前面提到的/etc/wpa_supplicant.conf
      

      断开连接

      wpa_cli -i wlan0 disable_network
      

      连接已有连接

      wpa_cli -i wlan0 list_network //列举保存过得连接
      wpa_cli -i wlan0 select_network //连接指定的ssid
      wpa_cli -i wlan0 enable_network //使能制定的ssid
      

      网络连接成功的配置文件示例

      ctrl_interface=/var/run/wpa_supplicant/
      ap_scan=1
      network={
      scan_ssid=1
      ssid="xxxx"
      psk="xxxx"
      bssid=
      priority=2
      }
      

      例如:

      wpa_cli -i wlan0 scan;
      wpa_cli -i wlan0 scan_result;
      wpa_cli -i wlan0 add_network;
      wpa_cli -i wlan0 set_network 0  ssid '"AW-PDC-PD2-fly2.4g"';
      wpa_cli -i wlan0 set_network 0  key_mgmt WPA-PSK;
      wpa_cli -i wlan0 set_network 0  psk '"xxxxxxxx"';
      wpa_cli -i wlan0 save_config;
      wpa_cli -i wlan0 select_network 0;
      wpa_cli -i wlan0 enable_network 0;
      wpa_cli -i wlan0 list_network;
      wpa_cli -i wlan0 status;
      

      问题记录

      • 错误1
        Successfully initialized wpa_supplicant
        ioctl[SIOCSIWENCODEEXT]: Invalid argument
        ioctl[SIOCSIWENCODEEXT]: Invalid argument

      原来在命令中sudo wpa_supplicant -B -D n180211,wext -i wlo1 -c /home/wpa_supplicant.cfg
      错把nl80211写成n180211,注意是数字1与字母l的区别。

      • 错误2
        wpa supplicant: No network configuration found for current AP
        说明配置文件写的不对,尤其从网上复制过来时常有看不见的tab字符等。
        解决办法:从Archlinux文档上复制了一份格式正确的配置,再改一改就OK了

      • 错误3
        ctrl_iface exists and seems to be in use - cannot override it
        Delete ‘/var/run/wpa_supplicant/wlo1’ manually if it is not used anymore
        Failed to initialize control interface ‘/var/run/wpa_supplicant’.
        You may have another wpa_supplicant process already running or the file was
        left by an unclean termination of wpa_supplicant in which case you will need
        to manually remove this file before starting wpa_supplicant again.
        系统已经存在打开的多个wpa_supplicant实例,执行一下sudo killall wpa_supplicant杀死所有wpa_supplicant即可。

      • 错误4
        Successfully initialized wpa_supplicant
        [ 2093.037373] ieee80211_do_open: vif_type=2, p2p=0, ch=3, addr=34:0f:51:ac:5f:97
        [ 2093.045662] [STA] !!!xradio_vif_setup: id=0, type=2, p2p=0, addr=34:0f:51:ac:5f:97
        [ 2093.055088] [AP_WRN] BSS_CHANGED_ASSOC but driver is unjoined.
        nl80211: deinit ifname=wlan0 disabled_11b_rates=0
        [ 2093.088882] [STA_WRN] !!! xradio_remove_interface: vif_id=0
        wlan0: Failed to initialize driver interface

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决在线mp3流媒体seek异常?

      现象

      tplayerdemo播放任意在线mp3 http/https流,刚开始播放约几秒后,执行命令 seek to: 100 ,会从0开始播放。

      注意:出现以上问题的码流为包含ID3V2.3标签的mp3流,且仅在网络播放时才会复现该问题。该类问题码流可通过工具HxD查看识别,如下图所示:

      399d34c948c64dd2863ff9e0b79c45f1.jfif

      红框是在文件的首部顺序记录的10个字节的ID3V2.4的头部。数据结构如下:

      char Header[3];     //必须为"ID3"否则认为标签不存在
        char Ver;       //版本号 ID3V2.4就记录4
        char Revision;     //副版本号 此版本记录为0
        char Flag;       //存放标志的字节,这个版本只定义了三位
        char Size[4];      //标签大小,包括标签头的10 个字节和所有的标签帧的大小
      

      具有以上类似标签的为问题码流,可复现以上seek失败的问题。

      问题码流

      https://openfreetystvip.migu.cn/public/product9th/product42/2020/10/0117/2020年10月01日14点12分紧急内容准入咪咕音乐自有版权4222首/标清高清/MP3_128_16_Stero/69905304100175532.mp3?channelid=08&msisdn=c9ae4994-20fb-4019-a62f-462bf83f4841&k=0112e08c04770255&t=1603096249914

      问题分析

      因为客户提供的MP3文件包含ID3V2部分,该ID3 tag信息位于文件开头,所以文件播放时会有一个 baseOffset 偏移。在执行seek时,由于 baseOffset 的偏移值非0,导致控制流函数进入了错误的else分支,startPos未能正确的设置给函数 CdxHttpSetField(httpHdr, str) ,而是错误的将baseOffset设置给函数 CdxHttpSetField(httpHdr, str) ,导致每次seek都会从头开始播放。

      解决方法

      添加限制条件,将原来的 if(pos == 0) 改为 if(pos == 0 || pos < d->startPos),使开始播放的位置正确,即设置正确的Range值。

      (patch见附件,基于tina-v3.5)
      0001-libcedarx-Solve-seek-abnormal-problem-of-online-MP3-.patch

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何实现Tina secureboot 打包分离模式支持?

      问题描述

      目前Tina安全固件签名打包都是在一台PC机器上完成,此时签名的相关密钥也保存在此PC上。部分客户内部有专门的安全服务器存放安全密钥,不希望将密钥直接放在本地PC上。

      问题分析

      为保护签名密钥,有一种简单的方式,就是在安全服务器上搭建一份Tina环境,编译签名打包都在安全服务器上进行,这样就避免密钥分散到本地PC。

      Tina SDK较大,编译时也会耗费大量CPU、内存、硬盘资源。有些客户的安全服务器性能达不到需求;另外部分客户安全服务器比较独立,只会存放关键数据,在安全服务器上存放大量内容,同时进行编译,是不允许的。此时需要在本地PC上进行编译,在安全服务器上使用密钥来进行签名打包。

      解决办法

      提供一种解决办法:签名服务器端只放key与打包脚本。本地编译完成后,先执行pack -s执行前半段的打包,即设置好各种配置文件、镜像、工具等,并存放在tina/client目录。将tina/client目录下内容复制到安全服务器端,安全服务器执行pack脚本继续后半段的签名打包。生成安全固件之后,再将安全固件从安全服务器复制到本地PC上。

      请按照附件secure_server_pack.7z中的readme.txt进行操作。
      secure_server_pack.7z

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何通过wpa_cli手动调试wifi station?

      问题背景

      在某些情况,需要手动调试wifi station

      问题分析

      wpa_cli作为wpa_supplicant的客户端,通过socket与之通信,实现对wifi的管理和控制,因此可借助wpa_cli实现wifi station相关操作,具体命令支持列表可通过"wpa_cli -h"查看

      调试步骤

      3.1 前提条件

      勾选wifi驱动及其fw、wpa_supplicant和wpa_cli

      3.2 调试步骤示例

      (1) 加载驱动(rtl8723ds)

      insmod /lib/modules/4.9.191/8723ds.ko
      

      (2) 创建wpa_supplicant.conf文件

      mkdir -p /var/run/wpa_supplicant
      echo 'ctrl_interface=/var/run/wpa_supplicant' > /var/run/wpa_supplicant/wpa_supplicant.conf
      echo 'update_config=1' >> /var/run/wpa_supplicant/wpa_supplicant.conf
      

      (3) 启动wpa_supplicant进程

      wpa_supplicant -Dnl80211 -iwlan0 -c/var/run/wpa_supplicant/wpa_supplicant.conf &
      

      (4) 连接热点

      wpa_cli -iwlan0 scan                                   //触发扫描
      wpa_cli -iwlan0 scan_results                           //获取扫描结果
      wpa_cli -iwlan0 add_network                            //添加一个网络,若为第一次添加,则返回network id=0
      wpa_cli -iwlan0 set_network 0 ssid \"XXXXXXXX\"        //设置要连接热点的ssid,格式为\"XXXXXX\"或'"XXXXXX"'
      wpa_cli -iwlan0 set_network 0 psk \"YYYYYYYY\"         //设置要连接热点的pwd,格式为\"XXXXXX\"或'"XXXXXX"'
      wpa_cli -iwlan0 select_network 0                       //选择#id网络连接,禁用其它网络
      wpa_cli -iwlan0 save_config                            //将当前连接信息保存至wpa_supplicant.conf中
      

      其它常用命令:

      wpa_cli -iwlan0 status                                 //查看当前WPA/EAPOL/EAP状态
      wpa_cli -iwlan0 list_networks                          //查看所有配置网络
      wpa_cli -iwlan0 disable_network #id                    //禁用指定网络,必须通过enable/select_network #id重新启用网络
      wpa_cli -iwlan0 remove_network #id                     //移除指定网络,若已连接,将断开连接
      wpa_cli -iwlan0 disconnect                             //断开连接,可通过reconnect回连
      wpa_cli -iwlan0 reconnect                              //回连
      ......
      

      (5) 获取ip地址

      udhcpc -i wlan0
      

      (6) 确定网络连通性

      举例:

      ping网关: ping 192.168.1.1
      ping外网: ping www.baidu.com       //前提热点与外网连通
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决Tina双系统安全固件启动失败问题?

      问题描述

      内核双备份系统安全固件启动失败,有如下log:

      [02.968]kernel len:10659840, part len:15728640
      pubkey boot_a not found
      check rootpk[boot_a] in rootcert fail
      [03.050]boota: verify the boot_a failed
      

      问题分析

      从log中看,提示没有找到名字为boot_a的公钥。

      此问题是签名key名字与分区名的匹配问题。客户为双系统,内核分区有两个,名字分别为boot_a与boot_b,均使用boot.fex。公钥的名字可以从签名配置文件dragon_xxx.cfg中查看,下面是boot.fex镜像对应的公钥名字为“boot”。

      [toc1]
      onlykey=boot, boot.fex, SCPFirmwareContentCertPK
      

      在uboot校验时,默认会根据分区名来找key,但是没有名为boot_a的key,所以提示找不到。

      解决办法

      有两种处理办法。

      第一种,修改uboot校验逻辑,对于内核分区,强制设置key名字为boot,修改如下:

      tina/lichee/brandy-2.0/u-boot-2018/board/sunxi/sunxi_image_verifier.c,补丁如附件uboot-set-boot-cert-name.patch所示。
      

      第二种,boot_a与boot_b使用不同的镜像名字,需要修改dragon_xxx.cfg文件,改动如下:

      [toc1]
      onlykey=boot_a, boot_a.fex, SCPFirmwareContentCertPK
      onlykey=boot_b, boot_b.fex, SCPFirmwareContentCertPK
      

      附件:uboot-set-boot-cert-name.patch

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列Wi-Fi唤醒问题排查思路

      问题背景

      硬件:R系列公板+RTL8723ds
      软件:Tina3.0及以上
      操作:利用wifimanager应用进行联网
      说明:该FAQ旨在总结Wi-Fi休眠唤醒失败问题的一般解决思路。

      问题简述

      R18公板使用RTL8723ds模组,通过Wi-Fi ping的方式唤醒失败。

      问题分析

      Wi-Fi唤醒的一般测试步骤

      • 准备两块R18板子,记为A和B,系统正常上电后利用wifimanger连接同一个路由。
      • 分别执行ifconfig查看ip地址,A:ipA,B:ipB。
      • 利用ping命令确保A,B板在未进入休眠的状态下能够相互ping通。
      • A板执行echo mem > /sys/power/state进入休眠。
      • B板执行ping ipA,确认是否能够成功唤醒A板。

      问题分析流程

      休眠唤醒从整体看分为两个阶段,休眠和唤醒。

      1.首先确保休眠流程正常。可以使用定时唤醒或者按键唤醒。

      (sun50iw1p1_R18)
      echo 5 > /sys/power/sunxi/time_to_wakeup_ms
      (sun8iw18p1_R328/)
      echo 5 > /sys/power/sunxi_debug/time_to_wakeup_ms
      (sun8iw8p1_R11/R7s/R331/R332/R333  sun8iw5p1_R16)
      echo 1000 > /sys/module/pm_tmp/parameters/time_to_wakeup;
      (sun3iw1p1_R6)
      echo 10 > /sys/module/pm_tmp/parameters/time_to_wakeup;
      (sun8iw17p1_T7/sun8iw15p1_MR133/R311)
      echo 1000 > /sys/module/pm/parameters/time_to_wakeup_ms
      echo +5 > /sys/class/rtc/rtc0/wakealarm;  or echo 5 > /sys/class/rtc/rtc0/time;
      (sun50iw3p1_R30/)
      echo 5000 > /sys/module/pm/parameters/time_to_wakeup_ms
      echo 5 > /sys/class/rtc/rtc0/time;
      

      2.在步骤1的前提下说明休眠和唤醒流程两个阶段都正常,那么就是Wi-Fi本身的问题,进而又细分为三个阶段:发出ping包,接收ping包(接收中断),中断处理(唤醒SOC)

      2.1利用抓包网卡确认B板的ping包是否有正常发出,一般可以尝试用其他正常的板子做验证即可,只要可以正常ping唤醒其他任何设备,说明B板ping包正常发出。

      2.2利用示波器直接查看中断引脚,一般默认为低,有中断来临会被拉高,若示波器测量发现未被拉高,尝试直接短接的方式拉高(一般用该引脚的供电电压)

      • 情况1:中断引脚一直为低,且直接短接拉高可以正常唤醒,说明未收到ping包(或者中断未触发)。
      • 情况2:中断引脚从低被拉高,依然无法唤醒,说明是主控未对中断响应。

      该问题属于情况2:即通过示波器能够明显的看到中断引脚从低拉到高,说明已经正常的接收到ping包,产生了中断。

      此时排查思路如下:
      5f073faf569c42c594f68dd45d289dd2.jfif
      检查中断引脚的配置:
      引脚功能:输入,输出,中断,其他复用**(配置中断功能)**
      触发方式:低电平,高电平,上升沿,下降沿,双边沿触发**(任选一种)**
      中断号使能:(一般都是一组gpio的中断号,该例为PL)
      中断引脚的使能:(具体引脚的使能,该例为PL8)

      如下图:

      2b68924d23304cd690e9186174def5c0.jfif

      最终发现是gpio的中断使能没有开。

      进一步排查发现在休眠阶段会清掉所有中断的使能,这个时候就需要在具体的设备的suspend函数中做处理,使能对应中断。

      解决办法

      使能PL7的中断功能即可。

      注:上面图是采用直接改寄存器的方式。
      正常请用接口irq_enable()

      更详细的说明可见附件《R18设置PL8为Wi-Fi唤醒源问题.pdf》

      R18设置PL8为Wi-Fi唤醒源问题.pdf

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何于Tina下支持多用户?

      新增用户

      Linux 系统是一个多用户多任务的分时操作系统,多个用户可以在同一时间内登录同一个系统执行各自不同的任务,而互不影响。

      不同的用户具有不同的权限,每个用户在权限允许的范围内完成不同的任务。Linux 通过这种权限的划分与管理,实现多用户的运行机制。

      每个用户都用一个唯一的用户名和用户口令,在登录系统时,只有正确输入了用户名和密码,才能进入系统和自己的主目录。

      Tina SDK默认只有一个用户,root。 支持多用户的话,首先需要新增用户。

      Tina 中 busybox 中包含了 adduser 命令,执行 make menuconfig,使能“CONFIG_BUSYBOX_CONFIG_ADDUSER”即可加入该命令。使用命令 adduser 来新建一个用户,需要输入密码。生成完之后可以在 /etc/passwd 和 /etc/shadow 文件中看到相关信息。

      root@TinaLinux:~# adduser test
      addgroup: number 3 is not in 0..0 range
      adduser: /home/test: No such file or directory
      Changing password for test
      New password:
      Bad password: too short
      Retype password:
      passwd: password for test changed by root
      root@TinaLinux:~# cat /etc/passwd | grep test
      test:x:3:3:Linux User,,,:/home/test:/bin/ash
      root@TinaLinux:~# cat /etc/shadow | grep test
      test:$1$hzP6ufas$E3sHJb8pYA3/jSGNfLqk2/:0:0:99999:7:::
      root@TinaLinux:~# openssl passwd -1 -salt 'hzP6ufas' 'test'
      $1$hzP6ufas$E3sHJb8pYA3/jSGNfLqk2/
      

      如上面例子,新建了一个 test 用户,密码是 test。从 passwd 中可看到其 id 为 3。 从/etc/shadow 中可看到其密码的相信息,其中1表示的是采用 MD5 算法,hzP6ufas表示salt,后面的$E3sHJb8pYA3/jSGNfLqk2/就是对密码 “test” 进行哈希运算的结果。

      同理,我们可以猜测出 root 的密码为 tina。

      root@TinaLinux:~# cat /etc/shadow /etc/passwd | grep root
      root:91rMiZzGliXHM:1:0:99999:7:::
      root:x:0:0:root:/root:/bin/ash
      root@TinaLinux:~# openssl passwd -salt 91 tina
      91rMiZzGliXHM
      

      如果希望固件中就包含 “non-root user”,可以首先在小机端执行 adduser,然后将/etc/passwd与/etc/shadow 中的相关行加入到“tina/package/base-files/files/etc/”或“tina/target/allwinner/${BOARD}/base-files/etc”等目录下对应的文件中,同时在 rootfs 的 home 目录下新增一个 “non-root user” 对应的目录。

      通常还需要修改/etc/group,方法类似。

      如果希望开机直接进入 test 用户,可以修改 rootfs 中的/etc/inittab 文件,删除所有的 askfirst与 askconsole 行,加入“::askconsole:/bin/su - test”行。

      如果希望开机后动态选择用户登录,可以修改 rootfs 中的/etc/inittab 文件,删除所有的 askfirst 与 askconsole 行,加入“::askconsole:/bin/login”行。

      切换用户

      可以通过 su 命令来在不同的用户间进行切换。Tina 执行 make menuconfig,使能 “CONFIG_BUSYBOX_CONFIG_SU” 即可加入 su 命令。

      test@TinaLinux:~$ su - root
      su: must be suid to work properly
      test@TinaLinux:~$ ll /bin/busybox /bin/su
      -rwxr-xr-x 1 root root 412024 Oct 15 2020 /bin/busybox
      lrwxrwxrwx 1 root root 7 Oct 15 2020 /bin/su -> busybox
      test@TinaLinux:~$ reboot
      reboot: Operation not permitted
      test@TinaLinux:~$ date -s "2020-10-16 00:00:00"
      date: can't set date: Operation not permitted
      Fri Oct 16 00:00:00 UTC 2020
      

      如上面例子所示,在 test 用户下,执行 su 命令,提示出错。对于一些二进制文件,虽然 o 中包含了可执行权限,但是执行时,仍然会失败。因为这些二进制程序运行后,owner 是 test,如果此进程有写文件或执行其他程序等,会因为权限不足而出错。如果将此二进制文件加上 suid,就可以正确执行。类似的命令还有 date、reboot 等。

      对于 busybox,除了加上 suid,还需要在/etc/busybox.conf 文件中加入对应命令的 suid 配置。 执行make menuconfig,使能 “CONFIG_BUSYBOX_CONFIG_FEATURE_SUID”、“CONFIG_BUSYBOX_CONFIG_FEATURE_SUID_CONFIG” 加入对/etc/busybox.conf的支持。

      root@TinaLinux:~# ll /bin/busybox
      -rwxr-xr-x 1 root root 412024 Oct 15 07:11 /bin/busybox
      root@TinaLinux:~# chmod u+s /bin/busybox ; ll /bin/busybox
      -rwsr-xr-x 1 root root 412024 Oct 15 07:11 /bin/busybox
      root@TinaLinux:~# cat /etc/busybox.conf
      [SUID]
      reboot = ssx root.root
      date = ssx root.root
      root@TinaLinux:~# exit
      test@TinaLinux:~$ date -s "2020-10-16 10:00:00"
      Fri Oct 16 10:00:00 UTC 2020
      test@TinaLinux:~$ reboot
      

      实际在使用过程中,可以根据需要,对二进制文件加入 suid/sgid 权限。

      当切换用户后,后续在控制台执行的命令都是属于当前用户的。可以使用如下命令开启一个属于其他用户的进程:

      su <user name> -c "command"
      test@TinaLinux:~$ su root -c "sleep 1000 &"
      Password:
      test@TinaLinux:~$ su root
      Password:
      root@TinaLinux:/home/test# su test -c "sleep 2000 &"
      root@TinaLinux:/home/test# su test
      test@TinaLinux:~$ ps | grep sleep
      2409 root 3016 S sleep 1000
      2412 test 3272 S sleep 2000
      2415 test 3272 R grep sleep
      

      如上面例子所示,在 test 用户下,以 root 用户开启了一个sleep 1000的进程;在 root 用户下,以 test 用户开启了一个sleep 2000的进程。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何解决Tina删除内核根目录.config后一直编译失败的问题?

      问题描述

      客户删除Tina内核根目录下的.config文件后,按照正常流程编译会失败,log如下,提示找不到内核根目录下的.config文件。

      make[4]: *** No rule to make target `/home/XXX/work/tina/out/rxxx-evb1/compile_dir/target/linux-rxxx-evb1/linux-x.x.x/.config', needed by `/home/XXX/work/tina/out/rxxx-evb1/compile_dir/target/linux-rxxx-evb1/linux-x.x.x/.modules'.  Stop.
      make[4]: Leaving directory `/home/XXX/work/tina/target/allwinner/rxxx-evb1'
      make[3]: *** [compile] Error 2
      make[3]: Leaving directory `/home/XXX/work/tina/target/allwinner'
      make[2]: *** [target/allwinner/compile] Error 2
      make[2]: Leaving directory `/home/XXX/work/tina'
      make[1]: *** [/home/XXX/work/tina/out/rxxx-evb1/staging_dir/target/stamp/.target_compile] Error 2
      make[1]: Leaving directory `/home/XXX/work/tina'
      Build failed - please re-run with -j1 to see the real error message
      

      客户尝试重新source/lunch、make kernel_menuconfig等操作,均编译失败,导致不能恢复。

      问题简述

      AW向客户提供longon、Tina等多套SDK,客户可能延续其他SDK的开发习惯,删除内核.config,其他SDK编译时会自动生成,目前Tina不会,因此导致上述问题。

      问题分析

      log提示找不到内核.config文件,Tina下生成内核.config操作位于tina/build/kernel-defaults.mk文件中的Kernel/Configure/Default定义下。

      其主要逻辑如下:

      • 根据tina的defconfig、内核的linux-x.x配置等一起在内核根目录下生成.config.set文件
      • 比较内核根目录下.config.set与.config.prev文件,如果相同,不进行任何操作;如果不同,将.config.set复制为.config,同时将.config.set复制为.config.prev

      如果重新source/lunch,不做任何改动,生成的.config.set与上次保存的配置.config.prev是一样的,因此不会重新生成.config文件。

      同理如果执行make kernel_menuconfig,不修改配置,生成的.config.set依旧与上次保存的.config.prev一致,也不会重新生成.config文件。

      解决办法

      根据.config的生成逻辑,可以有多种处理办法。

      • 方法一:删除内核根目录下的.config.prev。当然删除tina/out目录也行,其作用相当于删除.config.prev
      • 方法二:执行make kernel_menuconfig,修改一些配置,保存。目的是确保.config.set与.config.prev不同,重新生成.config
      • 方法三:使用附件补丁0001-kernel-defaults-cp-.config.set-to-.config-when-there.patch,该补丁作用是,如果.config不存在,将.config.set复制为.config
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何进行WiFi驱动收发帧打印控制?

      问题背景

      对于搭载了XRadio WiFi模组(XR819/XR819S/XR829)的产品,在开发或测试过程中可能会遇到一些常见网络问题,如ping不通外网、wifi连接失败、wifi异常断线等问题,这时可借助驱动收发帧打印来协助定位问题

      问题分析

      对于常见网络问题,需要从发送通路和接收通路的完整性角度出发对问题进行排查,对于"wifi连接失败"问题,在wifi连接过程中主要有认证和关联帧的交互,对于"ping不通外网"问题,ping过程主要涉及ICMP请求和响应的发送和接收,同时也要考虑到本地设备是否成功拿到ip地址,这里会涉及到DHCP交互流程。

      解决办法

      (1) 确认XRadio WiFi驱动打开debugfs选项,驱动初始化完成后会在/sys/kernel/debug/ieee80211/phy*/xradio目录生成parse_flags节点,该节点可控制驱动层是否打印收发帧信息

      (2) 命令:echo tx,rx > parse_flags
      说明:设定收发帧打印,tx为发送帧解释参数,rx为接收帧解释参数
      命令:cat parse_flags
      说明:查看当前收发帧解释参数

      (3) 解释参数说明如下:

      5895c8a3-43aa-47d2-bc7a-788fe7b20ad4-image.png

      举例说明

      命令:echo 0xc0,0xc0 > parse_flags
      说明:显示发送和接收的DHCP和ICMP帧信息(0xc0=0x80 | 0x40)

      驱动帧打印:

      [XRADIO] if0-TX---DHCP, Opt=53, MsgType=1
      [XRADIO] if0-RX---DHCP, Opt=53, MsgType=2
      [XRADIO] if0-TX---DHCP, Opt=53, MsgType=3
      [XRADIO] if0-RX---DHCP, Opt=53, MsgType=5
      ......
      [XRADIO] if0-RX---ICMP(reply), Seq=1
      [XRADIO] if0-RX---ICMP(reply), Seq=2
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列如何解决wpa_supplicant服务启动问题?

      问题背景

      硬件:R系列公板+ Wi-Fi模组(XRADIO/RTL/BCM/ESP/…)
      软件:Tina3.0及以上
      操作:利用wifimanager应用进行联网

      问题简述

      系统启动利用wifimanager联网失败。提示:

      root@TinaLinux:/# wifi_connect_ap_test AW-PDC-PD2-fly2.4g 22224444
      ==================================
      connect wpa_supplicant failed,please check wifi driver!
      wifi on failed
      

      问题分析

      从打印定位看是连接wpa_supplicant失败,逐步排查发现:
      lsmod->驱动正常加载
      ifconfig->wlan0正常起卡
      ps | grep wpa_supplicant->发现wap服务没有启动。

      解决办法

      • 情况1:手动执行./etc/init.d/wpa_supplicant start提示:
      Failed to open config file '/etc/wpa_supplicant.conf', error: No such file or directory
      

      经过排查正确的配置文件在/etc/wifi/wpa_supplicant.conf中。客户自己改了路径。
      解决:适配正确的配置文件路径后测试,wpa服务正常启动,可以正常联网。

      • 情况2:同样是发现wpa服务没有启动,于是手动执行:
      root@TinaLinux:/# wpa_supplicant -i wlan0 -Dnl80211 -c/etc/wifi/wpa_supplicant.c
      onf -O /etc/wifi/sockets -B
      Successfully initialized wpa_supplicant
      [  796.252780] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
      mkdir[ctrl_interface=/etc/wifi/sockets]: Read-only file system
      Failed to initialize control interface '/etc/wifi/sockets'.
      

      从打印可以看出是创建sockets时失败了,分析发现还是路径的问题。

      解决:sockets路径切换到/etc/wifi/下正常,或者自己去该路径下自己创建一个也可临时使用。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何在DragonSN烧写mac地址?

      问题背景

      硬件:R528+ Wi-Fi模组(XR829)
      软件:Tina3.0及以上
      说明:该FAQ旨在介绍DragonSN烧写mac地址的过程。

      问题简述

      如何从私有分区获取mac地址?

      问题分析

      从私有分区获取mac地址,需要利用到DragonSN工具烧写mac地址到私有分区,然后借助uboot以comdline的形式传递到内核,内核addr_mgt驱动解析。

      这里简要描述一下上述过程:

      1.lichee/brandy-2.0/u-boot-2018/board/sunxi/sunxi_bootargs.c

      +int update_user_data_ali(void)
      +{
      +       int data_len;
      +       int ret;
      +       char output[SST_WIFI_MAC_ADDR_LEN+1];
      +       char *sst_info = NULL;
      +       int sec_inited      = !sunxi_secure_storage_init();  //分区初始化
      +       memset(output, 0, SST_WIFI_MAC_ADDR_LEN+1);  //获取存放mac地址的地址空间并初始化
      +       if (sec_inited) {
      +               sst_info = (char *)malloc(SST_INFO_KEY_VALUE_ACTUAL_LEN);  //分配存放mac地址的空间并赋值给sst_info结构体
      +               if (get_boot_work_mode() != WORK_MODE_BOOT) {
      +                       return 0;
      +               }
      +
      +               ret = sunxi_secure_object_read(SST_INFO_KEY_NAME, sst_info, SST_INFO_KEY_VALUE_ACTUAL_LEN, &data_len); //从flash secure storage读出
      +               if (ret)
      +                       pr_msg("=========%s->%d sunxi_secure_object_read failed==============\n", __func__, __LINE__);
      +               memcpy(output, sst_info + SST_WIFI_MAC_ADDR_OFFSET, SST_WIFI_MAC_ADDR_LEN);
      +               env_set("wifi_mac", output);
      +               pr_msg("=========%s->%d fly  test wifi_mac:%s==============\n", __func__, __LINE__, output);
      +       }else{
      +               pr_msg("=========%s->%d sunxi_secure_storage_init failed==============\n", __func__, __LINE__);
      +       }
      +
      +       free(sst_info);
      +       return 0;
      +}
      

      通过sunxi_secure_object_read()接口根据偏移量读取分区中已经烧好的mac地址,赋值给wifi_mac。在通过env_set()接口将获取到的mac地址传递到env。

      2.device/config/chips/r818/configs/ailabs_dictpen/linux/env.cfg

      27 #set kernel cmdline if boot.img or recovery.img has no cmdline we will use this
      28 setargs_nand=setenv bootargs console=${console}...mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac}
      29 setargs_mmc=setenv bootargs console=${console}...mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac}
      

      内核读取env.cfg时再把wifi_mac取出来,通过addr-mgt驱动获取。

      3.lichee/linux-4.9/drivers/misc/sunxi-addr-mgt/sunxi-addr-mgt.c

      83 int get_wifi_custom_mac_address(char *addr_str)
       84 {
       85         if (IS_TYPE_INVALID(info.type_cur_wifi) ||
       86                 addr_parse(info.addr_wifi, 1))
       87                 return -1;
       88
       89         strcpy(addr_str, info.addr_wifi);  //直接拷贝info结构体的mac地址属性,最原始的就是uboot阶段的sst_info
       90         return info.type_cur_wifi;
       91 }
      
      

      4.xr829驱动获取lichee/linux-4.9/drivers/net/wireless/xr829/wlan/main.c

      478 extern int get_wifi_custom_mac_address(char *addr_str);
      479
      480 #define MAC_FROM_CHIPID
      481 static void xradio_get_mac_addrs(u8 *macaddr)
      482 {
      483         int ret = 0;
      484         char addr_str[20];
      485         SYS_BUG(!macaddr);
      486         /* Check mac addrs param, if exsist, use it first.*/
      487 #ifdef XRADIO_MACPARAM_HEX
      488         memcpy(macaddr, xradio_macaddr_param, ETH_ALEN);
      489 #else
      490         if (xradio_macaddr_param) {
      491                 ret = xradio_macaddr_char2val(macaddr, xradio_macaddr_param);
      492         }
      493 #endif
      494         if (ret < 0 || !MACADDR_VAILID(macaddr)) {
      495                 ret = get_wifi_custom_mac_address(addr_str);  //直接调用addr_mgt驱动的接口,即从分区读的方式获取mac地址。
      496                 if (ret != -1) {
      497                         sscanf(addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
      498                                                 &macaddr[0], &macaddr[1], &macaddr[2],
      499                                                 &macaddr[3], &macaddr[4], &macaddr[5]);
      500                 }
      501         }
      502
      503         /* Use random value to set mac addr for the first time,
      504          * and save it in  wifi config file. TODO: read from product ID*/
      505         if (ret < 0 || !MACADDR_VAILID(macaddr)) {
      506 #ifdef XRADIO_MACPARAM_HEX
      507                 ret = access_file(WIFI_CONF_PATH, macaddr, ETH_ALEN, 1);  //自定义mac地址写入文件后,从文件获取mac地址
      508 #else
      509                 char  c_mac[XRADIO_MAC_CHARLEN+2] = {0};
      510                 ret = access_file(WIFI_CONF_PATH, c_mac, XRADIO_MAC_CHARLEN, 1);
      511                 if (ret >= 0) {
      512                         ret = xradio_macaddr_char2val(macaddr, c_mac);
      513                 }
      514 #endif
      515
      516                 if (ret < 0 || !MACADDR_VAILID(macaddr)) {
      517 #if defined(MAC_FROM_CHIPID)
      518                         u32 databuf[4] = {0};
      519
      520                         sunxi_get_soc_chipid((u8 *)databuf); //获取chipid后定制mac地址的方式
      521                         macaddr[0] = (((databuf[1] >> 28) & 0x0f) | ((databuf[2] & 0x0f) << 4)) & 0xff;
      522                         macaddr[1] = (databuf[2] >> 4)  & 0xff;
      523                         macaddr[2] = (databuf[2] >> 12) & 0xff;
      524                         macaddr[3] = (databuf[3] >> 6)  & 0xff;
      525                         macaddr[4] = (databuf[3] >> 16) & 0xff;
      526                         macaddr[5] = (databuf[3] >> 26) & 0xff;
      527 #else
      528                         get_random_bytes(macaddr, 6);  //随机生成mac地址的方式
      529 #endif
      530                         macaddr[0] &= 0xFC;
      531 #ifdef XRADIO_MACPARAM_HEX
      532                         ret = access_file(WIFI_CONF_PATH, macaddr, ETH_ALEN, 0);
      533 #else
      534                         ret = xradio_macaddr_val2char(c_mac, macaddr);
      535                         ret = access_file(WIFI_CONF_PATH, c_mac, ret, 0);
      536 #endif
      537                         if (ret < 0)
      538                                 xradio_dbg(XRADIO_DBG_ERROR, "Access_file failed, path:%s!\n",
      539                                            WIFI_CONF_PATH);
      540                         if (!MACADDR_VAILID(macaddr)) {
      541                                 xradio_dbg(XRADIO_DBG_WARN, "Use default Mac addr!\n"); //驱动默认可以写死一个mac地址。
      542                                 macaddr[0] = 0xDC;
      543                                 macaddr[1] = 0x44;
      544                                 macaddr[2] = 0x6D;
      545                         } else {
      546                                 xradio_dbg(XRADIO_DBG_NIY, "Use random Mac addr!\n");
      547                         }
      548                 } else {
      549                         xradio_dbg(XRADIO_DBG_NIY, "Use Mac addr in file!\n");
      550                 }
      551         }
      552         xradio_dbg(XRADIO_DBG_NIY, "MACADDR=%02x:%02x:%02x:%02x:%02x:%02x\n",
      553                    macaddr[0], macaddr[1], macaddr[2],
      554                    macaddr[3], macaddr[4], macaddr[5]);
      555 }
      

      解决方法

      1.工作获取

      从全志一号通入口获取
      https://one.allwinnertech.com/#/devtool?menuID=37
      a8203b64ba8e4e7aa280601c97a2e095.jfif

      2.烧写流程

      前提条件:软件支持从private分区获取mac地址。

      2.1配置添加类型
      464f186fa856440b973c1ae85f141fe0.jfif

      2.2设置key类型

      7db4b3c81ae64de9b131a0e7605d14dd.jfif

      2.3开始烧写

      2efb03b1da4f40baac83c9a5f7fcb766.jfif

      2.4烧写成功

      0ad8ea85eb80430a9e8442ba373aaaf0.jfif

      3.确认操作
      可以直接通过系统起来后ifconfig命令查看mac地址是否与烧写的一致

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列Tina内核配置不生效如何解决?

      问题描述

      客户执行make kernel_menuconfig开启CONFIG_DEBUG_INFO,编译固件烧录到开发板中,查看/proc/config.gz发现"# CONFIG_DEBUG_INFO is not set",相关内核功能也没有支持。

      问题简述

      共性问题,对于部分内核配置,执行make kernel_menuconfig开启,内核配置文件linux-x.x中也显示开启,但是编译过程中对应模块却没有编译,同时检查内核根目录下的.config中配置,发现配置没有开启。

      问题分析

      此问题与Tina编译环境有关系。
      Tina编译内核时,会实时生成内核.config文件,使用tina的配置defconfig中以CONFIG_KERNEL_XXX开头的宏来覆盖内核中CONFIG_XXX。
      具体处理逻辑在tina/build/kernel-defaults.mk文件中的Kernel/Configure/Default定义下实现。

      解决办法

      执行make menuconfig,开启对应的CONFIG_KERNEL_XXX配置。
      针对客户本次问题,就是需要开启CONFIG_KERNEL_DEBUG_INFO。

      扩展

      基于Tina这种特殊操作,我们可以在Tina中加入选项来控制内核的配置,避免配置完tina后,还需要再次配置内核。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列如何进行Tina根文件系统定制?

      问题背景

      硬件:R系列公板
      软件:Tina3.0及以上
      说明:该FAQ旨在总结Tina根文件系统的定制方法

      问题简述

      客户需要临时添加或是修改生成的rootfs,但又不想重新去编译整个SDK。

      问题分析

      当前Tina SDK支持make menuconfig和make kernel_menuconfig配置,配置好相应功能后进行编译。在:out/[平台]/compile_dir/target/rootfs路径下生成一个rootfs,再通过out/host/bin/下的命令生成对应文件格式的镜像,默认为:squashfs–>rootfs.img,最后通过打包命令生成固件。

      存在问题:

      • 如果当前需要添加或是修改生成的rootfs,则需要重新配置,编译,打包。
      • 所以针对添加和修改两种不同需求提出根文件系统模板和工具定制功能。

      则需要重新配置,编译,打包。所以针对添加和修改两种不同需求提出根文件系统模板和工具定制功能。

      解决办法

      在build/envsetup.sh中添加add_rootfs_demo和crootfs、recomp_rootfs三条命令。

      根文件系统定制_模板

      Tina/package/add_rootfs_demo
                            |___bin
                            |___sbin
                            |___usr
                               |___bin
                               |___sbin
                            |___sys
                            |___README
                            |___......
                            |___new package
      

      在package目录下新建一个最基础的根文件系统模板(add_rootfs_demo),包括一些常用的空目录和一个README文件,使用时可以在相应目录添加自己的包,然后将该模板复制到第一次编译生成的rootfs中(out/[平台]/compile_dir/target/rootfs),如果此刻有冲突产生,则以该模板新添加的为标准,再重新制作成对应文件系统格式的镜像(此处README文件不会被打包到镜像中),最后重新打包生成新的固件。

      根文件系统定制_工具

      在第一次编译生成的rootfs中(out/[平台]/compile_dir/target/rootfs)直接添加或修改,然后重新调用out/host/bin下的命令生成对应文件格式的镜像,最后重新打包生成新的固件。

      使用介绍

      定制根文件系统模板

      1.将自定义的命令导入环境变量;
      -->source build/envsetup.sh
      2.选择平台;
      -->lunch platform(azalea_m2ultra-tina/tulip_d1-tina/sitar_perf1-tina...)
      3.转到根文件系统模板目录下;
      -->cd package/add-rootfs-demo
      4.添加自己的包,应用程序,文件等;
      -->"add your own package or application"(注:添加的包或应用程序需要编译成可执行文件。)
      5.执行命令重新生成文件系统镜像;
      -->add-rootfs-demo
      6.重新打包;
      -->pack
      7.烧写
      

      定制根文件系统工具

      1.将自定义的命令导入环境变量;
      -->source build/envsetup.sh
      2.选择平台;
      -->lunch platform(azalea_m2ultra-tina/tulip_d1-tina/sitar_perf1-tina...)
      3.第一次配置好menuconfig和kernel_menuconfig后编译;
      -->make kernel_menuconfig
      -->make menuconfig
      -->make
      4.转到第一次生成的rootfs目录下;
      -->crootfs
      5.添加或修改rootfs;
      -->"......"
      6.执行命令重新生成对应文件格式的镜像;
      -->recomp_rootfs
      7.重新打包;
      -->pack
      8.烧写
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何进行coredump的配置与调试?

      问题背景

      应用调试时出现段错误的情况。

      程序运行过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做CoreDump。

      可以认为CoreDump是内存快照,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时记录下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。CoreDump对于调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而CoreDump文件可以再现程序出错时的情景。

      问题描述

      客户基于btmanager开发蓝牙应用或者调试其他应用时,有时候会遇到崩溃的问题。
      只看到应用退出了,然后留下一行Segmentation fault的错误,却没有其他更多的信息。
      比如:

      fd1a354c2b5c4095b5d662d39ecf918e.jfif

      问题分析

      报错只有 Segmentation fault,而不是Segmentation fault (core dumped),说明没有使用CoreDump。

      解决办法

      SDK配置coredump和gdb
      m menuconfig进入配置菜单

      (1)Global build settings —>

      [*] Enable process core dump support
      fcd55fe527444dc29338b18b1710d5fe.jpg

      (2)Global build settings —>

      Binary stripping method (none) —>
      9eb58a3ef8514f988b3f27a59d14d7e6.jpg

      (3)Development —>

      <*> gdb… GNU Debugger
      43cbfb70c80042fdb9fe2847b34c9343.jpg

      小机端配置
      (1)ulimit -c unlimited
      表示在异常时产生core dump文件,不对core dump文件的大小进行限制。
      (2)echo /tmp/coredump > /proc/sys/kernel/core_pattern
      设置产生的core文件的文件名以及路径。

      例如:
      5c9161e95dc543cc85b6e9a36ab5eaf6.jpg

      出现Segmentation fault 之后,会有(core dumped)的字样。

      对coredump的简单debug

      (1)使用gdb调试coredump文件。
      gdb xxxx /tmp/coredump
      xxxx是具体的应用程序,比如/usr/bin/bt_test

      (2)在gdb 终端中输入bt
      输入bt之后,可以查看堆栈的信息。注意:这里的bt不是蓝牙的意思。

      如下图所示:
      86b96dd7b66d4ddbba07077982c8f270.jpg
      这样就可以大致查看出错的点,方便分析调试。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329如何查看和修改sdio的频率?

      【问题背景】

      硬件:R328+ Wi-Fi模组(XRADIO)
      软件:Tina3.0及以上
      说明:该FAQ旨在记录XRADIO驱动常见的调试Tips。与具体驱动相关,具有一般性。

      【问题简述】

      客户在做吞吐性能优化过程中问到:xr829如何调整sdio的扫卡频率?

      【问题分析】

      适当的调整sdio的频率,可以提升网络的性能,但是如果设置不恰当,也会引起一些难以预料的问题。

      所以这里总结一下sdio频率的查看和修改的一般方法。

      【解决方法】

      1)启动log查看:

      sunxi-mmc sdc1: sdc set ios:clk 0Hz bm PP pm UP vdd 21 width 1 timing LEGACY(SDR12) dt B
      sunxi-mmc sdc1: no vqmmc,Check if there is regulator
      sunxi-mmc sdc1: sdc set ios:clk 400000Hz bm PP pm ON vdd 21 width 1 timing LEGACY(SDR12) dt B
      sunxi-mmc sdc1: sdc set ios:clk 400000Hz bm PP pm ON vdd 21 width 1 timing LEGACY(SDR12) dt B
      sunxi-mmc sdc1: sdc set ios:clk 400000Hz bm PP pm ON vdd 21 width 1 timing LEGACY(SDR12) dt B
      sunxi-mmc sdc1: sdc set ios:clk 400000Hz bm PP pm ON vdd 21 width 1 timing SD-HS(SDR25) dt B
      sunxi-mmc sdc1: sdc set ios:clk 50000000Hz bm PP pm ON vdd 21 width 1 timing SD-HS(SDR25) dt B
      sunxi-mmc sdc1: sdc set ios:clk 50000000Hz bm PP pm ON vdd 21 width 4 timing SD-HS(SDR25) dt B
      一开始是400kHZ,后面是50MHZ
      

      2)系统节点操作:

      root@TinaLinux:/sys/kernel/debug/xradio_host_dbg# ls
      dbg_ap          dbg_logfile     dbg_sta         hwinfo
      dbg_bh          dbg_pm          dbg_tpa_node    set_sdio_clk
      dbg_common      dbg_sbus        dbg_txrx        tx_burst_limit
      dbg_etf         dbg_scan        dbg_wsm
      set_sdio_clk默认是0表示即扫卡的频率
      操作:echo 50000000 > set_sdio_clk
      

      3)在dts或者sys_config.fex中修改:

      3.1)sys_config.fex
      402 [sdc1]
      403 sdc1_used               = 1
      404 bus-width               = 4
      405 sdc1_clk                = port:PG00<2><1><3><default>
      406 sdc1_cmd                = port:PG01<2><1><3><default>
      407 sdc1_d0                 = port:PG02<2><1><3><default>
      408 sdc1_d1                 = port:PG03<2><1><3><default>
      409 sdc1_d2                 = port:PG04<2><1><3><default>
      410 sdc1_d3                 = port:PG05<2><1><3><default>
      411 cap-sdio-irq            =
      412 max-frequency           = 25000000  //从150M改为25M的.wifi最大到50M.
      
      3.2)board.dts
       565 &sdc1 {
       566         bus-width = <4>;
       567         no-mmc;
       568         no-sd;
       569         cap-sd-highspeed;
       570         /*sd-uhs-sdr12*/
       571         /*sd-uhs-sdr25;*/
       572         /*sd-uhs-sdr50;*/
       573         /*sd-uhs-ddr50;*/
       574         /*sd-uhs-sdr104;*/
       575         /*sunxi-power-save-mode;*/
       576         /*sunxi-dis-signal-vol-sw;*/
       577         cap-sdio-irq;
       578         keep-power-in-suspend;
       579         ignore-pm-notify;
       580         max-frequency = <150000000>;  //调整这个最大频率参数
       581         ctl-spec-caps = <0x8>;
       582         status = "okay";
       583 };
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列启动频率的修改方法

      【问题背景】

      硬件:R系列公板
      软件:Tina3.0及以上
      说明:该FAQ旨在总结Tina系统启动频率的修改方法。

      【问题简述】

      R11设置启动频率以1.2G启动出现高概率挂死,且挂死阶段不唯一(uboot和内核乃至rootfs都出现过)。

      【问题分析】

      1.分析启动log没有异常打印。
      2.初步怀疑是IC的启动频率的设置太高。

      这里记录一下修改启动频率的方法:

      方法一:进入系统后从寄存器更改。

      1.利用sunxi_dump节点启动后更改为1.2G。(具体寄存器以具体IC为准)
          echo 0x01c20000 > /sys/class/sunxi_dump/dump;
          cat /sys/class/sunxi_dump/dump;
          echo 0x01c20000 0x90001810 > /sys/class/sunxi_dump/write;
          cat /sys/class/sunxi_dump/write;

      方法二:全部配置好后再启动。

      1.内核配置选上dvfs驱动

      make kernel_menuconfig
              CPU Power Management  --->
                          CPU Frequency scaling  --->
                                   [*] CPU Frequency scaling   
        │ │                                      <*>   CPU frequency translation statistics      
        │ │                                      [ ]     CPU frequency translation statistics details  
        │ │                                            Default CPUFreq governor (performance)  --->        
        │ │                                      -*-   'performance' governor                           
        │ │                                      < >   'powersave' governor        
        │ │                                      < >   'userspace' governor for userspace frequency scaling
        │ │                                      < >   'ondemand' cpufreq policy governor      
        │ │                                      < >   'interactive' cpufreq policy governor           
        │ │                                      < >   'conservative' cpufreq governor              
        │ │                                            ARM CPU frequency scaling drivers  --->
                                                              [*] SUNXI CPUFreq driver support
      

      利用调频策略的节点更改
      echo usrspace > scaling_governor
      echo 频点 > scaling_setspeed

      2.sys_config.fex配置.

      boot_clock=912
      extremity_freq = 1200000000
      max_freq = 1200000000
      LV1_freq = 1200000000

      方法三:系统无法启动时进入uboot临时更改使正常。

      按住s启动进入uboot
      执行:

      sunxi#setcfg dvfs_table
      –dvfs_table–
      extremity_freq :912000000?1200000000
      max_freq :1200000000?
      min_freq :60000000?
      LV_count :8?
      LV1_freq :1200000000?
      LV1_volt :1200?
      LV2_freq :912000000?
      LV2_volt :1100?
      LV3_freq :912000000?
      LV3_volt :1100?
      LV4_freq :912000000?
      LV4_volt :1100?sunxi#boot
      

      需要更改的直接在后面输入更改的数字,不需要更改就按enter,最后按下ctrl+c停止设置回到
      sunxi#命令行,输入boot重启即可。

      【解决办法】

      最终发现的确是启动频率太高,后改为uboot和kernel启动均以912M。
      启动挂死问题得以修复。

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 Tina下如何使用硬件Watchdog?

      问题背景

      一些产品需要使用硬件看门狗(watchdog)复位功能,以避免死机后系统没有办法重启,影响用户体验。全志平台基本都带了硬件watchdog,并且内核中也已经包含驱动,只是需要在内核和应用使用即可。

      解决方案

      配置kernel
      使能SUNXI Watchdog驱动;
      可以直接在执行make kernel_menuconfig进行配置,路径如下:

      Device Drivers
          -- Watchdog Timer Support 
              -- SUNXI Watchdog
      

      系统中添加喂狗操作
      procd方式和busybox启动方式下,对watchdog的操作方式有些差异:

      1)procd 启动

      在procd启动方式下,系统启动时候,会在procd init进程加载watchdog,然后在后台进行“喂狗”操作,如果系统crash,watchdog会reset系统。

      具体的代码:
        procd-2016-02-08/initd/init.c
        procd-2016-02-08/initd/watchdog.c

      因此在procd启动方式下,应用可以不用对watchdog进行操作,如果需要改为应用喂狗,可以去掉init中对watchdog的操作;

      2)busybox启动

      Busybox启动时,init默认不会自动操作watchdog,需要由应用程序自行“喂狗”,启动代码可以参考下面示范代码:

      /*
       * Watchdog Driver Test Program
       */
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <unistd.h>
      #include <fcntl.h>
      #include <sys/ioctl.h>
      #include <linux/types.h>
      #include <linux/watchdog.h>
      
      int fd;
      
      /*
       * This function simply sends an IOCTL to the driver, which in turn ticks
       * the PC Watchdog card to reset its internal timer so it doesn't trigger
       * a computer reset.
       */
      static void keep_alive(void)
      {
          int dummy;
      
          ioctl(fd, WDIOC_KEEPALIVE, &dummy);
      }
      
      /*
       * The main program.  Run the program with "-d" to disable the card,
       * or "-e" to enable the card.
       */
      int main(int argc, char *argv[])
      {
          int flags;
      
          fd = open("/dev/watchdog", O_WRONLY);
      
          if (fd == -1) {
      	fprintf(stderr, "Watchdog device not enabled.\n");
      	fflush(stderr);
      	exit(-1);
          }
      
          if (argc > 1) {
      	if (!strncasecmp(argv[1], "-d", 2)) {
      	    flags = WDIOS_DISABLECARD;
      	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
      	    fprintf(stderr, "Watchdog card disabled.\n");
      	    fflush(stderr);
      	    exit(0);
      	} else if (!strncasecmp(argv[1], "-e", 2)) {
      	    flags = WDIOS_ENABLECARD;
      	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
      	    fprintf(stderr, "Watchdog card enabled.\n");
      	    fflush(stderr);
      	    exit(0);
      	} else {
      	    fprintf(stderr, "-d to disable, -e to enable.\n");
      	    fprintf(stderr, "run by itself to tick the card.\n");
      	    fflush(stderr);
      	    exit(0);
      	}
          } else {
      	fprintf(stderr, "Watchdog Ticking Away!\n");
      	fflush(stderr);
          }
      
          while(1) {
      	keep_alive();
      	sleep(1);
          }
      }
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列休眠唤醒使用和框架介绍

      【问题背景】

      硬件:R系列芯片
      软件:Tina

      【问题简述】

      说明:该FAQ旨在记录休眠唤醒的基本框架。

      【问题分析】

      1.相关术语
      B19F6272-2FED-44d5-88EA-E203005E5B55.png

      2.简要概述

      所谓的功耗管理通俗的讲就是省电,两个出发点:
      能不用就不用-间歇供电和断电--->静态功耗。
      必须用时少用-降低供电电压和频率--->动态功耗。
      功耗管理可分为静态功耗管理与动态功耗管理,当前Linux下的功耗管理技术主要如下图所示。

      44b5af95541443ef832fcfe5f7f4a626.jfif

      静态功耗管理通常指的是对待机情况下的功耗进行管理,它需要检测整个系统的工作状态。
      动态功耗管理通常指的是对运行时的CPU或device的电压频率进行调整。
      因此功耗管理会涉及包括供电(Power Supply)、充电(Charger)、时钟(Clock)、频率(Frequency)、电压(Voltage)、休眠/唤醒(Suspend/Resume)等方面。

      2.1配置

      make kernel_menuconfig

      96d9a6fe9aa94a9184cfb6aa2c70edd6.jfif

      [*] Suspend to RAM and standby	Standby基础功能,配置会默认选上部分依赖。
      [*] Wake lock	借鉴安卓锁机制,有锁就不能进入深度休眠。
      [*] Scene lock	用于设置系统进入何种场景standby,如:normal,super,usb...
      [*] Early suspend	浅度休眠,配合wake_lock机制使用,一般用来关屏。
      [*] Opportunistic sleep	Autosleep机制。
      [*]Power Management Debug Support	调试相关宏的开关。
      

      2.2文件节点

      配置好相应功能后进行编译,烧写到小机端会产生/sys/power目录,并在其下产生一些文件节点。

      R18平台的文件节点如下图:

      36054134547943bd8b64a6dfcdfb0d2d.jfif

      2.3框架流程

      6717d60e461c425b84833c3effab8a8c.jfif

      P表示platform,也即系统相关的处理,实现整个系统的休眠操作;

      D表示device,表示设备相关的处理,实现设备相关的休眠操作,这部分在各设备驱动中实现。
      可以看到suspend/resume大致流程:

      冻结所有进程/线程(除开当前线程) → 各设备驱动进行相关的状态保存、降频等操作 → 关闭非启动CPU(仅保留CPU0) → 进入P.enter → 开启所有CPU → 各驱动设备恢复状态 → 解冻进程/线程。

      其中P.enter是最关键的操作,该函数不同的处理代表不同的standby模式。当然进入不同的standby,需要相关配套的硬件。AXP的作用是可以控制各路电源,没有AXP,就不能关闭CPU电源,相当于就不能进入Super standby。CPUS在CPU断电的情况下继续运行,在收到各种唤醒源之后,通过AXP将CPU以及其他各路电压恢复,让系统唤醒。

      Super standby的必要条件是AXP,但是有CPUS可以扩展唤醒源。

      由上面的分析可以简单的得出一个结论:休眠唤醒可以按照进程,设备,系统等分为不同的程度,而且是串行的,也就是说这条链中一旦有某个环节(如某个设备无法休眠或唤醒)出问题,那么整个系统就无法正常休眠或唤醒。

      【使用介绍】

      1.系统休眠

      休眠操作就一条命令:
      echo mem > /sys/power/state;
      系统就会进入休眠。
      现象:控制台打印“PM: Entering mem sleep”,然后控制台关闭。如下图:

      2d4b1f2cf15c474e8a9d12f6661dcd93.jfif

      2.系统唤醒

      通过触发中断的方式,唤醒系统。常用唤醒源有:

      • 电源按键唤醒
      • 其他按键唤醒
      • Wifi唤醒
      • 蓝牙唤醒
      • Usb唤醒
      • Sd卡唤醒
      • 定时唤醒
      • 自配置GPIO唤醒

      目前Tina系统普遍支持的有按键、wifi、自配置GPIO。
      现象:控制台打开,打印“PM: Finishing wakeup.”。

      637f0ec5d24d48c19e7fc3f896a53fb0.jfif

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 如何在Tina中添加package编译依赖?

      问题

      Tina 添加package 时,经常会遇到修改了配置或源文件修改,但是package没有自动编译的问题,在修改DEPENDS配置后也得不到解决。本文将介绍三个进阶配置方法,解决上述问题。

      解决方法

      PKG_BUILD_DEPENDS

      PKG_BUILD_DEPENDS表示该package的编译依赖PKG_BUILD_DEPENDS指定包的编译,有可能包括如下几种情况:

      • 本package编译时,用到了PKG_BUILD_DEPENDS指定包的头文件,但是没有用到库。

      • 本pacakge编译,需要依赖host端包先编译完成。比如,package/security/cryptsetup包需要依赖host端cryptsetup工具

      PKG_BUILD_DEPENDS:=cryptsetup/host
      

      PKG_CONFIG_DEPENDS 与 PKG_PREPARED_DEPENDS

      PKG_CONFIG_DEPENDS 表示如果在该宏指定的配置有改动,就会重新做本package的configure及其后续操作。

      PKG_PREPARED_DEPENDS 表示如果在该宏指定的配置有改动,就会重新做本package的prepare及其后续操作。

      通常用于一个package下有很多子配置的情况,或依赖其他包的子配置。

      举个例子,package/security/optee-helloworld/Makefile中包含如下语句。一旦CONFIG_OPTEE_ENCRYPT_TA、CONFIG_OPTEE_ENCRYPT_\TA_SSK_KEY、CONFIG_OPTEE_ENCRYPT_TA_ROTPK_DERIVE_KEY这三个配置发生修改,optee-helloworld都会重新configure及其后续操作。

      PKG_CONFIG_DEPENDS += CONFIG_OPTEE_ENCRYPT_TA CONFIG_OPTEE_ENCRYPT_TA_SSK_KEY CONFIG_OPTEE_ENCRYPT_TA_ROTPK_DERIVE_KEY
      

      PKG_FILE_DEPENDS

      PKG_FILE_DEPENDS 表示如果该宏指定的文件或目录下有改动,会自动编译本package。

      举个例子,package/base-files/Makefile下包含如下语句。一旦(PLATFORM_DIR)与(GENERIC_PLATFORM_DIR)/base-files目录下文件发生改变,就会重新编译base-files这个包。

      PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
      
      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列Tina-Linux4.9部分平台唤醒源配置

      【背景】

      Tina 休眠唤醒框架一直处于不断迭代,向内核标准配置过渡的过程,因此唤醒源配置也从自己实现的接口向内核配置接口过度,因此本文简要说明,Linux4.9部分平台MR813,R818,R329,R311,MR133,R328平台唤醒源配置说明。

      【简介】

      在Linux-4.9中, 存在两种配置配置唤醒源

      • 策略1:向内核声明wakeup-source,由内核保证唤醒中断使能。

      • 策略2:本质上是设置一个全局标志位,然后通过参数传递给底层休眠接口,并在休眠流程末,由平台注册的休眠函数重新使能标记中断。

      其中,策略1 为Linux内核提供的配置方式,也是Tina日后主流推广使用的方式, 策略2是由于过度阶段,部分GPIO唤醒源未能兼容Linux配置,所做的兼容配置

      【分析】

      • 策略1: 向内核声明wakeup-source,由内核保证唤醒中断使能
        常用平台有: MR813,R818,R329等

      • 方法1: 通过device_init_wakeup申请wakup_source,然后通过dev_pm_set_wake_irq注册中断号即可
        参考: linux-4.9/drivers/rtc/rtc-sunxi.c
        方法2: 通过device_init_wakeup申请wakup_source,然后在suspend/resume函数中,调用enable/disable_irq_wake即可
        参考: linux-4.9/drivers/input/keyboard/gpio_keys.c

      • 策略2: 设置一个标志位,在休眠后期,由平台注册的休眠函数重新使能中断
        常用平台有: R311,MR133,R328等

      • 方法1: 通过调用 int enable_gpio_wakeup_src(int para) 函数接口配置。(para 为KERNEL对GPIO解析得到的标号)

      • 参考: linux-4.9/drivers/bluetooth/rtl_btlpm.c
        上述方法1只能支持使用GPIO中断的外部唤醒源的配置,内部唤醒源配置一般也采用策略1中的两种方法。
        参考: linux-4.9/drivers/rtc/rtc-sunxi.c
        参考: linux-4.9/drivers/input/keyboard/sunxi-keyboard.c

      【其他】

      • 需要注意的是,本文所指的唤醒源配置仅是指 使能中断。
        例如,配置一个GPIO唤醒源,除了使能中断(配置唤醒源)外,还需驱动自己保证该IO的复用功能,上下拉状态配置正确。

      • 内部唤醒源和外部唤醒源
        内部唤醒源是指: 具有独立中断号的核内外设配置的唤醒源,如 lradc按键,RTC闹钟等
        外部唤醒源是指: 需要借助GPIO中断实现唤醒的外部设备,如WIFI唤醒,TP唤醒等

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R系列Tina系统Wi-Fi联网失败排查思路

      【问题背景】

      硬件:R系列公板+ Wi-Fi模组(XRADIO/RTL/BCM/ESP/…)
      软件:Tina3.0及以上
      操作:利用wifimanager应用进行联网
      说明:改FAQ旨在总结Wi-Fi联网失败问题的一般解决思路。后续会陆续增加常见问题解决方法的具体案例。

      【问题简述】

      执行 wifi_add_network_test AWTest 1qaz@WSX 1联网时提示

      root@TinaLinux:/# wifi_connect_ap_test AWTest 1qaz@WSX
      ==================================
      connect wpa_supplicant failed,please check wifi driver!
      

      【问题分析】

      Tina网络问题排查步骤一般按照如下顺序排查:
      加载驱-》扫卡-》下载firmware-》起wlan0网卡-》起wpa_supplicant服务-》利用wifimanaer应用联网

      • lsmod查看对应Wi-Fi驱动是否加载。
        若没有加载则执行insmod insmod /lib/modules/4.9.118/xxx.ko(仍然失败则仔细分析加载log是否有异常)
      • ifconfig查看wlan0是否成功起卡。
        若没有起卡执行ifconfig wlan0 up手动起卡。
      • ps | grep wpa_supplicant查看wpa服务是否成功启动。
        若没有执行./etc/init.d/wpa_supplicant start手动起服务。
      • wifi_scan_results_test扫描确认网络是否正常。

      【解决办法】

      一.配置问题

      • 内核驱动,Tina modules, Tina firmware三者必须正确对应同一个模组.
      • 注意common下的modules.mk的编写.
      • Sdio的配置一定要根据原理图选择对应busnum.

      可能导致:

      • 扫卡失败.
      • 下载firmware失败.
        最终导致驱动加载失败.

      二.供电问题

      检查VCC_WIFI和VCC_IO_WIFI两路电

      不同模组对供电时序有一定要求,比如RTL8723ds需要两路电同时供电,针对有AXP的方案,一定要注意供电的配置,特别是enable的时间.

      • 硬件方面:主要排查两路电的供电方案,是否是同一路供电,若是分开供电,要考虑两路供电的时序,例如DCDC1—>VCC_WIFI,LDOA—>VCC_IO_WIFI,那么DCDC1和LDOA的时序就得考虑.
      • 软件方面主要是sysconfig.fex或者boart.dts的配置,分开供电的是否需要单独配置.
        如:R818硬件设计是两路电分开供电,
      1438                         compatible    = "allwinner,sunxi-wlan";
      1439                         clocks        = <&clk_losc_out>;
      1440                         pinctrl-0;
      1441                         pinctrl-names;
      1442                         wlan_busnum    = <0x1>;
      1443                         wlan_power    = "axp806-dcdce";  //该路可配可不配
      1444                         wlan_io_regulator = "axp806-aldo2"; //该路必须配
      1445                         wlan_io_voltage = <3300000>;
      1446                         wlan_power_voltage = <3300000>;
      1447                         wlan_regon    = <&r_pio PL 5 1 0x1 0x2 0>;                                                                                                
      1448                         wlan_hostwake = <&r_pio PL 6 6 0x1 0x2 0>;
      1449                         chip_en;
      1450                         power_en;
      1451                         status        = "okay";
      1452                         wakeup-source;
      1453                 };
      

      97336fadec1a4642beac6924dd13f42c.jfif

      可能导致:

      • 扫卡失败.
      • 下载firmware失败.
      • sdio_clk没有时钟.
      • 32k晶振不起振.

      最终导致驱动加载失败.

      三.Sdio问题

      • sdio busnum配置错误.
      • 驱动WL-REG-ON的方式不对.例如:
        XR819模块出现
        [SBUS_ERR] sdio probe timeout!
        [XRADIO_ERR] sbus_sdio_init_failed
        这个问题主要是sdio扫卡失败,跟sdio上电时序有关,可在drivers/net/wireless/xradio/wlan/platform.c中xradio_wlan_power函数sunxi_wlan_set_power(on)后面加上一段延时。
        RLT8723ds需要先高-低-高的方式。
      • sdio的供电电压,RTL8821cs就是用的1.8v.
           sdio-used-1v8;
      • 列表Sdio-clk,飞线方式时,传输比较差,就需要降低频率.
         max-frequency = <25000000>; //降低到25M.

      可能导致:

      • 扫卡失败
      • 下载firmware失败
      • sdio_clk没有时钟
      • 32k竞争不起振
      • WL-REG-ON无法正常被拉高.

      最终导致驱动加载失败.

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329出现以太网使能报No phy found或Initialize hardware error怎么解决?

      1.【问题现象】

      执行ifconfig eth0 up命令,出现"No phy found"或"Initialize hardware error"异常log,有如下类似打印:

      root@TinaLinux:/# ifconfig eth0 up
      [  130.363159] libphy: gmac0: probed
      [  130.366897] sunxi-gmac gmac0 eth0: No PHY found!
      ifconfig: SIOCSIFFLAGS: Invalid argument
      
      root@TinaLinux:/# ifconfig eth0 up
      [   30.109456] libphy: gmac0: probed
      [   30.113921] sunxi-gmac gmac0 eth0: eth0: Type(7) PHY ID 0000ffff at 0 IRQ poll (gmac0-0:00)
      [   30.133308] sunxi-gmac gmac0 eth0: Initialize hardware error
      

      2.【问题分析】

      • 出现"No phy found",常见原因是供给phy使用的25M时钟异常,导致phy工作不正常,gmac驱动通过mdio接口也读不到phy的设备信息;
      • 出现"Initialize hardware error",一般是由于phy没有输出rx clk至mac控制器,导致mac控制器内部soft reset失败,常见原因是phy供电异常或25M时钟异常;

      3.【排查步骤】

      • 检查phy供电是否正常;
      • 检查phy使用的25M时钟(Soc ephy25M或外部晶振)是否正常;
      • 检查phy-mode是否按板级实际情况配置(mii/rmii/rgmii);
      • 检查phy-rst引脚配置是否正确;
      • 检查phy芯片的rx clk和tx clk引脚信号是否正常,若出现异常,需检查phy外围电路是否符合规范;

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329以太网常用调试命令和排查手段

      1.【以太网常用调试命令】

      1.1 打开/关闭网络设备

      打开网络设备:ifconfig eth0 up
      关闭网络设备:ifconfig eth0 down
      

      1.2 查看网络设备信息

      查看网口状态及收发包统计:ifconfig eth0
      查看收发包统计:cat /proc/net/dev
      查看当前速率:cat /sys/class/net/eth0/speed
      

      1.3 配置网络设备

      设置静态IP地址:ifconfig eth0 192.168.1.100
      设置置MAC地址:ifconfig eth0 hw ether 00:11:22:aa:bb:cc
      动态获取IP地址:udhcpc -i eth0
      配置PHY强制模式:ethtool -s eth0 speed 100 duplex full autoneg on(设置100Mbps速率、全双工、开启自协商)
      

      1.4 常用测试命令

      测试设备连通性:ping 192.168.1.100
      
      TCP吞吐测试:
      Server端:iperf -s -i 1
      Client端:iperf -c 192.168.1.100 -i 1 -t 60 -P 4
      
      UDP吞吐测试:
      Server端:iperf -s -u -i 1
      Client端:iperf -c 192.168.1.100 -u -b 100M -i 1 -t 60 -P 4
      

      2.【以太网常用排查手段】#

      2.1 常用软件排查手段

      • 检查menuconfig及dts以太网配置是否打开;
      • 检查phy-mode配置是否与PHY和GMAC之间的物理接口匹配,如rgmii、rmii等;
      • 检查clk配置是否正确,如gmac clk、ephy_25m clk;
      • 检查GPIO配置是否正确,如IO复用功能、驱动能力等;
      • 检查phy-reset配置是否正确;
      • 通过cat /proc/net/dev命令查看eth0收发包统计;
      • 通过cat /proc/interrupts命令查看gmac中断统计;
      • 通过cat /sys/devices/platform/soc/gmac0/extra_tx_stats(或extra_rx_stats)命令查看gmac控制器收发包统计;
      • 通过cat /sys/devices/platform/soc/gmac0/mii_reg命令查看phy状态;

      2.2 常用硬件排查手段

      • 检查phy供电(vcc-ephy)是否正常,与GPIO耐压是否匹配;
      • 检查phy时钟(ephy25M或外部晶振)是否正常;
      • 检查tx/rx通路是否正常,如是否漏焊tx-delay/rx-delay电阻、差分走线、阻抗匹配、端接电阻异常、ESD器件异常等;
      • 检查RJ45外围电路是否正常;

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329以太网网络不通或丢包严重怎么解决?

      1.【问题现象】

      现象1:ifconfig eth0 up正常,但一直无法动态获取ip地址,有如下类似打印:

      [   12.296892] libphy: gmac0: probed
      [   12.420621] sunxi-gmac gmac0 eth0: eth0: Type(7) PHY ID 001cc916 at 0 IRQ poll (gmac0-0:00)
      [   15.524572] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
      [   23.708540] sunxi-gmac gmac0 eth0: Link is Up - 100Mbps/Full - flow control rx/tx
      root@TinaLinux:/#
      root@TinaLinux:/# udhcpc -i eth0
      udhcpc: started, v1.27.2
      udhcpc: sending discover
      udhcpc: sending discover
      udhcpc: sending discover
      

      现象2:ifconfig eth0 up正常,配置静态ip地址后,无法ping通对端设备,有如下类似打印:

      root@TinaLinux:/# ifconfig eth0 192.168.1.100
      root@TinaLinux:/# 
      root@TinaLinux:/# ifconfig eth0
      eth0      Link encap:Ethernet  HWaddr 36:C9:E3:F1:B8:05  
                inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
                inet6 addr: fe80::34c9:e3ff:fef1:b805/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                RX packets:0 errors:239 dropped:0 overruns:0 frame:0
                TX packets:232 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000 
                RX bytes:0 (0.0 B)  TX bytes:77384 (75.5 KiB)
                Interrupt:124 
      root@TinaLinux:/# 
      root@TinaLinux:/# ping 192.168.1.101
      PING 192.168.1.101 (192.168.1.101): 56 data bytes
      

      2.【问题分析】

      通常原因是tx或rx通路某条通路不通,tx通路异常导致数据发不出去,同理rx通路异常导致接收不到数据。
      注:

      • tx通路指发送数据通路,路径为mac->phy->rj45->…
      • rx通路指接收数据通路,路径为…->rj45->phy->mac

      3.【排查步骤】

      • 配置静态ip地址,和对端设备处于同一子网内,同对端设备互相ping;
      • 开发板ping对端设备,通过ifconfig eth0命令检查对端设备能否收到数据,若能收到,则说明开发板tx通路正常,否则tx通路异常;
      • 对端设备ping开发板,通过ifconfig eth0命令检查开发板能否收到数据,若能收到,则说明开发板rx通路正常,否则rx通路异常;
      • 若tx通路异常,可调整dts gmac模块的tx-delay参数并通过"cat /sys/devices/platform/soc/gmac0/extra_tx_stats"确认是否有错误包,
        或者对照硬件原理图检查tx通路是否异常,如漏焊关键器件;
      • 若rx通路异常,可调整dts gmac模块的rx-delay参数并通过"cat /sys/devices/platform/soc/gmac0/extra_tx_stats"确认是否有错误包,
        或者对照硬件原理图检查rx通路是否异常,如漏焊关键器件;
      • 检查phy供电与GPIO耐压是否匹配;

      注:

      • RGMII接口对时钟和数据的相位要求比较严格,因此通常需要调整tx-delay和rx-delay参数保证数据传输的正确性;
      • tx-delay:tx clk延迟,取值0~7,一档约536ps(皮秒);
      • rx-delay:rx clk延迟,取值0~31,一档约186ps(皮秒);

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329以太网模块初始化失败如何解决?

      1.【问题现象】
      执行ifconfig -a/ifconfig eth0/ifconfig eth0 up命令,找不到eth0设备,有如下类似打印:

      root@TinaLinux:/# ifconfig -a
      lo        Link encap:Local Loopback  
                inet addr:127.0.0.1  Mask:255.0.0.0
                inet6 addr: ::1/128 Scope:Host
                UP LOOPBACK RUNNING  MTU:65536  Metric:1
                RX packets:6480 errors:0 dropped:0 overruns:0 frame:0
                TX packets:6480 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1 
                RX bytes:505440 (493.5 KiB)  TX bytes:505440 (493.5 KiB)
      
      root@TinaLinux:/# 
      root@TinaLinux:/# ifconfig eth0
      ifconfig: eth0: error fetching interface information: Device not found
      root@TinaLinux:/# 
      root@TinaLinux:/# ifconfig eth0 up
      ifconfig: SIOCGIFFLAGS: No such device
      

      2.【问题分析】

      以太网模块配置未生效或存在GPIO冲突

      3.【排查步骤】

      步骤1:抓取内核启动log,搜索"gmac"关键字段,检查gmac驱动是否probe成功;

      步骤2:若内核启动log显示probe失败,常见原因是GPIO资源冲突导致,有如下类似打印:

      sun50iw10p1-pinctrl pio: pin PH0 already requested by twi0; cannot claim for gmac0
      sun50iw10p1-pinctrl pio: pin-224 (gmac0) status -22
      sun50iw10p1-pinctrl pio: could not request pin 224 (PH0) from group PH0  on device pio
      sunxi-gmac gmac0: Error applying setting, reverse things back
      sunxi-gmac: probe of gmac0 failed with error -22
      

      步骤3:若内核启动log无gmac相关打印,则需要确认以太网配置是否生效。

      4.【解决办法】

      4.1 GPIO冲突

      (1) 首先,结合内核启动log定位与哪个模块存在GPIO冲突,有如下类似打印:

      sun50iw10p1-pinctrl pio: pin PH0 already requested by twi0; cannot claim for gmac0
      

      (2) 然后,确认该模块GPIO配置是否有误或者是否可以关闭该模块。

      4.2 以太网配置未生效

      (1) 首先,确认内核menuconfig以太网模块配置是否打开,路径及截图如下:
      menuconfig -> Device Drivers -> Network device support -> Ethernet driver support

      3dcc7d980e5444a7974c067edefb4933.jfif

      (2) 然后,确认board.dts/sys_config.fex中GMAC模块是否打开,board.dts配置示例如下:

      gmac0: eth@05020000{
          phy-mode = "rgmii";
          use_ephy25m = <1>;
          tx-delay = <7>;
          rx-delay = <0>;
          status = "okay";
      };
      

      注:

      • status = “okay"代表打开该模块,status = “disabled"代表关闭该模块;
      • 确保PHY与GMAC之间物理接口与软件配置相匹配,对于RGMII接口phy-mode配置为"rgmii”,RMII接口phy-mode配置为"rmii”;
      • use_ephy25m=1代表PHY使用SOC内部EPHY_25M时钟,use_ephy25m=0或者不配置该参数,代表PHY不使用SOC内部EPHY_25M时钟,
        需外挂25M晶振为PHY提供时钟;

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 Tina中使用如何使用perf分析CPU使用率?

      perf简介

      Perf是是内置于Linux内核源码树中的性能剖析(profiling)工具。

      • 不仅可以用于应用程序的性能统计分析,还可以用于内核的性能统计和分析。
      • 它基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。
      • 常用于性能瓶颈的查找与热点代码的定位。

      Tina上开启perf功能

      删除out目录,开启如下Tina与内核的相关选项,重新编译。客户的程序不能strip。

      52922898c4824c2c9899e4f345523674.jfif

      如果客户应用程序没有嵌入到Tina一起编译,建议客户检查相关编译选项,主要是浮点、neon、优化等选项,如”-Os -march=armv7-a -mtune=cortex-a7 -mfpu=neon -mfloat-abi=hard“等。

      使用perf工具分析CPU使用率

      • 设备端先采集:
        ① perf record -e cpu-clock -g -p --> 采集指定PID进程的cpu使用情况,采集的数据存放到当前目录下的perf.data文件中
        perf record -e cpu-clock -g -a --> 采集指定整个系统的cpu使用情况,采集的数据存放到当前目录下的perf.data文件中
        ② perf script -i perf.data > /tmp/perf.data.txt --> 解析perf.data转换为文本文档
        ③ perf report --> 设备端解析当前路径下perf.data文件生成报告

      • PC端借助flamegraph生成火焰图(也可以直接在设备端执行perf report来分析):
        ① adb pull /tmp/perf.data.txt .
        ② ./stackcollapse-perf.pl perf.data.txt > perf.data.fold --> 将文本文档中的符号进行折叠
        ③ ./flamegraph.pl perf.data.fold > perf.svg --> 生成svg图

      • PC端(ubuntu)工具如附件FlameGraph.tar.xz所示。

      火焰图说明

      生成的火焰图类似下图。其中x轴表示抽样数,如有一个函数在x轴上的长度越长,表明抽样的次数越多,则执行时间越长,占用cpu越多。y轴表示调用栈,每个函数占据一层,层数(火焰)越高,表明调用栈越深。

      797c3e02b9ee4140ba67f4f1ed4c25a8.jfif

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R329 Tina中如何使用adb/串口密码登录?

      如果需要在adb shell密码登录命令行终端,可按以下步骤进行操作。

      /etc/shadow 文件,用于存储 Linux 系统中用户的密码信息,又称为“影子文件”。

      文件中每行代表一个用户,同样使用 “:” 作为分隔符,不同之处在于,每行用户信息被划分为 9 个字段。每个字段的含义如下:

      用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段

      adb 设置密码登录,操作如下:

      1、创建密码:

      这个操作可通过 makepasswd 工具创建,命令如下:

      makepasswd  --clearfrom=-  --crypt-md5 <<< YourPass
      
      eg:
      usr # makepasswd  --clearfrom=-  --crypt-md5 <<< allwinner
      allwinner   $1$z6v447Dx$HH4Ytv0Hvi5MfxVgQ6uSE.
      

      2、填充 /etc/shadow 文件:

      在 target/allwinner/方案名/base-file/etc/shadow 文件中,添加如下信息,第二字段的信息就是上述 makepasswd 创建的密码密文:

      root:$1$z6v447Dx$HH4Ytv0Hvi5MfxVgQ6uSE.:1:0:99999999999:7:::
      

      3、修改 adb_shell 文件:

      在 tina/package/utils/adb 目录下,修改当前目录的 adb_shell 文件,将该文件的 /bin/sh 替换为 /bin/login;

      4、执行 make menuconfig

      在 Base system —> <> busybox —> Login/Password Management Utilities —> [] login,按照上述路径选上 login;

      5、重新编译烧写固件

      adb shell命令之后将会需要输入用户名和密码,上述的例子,用户名为:root,密码为:allwinner;

      注意:上述的操作,只是 adb shell 需要登录密码,在串口端仍不需要登录密码。

      串口端也进行密码登录的操作

      如果在串口端也需要进行相应的密码登录验证,需要修改 /etc/inittab 这个文件。在 target/allwinner/方案名/base-file/etc 目录下存在 inittab 文件,原文件如下:

      ::sysinit:/etc/init.d/rcS S boot
      ::shutdown:/etc/init.d/rcS K shutdown
      ::askconsole:/bin/ash --login
      

      修改为

      ::sysinit:/etc/init.d/rcS S boot
      ::shutdown:/etc/init.d/rcS K shutdown
      ::askconsole:/bin/login
      

      使串口终端通过 login 登录,注意,这个一样需要 login 的支持,所以 busybox 需要选上 login(参照上述adb的第 4 点选上 login)。

      通过公私钥的加密验证方式登录 adb 终端

      ubuntu 系统,~/.ssh 目录下,会存在一个 adb 使用的公私钥,分别是 id_rsa.pub 和 id_rsa ,而 windows 则是在系统盘的 user 目录下有 .android 目录存放公私钥。将 PC 端的公钥添加到设备端的某个路径,设备端的服务开启公私钥加密验证的方式,在使用 adb 的时候,将需要使用 PC 端的秘钥和设备端的公钥进行验证,验证通过之后才可以通过 adb 进入设备终端。
      当前 Tina 系统有支持通过adb的公私钥进行验证的,patch 如下:

      diff --git a/utils/adb/Makefile b/utils/adb/Makefile
      index c57fc6b..28c4ddb 100755
      --- a/utils/adb/Makefile
      +++ b/utils/adb/Makefile
      @@ -133,6 +133,9 @@ define Package/adbd_auth_service/install
              $(INSTALL_DIR) $(1)/bin
              $(INSTALL_BIN) $(PKG_BUILD_DIR)/auth/adbd_auth_service $(1)/bin/
       
      +       $(INSTALL_DIR) $(1)/etc
      +       $(INSTALL_DATA) ./id_rsa.pub $(1)/etc/
      +
              $(INSTALL_DIR) $(1)/etc/init.d
              if [[ $(KERNEL_PATCHVER) == 4.* ]]; then \
                $(INSTALL_BIN) ./adbd-configfs.init $(1)/etc/init.d/adbd; \
      diff --git a/utils/adb/auth/Makefile b/utils/adb/auth/Makefile
      index efc4816..c68e22c 100755
      --- a/utils/adb/auth/Makefile
      +++ b/utils/adb/auth/Makefile
      @@ -22,7 +22,7 @@ $(ADB_AUTH_LIB): $(LIB_OBJS)
              $(CC) -shared $(LOCAL_CFLAGS) $(LDFLAGS) -lev $^ -o $@
       
       $(ADB_AUTH_SERVICE): $(SERVICE_OBJS)
      -       $(CC) $(LDFLAGS) $(SERVICE_LIB) $^ -o $@
      +       $(CC) $(LDFLAGS) $(SERVICE_LIB) $^ -o $@ -lm
       
       lib:$(ADB_AUTH_LIB)
       
      diff --git a/utils/adb/auth/aw_adb_auth.c b/utils/adb/auth/aw_adb_auth.c
      index 24519f7..9817bee 100644
      --- a/utils/adb/auth/aw_adb_auth.c
      +++ b/utils/adb/auth/aw_adb_auth.c
      @@ -29,6 +29,37 @@ static int debug_mask = 0;
       static pubkey_detector_t g_pubkey_detector_func;
       static char *g_key_path = DEFAULT_KEY_PATH;
       
      +/*
      + * Copy src to string dst of size siz.  At most siz-1 characters
      + * will be copied.  Always NUL terminates (unless siz == 0).
      + * Returns strlen(src); if retval >= siz, truncation occurred.
      + */
      +size_t
      +strlcpy(char *dst, const char *src, size_t siz)
      +{
      +        char *d = dst;
      +        const char *s = src;
      +        size_t n = siz;
      +
      +        /* Copy as many bytes as will fit */
      +        if (n != 0) {
      +                while (--n != 0) {
      +                        if ((*d++ = *s++) == '\0')
      +                                break;
      +                }
      +  }
      +
      +        /* Not enough room in dst, add NUL and traverse rest of src */
      +        if (n == 0) {
      +                if (siz != 0)
      +                        *d = '\0';              /* NUL-terminate dst */
      +                while (*s++)
      +                        ;
      +        }
      +
      +        return(s - src - 1);    /* count does not include NUL */
      +}
      +
       void free_environment(const char *env[], int num)
       {
              int i;
      diff --git a/utils/adb/auth/aw_adb_auth_service.c b/utils/adb/auth/aw_adb_auth_service.c
      index 17a5c85..e8da189 100644
      --- a/utils/adb/auth/aw_adb_auth_service.c
      +++ b/utils/adb/auth/aw_adb_auth_service.c
      @@ -17,7 +17,7 @@ static bool publickey_detector(const char *pubkey, int len)
       {
              char *ptr = NULL;
              printf("get public key:\n%s\n", pubkey);
      -       ptr = strstr(pubkey, "forevercai");
      +       ptr = strstr(pubkey, "chengwei");
              if (!ptr)
                      return false;
              return true;
      @@ -35,14 +35,14 @@ int main()
                      printf("aw_adbd_create failed\n");
                      return -1;
              }
      -       /*aw_adbd_set_key_path(handle, "/opt/adb_keys");*/
      +       aw_adbd_set_key_path(handle, "/etc/id_rsa.pub");
              ret = aw_adbd_start(handle);
              if (ret != 0) {
                      printf("aw_adbd_start failed\n");
                      return -1;
              }
       
      -       /*aw_adbd_install_pubkey_detector(publickey_detector); */
      +       aw_adbd_install_pubkey_detector(publickey_detector);
              aw_adbd_event_loop(handle);
              printf("adbd_auth_service finish\n");
       }
      

      在上述的patch中,解析如下:

      • utils/adb/Makefile 中的修改,主要是将公钥文件拷贝到机器端,在使用adb功能时将会使用到公钥文件;
      • aw_adbd_set_key_path(handle, “/etc/id_rsa.pub”); 则是告知adb服务,公钥保存在机器端的位置;
      • aw_adbd_install_pubkey_detector(publickey_detector); 则是增加公钥的检查,在 publickey_detector() 中检查一下公钥,是否是正确的;

      按照上述配置修改编译之后,可验证只有 PC 端存在和设备端匹配的私钥才可以通过 adb 登录设备终端。

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R11移植camera senor时报I2C错误如何解决?

      在移植sensor时,最常遇到的问题是I2C通信失败,下面将就I2C通信失败问题进行相应的debug。

      DEBUG流程

      • 确认sys_config.fex中配置的sensor I2C地址是否正确(sensor datasheet中标注,读地址为0x6d,写地址为0x6c,那么sys_config.fex配置sensorI2C地址为0x6c);

      • 在完成以上操作之后,在senor上电函数中,将掉电操作屏蔽,保持sensor一直上电状态,方便debug;

      • 确认I2C地址正确之后,测量sensor的各路电源电压是否正确且电压幅值达到datasheet标注的电压要求;

      • 测量MCLK的电压幅值与频率,是否正常;

      • 测量sensor的reset、pown引脚电平配置是否正确,I2C引脚SCK、SDA是否已经硬件上拉;

      • 确认I2C接口使用正确并使能(CCI / TWI);

      • 如果还是I2C出错,协调硬件同事使用逻辑分析仪等仪器进行debug;

      经典错误

      1、I2C没有硬件上拉

      twi_start()450 - [i2c2] START can't sendout!
      twi_start()450 - [i2c2] START can't sendout!
      twi_start()450 - [i2c2] START can't sendout!
      [VFE_DEV_I2C_ERR]cci_write_a16_d16 error! slave = 0x1e, addr = 0xa03e, value = 0x  1
      

      出现上述的问题是因为SDA、SCK没有拉上,导致在进行I2C通信时,发送开始信号失败,SDA、SCK添加上拉即可。

      2、没有使能I2C

      [VFE]Sub device register "ov2775_mipi" i2c_addr = 0x6c start!
      [VFE_ERR]request i2c adapter failed!
      [VFE_ERR]vfe sensor register check error at input_num = 0
      

      出现上述的错误,是因为使用twi进行I2C通信但没有使能twi导致的错误。

      3、混用 cci 和 twi

      通过查看原理图确认,sensor是通过什么接口与主控进行通信的,在确认硬件连接没有问题的情况下,可查看出错时的log信息得知当前使用的接口。

      • 如果当前配置使用 CCI 进行 I2C 通信,出错将会报“[VFE_DEV_CCI_ERR]”或者“[VIN_DEV_CCI_ERR]”;

      • 如果当前配置使用的是 TWI 进行 I2C 通信,出错将会是“[VFE_DEV_I2C_ERR]”或者“[VIN_DEV_I2C_ERR]”;
        在出现问题的时候,可以注意 I2C 的错误打印信息,看看是什么标号开头的,这样可以确定,本身应该使用 TWI 的,但却报”[VFE_DEV_CCI_ERR]“错误,这个时候可以检查,是不是关于 cci 的配置没有弄好,相应的配置没有失能或者屏蔽,或者是定义了 USE_SPECIFIC_CCI 宏。

      4、sensor上电时序不对

      在sensor的上电过程,加上一定的延时是必要的。在主控输出MCLK、设置电源等操作之后,立刻sensor detect读取I2C,有可能会导致I2C读写失败的。因为这个时候,senor内部硬件没有准备好,这时候读写I2C将会出错,所以需要在上电之后,加上一定的延时操作。

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【FAQ】全志R11 Tina如何替换开机Logo?

      1. 准备工作

      准备一张bmp格式的图片,重命名为bootlogo.fex

      这里以R11平台为例

      把bootlogo.fex替换下面目录的文件

      tina/target/allwinner/banjo-R11_pref1/configs/bootlogo.fex
      

      再重新打包固件

      2. 注意事项

      开机logo的色彩空间要和sys_config.fex中fb0_format配置的一致

      比如fb0_format配置的是ARGB8888 32bit,logo的是RGB888 24bit,开机logo显示正常,但是运行MiniGUI等程序的时候会异常

      可以执行下面的命令看framebuffer的色深从32被改成24了

      cat /sys/class/graphics/fb0/bits_per_pixel
      

      再看一下图层信息

      cat sys/class/disp/disp/attr/sys
      

      fb0_format被改成RGB888 24bit的了

      再比如fb0_format配置的是RGB565 16bit,有些图片看信息是16bit的,但是不是RGB565,而是RGBA5551的,显示也会不正常

      如果不知道怎么转换图片的位深度,可以点击BMP图片格式转换

      1.png

      下面列出fb0_format配置对应的色彩空间格式

      //fb0_format	
      DISP_FORMAT_ARGB_8888 = 0x00, //MSB  A-R-G-B  LSB
      DISP_FORMAT_ABGR_8888 = 0x01,
      DISP_FORMAT_RGBA_8888 = 0x02,
      DISP_FORMAT_BGRA_8888 = 0x03,
      DISP_FORMAT_XRGB_8888 = 0x04,
      DISP_FORMAT_XBGR_8888 = 0x05,
      DISP_FORMAT_RGBX_8888 = 0x06,
      DISP_FORMAT_BGRX_8888 = 0x07,
      DISP_FORMAT_RGB_888 = 0x08,
      DISP_FORMAT_BGR_888 = 0x09,
      DISP_FORMAT_RGB_565 = 0x0a,
      DISP_FORMAT_BGR_565 = 0x0b,
      DISP_FORMAT_ARGB_4444 = 0x0c,
      DISP_FORMAT_ABGR_4444 = 0x0d,
      DISP_FORMAT_RGBA_4444 = 0x0e,
      DISP_FORMAT_BGRA_4444 = 0x0f,
      DISP_FORMAT_ARGB_1555 = 0x10,
      DISP_FORMAT_ABGR_1555 = 0x11,
      DISP_FORMAT_RGBA_5551 = 0x12,
      DISP_FORMAT_BGRA_5551 = 0x13,
      

      附件:FlameGraph.tar.xz

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 【小白自制Linux开发板】 一. 瞎抄原理图与乱画PCB

      《论语》说:见贤思齐焉。所以现在墨云又开始瞎折腾了

      为啥突然想做嵌入式开发呢,因为看见了下面两位牛人

      【稚晖君】

      https://www.bilibili.com/video/av65365123/

      【在名片上运行的Business Card Linux】

      https://www.thirtythreeforty.net/posts/2019/12/my-business-card-runs-linux/

      于是躁动的心开始蠢蠢欲动。

      先定个小目标:

      设计一个没啥作用,但是可以运行Linux的小板。

      样子大概长这样:

      1.png

      所以有了初步想法,那开始吧。

      1.工具与芯片说明

      立创EDA:电路图与PCB设计工具,本次硬件部分设计全部使用立创EDA完成

      F1C100s :全志的一款基于Arm的小型Soc,自带32MB的内存,其升级版F1C200s为64MB内存,因为其极其便宜(当然最近因为芯片涨价影响),可以运行Linux,最典型的基于该芯片的荔枝派开发板。

      CH340E:USB转串口通信芯片,是作为与外界通信的唯一接口 、CH340E个头小、外围电路少,使用简单。

      原理图:先后参考了(baipiao)了Licheepi Nano、Business LinuxCard、LiShanwenGit(https://www.oshwhub.com/LSW12315)立创开源广场的一系列项目

      2.原理图说明

      电源管理

      电源部分使用USB方式供电,输入电压为5V,这里供电部分和串口电路共用相同USB端口。

      2.png

      通过查询F1c100s数据手册:

      3.png
      4.png

      通过综合分析,我们可以大概把电源分为4类

      Vdd-Core:1.1V

      Vcc-Dram:2.5V

      AVCC : 3.0V

      UVCC/VCC-IO/TV-AVCC/TTL:3.3

      这里主要使用 SY8088AAC 同步降压DC-DC稳压器,为SOT32-5的封装方式,通过使用外围电阻调整输出电压。

      公式为:Vout = 0.6 * (`1+Ra/Rb)

      而AVCC使用XC6206P302MR-SOT23的封装方式,输入5V 输出为3.0V

      因为 AVCC为模拟电源电压,为了避免引入电源干扰,通常需要把把模拟电路与数字电路分开隔离开(这个地方解释可能不对,欢迎指正)。

      电源部分的原理图如下:

      5.png

      电压输入输出端都使用滤波电容进行处理,使用还要接入2.2uH的功率电感,注意一定要用功率电感,电流要求可以达到1A以及以上的才行

      这个板子使用0805的功率电感,建议最好使用CD32类型的绕线功率电感。

      核心原理图

      对于核心部分的原理图如下,因为本次电路设计主要以验证为主,所以并没有做太多的外设电路。

      6.png

      除了常规的核心、外围、DRAM工单引脚,核心部分还引出了

      1. TF卡引脚,作为本板子唯一的系统加载电路,这是必须的

      2.晶振,使用规格为24Mhz的有源晶振、加两个15pf的负载电容

      3.串口调试 作为板子与外界唯一交互的通道,这个也是必须的,然而在做这个成功的给自己挖坑了。

      4.LED灯,这是这个板子唯一的外设,也是用来学习驱动开发的第一步。

      5.dram_vref、Var1、Var2 这是必须要接的、外围电路,我也不知道的干啥的 ~_~…

      6.USB OTG 也是作为一个通信接口来使用,通过这个接口可以为板载Flash下载程序,但是因为本板没有做Flash,所以目前唯一的作用就是放到验证fel是否可以调通。

      7.复位按钮

      挖坑点

      一直以来认为发光二极管也是二极管,所以就有下面的设计(乱画),于是后来感觉板子没问题,但是就是串口死活不显示数据、在众多大佬的帮助下,才发现了这个其妙(naocan)

      的接线方法,于是将两个发光二极管位置放了两个0欧的电阻,一下子就成功调通了。

      7.png

      对于芯片电源输入端的滤波电容与Dram_vref接线如下:

      对于滤波电容简单的说法就是,对于供电端的电压,因为电路设计或者外界干扰等等,其实不是完美的电压,总会存在高频或是低频的噪声,而用小容量的电容就可以降低这些干扰。

      常规的容值就是 10uf 、1uf、100nf

      8.png

      通信电路

      我们在核心原理图中看到了引出的串口线路,而串口的接口如下:

      9.png
      10.png

      显然在你看看你超博的笔记本机身,并没有发现这个接口,偶尔还有一些老的笔记本上面可以看到类似的接口,对不起——那是显示屏的VGA接口。

      那我们如何使用串口传输的信息呢,我们需要一个USB转串口的芯片,usb转串口的芯片很多,这里选择 CH340E 这个型号,因为其很小,接线也方便。

      原理图如下:
      11.png

      前面提到,这个板子共用了电源与TTL共用了一套设计,也就是是说USB线插上就可以启动小板,并且开始进入串口调试。

      原理图中的U5是一个自恢复保险丝。

      这里需要注意一下:

      根据CH340E官方的原理图,当VCC接入5V的时候,V3 需要接一个100nf的电容,但是此处在V3直接接入5V,也可以工作。

      实际使用的时候最好不要这样做。

      TF卡接口

      和电脑主机在BIOS选择启动方式一样, F1C100s 支持多种方式的系统加载机制比如通过SPI接口加载Flash芯片中的镜像,或者通过TF卡接口加载镜像。

      这里使用TF卡作为启动源,这样做是因为

      1.TF卡容量可以自己控制。

      2.系统烧写调试方便

      这部分电路相对简单,原理图如下:

      12.png

      OTG 与唯一的外设LED灯

      13.png

      3.PCB绘制

      PCB尺寸为42mm*29mm ,可以说非常小了,为了便于焊接,所有容阻都是用0805的封装方式

      电源走线为14mil ,信号线为8mil

      14.png

      4.PCB焊接

      焊接PCB是一项手艺活,尤其是QFN方式封装的F1C100s 更是难到发指,还好借助焊台和热风枪,完美的完成了焊接,当然放大镜、洗板水是不可缺少的。

      并且因为板子时长需要在手上把玩(盘PCB)。所以选择了无铅稀浆进行焊接。

      效果如下:

      15.png
      16.png

      成功运行Linux,

      因为还没开始着手做Linux移植,暂时使用LicheePi 的镜像,下一节开始做Linux的移植。

      17.png

      5. 后记

      事实上世界上从来没有所谓轻易的成功,对于初次玩PCB的小白更是如此,现在这个小板能成功也是经历三四个月,五六次打板才成功的。以下是早期的趟雷PCB场景与先烈。 (右下角为成功的小板)
      18.png
      19.png

      硬件资料包:

      下载

      以上内容来自 WhyCan Forum哇酷开发者社区
      小白自制Linux开发板(F1C200s)整理系列,持续更新中
      作者:twzy

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 回复: 【素材汇总】D1开发板图片素材汇总

      D1S MANGO正扣black.png

      发布在 公告
      q1215200171
      budbool
    • 回复: 支持鸿蒙的蓝牙开发板

      https://xr806.docs.aw-ol.com/xr806_dev/

      发布在 其它全志芯片讨论区
      q1215200171
      budbool
    • 回复: 【素材汇总】D1开发板图片素材汇总

      “1”为智能对象-1.png

      发布在 公告
      q1215200171
      budbool
    • 【R329-NPU助力】Maix-Speech为嵌入式环境设计的离线语音库

      Maix-Speech是专为嵌入式环境设计的离线语音库,设计目标包括:ASR/TTS/CHAT

      作者的设计初衷是完成一个低至Cortex-A7 1.0GHz 单核下可以实时运行的ASR库。

      目前市面上的离线语音库非常稀缺,即使有也对主控要求很高,Maix-Speech 针对语音识别算法进行了深度优化,在内存占用上达到了数量级上的领先,并且保持了优良的WER。

      基本情况

      Maix-Speech刚发布了一个面向嵌入式设备的离线语音识别库,可以在低至Coretx-A7 1.0GHz, 64MB系统内存的嵌入式设备上实时运行(RTF<1.0)

      最低内存占用25MB,磁盘占用35MB(含语言模型);最优aishell wer约5.4%;支持流式识别,支持连续数字识别,关键词识别,连续大词表语音识别等

      支持:x86_64, armv7, aarch64, riscv64 等多种硬件平台,支持 AWNN, Zhouyi AIPU 加速。

      感兴趣的可以跳转githuib来点个赞。

      链接:https://github.com/sipeed/Maix-Speech

      Maix-Speech 的优势

      • 列表多平台支持

      Maix-Speech 支持多种嵌入式平台

      1.png

      • 列表极低的内存要求和优良的正确率

      Maix-Speech的内存占用相对于市面上的其他语音识别框架有数量级上的领先优势,并且保持良好的WER水平。

      Maix-Speech最低可以实时运行(RTF<1)于典型的 1.0GHz Cortex-A7 内核的芯片上,并且最低仅占用25MB左右内存, 也就意味着它可以实时运行在典型的内封64MB内存的A7芯片上。

      2.png
      常见离线语音识别工具对比

      • 细节优化

      优化了openfst及wfst解码,使得整个解码图无需载入内存即可实时读取解码。

      可选载入内存的LG.fst解码图,压缩为lg.sfst, 尺寸为原始fst的1/3左右,占用内存为kaldi载入相同fst的内存占用的 1/20左右(kaldi需要6.5倍左右内存载入fst文件)。

      使用新的sMBR等效的方式(无需修改loss)进行鉴别性训练,提升流式识别的准确率。

      • 效果展示

      在全志 R329 上的运行效果,视频中板卡为 MaixSense

      连续大词汇量语音识别(LVCSR)

      连续中文数字识别 (DIGIT)

      关键词识别(KWS)

      Maix-Speech 工程结构

      [├── assets
      │   └── test_files                # 提供的测试文件,方便上手测试
      ├── components                     # 组件
      │   ├── asr_lib                   # 组件 asr_lib
      │   │   ├── CMakeLists.txt       # 组件配置文件
      │   │   ├── include              # 头文件
      │   │   ├── Kconfig              # 组件 menuconfig 配置文件
      │   │   ├── lib                  # 各个平台的库文件
      │   │   └── src                  # 源文件
      │   └── utils                     # 工具类组件,包括了跑分、字体等
      ├── Kconfig                       # 最顶级的 menuconfig 配置文件
      ├── LICENSE                       # 开源协议(证书)
      ├── projects                      # 工程
      │   └── maix_asr                 # ASR 工程
      │       ├── CMakeLists.txt       # 工程配置文件
      │       ├── main                 # 工程里面的主组件
      │       └── project.py           # 构建脚本,方便输入命令
      ├── README.md                     # 项目首页英文文档
      ├── README_ZH.md                  # 项目首页中文文档
      ├── tools                         # 项目构建相关代码,一般不用看
      └── usage_zh.md                   # 使用方法]
      

      构建代码

      项目支持多平台, 不同的平台使用的工具链和库可能有差异,注意区别。

      PC环境的推荐系统为 Ubuntu 18.04 以上,gcc 7.5 以上,CMake 3.20以上,失能conda虚拟环境。其他环境可能有部分软件需要额外设置,不建议新手使用。

      其他嵌入式环境的交叉编译方式可能存在一些细节使用问题,商业用户可以联系support@sipeed.com 获取支持。

      • 环境准备

      首先电脑安装工具链和库(Ubuntu 为例)

      sudo apt update 
      
      sudo apt install git python3 cmake
      

      python 只是用在编译脚本上的,方便简单地输入编译命令, 如果你电脑里有任何一个版本的 python 都是可以的, 为确保不出问题最好是Python3。如果实在不想装 python , 也可以手动使用 cmake 命令进行编译。

      x86 (Linux) 或 在跑在其它架构的系统里编译,比如在R329或树莓派的系统里使用GCC编译 安装工具链和库(Ubuntu为例)。

      sudo apt install build-essential libasound2-dev
      

      交叉编译 下载工具链,并解压到指定文件夹 比如R329, 从 realease 下载 r329_toolchain.tar.gz, 并解压到一个路径,比如 /opt/r329_toolchain 比如 v83x, 在这里找到工具链下载链接并下载工具链,解压到一个文件夹,比如/opt/toolchain-sunxi-musl

      3.png

      克隆代码

      git clone https://github.com/sipeed/Maix-Speech
      
      • 编译

      x86(Linux)或在跑在其它架构的系统里编译,比如在R329或 树莓派 的系统里使用GCC编译

      注意,conda 环境下工具链可能有问题,如果出现错误可以先尝试 退出conda环境使用原生环境编译。

      cd projects/maix_asr
      python project.py clean_conf    # 清除工具链配置
      python project.py menuconfig    # 配置选择芯片架构(ARCH),默认是 x86
      python project.py build#python project.py rebuild          # 如果有新建文件需要使用 rebuild
      # python project.py build --verbose # 打印详细构建过程
      
      ./build/maix_asr                # 测试下运行可执行文件,可以执行即可
      
      python project.py clean         # 清除构建内容
      python project.py distclean     # 彻底清除构建内容, 包括 menuconfig 内容
      
      • 其它架构(交叉编译)

      交叉编译需要工具链, 前面的准备工作中已经下载了工具链,在编译时需要配置工具链信息到工程里面

      需要配置:

      工具链可执行文件所在文件夹路径,比如

      /opt/r329_toolchain/bin

      /opt/toolchain-sunxi-musl/bin

      工具链前缀,可在前面的表格中找到, 比如aarch64-openwrt-linux-

      cd projects/maix_asr
      # 配置工具链位置和前缀, distclean 不会清除工具链配置, 这会在目录下生成一个 .config.mk 文件
      python project.py --toolchain 工具链可执行文件路径路径 --toolchain-prefix 前缀名 config
      # python project.py --toolchain /opt/r329_toolchain/bin --toolchain-prefix aarch64-openwrt-linux- config
      
      python project.py menuconfig       # 选择 架构
      python project.py build
      
      # python project.py clean_conf     # 清除工具链配置
      

      运行语音识别例程

      以x86(Linux)平台为例的快速验证 demo, 其它平台特别是交叉编译的平台需要自行拷贝可执行文件到开发板的系统里面再运行:

      先保证编译通过, 可执行文件 projects/maix_asr/build/maix_asr 存在并且可以运行

      在release页面找到 am_7332.ziplmM.zip 文件并下载, 解压到assets/test_files 目录, 解压后assets目录结构如下

      assets
      ├── image
      └── test_files
          ├── 1.2.wav
          ├── am_7332
          ├── asr_wav.cfg
          └── lmM
      

      主要包含了两种模型 声学模型AM 和 语言模型LM, 每种模型又有几种模型大小选择,越大精度越高资源消耗越大, 另外还有字体文件

      不同平台实时运行的典型配置

      Cortex-A7  1.0GHz, <=128M 系统内存:am_3316 + lmS, is_mmap=1, beam<5
      Cortex-A7  1.0GHz, >=256M 系统内存:am_3316 + lmM, is_mmap=0, beam=5~10
      Cortex-A53 1.2GHz, >=256M 系统内存:am_3324 + lmM, is_mmap=0, beam=5~10
      Cortex-A72 1.5GHz, >=1G   系统内存:am_3332 + lmL, is_mmap=0, beam=5~10
      

      带NPU的硬件平台,选用对应转换好的 NPU 硬件加速的声学模型,比如R329下载r329_7332_192.bin, 然后根据系统内存选择对应的语言模型,语言模型目前没有硬件加速,均使用 CPU 运算

      进入到 test_files 目录

      cd assets/test_files
      

      执行测试

      ../../projects/maix_asr/build/maix_asr asr_wav.cfg
      

      可以看到语音识别的结果

      HANS: 一点 二三 四五 六七 八九 
      PNYS: yi4 dian3 er4 san1 si4 wu3 liu4 qi1 ba1 jiu3
      

      如果是 Windows 需要 GBK编码则修改asr_wav.cfg中的

      words_txt:lmM/words_utf.bin
      

      为

      words_txt:lmM/words.bin
      

      测试其他 wav 文件只需要修改 asr_wav.cfg 中的 device_name 到对应测试 wav 路径即可,测试其它模型,修改model_name指定文件路径即可。

      注意 wav 需要是 16KHz 采样,S16_LE 存储格式。另外还支持 PCM 或者 MIC 实时识别,详见 usage_zh.md 中对 cfg 文件的介绍。

      可以使用工具转换,比如 arecord -d 5 -r 16000 -c 1 -f S16_LE audio.wav

      Maix ASR 模型选择

      MAIX ASR 声学模型按尺寸分为:7332,3332,3324,3316

      大小如下表:

      4.png

      MAIX ASR 语言模型可以自由选择,默认开放三种尺寸的模型:lm_s,lm_m,lm_l
      每种模型分成 sfst,sym,phones,words 四部分,其中 sym,phones,words 仅用于输出字符串使用,无需加载入内存,仅放在磁盘
      sfst为解码图文件(LG.fst的压缩版),可选载入内存或者mmap实时读取。表中wer表示 aishell 测试集的汉字转拼音作为输入,通过LM转汉字后的错误率。

      5.png

      以下是各个模型的benchmark

      pny wer表示带声调的拼音错误率,lmX表示加上对应语言模型后的汉字错误率。

      6.png

      模型说明:

      下划线后的数字表示选取的帧长度,如192表示一帧为192x8=768ms,asr库每采集完一帧后进行一次处理。

      帧长度关系到识别延迟,如192就会最大有768ms延迟,128则为512ms,可见帧长的模型错误率更优,但是延迟稍长。

      表中默认为流式识别,使用有限的上下文(一帧长度),noflow表示非流式识别(整体识别),可见非流式识别错误率大幅下降。

      ali表示对齐优化后的结果,即类sMBR处理后的结果,可见对齐训练后错误率大幅下降。

      附件默认上传了192长度的流式识别模型,需要其他识别模型的可以联系矽速。

      -End-

      微信直通车:
      官网直通车:

      发布在 A Series
      q1215200171
      budbool
    • 飞桨模型在“周易”NPU上的部署(基于R329开发板)

      本文作者:逍遥
      个人简介:飞桨社区开发者,研究方向为计算机视觉和推理部署

      本教程以搭载安谋科技“周易”(Arm China “Zhouyi”) NPU的“全志R329”开发板为例,介绍如何使用Paddle2ONNX模型转换工具将飞桨模型(以ResNet50为例)转换为ONNX模型,然后通过“周易”的AIPU工具将ONNX模型转换成.bin格式的模型,并在R329上部署。最后我们将会使用“周易”的Demo运行查看ResNet50模型在R329上的运行效果。

      关于“周易” NPU

      “周易”NPU是安谋科技设计的人工智能处理单元IP,采用为神经网络运行及相应的前后处理设计的专用指令集,具有均衡的可编程能力和优化的标准处理能力,融合了多种执行粒度的指令,满足不同人工智能算法需求。“周易”NPU适合各种端(边缘计算)侧人工智能设备,可以广泛应用于安防、智能家居、移动设备、物联网、车载等市场。

      一、准备开发板环境

      在开始部署前需要准备如下软件和硬件来配置开发板环境。

      136483276-61889ceb7bfb7.png
      准备好后即可开始向SD卡中烧录镜像。烧录好镜像的SD卡在插入R329开发板后,即可使用UBS—Type-C数据线连接并操作R329开发板了。详细烧制过程如下所示:

      1.格式化SD工具。使用SD Card Formatter软件格式化SD卡。

      2.png

      2.使用dd命令,烧录镜像到SD卡。

      $:ls /dev/disk*    #通过插拔SD卡,确认待使用SD卡设备号;本教程SD卡号为“/dev/disk4”
      $:diskutil unmountDisk /dev/disk4    #取消待使用SD卡的挂载
      $:sudo dd bs=1m if=Armbian_21.08.0-trunk_Maixsense_bullseye_edge_5.14.0.img of=/dev/disk4    #使用dd命令烧录镜像(dd命令的详细使用方法可以通过输入“参见dd --–help”命令查看)
      $:diskutil eject /dev/disk4    #弹出SD卡
      

      3.插卡开机。将烧录好镜像的SD卡插入R329开发板,使用UBS—Type-C数据线将开发板和Mac电脑连接后,开发板便会自动开机。

      4.在Mac电脑上利用minicom登录开发板,开展后续工作。

      $:minicom -s    # 打开串口配置菜单。如下图所示,在菜单中选择“Serial port setup”后将进入设置界面。修改“A- Serial Device”为开发板串口id:“/dev/tty.usbserial-14110”,再修改“E- Bps/Par/Bits”将波特率设置为:115200 8N1,然后按Esc键退出设置界面,最后选择“Exit”退出。
      $: minicom – D /dev/tty.usbserial-14110 #登录开发板
      

      3.png
      图.串口配置菜单

      4.png
      图.设置界面

      5.配置开发板网络等,熟悉开发板使用。
      利用nmtui命令为开发板配置网络,方便后续使用scp命令将Mac电脑上资料拷贝到开发板上。(注意:使用scp命令时,需要保证本地电脑和开发板在同一个局域网中)参考下方参考链接中“开箱测试”、“上手使用”详细描述,了解配置网络方法,熟悉开发板的使用。

      烧录系统的具体信息请参考:https://wiki.sipeed.com/hardware/zh/maixII/M2A/MaixSense/start/start.html

      二、搭建飞桨开发环境

      1.安装飞桨框架

      根据电脑是否有GPU硬件,从如下命令中选择一条来安装飞桨框架。本教程使用的是CPU版本的安装命令。

      $:pip3 install paddlepaddle --upgrade -i https://mirror.baidu.com/pypi/simple  #安装CPU版本的飞桨框架
      $:pip3 install paddlepaddle-gpu --upgrade -i https://mirror.baidu.com/pypi/simple  #安装GPU版本的飞桨框架
      

      2.安装PaddleClas,并修改处理代码

      $:git clone https://github.com/PaddlePaddle/PaddleClas.git
      $:cd PaddleClas
      $:sudo pip3 install -r requirements.txt   #用于安装必要的安装包。注意:请使用sudo权限,否则包下载完后安装没有权限。
      $:vim ppcls/engine/engine.py    #按照下图修改engine.py中第381行代码。(由于R329配置的屏幕尺寸是224*224,因此需要将Demo的输入图像尺寸设定成固定维度。)
      

      5.png

      安装飞桨框架和PaddleClas具体方法可以参考:https://github.com/PaddlePaddle/PaddleClas/blob/release/2.1/docs/zh_CN/tutorials/install.md

      3.安装Paddle2ONNX

      安装Paddle2ONNX,用于将飞桨模型转换成ONNX格式。具体命令如下:

      $:pip3 install paddle2onnx
      $:pip3 install onnx
      

      安装Paddle2ONNX参考链接:https://github.com/PaddlePaddle/Paddle2ONNX

      三、模型格式转换

      1.飞桨模型转为ONNX格式的模型:

      模型转换包括两步,第1步:导出飞桨模型;第2步:将飞桨模型格式转换成ONNX模型格式。

      第1步:导出飞桨格式模型

      $:cd PaddleClas
      $:wget -P ./cls_pretrain/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/ResNet50_vd_pretrained.pdparams   #下载飞桨训练好的分类模型
      $:python3.7 tools/export_model.py -c ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml -o Global.pretrained_model=./cls_pretrain/ResNet50_vd_pretrained -o Global.save_inference_dir=./deploy/models/class_ResNet50_vd_ImageNet_infer -o Global.device=cpu   #导出飞桨模型,导出格式如下所示。
      

      输出介绍:

      ├── class_ResNet50_vd_ImageNet_infer
      │   ├── inference.pdiparams
      │   ├── inference.pdiparams.info
      │   └── inference.pdmodel
      

      注意:在执行上述命令时,可能存在缺少对应python包的情况,直接使用pip3 install **安装即可。例如作者运行中报错ModuleNotFoundError: No module named‘sklearn',直接pip3 install sklearn即可。

      第2步:飞桨模型格式转ONNX模型格式:

      $:paddle2onnx -m ./deploy/models/class_ResNet50_vd_ImageNet_infer --model_filename inference.pdmodel --params_filename inference.pdiparams -s ./deploy/models/class_ResNet50_vd_ImageNet_infer/paddle2onnx_resnet50_model.onnx --opset_version 11  #参数说明如下所示
      

      参数说明:
      -m:第一步生成.pdmodel、.pdiparams文件路径,相对路径和绝对路径均可。
      -s:最终生成的ONNX模型的保存路径。

      2.ONNX模型转R329支持的.bin格式模型

      第1步:配置转换所需docker环境。(默认系统已经安装docker工具)

      $:sudo docker pull zepan/zhouyi
      $:sudo docker run -i -t zepan/zhouyi  /bin/bash
      $:cd /root/demos/tflite
      

      参考链接:https://aijishu.com/a/1060000000216857

      第2步:准备模型量化校准数据。
      准备模型量化校准数据操作,主要是将图像和对应标签转换成.npy格式,对于模型分类任务,如下命令执行dataset/preprocess_dataset.py即可实现数据准备工作。
      $:python3 dataset/preprocess_dataset.py
      输出dataset/dataset.npy和dataset/label.npy;

      第3步:在docker 中利用AIPU工具进行模型转换

      $:mkdir baidu
      $:cd baidu
      $:docker cp paddle2onnx_resnet50_model.onnx 298d15395846 :/root/demos/tflite/baidu/.  #使用docker cp命令将上一步生成的.onnx格式的模型从Mac电脑拷贝到docker容器中。
      $:vim resnet_50_build_run.cfg    #配置文件完整内容见下方框格。
      $:cd ..
      $:aipubuild baidu/resnet_50_build_run.cfg   #在根目录下生成paddle_onnx_resnet50_50Z2_1104_build.bin模型
      

      注意:
      1.在使用aipubuild命令转换过程中,可能存在无法识别的input/ouput/layer name,是AIPU存在部分特殊字符无法识别的情况,使用node name即可避免该问题。
      2.在模型转换过程中出现negative dimension错误,原因是没有按照二中“2.安装PaddleClas,并修改处理代码”步骤修改shape为“1,3,224,224”造成的。

      resnet_50_build_run.cfg配置文件内容如下:其中[Parser]中input和output可以使用飞桨visualDL工具查看layer name,或者使用node name。

      注:

      [Common]
      mode = build
      
      [Parser]
      model_type = onnx
      input_data_format = NCHW
      model_name = resnet_50
      detection_postprocess = 
      model_domain = image_classification
      input_model = ./baidu/paddle2onnx_resnet50_model.onnx
      input = x
      input_shape = [1, 3, 224, 224]
      output = Softmax_0
      
      [AutoQuantizationTool]
      output_nodes = 
      quantize_method = SYMMETRIC
      ops_per_channel = DepthwiseConv
      reverse_rgb = False
      label_id_offset = 0
      preprocess_mode = normalize
      quant_precision = int8
      calibration_data = ./dataset/dataset.npy 
      calibration_label = ./dataset/label.npy 
      
      [GBuilder]
      output = paddle_onnx_resnet50_50Z2_1104_build.bin
      profile=True
      target = Z1_0701
      

      四、运行Demo

      1.下载官方Demo

      通过下方链接下载官方Demo解压,并使用scp命令拷贝到开发板。该官方Demo已经完成了基于R329开发版的交叉编译工作,可直接在开发板上运行
      官方Demo下载链接:

      https://dl.sipeed.com/shareURL/MaixII/MaixII-A/example
      如需对Demo工程或者其它AIPU工程进行交叉编译,参见下方链接。
      交叉编译参考链接:https://aijishu.com/a/1060000000224083

      2.运行Demo

      $:scp -r zhouyi_test root@*.*.*.*:/root    #4个*为开发板IP,需要保证开发板和Mac电脑在同一个局域网
      $:run.sh     #运行Demo,使用官方自带的aipu.bin模型做推理
      

      命令行输出结果如下图所示:

      8.png
      官方自带的aipu.bin模型推理效果如下图,该模型在R329上推理速度约为在20fps。

      6.png

      3.运行飞桨模型转换Demo
      将三中生成的paddle_onnx_resnet50_50Z2_1104_build.bin模型拷贝到开发板上,替换Demo中的模型,运行查看效果。

      $:scp paddle_onnx_resnet50_50Z2_1104_build.bin root@*.*.*.*:/root/ zhouyi_test
      $:./zhouyi_cam paddle_onnx_resnet50_50Z2_1104_builds.bin unsigned
      

      运行效果如下:

      7.png

      ResnNet50原生模型在R329上推理速度约为7fps。

      4.Demo函数简单说明。
      该Demo教程主要程序在main.cpp函数中实现,通过OpenCV循环读取摄像头数据,送给推理引擎,对采集到的图像进行分类。其中推理引擎使用周易NPU的相关接口。

      至此,利用Paddle2ONNX和周易NPU工具,即可完成分类模型的转换及部署工作。大家可结合自己具体的业务需求,借助上述步骤完成模型转换,并利用周易NPU的相关API完成推理代码,交叉编译后即可放到板子上运行。

      来源:飞桨PaddlePaddle公众号

      发布在 A Series
      q1215200171
      budbool
    • 回复: 挪威科技大学使用全志D1哪吒开发板开设操作系统课程

      @tripod9 👍 👍 👍 安利一个这位老哥的好帖,帮助D1实现裸机开发 全志D1裸奔工具XFEL

      发布在 MR Series
      q1215200171
      budbool
    • 挪威科技大学使用全志D1哪吒开发板开设操作系统课程

      近日,哪吒走进了北欧的大学课堂。挪威科技大学的Michael Engel教授就在操作系统的课程中介绍并使用了哪吒D1及玄铁C906,并在课件中详细展示了如何在哪吒上玩转MIT的xv6 OS。

      3EA0524A-3C66-454c-9E55-0133DB729C4F.png

      挪威科技大学,挪威全国最顶尖的工程学与工业技术的研究中心,北欧五校联盟成员。挪威科技大学在石油与海洋技术类、生理学与医学、化学工程、电气电子及生产与质量工程类学科拥有很强的技术和学术实力,属世界一流。其海洋工程学更是位居世界第二位。挪威科技大学强大的工程技术实力吸引了全球学生申请。2019年,NTNU位列2019软科世界大学学术排名101-150段。NTNU曾有五位校友获得诺贝尔奖。

      xv6 OS是由麻省理工学院(MIT)为操作系统工程的课程(代号6.828),开发的一个教学目的的操作系统。

      与Linux或BSD系统不同,xv6 OS很简单,可以在一个学期讲完,全部代码只有8千行多,但仍包括了Unix的重要概念和组织结构。

      在MIT以外,很多其它大学也在操作系统课程中使用了xv6 OS或其变种,如耶鲁,清华等。

      1031BA42-59A8-48da-A33B-8A657E32D28F.png
      xv6 OS移植哪吒的相关内容

      业内知名学者、RISC-V国际基金会委员陈博士说,通过RVI全球学术开发板项目,全志哪吒开发板已经进入全球14个国家的多所高校。D1芯片、玄铁C906、玄铁开源也已变成热门讨论的话题。OS课程,编程,体系架构等课程都可以使用。

      D0978ABA-E6DB-44c2-ABBD-FF37A9C1B70B.png
      课件中展示的哪吒D1

      2021年4月,全志科技宣布推出「D1」处理器,其是全球首颗量产的,搭载平头哥玄铁906 RISC-V的应用处理器。同时为了方便开发者学习,合作伙伴进行方案评估,全志在线基于D1芯片,定制了高集成度专用开发板,代号:哪吒。

      哪吒开发板-侧面芊卉p图-resize1d.jpg
      全志D1哪吒开发板

      作为全球首款支持64bit RISC-V指令集,以及Linux系统的开发板,哪吒和D1,获得了广泛的应用。板身大小虽与银行卡相当,但却拥有非常丰富的接口资源,可以应用于智慧城市、智能汽车、智能商显、智能家电、智能办公和科研教育等前沿领域,不仅在商业用途上潜力巨大,也在科研教学方面做出了贡献。

      凭借强大的性能以及广泛的用途,哪吒在业界受到广泛好评,不仅实现了开发板自身在各领域中百花齐放的目标,也迈出了中国芯走向世界的第一步。

      -End-

      微信直通车:https://mp.weixin.qq.com/s/0XWf2wp1msRDiTOsHU0kOA
      官网直通车:https://www.aw-ol.com/news/14

      编辑:Budbool
      技术顾问:Kirin

      发布在 MR Series
      q1215200171
      budbool
    • 基于星辰处理器的全志XR806鸿蒙开发板上手体验

      有幸收到了全志科技赠送的XR806鸿蒙开发板,也是第一次体验鸿蒙系统的开发,故作个记录。

      开发板实物

      1.xr806开发板是真的小巧,整个板子体积不过 25.8mm*42mm。

      1.jfif

      2.开发板通过type-C接口提供UART通信和供电能力,
      连接USB线接入PC,可自动识别到COM口(基于CP2120芯片)。
      设置波特率为115200,可在串口调试助手中看到打印信息。

      2.png

      3.连接wifi
      XR806是一款支持WiFi和BLE的高集成度无线MCU芯片,当模块工作起来之后,输入相关指令,即可体验wifi功能。
      wifi开启:hm net sta enable
      搜索热点:hm net sta scan
      获取搜索结果:hm net sta scan_result n=30
      搜索成功后连接指定热点:hm net sta connect < ssid > < psk >
      wifi断开连接:hm net sta disconnect
      wifi关闭:hm net sta disable

      XR806开发环境搭建

      1.repo工具下载系统源码

      • 列表下载新版本的repo文件

      repo工具用于获取xr806的源代码。
      笔者使用ubunt 18.04系统,在/usr/bin路径下已经存在repo文件。当直接执行repo init时候,系统会提示连接超时。
      因为Repo init 默认会访问的url地址https://gerrit.googlesource.c...往往会失败;
      git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo
      直接用下载的git-repo/repo文件去替换/ust/bin/repo.

      • 列表修改repo镜像地址

      因为Repo init 默认会访问的url地址https://gerrit.googlesource.c...往往会失败;
      所以我们需要替换为国内的地址https://mirrors.ustc.edu.cn/a...
      在修改repo中提到的repo地址ls,如下图所示。
      3.png

      • 列表获取系统源码

      repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify

      4.png repo sync -c

      5.png repo forall -c 'git lfs pull'

      2.下载xr806源码

      将下载的两个文件夹放到系统源码路径下,确定文件路径结果如图所示。

      • 列表从https://gitee.com/openharmony... 下载device仓内容,放到device路径下。
        6.1.png
        6.png

      2.从https://gitee.com/openharmony... 下载vendor仓内容,放到vendor路径下。
      7.1.png
      7.png

      3.下载交叉编译工具

      注意,不要选择最新版的,亲测后续编译会不成功。成功版本如链接所示,
      wget https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2~~~~

      解压,放到指定路径。

      • 列表修改device/xradio/xr806/liteos_m/config.gni中的board_toolchain_prefix为实际环境下的gcc路径
        8.png

      • 列表修改device/xradio/xr806/xr_skylark/gcc.mk
        9.png

      4.安装鸿蒙系统开发环境

      这一步,需要安装鸿蒙相关开源环境,具体可参考鸿蒙官方指导教程。
      在安装环境成功后,才能执行hb命令,编译生成镜像文件

      5.SDK配置

      在修改完交叉编译工具路径后 ,在xr_skylark目录下执行

      • 列表复制配置文件

      ​ cp project/demo/wlan_ble_demo/gcc/defconfig .config

      • 可使用图形化界面确认配置

      ​ make menuconfig
      10.png
      ​

      • 清除过程文件

      ​ make build_clean

      • 列表生成静态库已经自动生成头文件

      ​ make lib -j

      成功结果如图
      11.png

      6.系统源码编译

      回到xr806系统源码目录
      12.png
      hb set #选择skylark
      13.png
      hb build -f
      14.png
      生成的镜像文件xr_system.img
      15.png

      7.烧录工具

      生成的镜像位于device/xradio/xr806/xr_skylark/out,

      烧录工具名称为phoenixMC,位于device\xradio\xr806\xr_skylark\tools下。
      在windows下,打开该工具,通过串口烧写镜像
      16.png

      烧写完成,重新运行开发板
      17.png

      运行中的开发板
      18.png

      (文章转载自:极术社区 Pingyang)
      (原文链接:https://aijishu.com/a/1060000000247851 )

      发布在 Wireless & Analog Series
      q1215200171
      budbool
    • 回复: 【素材汇总】XR806芯片及开发板图片素材汇总

      IMG_20211021_101324.jpg IMG_20211021_101307.jpg

      发布在 公告
      q1215200171
      budbool
    • 全志D1 哪吒开发板Debian系统刷机记录

      哪吒开发板
      一些刷机的注意事项

      参考连接

      • 「RVBoards-哪吒」D1 Debian系统镜像和安装方法 | RVBoards 论坛

      • 全志开发者社区 - 资源下载

      • D1在线文档

      刷debian
      先刷kernel

      ————————————————

      • 列表先打开下面的软件

      20210608174312958.png

      • 列表选择好要刷的image

      20210608174319768.png

      • 列表安装板子上的FEL按键,然后上电(OTG)线,放开FEL按键,板子自动刷机,如果存在问题,可能是由于没有安装全志的镜像。

      再解压rootfs 文件

      • 列表先将SD卡文件系统格式化为这个ext4,然后将pax -rvf “文件名”.cpio(建议root权限下解压,不然会出现文件权限问题,主机切换为root用户)

      • 列表将SD卡,插入卡槽,然后重新上电,设备启动

      进入设备的一些配置

      • 列表通过CH340 串口,来完成与设备的交互

      20210608174349452.png
      启动时,这里会存在倒数的数字,直接回车进入这个配置

      • 列表设置相关的环境变量
      setenv  mmc_root /dev/mmcblk0p1 
      setenv  rootfstype ext4,rw
      saveenv
      printenv # 查看相关的变量是否修改成功
      boot     #启动设备
      
      • 列表进入设备的一些配置
      #进入根目录
      cd /
      dpkg -i perl*.deb 
      chmod +755 /
      chmod 4755 /usr/bin/su
      
      
      - 新建用户
      adduser user
      
      • 列表修改存在的问题

      • 列表Linux—linux下sudo显示sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set_锥子A的博客-CSDN博客
        【Linux】Ubuntu16.04 创建新用户账户并添加sudo权限_heiheiya的博客-CSDN博客_ubuntu添加用户sudo权限

      • 列表修改成静态IP,目前动态IP无法自动获取

      20210608174611409.png

      • 列表重启网络服务
      /etc/init.d/networking restart
      
      • 列表目前修改到的网络字段
      10.0.21.80
      10.0.21.99
      
      
      
      10.0.21.81 
      10.0.21.82
      10.0.21.83
      
      user@10.0.21.99 user
      

      (文章转载自:CSDN TuT_today)
      (原文链接:https://blog.csdn.net/weixin_37210821/article/details/117710917 )

      发布在 MR Series
      q1215200171
      budbool
    • 回复: 【素材汇总】XR806芯片及开发板图片素材汇总

      c.png
      z.png
      b.png

      发布在 公告
      q1215200171
      budbool
    • 回复: 【素材汇总】XR806芯片及开发板图片素材汇总

      侧面:
      IMG_20211018_131913.jpg

      正面:
      IMG_20211018_131824.jpg

      背面:
      IMG_20211018_131835.jpg

      发布在 公告
      q1215200171
      budbool
    • 全志XR806鸿蒙开发板实物图释放

      侧面:
      IMG_20211018_131913.jpg
      c.png

      正面:
      IMG_20211018_131824.jpg
      z.png

      背面:
      IMG_20211018_131835.jpg
      b.png

      发布在 Wireless & Analog Series
      q1215200171
      budbool
    • XR806鸿蒙开发板硬件原理图释放!!!

      文档下载链接:https://www.aw-ol.com/downloads?cat=12

      1.png
      2.png
      3.png
      4.png

      发布在 Wireless & Analog Series
      q1215200171
      budbool
    • 【D1s开发板来啦!】D1s核心板/开发板采购、软硬件外包、整体解决方案提供欢迎联系~

      1 开发板概述

      1.1 编写目的
      方便用户更快熟悉D1s开发板, 缩短项目研发周期,快速上手,满足不同客户的需求。

      1.2 适用范围与特点
      本文档适用于全志D1s开发板。

      • 扩展接口丰富:引出了所有接口

      • 尺寸最小化:核心板的尺寸为52*39mm

      提供:软件、硬件、原理图、SDK、调试指导、设计参考指南资料等。

      1.3 产品应用市场

      • 仪表仪器

      • 智能家居、网关、家电

      • 故事机、广告机

      • 数码相框

      • MP5

      资料列表(资料多,请联系商务获取):

      • Linux_U-Boot_开发指南

      • Linux_内存优化_开发指南

      • Linux_SPI_LCD_调试指南

      • Linux_LCD_开发指南

      • …

      2 芯片介绍

      2.1 D1s处理器介绍
      图片1.png

      2.1.1 框图和基本规格
      图片2.png

      3 软硬件与接口概述

      B846D3F3-8E43-48cd-9800-FBB0D2C8FDA2.png

      开发板正面效果图:
      图片3.png

      开发板背面效果图:
      图片4.png

      开发板运行效果图:
      图片5.png

      开发板接口标注:
      图片6.png

      核心板正面图:
      图片7.png

      4 商务合作模式

      • 核心板采购

      • 开发板采购

      • 软件/硬件外包开发

      • 整套方案购买

      • …

      更多具体合作模式可联系商务,吴工 13048855370

      发布在 MR Series
      q1215200171
      budbool
    • 男人至死都是孩子——大佬在D1开发板上移植魂斗罗游戏

      小白通过buildroot搭建哪吒D1开发环境详细步骤,并且在HDMI显示器上玩上了魂斗罗(基于QT5).(感谢晕哥对我的指导)
      所有的内容都通过buildroot搭建,包括uboot,内核,qt5等等。
      我是通过UBUNTU18.4搭建的,如果在buildroot的下载过程中遇到了半天都下不下来,直接就强行终止,然后执行
      sudo systemd-resolve --flush-caches (UBUNTU18.4,其他的版本需要自己查)这个是刷DNS,我有的时候下载不动就用此命令。

      1.apt-get update

      2.sudo apt-get install -y sed make binutils build-essential gcc g++ bash patch gzip bzip2 perl tar cpio unzip rsync file bc wget python cvs git mercurial rsync scp subversion android-tools-mkbootimg libncurses5-dev

      Bzr 注意:第2步骤是我自己摸索出来的,与韦东山老师要求安装的库的不同,请注意。

      3.找一个文件夹 或者是home文件夹 mkdir -p ~/Neza-D1/ && cd ~/Neza-D1/ 这样就有Neza-D1文件夹了。

      4.git clone https://gitee.com/weidongshan/neza-d1-buildroot.git buildroot-2021 这个是韦东山老师的buildroot,下载速度应该是比较快。

      5.在buildroot-2021/configs/的文件夹下有neza-d1_defconfig,这个就是默认的配置文件。 通过make neza-d1_defconfig 生成默认文件。然后通过
      make menuconfig 进入buildroot配置,Qt5的这三个库去掉。(我是下载不下来没有办法去掉的,如果可以下载下来,也不用去掉)
      Qt5-coap需要去掉
      Qt5-knx 需要去掉
      Qt5-mqtt需要去掉

      6.make all,这个过程非常漫长。完成之后会在buildroot/image下生成sdcard.img,通过写SD卡的工具写入就可以了。

      7.写入之后,可以通过串口启动,就成功了一半,这个时候插入HDMI是不能识别,好像是sink什么什么错误。然后执行

      mount -t debugfs none /sys/kernel/debug;
      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;
      

      然后你的显示屏幕就只能显示左边一部分,然后你执行 cat /dev/urandom > /dev/fb0 应该可以看到左边一小半屏幕有雪花屏幕。

      8.我的LCD是1024x600的,显示不全应该是设备树的问题,然后就修改uboot设备树和linux内核设备树。
      uboot与linux内核都在 buildroot的output/build/目录下
      uboot设备树在 uboot-origin_master文件夹下的 arch/boot/dts/uboot-board.dts
      linux内核设备树在 linux-origin_master文件夹下的 arch/riscv/boot/dts/board.dts
      两个设备树都要修改成下面这种,-就是要去掉,+就是要增加,其中dev0_output_mode是调分辨率

      • <10>就是1080p
      • <5> 就是720p
      • <2> 就是360p

      具体可以查文档

              disp_init_enable         = <1>;
              disp_mode                = <0>;
      -       screen0_output_type      = <1>;
      -       screen0_output_mode      = <4>;
      -
      -       screen1_output_type      = <3>;
      -       screen1_output_mode      = <10>;
      -
      -       screen1_output_format    = <0>;
      -       screen1_output_bits      = <0>;
      -       screen1_output_eotf      = <4>;
      -       screen1_output_cs        = <257>;
      -       screen1_output_dvi_hdmi  = <2>;
      -       screen1_output_range     = <2>;
      -       screen1_output_scan      = <0>;
      -       screen1_output_aspect_ratio = <8>;
      -
      -       dev0_output_type         = <1>;
      -       dev0_output_mode         = <4>;
      +    screen0_output_type      = <3>;
      +    screen0_output_mode      = <10>;
      +
      +    screen0_output_format    = <0>;
      +    screen0_output_bits      = <0>;
      +    screen0_output_eotf      = <4>;
      +    screen0_output_cs        = <257>;
      +    screen0_output_dvi_hdmi  = <2>;
      +    screen0_output_range     = <2>;
      +    screen0_output_scan      = <0>;
      +    screen0_output_aspect_ratio = <8>;
      +
      +    screen1_output_type      = <1>;
      +    screen1_output_mode      = <4>;
      +
      +    dev0_output_type         = <4>;
      +    dev0_output_mode         = <10>;
              dev0_screen_id           = <0>;
      -       dev0_do_hpd              = <0>;
      -
      -       dev1_output_type         = <4>;
      -       dev1_output_mode         = <10>;
      -       dev1_screen_id           = <1>;
      -       dev1_do_hpd              = <1>;
      +       dev0_do_hpd              = <1>;
      

      改完成之后,在uboot-origin_master文件夹下与 linux-origin_master文件夹下都需要执行
      rm .stamp_built
      然后 在buildroot目录下 make all
      然后下载到sd卡,
      cat /dev/urandom > /dev/fb0 应该是全屏幕的雪花

      9.这个时候插入鼠标键盘虽然有打印消息但是没有/dev/input/ 这个时候需要在内核加入Event interface,
      修改完成还是需要 rm .stamp_built,烧入sd卡,这个时候就有/dev/input/eventx,这个时候鼠标与键盘还是不能用在qt5中。

      export QT_QPA_GENERIC_PLUGINS=tslib,evdevkeyboard:/dev/input/eventx,evdevmouse:/dev/input/eventx

      这个eventx需要根据实际情况来 这个时候qt5就支持键盘了.

      10.交叉编译QT5的NES模拟器,我在github下的,它那个需要很多的依赖,
      例如需要继承OPENGL。我后面就改成了,只要有最基本的库就可以了。(文件会随后发出来)
      qmake在 buildroot的output/host/bin目录下,有qmake就可以交叉编译。

      qt4-NES4_5_512_480_640_480.7z
      这个是QT5源文件,,qt4-NES4_5_512_480_640_480/Qt/hdl.nes 拷贝到根目录可以直接一运行,接上键盘就可以直接玩。
      1 2 A W S D L O通过这几个键就可以玩魂斗罗啦,嘻嘻。

      微信图片_20211013132647.jpg
      这个是我的HDMI显示器图

      for (y = 0; y < NES_DISP_HEIGHT; y++ )//240
      {
      for (x = 0; x < NES_DISP_WIDTH; x++ )//256
      {
      p=(WorkFrame+(y*NES_DISP_WIDTH)+x);
      ((WorkFrameX+(y<<1))+(x<<1))=*p;
      ((WorkFrameX+(y<<1))+((x<<1)+1))=*p;
      ((WorkFrameX+((y<<1)+1))+(x<<1))=*p;
      ((WorkFrameX+((y<<1)+1))+((x<<1)+1))=*p;
      }
      }
      这个是将图像放大两倍,mask一个标签
      infones的linux版本 绘制点是一点一点计算,如果屏幕比较大,应该就比较慢

      (文章转载自:WhyCan Forum 哇酷开发者社区 )
      (原文链接:https://whycan.com/t_7253.html )

      发布在 MR Series
      q1215200171
      budbool
    • 阿里JS轻应用框架在D1上适配

      距D1的发布已有近半年的时间,作为主打RISC-V架构芯片的国产开发板,哪吒和D1受到了无数企业和开发者的青睐,那么基于D1进行的开发自然也层出不穷,其中,合作伙伴阿里就在D1开发板上移植了,JS轻应用框架语音面板demo

      视频中展示了通过语音控制板子上小灯开关的动作,同时也有UI界面反馈此时正在进行的这个语音交互的内容,当然这也不仅仅是一块简单的小板子和屏幕,我们再把屏幕和智能音箱放在一起看看。

      这样再一看,就突出一个“合理”。

      在给开发板套上一套外设之后,开发板摇身一变成为智能面板,成为了一个家庭/房间的“控制中枢”,可以通过语音或者交互界面对房间中的设备进行控制。

      D1支持的MIPI-DSI的屏幕输出、HDMI等的显示输出接口,这些配置可以满足我们想要“看见”的需求,接上屏幕连上网,感觉整个世界都可以被这块屏幕掌控。当然除了D1本身高度契合AIoT时代海量的场景需求,想要将IoT设备真正控制起来,同样也离不开阿里基于JS做的轻应用demo。

      视频中展示了通过屏幕进行wifi设置、场景设置、设备控制的功能,这些功能的使用都可以通过阿里的轻应用框架实现。

      通过阿里的轻应用框架,可以实现带屏类IoT产品的快速部署。

      以D1为例,CPU就是采用阿里平头哥玄铁C906的RISC-V CPU,通过轻应用框架可以将底层系统、驱动和上层应用开发剥离开来,大大降低了研发投入,提高了可移植性。

      p176648.png
      轻应用运行原理

      在CPU满足了JS在嵌入式设备上开发的必要条件下,这类轻应用的诞生,就很好的满足了人们在使用IoT设备时的需求,让如何营造用户生态不再是向AIoT发展中最棘手的问题。

      D1在这项实例中适配了JS的轻应用框架,展现出了其具备语音控制以及显示流程的界面的能力。据悉,阿里的整体框架及应用将于今年10月份发布,期待可以有更多的企业和开发者加入进来,一起探索在各个领域中的无限可能。

      ““IMG_20210929_145813”为智能对象-1”为智能对象-1.jpg
      阿里JS轻应用框架在D1上适配实例示意图

      带字公众号 Q.png

      编辑:Budbool
      技术顾问:BedRock、Kirin

      微信推文跳转:https://mp.weixin.qq.com/s/H_ugDlG_00a1p7VvmG9scg

      发布在 MR Series
      q1215200171
      budbool
    • 回复: 【素材汇总】XR806芯片及开发板图片素材汇总

      XR806概念板1.png

      发布在 公告
      q1215200171
      budbool
    • XR806淘宝预售上线了

      简单粗暴,直接上链接

      链接戳这里→→→XR806全志在线淘宝店链接

      微信图片_20210918152124.jpg

      发布在 Wireless & Analog Series
      q1215200171
      budbool
    • 阿里云游戏——用云原生和低代码打造边缘计算的元宇宙

      元宇宙,这三个字近段时间频频出现在大众的视野当中,但其实它并不是一个最近才被提出的新概念,早在几年前国内外各大科技巨头就在元宇宙这条赛道上进行布局,展现出对这条新赛道的浓厚兴趣。

      头号玩家.png
      (Cr:电影《头号玩家》)

      关于元宇宙的讨论为什么会在最近才井喷式的爆发?

      5G以及VR/AR技术的发展相较于几年前已有了长足的进步,再有世界疫情的反复让人们的外出时间逐渐减少,取而代之的自然是在虚拟世界中的其他娱乐方式,这不仅给了人们了解元宇宙的机会,同时也给了元宇宙相关公司一个洞见未来发展方向的机会。

      当然,元宇宙技术现在仅是在赛道上完成了起跑,发展底层的算力、区块链技术以及前后端的5G、AR/VR等技术就成了冲向终点的必由之路,而近期云游戏的诞生,也是给近乎一张白纸的的元宇宙概念添上了浓墨重彩的一笔。

      阿里云游戏

      目前来说,游戏是元宇宙公认的最佳载体,至少在元宇宙发展的早期,游戏是一股很重要的推进力量。

      云游戏是目前最接近元宇宙概念的存在,在不少实时性,兼容性,无限开创特性等关键特性的理念上不谋而合,云游戏的诞生更是为元宇宙的发展打下牢固的地基。

      阿里巴巴在去年的阿里云云栖大会上正式推出了自己的阿里云游戏PaaS平台,阿里云基于自身强大的云服务能力为游戏从业者与业务方提供一站式PaaS服务,可以在低成本的前提下快速云化游戏、搭建属于自己的云游戏平台。

      1.png
      阿里云游戏平台结构(Cr:阿里云)

      这是如何做到的呢?

      在该平台上,所有你想玩的游戏都会在云端的服务器上运行,在云端上,服务器会完成所有游戏画面的渲染并将画面通过网络传给用户,在用户端,只需要完成对视频数据的反解码即可呈现出游戏图像,实现用户无需高端显卡就能畅游3A大作的心愿。

      2.png
      解决方案技术架构(Cr:阿里云)

      • 解决方案优势
        低延迟高画质:支持1080P、4K画质,60帧率;智能码率控制,流畅不卡顿

      • 列表低配设备跨平台随意玩高配游戏:无需高配置电脑,PC、手机、电视等多终端随时随地畅玩 3A 级游戏大作

      • 列表防外挂:游戏完全在云端运行,不用再担心外挂,减少客户端开发成本

      • 列表轻量客户端:下载轻量级的游戏客户端,即点即玩,免下载安装,告别庞大的游戏客户端,减少用户流失

      • 列表快速接入、平稳上线:使用阿里云资源提供Turnkey解决方案,帮助客户快速上线运营

      • 列表丰富的云资源,优化成本:全国高性能服务节点与高效调度策略,多维度降低成本

      云游戏之所以被冠以“云”,不仅仅是依靠其云端所提供的强大的硬件基础作为辅助,同样不可或缺的也有云原生、低代码这样的新兴概念。

      云原生

      曾经,人们热衷于收藏各种歌星的光碟、磁带,要是那时候告诉他们,在未来听歌根本不需要这些东西,那人们一定觉得你疯了。现在的年轻人又热衷于收集游戏卡、游戏盘,那要是现在再跟他们说,以后玩游戏不仅不需要这些甚至都不再需要游戏机了,只需要一块单核玄铁C906的D1开发板,还会被当做疯子对待吗?

      8.JPG
      阿里云游戏狂野飙车 demo(运行平台:D1哪吒开发板)

      云游戏的发展或许能给云原生以无限遐想的空间。

      云原生作为基于分布部署和统一运管的云端服务,是以容器、微服务、DevOps等技术为基础建立的一套云技术产品体系。在使用云原生技术后,开发者无需考虑底层的技术实现,可以充分发挥云平台的弹性和分布式优势,实现快速部署、按需伸缩、不停机交付等。

      3.png
      云原生相关概念关系图(Cr:大数据DT)

      时至今日,虽然云原生的概念并没有做到完全统一,但都达成共识的一点是,云原生应用就是面向“云”而设计的应用。拿云游戏来举例,游戏它本身的存在就是基于云的存在,利用云端强大的CPU、GPU以及AI运算能力去驱动游戏,并且将所有数据存储在云端,当我们想玩的时候就可以让游戏在云上直接运行。

      但真正的“云”并不是直接将应用简单的迁移到平台上。

      如果应用本身没有基于云原生进行重构,那么即使业务运行没有问题,应用也不能充分利用云原生运行环境的能力去展现应用本身的特点。应用应基于云原生平台的云服务属性,不仅仅利用云原生的特点和属性,也要结合云平台的属性去创造自己的特点,解决分布式复杂性问题,同时也构建出更加合适与在云原生平台上使用的应用。


      在阿里云游戏平台玩狂飙(运行平台:D1哪吒开发板)

      PC端游戏在出现之前也不曾被主机游戏的开发商看好,移动端游戏的出现前也被怀疑难以复制PC端的成功,但实际上各个领域的应用都依靠各自领域的特点以及优势,创造出属于自身独一无二的特性。不仅仅局限于游戏,游戏也可以映射到其他应用的方方面面,那出现在眼前的基于云原生的这团迷雾,也就显得更值得被探索了。

      低代码

      低代码,即Low-Code,其中的Low并不是说代码很low,也不是说代码在最底层的意思,而就是字面上要表示的只需要很少代码的意思。

      少写代码并不意味着减少了项目的整体工程,而是低代码可以提供到更多的更多的代码去代替部分手写代码的功能,剩下的部分才是通过开发者进行可视化或是可配置化亦或是手写代码来完成。

      低代码的突出特点就是快速交付,低代码平台将平时一个开发的简单流程中类似数据库设计,前端UI设计,逻辑设计,接口设计等流程统一设计成标准化的流程,其他不是流程化的东西就通过参数化配置,低代码平台“快”的实现就是围绕着这两个方面来进行。

      5.jpg
      阿里云游戏狂野飙车 demo(运行平台:D1哪吒开发板)

      低代码平台的敏捷性极强,可以更好地应对市场需求不断变化的情况。低代码可以轻松地将各种组件集成到应用程序之中,利用该类与敏捷性相关的技术来帮助实现应用程序的实现,轻松达成需求与业务的交互。

      基于低代码开发复杂度降低的属性,运用低代码的门槛被大大的降低,这给了非专业人员也可以在学习后就上手操作的机会。

      对于非专业人员来说,并不需要知道低代码平台的原理以及组成,只需要会简单的操作就可以。但对于专业的技术人员来说,可以在此基础上基于低代码平台做出与众不同的内容,甚至形成自己的生态。

      9.jpg
      连接手柄操作狂野飙车 demo(运行平台:D1哪吒开发板)

      最重要的一点是,低代码对资源以及硬件的要求极低,这也与它本身时效性强以及易上手的特点呼应,D1就很好的适配了低代码的这些特性,成功被移植上了阿里云游戏。在芯片资源紧张的这段时间,或许会成为低代码技术发展和普及的黄金时间。

      未来机遇

      目前来说,云原生确是当下低代码开发应用的最好架构选择。

      低代码与云原生的相得益彰,低代码提供给企业方面缩短软件生命周期的同时,也可以帮助开发人员轻松地进行原型设计和迭代,使应用程序开发更简单,更快捷;云原生则可以满足用户端对应用程序所需要的硬件配置需求,还为应用程序及用户提供了数据存储在云端的安全保证。

      随着浪潮的涌起,国内多家公司纷纷建立起自己的云原生或低代码平台,而阿里云游戏团队已经在D1哪吒开发版上移植了云游戏demo,并在今年6月份上海的RISC-V峰会中进行展示。

      697AF6D1-F4A0-4068-AEE9-657643A63B26.png
      上海的RISC-V峰会中展示的阿里云游戏demo
      运行平台:哪吒D1开发板

      在可以预见的未来,将会有更多的云端应用,在各类边缘计算平台上落地,为我们的生活带来神奇的改变!。

      -End-

      带字公众号 Q.png

      编辑:Budbool
      技术顾问:BedRock、Kirin

      微信推文跳转:https://mp.weixin.qq.com/s/zAWamxvkhWSvkVeoTdtn2Q

      发布在 爱搞机专区
      q1215200171
      budbool
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 5 / 6