导航

    全志在线开发者论坛

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

    q1215200171 发布的帖子

    • 【AI & SoC】高算力低功耗,当下智能音箱的最优解?

      智能音箱这条赛道上,无论是传统的音频厂商还是互联网大厂都纷纷入局,在各大厂商在经过了数年的你追我赶后,都在智能音箱领域占领了属于自己的一亩三分地。

      8.png

      各智能音箱的制造商在宣传的时候总是冠以自己的智能音箱“AI”的名号,但智能≠AI,可能对于产品的边缘设备的 AI算力需求 ,结合云端的同时,搭配上CPU或GPU弥补一些不足就可以轻松达到要求。

      对于最近几年的智能音箱发展,对于AI算力的需求已经成为各厂商之间竞争的主旋律,部分智能音箱的主Soc中,CPU部分的算力越来越高,不过用CPU来解决算力不足的问题也只是当下的权宜之计,为了更好的辅助云端, 更着眼于未来的解决方法是给Soc加上专属的AI内核以及DSP 。

      全志R329此时也就应运而生了。

      1.png

      #01 前世

      在讲R329前,就不得不得讲一讲他的前世R328。

      R328可以提供语音交互方面的可靠应用,广泛适用于智能音箱等电子产品,R328集成了双核Cortex-A7、64 MB DDR 2或128 MB DDR 3,3个ADC通道和1个差分DAC通道,提供音频输入/输出接口和丰富灵活的麦克风阵列,无需再外挂芯片,其中采用的 Arm Cortex-A7 处理器,主要利用 CPU 来做智能语音产品。

      R328具有高集成度和丰富的扩展接口,也易让客户扩展定制个性化的功能,是目前市面上具有高竞争力的智能语音专用芯片方案,这也让R328抢占了国内智能音箱等电子产品的大部分市场,被广泛应用于在各大厂商的智能音箱。

      11.jpg

      #02 今生

      沿袭了R328的优良性能的同时,为了满足各大厂商对专用算力的需求,R329除了升级了为Arm Cortex-A53核心外,还全新搭配上了Arm中国[周易]AIPU,集成了高性能的AIPU、DSP、CPU,使得无论是性能表现还是功耗控制方面都保持了不错的水准。

      6.png
      核心功耗、算力对比

      -AI语音专用AIPU,算力全面升级-

      AI方面,全志科技R329搭载了Arm中国“周易”AIPU,提供最高达0.256TOPS的运算能力,为人工智能语音应用带来全新更充足的强大专用算力。周易AIPU作为AI专核,其理论AI算力是单核A7 1.2GHz的25倍,也是单核HIFI4 600MHz的25倍。基于周易AIPU的强大特性,将对以往产品有着算力及能效上的更大优势。采用深度学习做端到端的算法,相对于传统降噪、回声消除和关键词识别算法,效果提升巨大,显著提升识别率和交互体验。

      -双核Cortex-A53,性能提升卓越-

      全志R329性能强劲,它采用2个主频高达1.5GHz 的Arm Cortex-A53,与采用A35核的其他解决方案相比,具有明显算力优势。而相较于R328,全新升级的R329提供高达1.58倍整数算力,1.94倍浮点算力,为智能语音产品应用提供更充足的系统算力基础。

      -双核HIFI4,体验更加优秀-

      R329集成了双核HIFI4 400MHz,两个HIFI4可用作音频前、后处理,更大限度地释放原始音频算力。在智能交互的同时,音质也得到明显提升,HIFi级音效算法所带来的高品质声音享受,使普通智能音箱也能具备千元以上HIFI音箱的音效品质。

      3.jpg

      在拥有了优秀的配置的同时,全志也将Tina移植到了R329之上,因其极快的启动速度以及开源的属性,使得包括了音箱在内的其他智能家具,也可以通过改良后的AI接口进行对Tina的使用。目前国内和国际已经有成千上万的产品在使用Tina,Tina也为拥有优异性能的芯片提供了在落地到产品端的便利。

      #03 未来

      智能音箱作为智能家居早期布局的重要入口,一直是各大互联网巨头竞争的战场,小米也率先发布了首款搭载R329的智能音箱设备。

      4.png
      2021年8月10日发布,搭载R329的小米Sound

      不仅仅是智能音箱市场,搭载AIPU的R329的出现,可以在更多的物联网设备上实现人工智能,加速赋能整个AI市场。从智能音箱作为切入点,慢慢渗透进入广阔的智能家居市场,包括对智能家电、语音电视、智能汽车、语音面板方面进行涉猎。

      作为一款多核异构处理器,除了语音,R329 芯片是否可以用到诸如图像等其它领域?

      其实是可以的,全志科技副总裁陈风表示:如果一定要用 R329 来做编码、手势识别和人形识别是完全可以做到的,技术上面,极客、开发者、大学校园完全可以用它来做 AI 的训练,做任何模型都可以,但其本身定位不同,在市场上不会是竞争力最优的方案。

      7.png

      R329作为全志首次采用Arm中国[周易]AIPU的AI芯片,在性能和功耗方面大放异彩,是对R328一次成功的升级。

      在人工智能的不断发展的时代,永远需要性能更高、功耗更低、成本更低的芯片面世。R329作为全新AI语音专用芯片,不仅延续R328智能语音芯片的经典设计,而且一举大幅度提升芯片性能和集成度,并一贯的提供完整且易于使用的开发、量产工具,帮助产业链合作伙伴大幅降低智能产品应用开发难度和成本,满足各种不同应用场景产品的快速实现和落地。

      -End-

      社区直通车:【AI & SoC】高算力低功耗,当下智能音箱的最优解?
      微信直通车:【AI & SoC】高算力低功耗,当下智能音箱的最优解?

      编辑:Budbool
      技术顾问:Kirin,Black

      发布在 A Series
      q1215200171
      budbool
    • 回复: 【素材汇总】D1开发板图片素材汇总

      扣好的哪吒(无白边)
      扣好的哪吒.png

      发布在 公告
      q1215200171
      budbool
    • 基于R329的完整自研离线语音解决方案

      提及智能家居,我们最常想到及最常用到的可能就是通过后即App连接wifi这样的操作步骤来对家具设备进行联网控制。然而,随着智能语音识别技术等人工智能技术的发展和融入,智能家居的一些场景应用也逐渐得到升级改进。在某些应用场景下,家居智能化的简单操控实际上并不用通过联网控制这样复杂的方式就可以实现智能家居的简单化了。

      如比较常见的就是通过发送口令控制家居设备,让家居环境达到最符合用户需要的状态,同时也让用户的生活更加便捷、更简单、更智能。

      正是基于这样的需求,由用户本地操控便可以更好地实现人机交互的离线智能语音极术便随之诞生。这种不需要联网的离线语音技术不仅可以给智能家居各种设备的使用带来诸多方便,同时也给用户打造了一个极为简单的家居体验。

      对于离线语音识别技术而言,虽然看似不用联网操作那么复杂,但这也并不意味着离线语音识别技术是一种非常简单非常容易的开发的技术。毕竟在真正的使用过程中,用户的口音及环境噪音等问题,都可能会影响用户的使用体验。这也就对开发离线语音识别模块的厂商提出了巨大的考验。

      近日,sipeed(矽速科技)就基于全志R329做出了一个完整的自研离线语音解决方案,区别于需要联网进行的语音识别,离线语音识别技术离不开算法以及模型库的支持。

      人工智能算法模型库的建设是一个以知识为核心、研发与管控相结合的系统工程,该离线语音识别技术就是基于矽速科技自研的巨型模型库,光模型库预置的预料就达到了上百GB,一个足够丰富的模型库才能使得文字识别的准确率得到大幅度的提升。

      算法模型库对于人工智能的作用不言而喻,人工智能的原理和思想需要通过模型和算法予以展现,人工智能研究的发展必定要基于已有的算法模型,也一定会带来算法模型的升级更新。一个完备的算法模型库既是对当前算法模型研究的总结归纳,又是开拓下一个研究阶段的起点。

      发布在 A Series
      q1215200171
      budbool
    • 【R329开发板评测】基于R2329-AIPU的动态手势识别及实机部署运行

      一、模型与算法
      采用MIT开源的TSM算法,论文作者通过对特征进行shift操作,在不增加额外参数和算力的情况下进行时间建模,然后移植到了各种手机上进行了各种算法的对比。作者代码也移植到了jetson nano上能达到实时运行(没有使用CUDA),甚至在FPGA上也进行了移植,满满的工业风。

      二、效果展示

      模型backbone是mobileV2,然而运行只有18FPS,不应该啊,看了直播才知道,初代AIPU对分组卷积不太友好,ok好吧。我也尝试了在R329 CPU上运行,只有3FPS。模型在笔记本i7 cpu下TF pb模型能有65FPS,ONNX 120FPS。4009491768-6129cbf2ef7a3.jfif

      三、移植到AIPU

      3.1模型量化

      为了防止出现未知错误,我直接把作者的pytorch代码重构为TensoFlow代码,后面会开源。
      由于涉及到时间建模,模型输入有11个输入矩阵。1个图像矩阵,10个转移矩阵,输出也是11个矩阵,1个分类矩阵,10个转移矩阵。
      cfg配置如下:

      [[Common]
      mode = build
      use_aqt = True
      
      [Parser]
      model_name = mobilenet_v2
      model_type = tensorflow 
      detection_postprocess = 
      model_domain = image_classification
      output = fully_connected/BiasAdd,Slice,Slice_2,Slice_4,Slice_6,Slice_8,Slice_10,Slice_12,Slice_14,Slice_16,Slice_18
      input_model = ./input/model3.pb
      input = x_input,x_input0,x_input1,x_input2,x_input3,x_input4,x_input5,x_input6,x_input7,x_input8,x_input9
      input_shape = [1, 224, 224, 3],[1, 56, 56, 3],[1, 28, 28, 4],[1, 28, 28, 4],[1, 14, 14, 8],[1, 14, 14, 8],[1, 14, 14, 8],[1, 14, 14, 12],[1, 14, 14, 12],[1, 7, 7, 20],[1, 7, 7, 20]
      output_dir = ./
      
      [AutoQuantizationTool]
      quantize_method = SYMMETRIC
      quant_precision = int8
      ops_per_channel = DepthwiseConv
      reverse_rgb = False
      label_id_offset = 
      dataset_name = 
      detection_postprocess = 
      anchor_generator = 
      ts_max_file = ./input/max_dict2.npy
      ts_min_file = ./input/min_dict2.npy
      [GBuilder]
      outputs = aipu_mobilenet_v2Z2_1104.bin
      target = Z1_0701]
      

      由于模型涉及到多输入多输出,故不能直接使用训练集模型自动量化,所以需要手动求出每个节点的最值,按照技术手册里规定的格式,分别保存max,min的值为dict文件。

      3.2模型推理
      需要对输出结果微调,以下为推理和微调代码。

      /**
       * @file main.cpp
       * @brief 
       * 
       * Copyright (c) 2021 Sipeed team
       * ********************************
       * Modify by @zhai
       * *******************************
       */
      extern "C" {
      #include <stdio.h>
      #include <unistd.h>
      #include <stdint.h>
      #include <string.h>
      #include "fbviewer.h"
      #include "label.h"
      #include <sys/wait.h>
      #include <sys/types.h>
      }
      
      #include "standard_api.h"
      #include <iostream>
      #include <sys/time.h>
      #include<list>
      #include<vector>
      #include "opencv2/opencv.hpp"
      using namespace cv;
      #define DBG_LINE() printf("###L%d\r\n", __LINE__)
      
      int label_oft = 0;
      
      typedef struct {
          int index;
          int8_t val;
      } int8_data_t;
      
      typedef struct {
          int index;
          uint8_t val;
      } uint8_data_t;
      
      std::list<int8_t*> listbuffs;
      
      
      int8_t flag_frame_num=0 ;
      
      
      std::vector<int> history;
      
      
      
      int FindMax(int8_t a[], int n, int*pMaxPos)
      {
        int i;
        int8_t max;
        max = a[0];       
        *pMaxPos = 0;      
      
        for (i=1; i<n; i++)
        {
          if (a[i] > max)
          {
            max = a[i];
            *pMaxPos = i;   
          }
        }
        return max ;
      }
      cv::VideoCapture capture(0);
      
      int init_cam(void)
      {
          int x,y;
          getCurrentRes(&x, &y);
          printf("LCD width is %d, height is %d\n", x, y);
          cv::Mat img;
          VideoCapture cap;
          cap.isOpened();
          
          if(!capture.isOpened())
          {
              std::cout<<"video not open."<<std::endl;
              return 1;
          }
          //get default video fps, set fps to 30fps
          double rate = capture.get(CAP_PROP_FPS);
          printf("rate is %lf\n", rate);
          capture.set(CAP_PROP_FPS, 30);
          rate = capture.get(CAP_PROP_FPS);
          printf("rate is %lf\n", rate);
          //get default video frame info
          double frame_width = capture.get(CAP_PROP_FRAME_WIDTH);
          double frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);
          printf("frame_width is %lf, frame_height is %lf\n", frame_width, frame_height);
          //set video frame size to QVGA (then we crop to 224x224)
          frame_width = 320;
          frame_height = 240;
          if(!capture.set(CAP_PROP_FRAME_WIDTH,frame_width))
          {
              printf("set width failed\n");
              return 2;
          }
          if(!capture.set(CAP_PROP_FRAME_HEIGHT, frame_height))
          {
              printf("set width failed\n");
              return 3;
          } 
          return 0;
      }
      
      int init_graph(char* file_model, aipu_ctx_handle_t ** ctx, aipu_graph_desc_t* gdesc, aipu_buffer_alloc_info_t* info)
      {
          const char* status_msg =NULL;
          aipu_status_t status = AIPU_STATUS_SUCCESS;
          int ret = 0;
          //Step1: init ctx handle
          status = AIPU_init_ctx(ctx);       
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_init_ctx: %s\n", status_msg);
              ret = -1;
              //goto out;
          }
      
          //Step2: load graph
          status = AIPU_load_graph_helper(*ctx, file_model, gdesc);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_load_graph_helper: %s\n", status_msg);
              ret = -2;
              //goto deinit_ctx;
          }
          printf("[DEMO INFO] AIPU load graph successfully.\n");
      
          //Step3: alloc tensor buffers
          status = AIPU_alloc_tensor_buffers(*ctx, gdesc, info);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_alloc_tensor_buffers: %s\n", status_msg);
              ret = -3;
              //goto unload_graph;
          }
          
          return ret;
      }
      
      int cap_img(Mat* lcd_frame, Mat* ai_frame)
      {    
          Rect roi(40, 0, 240/4*3, 240);  //16/9 -> 4/3  
          Rect input_roi(8, 8, 224, 224);
          Size dsize = Size(240, 240);
          if(!capture.read(*lcd_frame))
          {
              printf("no video frame\r\n");
              return -1;
          }
          *lcd_frame = (*lcd_frame)(roi).clone();
          rotate(*lcd_frame, *lcd_frame, ROTATE_180);
          resize(*lcd_frame, *lcd_frame, dsize);
          cvtColor(*lcd_frame, *lcd_frame, COLOR_BGR2RGB);
          *ai_frame = (*lcd_frame)(input_roi).clone();
          //*ai_frame = (*lcd_frame)(input_roi).clone() + Scalar(-123, -117,-104);
           ai_frame->convertTo(*ai_frame,CV_16SC3);
           add(Scalar(-127, -127,-127),*ai_frame,*ai_frame);
           ai_frame->convertTo(*ai_frame,CV_8SC3);
      
          return 0;
      }
      
      int infer_img(Mat* ai_frame,Mat* x0,Mat* x1,Mat* x2,Mat* x3,Mat* x4,Mat* x5,Mat* x6,Mat* x7,Mat* x8,Mat* x9, aipu_ctx_handle_t ** ctx, aipu_graph_desc_t* gdesc, aipu_buffer_alloc_info_t* info, int signed_flag, int* label_idx, int* label_prob)
      {
          uint32_t job_id=0;
          const char* status_msg =NULL;
          int32_t time_out=-1;
          bool finish_job_successfully = true;
          aipu_status_t status = AIPU_STATUS_SUCCESS;
          int ret = 0;
      
          //std::cout<<* ai_frame<<std::endl;
      
          // printf("input_x:%d\n",info->inputs.tensors[0].size);
          // printf("input_x0:%d\n",info->inputs.tensors[1].size);
          // printf("input_x1:%d\n",info->inputs.tensors[2].size);
          // printf("input_x2:%d\n",info->inputs.tensors[3].size);
          // printf("input_x3:%d\n",info->inputs.tensors[4].size);
          // printf("input_x4:%d\n",info->inputs.tensors[5].size);
          // printf("input_x5:%d\n",info->inputs.tensors[6].size);
          // printf("input_x6:%d\n",info->inputs.tensors[7].size);
          // printf("input_x7:%d\n",info->inputs.tensors[8].size);
          // printf("input_x8:%d\n",info->inputs.tensors[9].size);
          // printf("input_x9:%d\n",info->inputs.tensors[10].size);
          
         
          memcpy(info->inputs.tensors[0].va, ai_frame->data,info->inputs.tensors[0].size);
      
      
          memcpy(info->inputs.tensors[1].va, x0->data, info->inputs.tensors[1].size);
          memcpy(info->inputs.tensors[2].va, x1->data, info->inputs.tensors[2].size);
          memcpy(info->inputs.tensors[3].va, x2->data,info->inputs.tensors[3].size);
          memcpy(info->inputs.tensors[4].va, x3->data, info->inputs.tensors[4].size);
          memcpy(info->inputs.tensors[5].va, x4->data,info->inputs.tensors[5].size);
          memcpy(info->inputs.tensors[6].va, x5->data,info->inputs.tensors[6].size);
          memcpy(info->inputs.tensors[7].va, x6->data, info->inputs.tensors[7].size);
          memcpy(info->inputs.tensors[8].va, x7->data,info->inputs.tensors[8].size);
          memcpy(info->inputs.tensors[9].va, x8->data, info->inputs.tensors[9].size);
          memcpy(info->inputs.tensors[10].va, x9->data,info->inputs.tensors[10].size);
      
          flag_frame_num=1;
          
      
          status = AIPU_create_job(*ctx, gdesc, info->handle, &job_id);
          //std::cout<<status<<std::endl;
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_create_job: %s\n", status_msg);
              ret = -1;
              //goto free_tensor_buffers;
          }
          status = AIPU_finish_job(*ctx, job_id, time_out);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_finish_job: %s\n", status_msg);
              finish_job_successfully = false;
          } else {
              finish_job_successfully = true;
          }
      
          if (finish_job_successfully) {
              int8_t *result = (int8_t *)info->outputs.tensors[0].va;
              
              uint32_t size = info->outputs.tensors[0].size;
           
      
              int8_t *buff=(int8_t *)malloc(27*sizeof(int8_t));
              memcpy(buff, result, sizeof(int8_t)*27);
              if(listbuffs.size()>5){listbuffs.pop_front();}
              listbuffs.push_back(buff);
      
      
      
              int8_t *buffsum;
              buffsum=(int8_t *)calloc(27,sizeof(int8_t));
      
              int Len=listbuffs.size();
              int k=0;
              std::list<int8_t *>::iterator iter;
              for(iter=listbuffs.begin();iter!=listbuffs.end();iter++){
      
                 for(k=0;k<27;k++){buffsum[k]=buffsum[k]+(*iter)[k];}
      
              }
      
              int i=0;
         
              memcpy((x0->data),info->outputs.tensors[1].va, info->outputs.tensors[1].size);  
              memcpy((x1->data),info->outputs.tensors[2].va,  info->outputs.tensors[2].size);
              memcpy((x2->data),info->outputs.tensors[3].va,  info->outputs.tensors[3].size);
              memcpy((x3->data),info->outputs.tensors[4].va,  info->outputs.tensors[4].size);
              memcpy((x4->data),info->outputs.tensors[5].va,  info->outputs.tensors[5].size);
              memcpy((x5->data),info->outputs.tensors[6].va,  info->outputs.tensors[6].size);
              memcpy((x6->data),info->outputs.tensors[7].va,  info->outputs.tensors[7].size);
              memcpy((x7->data),info->outputs.tensors[8].va,  info->outputs.tensors[8].size);
              memcpy((x8->data),info->outputs.tensors[9].va,  info->outputs.tensors[9].size);
              memcpy((x9->data),info->outputs.tensors[10].va,  info->outputs.tensors[10].size);
      
      
      
      
              int idx;
              
              FindMax(buffsum, 27, &idx);
              printf("idx:%d\n",idx);
              int label_covert=2;
              int errors_fre[]={7, 8, 21, 22, 3,10,11,12,13};
              i=0;
              for(i=0;i<9;i++){
                  if(idx==errors_fre[i]){idx=history.back();}
              }
      
              if(idx==0){idx=history.back();}
      
              if(idx!=history.back()){
                  if(history[history.size()-3]!=history.back()||history[history.size()-2]!=history.back()){idx=history.back();}
              }
      
              history.push_back(idx);
      
              *label_idx=history.back();
              if(history.size()>20){history.erase(history.begin());}
          
          }
      
          status = AIPU_clean_job(*ctx, job_id);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[TEST ERROR] AIPU_clean_job: %s\n", status_msg);
              ret = -2;
              //goto free_tensor_buffers;
          }
          return ret;
      }
      
      
      float cal_fps(struct timeval start, struct timeval end)
      {
          struct timeval interval;
          if (end.tv_usec >= start.tv_usec) {
              interval.tv_usec = end.tv_usec - start.tv_usec;
              interval.tv_sec = end.tv_sec - start.tv_sec;
          } else  {
              interval.tv_usec = 1000000 + end.tv_usec - start.tv_usec;
              interval.tv_sec = end.tv_sec - 1 - start.tv_sec;
          }
          float fps = 1000000.0 / interval.tv_usec;
          return fps;
      }
      
      volatile int exit_flag = 0;
      void my_handler(int s){
          printf("Caught signal %d\n",s);
          exit_flag = 1;
          return;
      }
      
      
      
      int main(int argc, char *argv[])
      {
          int ret = 0;
          uint32_t job_id=0;
          int32_t time_out=-1;
          bool finish_job_successfully = true;
          int model_inw, model_inh, model_inch, model_outw, model_outh, model_outch, img_size;    
          int8_t* bmpbuf;
          cv::Mat lcd_frame;
          cv::Mat ai_frame;
          int label_idx, label_prob;
          struct timeval start, end;
      
          int flag_frame=0;
          float fps=0;
      
          // cv::Mat x0 = cv::Mat::zeros(56,56 , CV_32FC(3)); 
          // cv::Mat x1 = cv::Mat::zeros(28, 28, CV_32FC(4)); 
          // cv::Mat x2 = cv::Mat::zeros(28, 28, CV_32FC(4)); 
          // cv::Mat x3 = cv::Mat::zeros(14, 14, CV_32FC(8)); 
          // cv::Mat x4 = cv::Mat::zeros(14,14 , CV_32FC(8)); 
          // cv::Mat x5 = cv::Mat::zeros(14,14 , CV_32FC(8)); 
          // cv::Mat x6 = cv::Mat::zeros(14, 14, CV_32FC(12)); 
          // cv::Mat x7 = cv::Mat::zeros(14,14 , CV_32FC(12)); 
          // cv::Mat x8 = cv::Mat::zeros(7,7 , CV_32FC(20)); 
          // cv::Mat x9 = cv::Mat::zeros(7, 7, CV_32FC(20 ));
      
          cv::Mat x0 = cv::Mat::zeros(56,56 , CV_8SC(3)); 
          cv::Mat x1 = cv::Mat::zeros(28, 28, CV_8SC(4)); 
          cv::Mat x2 = cv::Mat::zeros(28, 28, CV_8SC(4)); 
          cv::Mat x3 = cv::Mat::zeros(14, 14, CV_8SC(8)); 
          cv::Mat x4 = cv::Mat::zeros(14,14 , CV_8SC(8)); 
          cv::Mat x5 = cv::Mat::zeros(14,14 , CV_8SC(8)); 
          cv::Mat x6 = cv::Mat::zeros(14, 14, CV_8SC(12)); 
          cv::Mat x7 = cv::Mat::zeros(14,14 , CV_8SC(12)); 
          cv::Mat x8 = cv::Mat::zeros(7,7 , CV_8SC(20)); 
          cv::Mat x9 = cv::Mat::zeros(7, 7, CV_8SC(20 ));
      
      
      
      
         
          
      
          signal(SIGINT, my_handler); 
      
          
      
      
          history.push_back(2);
          history.push_back(2);
          
          
          printf("Zhouyi Cam test program: \r\n");
          printf("Usage: \r\n");
          printf("    ./zhouyi aipu.bin signed [label_oft]\r\n");
          printf("    signed=0, uint8 output; =1, int8 output\r\n");
          printf("    real_label_idx = predict_idx-label_oft, \r\n");
          printf("    NOTE: default cal with 224x224\r\n");
      
          aipu_ctx_handle_t * ctx = NULL;
          aipu_status_t status = AIPU_STATUS_SUCCESS;
          const char* status_msg =NULL;
          aipu_graph_desc_t gdesc;
          aipu_buffer_alloc_info_t info;
      
          //Step 0: parse input argv
          if(argc < 3) {
              printf("argc=%d error\r\n", argc);
              return -1;
          }
          if(argc >3) label_oft = atoi(argv[3]);
          char* file_model= argv[1];
          int signed_flag = 1;
          
          //Step 1: set USB camera
          ret = init_cam();DBG_LINE();
          if(ret != 0) {
              printf("[DEMO ERROR] init_cam err: %s\n", ret);
              goto out;
          }
          
          //Step 2: init model graph
          ret = init_graph(file_model, &ctx, &gdesc, &info);DBG_LINE();
          if(ret == -1) goto out;
          else if(ret == -2) goto deinit_ctx;
          else if(ret == -3) goto unload_graph;
          
          //MAIN LOOP
          
          while(!exit_flag)
          {
              //1. cap cam img
              if(cap_img(&lcd_frame, &ai_frame) != 0) {
                  break;
              }
              //2. infer cam img, get label
              gettimeofday(&start, NULL);
              
             if(flag_frame%2==0){
                  ret = infer_img(&ai_frame,&x0,&x1,&x2,&x3,&x4,&x5,&x6,&x7,&x8,&x9, &ctx, &gdesc, &info, signed_flag, &label_idx, &label_prob);
                 
                  
             
             
              if(ret != 0) goto free_tensor_buffers;
              gettimeofday(&end, NULL);
      
               fps = cal_fps(start, end);
      
               }
               flag_frame+=1;
              //3. draw lcd
              flip(lcd_frame, lcd_frame, 1);
              putText(lcd_frame, labels[label_idx], Point(0, 224), cv::FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0), 2);
              
              char fps_str[16];
              sprintf(fps_str, "%.1ffps", fps);
              putText(lcd_frame, fps_str, Point(0, 16), cv::FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0), 2);
             
              
              fb_display(lcd_frame.data, 0, 240, 240, 0, 0, 0, 0);
              
          }
      
      free_tensor_buffers:
          status = AIPU_free_tensor_buffers(ctx, info.handle);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_free_tensor_buffers: %s\n", status_msg);
              ret = -1;
          }
      unload_graph:
          status = AIPU_unload_graph(ctx, &gdesc);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_unload_graph: %s\n", status_msg);
              ret = -1;
          }
      deinit_ctx:
          status = AIPU_deinit_ctx(ctx);
          if (status != AIPU_STATUS_SUCCESS) {
              AIPU_get_status_msg(status, &status_msg);
              printf("[DEMO ERROR] AIPU_deinit_ctx: %s\n", status_msg);
              ret = -1;
          }
      
      out:
      
          return ret;
      }
      

      四、代码地址
      https://github.com/ZhaiFengYun/R329-AIPU-gesture-recognition

      (文章转载自:极术社区 zhai)
      (原文链接:https://aijishu.com/a/1060000000230937 )

      发布在 A Series
      q1215200171
      budbool
    • 【RISC-V & LVGL】现象级爆红的开源显示框架——LVGL究竟蕴藏怎样的魔力

      #01 LVGL简介

      1.png
      实用自行车码表

      9.png
      具有科技感的奖杯

      实现这些DIY作品的背后,都有同样一个功能强大的GUI——LVGL。

      LVGL的作者是来自匈牙利的Gabor Kiss-Vamosikisvegabor,LVGL用C语言编写,以实现最大的兼容性(与C ++兼容),模拟器可在没有嵌入式硬件的PC上启动嵌入式GUI设计,同时LVGL作为一个图形库,它自带着接近三十多种小工具可以供开发者使用。这些强大的构建块按钮搭配上带有非常丝滑的动画以及可以做到平滑滚动的高级图形,同时兼具着不高的配置要求以及开源属性,显著的优势使得LVGL蔚然成风,成为广大开发者在选择GUI时的第一选择。

      20190824152251444.gif

      -主要特性-

      • 强大的构建块,如按钮,图表,列表,滑块,图像等。
      • 高级图形动画,抗锯齿,不透明度,平滑滚动
      • 各种输入设备,如触摸板、鼠标、键盘、编码器等
      • 多语言支持与UTF-8编码
      • 多显示器支持,即使用更多的TFT,单色显示器同时
      • 完全可定制的图形元素与css类样式
      • 硬件独立与任何微控制器或显示器使用
      • 可扩展,使用少量内存(64kb Flash, 16kb RAM)
      • 支持操作系统、外部内存和GPU,但不是必需的
      • 单帧缓冲操作,甚至与高级图形效果
      • 用C编写的最大兼容性(c++兼容)
      • 模拟器在没有嵌入式硬件的PC上开始嵌入式GUI设计
      • 绑定到MicroPython
      • 教程,例子,快速GUI设计的主题
      • 文档可以在线和PDF格式获取
      • 麻省理工学院许可下的免费和开源

      图片1.png

      -配置要求-

      • 基本上,每个能够驱动显示器的现代控制器都适合运行 LVGL。最低要求是:16、32 或 64 位微控制器或处理器
      • 建议使用 16 MHz 时钟速度
      • 闪存/ROM:> 64 kB 用于非常重要的组件 (> 建议使用 180 kB)
        RAM:静态 RAM 使用量:0~2 kB,取决于使用的功能和对象类型
        堆: > 2kB (> 建议使用 8 kB)
        动态数据(堆): > 2 KB (> 如果使用多个对象,建议使用 16 kB). 在 lv_conf.h 文件中配置 LV_MEM_SIZE 生效。
        显示缓冲区:> “水平分辨率”像素(推荐> 10 × 10ד水平分辨率”)
        MCU 或外部显示控制器中的一个帧缓冲器
      • C99 或更新的编译器
      • 具备基本的 C(或 C++)知识

      一块能驱动显示屏且Flash大于64KB,RAM大于20KB的单片机都可以支持运行LVGL。这样也就说明只需要是我们经常用于开发的单片机几乎都可以支持(16bit及以上)LVGL,LVGL能够同时被这么多平台支持的主要原因是LVGL对硬件的要求并不算太高。

      -系统框架-

      LVGL本身是一个图形库。

      我们的应用程序通过调用LVGL库来创建GUI。它包含一个HAL(硬件抽象层)接口,用于注册显示和输入设备驱动程序。驱动程序除特定的驱动程序外,它还有其他的功能,可驱动显示器GPU、读取触摸板或按钮的输入。

      MCU有两种典型的硬件设置。一个带有内置LCD/TFT驱动器的外围设备,而另一种是没有内置LCD/TFT驱动器的外围设备。相同的是,这两种情况都需要一个帧缓冲区来存储屏幕的当前图像。

      集成了TFT/LCD驱动器的MCU如果MCU集成了TFT/LCD驱动器外围设备,则可以直接通过RGB接口连接显示器。在这种情况下,帧缓冲区可以位于内部RAM(如果MCU有足够的RAM)中,也可以位于外部RAM(如果MCU具有存储器接口)中。

      如果MCU没有集成TFT/LCD驱动程序接口,则必须使用外部显示控制器(例如SSD1963、SSD1306、ILI9341 )。在这种情况下,MCU可以通过并行端口,SPI或通过I2C与显示控制器进行通信。帧缓冲区通常位于显示控制器中,从而为MCU节省了大量RAM。

      #02 常见GUI对比

      早些年间大部分MCU的资源和处理能力有限,受制于资源以及处理能力的不足,很少有基于MCU通用的GUI。

      现如今,随着MCU技术的发展,MCU性能以及属性有了很大改变,相较从前,现在MCU资源增加,处理能力增强,市场需求增长,GUI的功能自然也越来越丰富了。

      -LVGL-

      LVGL集成了占用小、多平台使用、移植简单、操作简单、开源免费等一系列特点。对于使用者来说,LVGL拥有30多个可以随时使用的小部件的同时,甚至还可以自定义控件。

      LVGL经常被使用在MCU级别的设备上,因其可以在多平台上移植使用以及在不同显示器上,以C编写,对于资源紧张的MCU来说十分适合。

      图片5.png

      -MiniGUI-

      MiniGUI 是一款面向嵌入式系统的高级窗口系统和图形用户界面支持系统,遵循GPL协议。作为操作系统和应用程序之间的一个中间件,MiniGUI 将底层操作系统和硬件平台的细节隐藏起来,并为上层的应用程序提供了一致接口。

      MiniGUI同时具有多种技术特性,包括可在含有MMU的32位处理器架构之上运行;同时支持低端、高端显示设备以及具备副屏支持的功能;方便为不同操作系统和环境应运而生的三种运行模式以及内建资源的支持;嵌入式应用程序开发和调试的跨操作系统支持的属性;完备的多窗口机制和消息传递机制。

      3.jpg

      • 优点

        支持多种嵌入式操作系统,可移植性强;
        可伸缩的系统架构,易于扩展;
        功能丰富,可灵活剪裁;
        轻型,资源占用少;
        高性能,高可靠性。

      • 缺点

        对图形设备的抽象层次太高。

      -Qt(Qt for MCUs)-

      Qt for MCUs是一个完整的图形框架和工具包,包含在微控制器上设置、开发和部署GUI所需要的一切。您可以在裸机或实时操作系统上运行应用程序。

      Qt for MCUs带有三样开发工具,包括一个配备了完善的代码编辑器、版本控制等功能的IDE(Qt Creator);以Qt QML语言编写的帮助从头开始或基于咸亨UI空间快速设计和构建应用程序的组件WYS|WYG编辑器(Qt Quick Designer);Qt Quick Ultralite 图形框架提供了丰富的 QML API 集,用于构建流畅的 GUI 和渲染引擎。

      4.png

      • 优点

        复用您在微控制器上的现有技能;
        通过跨设备(从高端到大众设备)的技术一致性,来降低维护成本;
        在不影响图形性能的前提下,向微控制器演进以降低硬件成本;
        将传统解决方案升级到现代的跨平台图形工具包。

      -emWin-

      emWin支持在任何嵌入式系统上创建高效、高质量的图形用户界面,emWin支持资源受限的微控制器的系统,运行令人惊叹的交互界面。

      emWin与单任务和多任务环境兼容,可以使用专有的操作系统,也可以与任何商业RTOS兼容。它以C语言源代码提供,使其成为嵌入式市场的专业、通用GUI,可用于多种不同的场景。

      5.png

      • 优点

        创建惊人的图形与功能强大,易于使用的API
        适用于任何显示器和微控制器
        适用于任何ANSI C/C++开发环境
        体验可靠的图形解决方案
        嵌入式图形用户界面解决方案

      最后上一张对比图,更直观!

      6.png

      #03 D1哪吒 & LVGL

      轻量 的属性给LVGL带来了无数粉丝,在使用各种低配置的小型开发板时,大部分开发者都会第一时间想到LVGL,这同时又突出展现出了它的另一个特点 易移植 。

      同样是开源、精简、轻量级,RISC-V和LVGL在设计理念上简直不谋而合,他们或许就代表着未来十年科技发展的主流。

      目前,全志基于阿里平头哥C906核设计的RISC-V芯片已经支持LVGL。秉承着同样设计理念的两个网红黑科技,在全志的芯片上绽放出了奇妙的花火。

      在全志在线社区论坛上,有小伙伴发布了一篇将LVGL移植到哪吒D1上的帖子,一时也是引起广泛讨论,话不多说,先上视频看看效果。

      视频中使用的是D1哪吒开发板,配上一块带触摸的7寸MIPI屏幕。可以看到移植的LVGL DEMO在RISC-V指令集的芯片上丝滑运行,毫无压力。

      再上一条视频。

      借助芯片的双屏异显功能,D1可以一边用LVGL做UI交互,另一边又在解码播放视频,很好的解决追剧星人在追剧时候就难以同时操作的问题,不会占用HDMI屏幕输出需要太多资源的同时,LVGL也很好的帮助了屏幕内容在mipi上的丝滑输出,成功实现双屏异显。

      而要在哪吒上把LVGL玩起来也非常简单,只需要下载源码后使用编译命令编译源码:

      CC=/xxxx/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-gcc make
      

      然后使用Tina Linux自带的adb 将demo推到开发板里,就可以玩起来了。如果没有MIPI屏幕,使用HDMI显示器+鼠标也是同样支持的。

      当然,LVGL可以实现的远不止于此,快快开发你的脑洞,完成更多的大作吧!!!

      【带git仓库的哪吒D1开发板 LVGL7 源码】

      -End-

      带字公众号 Q.png

      编辑/策划:Budbool
      技术顾问:Anru、BedRock、Kirin

      微信推文跳转:https://mp.weixin.qq.com/s/1uiRfzT5AYs97PI9Z79-MQ

      发布在 MR Series
      q1215200171
      budbool
    • 【拆机报告】小米sound智能音箱拆机简评

      小米在8月10号发布了xiaomi sound 首款高端智能音箱,传闻是基于R329主控芯片的,所以迫不及待地购入了一台样机拆解研究,不过后面拆解出了一些意外,所以迟迟未出拆解评测,转眼已经到了九月,在此把xiaomi sound的拆解评测坑填上。

      目前xiaomi sound的硬件拆机已经在我爱音频网上有详细的报告,相关内容大家可以在 https://baijiahao.baidu.com/s?id=1709155959359762295 查看。

      本篇拆机评测尽量从不同角度对小米sound进行评测:

      1.开箱外观
      2.频响测试
      3.硬件概览
      4.固件分析

      开箱外观

      外观简单展示如下,最惊艳的是黑透的亚克力外观设计,很有高级感。
      另外说一句我是在8.20号之前预售购买xiaomi sound的,会额外收到一个小米小夜灯赠品,非常贴心。
      1.jpg
      2.jpg
      3.jpg

      频响测试

      在拆机之前,我们先测试下xiaomi sound的频响曲线,防止拆机对其的音腔性能造成影响。

      由于条件限制,我们没有在专业消音室里测试,但购买了入门级的声场测试麦克风进行测试(麦克风比小米sound还贵不少)

      4.jpg
      使用REW进行频响曲线测试,多次多角度多距离测试,以下是测试的典型曲线结果之一:
      5.png

      可以看到小米sound的10db下潜到60~70Hz之间,中频(0.25~2KHz)平坦度+-9db左右,高音到17KHz左右。

      然后我手上还有天猫精灵 CCMINI 蓝牙智能音箱(¥189),也顺便做了下测试:
      6.png

      可以看到低音只下潜到125Hz左右,不过意外的是中频平坦度不错,在+-5dB;高音坑比较多。

      最后再从网上找到了华为soundX(¥1999)的频响曲线:
      7.png
      低频下潜达到40~50Hz左右,中频很稳,平坦度 +-5db,高音有个坑。

      另外这里是网上的一个参数对比图,可见小米sound的表现与Bose Revolve+接近,后者价格在1600~1900元左右。
      8.jpg

      硬件概览

      硬件拆解上没有什么特别的,由于我爱音频网已经进行了详细的拆解,这里只放张拆解概览图。
      9.jpg

      13.png

      固件分析

      其实购入小米sound最大的原因还是其使用了R329主控,希望借此分析下R329在小米sound中实现了哪些功能。

      在主板上,我们可以看到D_T,D_R, D1_T, D1_R 的字样,推测是串口信号测试点;

      在PCB背面可以看到一个空焊的USB座子,推测是adb调试的OTG USB口。
      10.png
      h0ZW4O.md.png

      飞线出来后,我们上电测试,可以在其中一个串口看到如下信息:
      11.png
      推测这个应该是R329内置的DSP内核运行的RTOS的输出,但是这个控制台无法进行操作,输入help也无法进行交互,应该是屏蔽了相关功能。

      在另一个串口上,上电无任何输出,应该是禁用了系统串口输出。

      在USB口上,插入后并没有出现 USB设备,adb也无法连接上,看来也是禁用了adb功能。

      至此直接可进入的物理端口基本都无法访问(除了WiFi之外)。

      再尝试拆下主板上的Nand Flash,根据手册参数dump了其中的二进制内容。
      12.jpg

      可见在地址0附近没有标志性的eGON.BT0字符串或者TOC0.LGH字符串,说明固件是安全固件;

      再进行全局搜索,也没有任何典型字符串信息,说明该固件镜像进行了全局加密。

      由于全志的安全启动策略是使用的非对称加密,公钥的sha256是固化在efuse中,并且进行了逐层安全校验,很难直接注入系统,可能只有在fel模式下在sram里注册异常handle,启动系统后触发异常获取权限;或者在网络层面寻找注入的可能性,不过这些方式投入的成本太大,已经超出了拆解工作的范围,所以就此作罢。

      另外发现的有趣的现象是,镜像的前面1MB左右,都是前1KB有内容,后1KB全FF。开始以为是flash参数填写错误导致读取错误,后面才发现是全志芯片为了兼容旧的小扇区Nand flash做的boot0的兼容性措施。

      拆解小结
      小米sound是一款外观时尚高端,音质媲美大牌厂商1500~2000元档音箱,使用了较完善的安全措施的智能音箱,创新性地加入了UWB功能,在百元级音箱里性价比不错,可以作为日常音箱使用。

      (文章转载自:极术社区 泽畔)
      (原文链接:https://aijishu.com/a/1060000000232161 )

      发布在 A Series
      q1215200171
      budbool
    • 【全志R329】R329开发板上的周易AIPU语音识别实战(PPT+视频)

      近期,极术社区联合矽速科技组织了搭载周易AIPU处理器的R329开发板申领活动,很多工程师进行了评测,但是如何能够更有效得利用周易AIPU来进行AI应用的部署开发呢?请关注本期由矽速科技CTO吴长泽带来的公开课。

      分享内容

      全志科技在2020年发布了搭载安谋科技“周易”AIPU的AI语音专用芯片R329,它主攻智能语音市场,其高算力、低功耗的特性引起了行业内的广泛关注。 本期课程将分享在矽速科技的MaixSense R329开发板上利用“周易”AIPU快速进行实时语音识别功能的全流程实现过程,让大家了解“周易”AIPU Compass SDK的强大,同时大家可以在开发板上DIY属于自己的智能语音助理。

      以下是内容大纲

      • 矽速MaixSense R329开发板软硬件介绍

      • “周易”AIPU Compass SDK简介及使用技巧

      • R329开发板上的视觉算法部署简介

      • 端侧LVCSR(大词汇量连续语音识别)算法实现

      视频及PPT

      • 视频观看地址:https://aijishu.com/l/1110000000226394

      • PPT部分预览(文末提供下载)

      a.png
      b.png
      c.png

      Q&A精选

      如果大家有对周易 Z2 AIPU/R329的问题,欢迎在此提问 https://aijishu.com/t/aipu/questions

      嘉宾简介

      吴才泽 Caesar Wu

      d.jfif

      Sipeed 矽速科技 CTO

      Caesar 毕业于浙江大学,拥有多年嵌入式软硬件设计经验,熟悉端侧AIoT算法优化部署。他开发的矽速MAIX开源AIoT产品系列深受国内外工程师及创客欢迎,目前他组织的MaixPy开源项目在github star已超过1K 。

      本次视频分享为周易"AIPU"系列第五期,前四期请点击下方链接。

      第一期|Arm中国周易“AIPU”初探
      第二期|快速贯通全志智能语音技术,R329专用处理器大剖析
      第三期|全志Tina-Linux软件平台及R329应用开发介绍(视频+PPT)
      第四期|Arm中国周易Z2 AIPU概述(视频+PPT)

      欢迎关注周易"AIPU"专栏获取周易"AIPU"更多技术干货等。

      (文章转载自:极术社区 极术小姐姐)
      (原文链接:https://aijishu.com/a/1060000000230794 )

      发布在 A Series
      q1215200171
      budbool
    • 【R329开发板评测】愉快地在Windows下玩R329

      操作系统:Windows 10
      假定当前工作目录:L:\R329

      为嘛不Linux?因为window下都能完成啊
      收到板子没两天就出差了,一直肝到周末才回来,赶紧补上评测。

      1.png

      2.png

      板子真小巧,算上摄像头也就名片三分之二大小,麻雀虽小但五脏俱全,赞!

      主要软件

      1.开源软件

      WINSCP(开源) SSH及文件传输
      PUTTY(开源) SSH及文件传输

      2.全志官方软件

      PhoenixCard官方Tina镜像烧录
      ADB管理ADB方式连接及管理
      Windows下串口驱动串口方式连接主板所需驱动

      Windows下连接主板的两种方式

      1.烧录Tina镜像

      下载上面的【PhoenixCard】, 解压并双击【PhoenixCard.exe】启动,选择Tina镜像位置以及启动卡选项后,点烧卡等待提示【烧写结束】即可。
      一定要看到【烧写结束】才是成功完成。

      3.png

      4.png

      然后把TF卡放入主板并通电,线要插入上面的USB口,看到以下界面时可以继续下一步了

      5.png

      2.ADB方式连接(Tina镜像)

      首先下载上面【ADB管理】链接中的软件,并解压到当前工作目录,其中有个【drivers】子目录,这是驱动文件需要安装一下,安装完成后如果一切正常,此时我们打开设备管理器,可以看到多了类似如下图红框所示的设备
      6.png

      此时我们在命令行下CD到【ADB管理】软件目录,并输入以下命令

      adb shell
      

      如果返回如下图所示内容,说明我们成功地连接到R329了

      7.png

      使用此方式除了可以运行各种命令外,我们还可以方便的上传或下载文件。
      上传当前目录下的【test.jpg】到R329的【/root/test.jpg】

      adb push ./test.jpg /root/test.jpg
      

      8.png

      从R329上下载 【/root/test.jpg】并保存到当前目录

      adb pull /root/test.jpg ./test_copy.jpg
      

      9.png

      除了上传下载外【ADB】还可以截屏或录屏到文件

      adb shell screencap -p /root/screen.png
      

      10.png

      说明当前 Tina 镜像中并未包含此功能,不过能上传下载和执行各种命令已经够用了。

      3.串口方式连接

      R329 使用了 CH340 芯片。Windows下需要安装驱动才能通过串口连接主板,使用上面链接下载安装即可。使用串口方式时我们要把USB线插入下面的USB口,当屏幕显示下图所示时,

      11.png

      我们可以在【设备管理器】 中看到如下图红框所示的内容

      12.png

      其中 【COM15】中的【15】会因电脑不同,插入电脑中USB口不同而改变,我们使用工具连接时要用到,所以要注意。

      13.png

      端口号一定要改成自己的,【speed】只能是115200,点击【open】后可能出现如图所示乱码,

      14.png

      没有关系,此时我敲下【回车】即可,又看到熟悉的画面,

      15.png

      通过串口连接主板的优点是,系统启动或执行各种操作时可以看到更多内核级信息,但文件传输不大方便。我们插拔下一下摄像头,可以看到终端给出了详细的日志

      16.png

      4.WIFI连网及SSH

      在PUTTY执行以下命令可以连接WIFI

      wifi_connect_ap_test WIFI名  密码
      

      17.png

      连接成功,可以PING个域名验证一下

      18.png

      网络一切正常了,看下R329的IP地址吧

      19.png

      由于不知道镜像root的密码,先修改一下

      passwd
      

      20.png

      修改成功,我们可以用【WINSCP】连SSH了,文件协议用【SCP】,密码是刚才修改时的密码

      21.png

      【SSH】连接成功后,可以看到之前【ADB】上传的【test.jpg】正在睡大觉

      22.png

      更多配置相关的信息可以参考官网文档

      运行量化后的模型

      1.仿真环境安装及量化在此不多说了,可以参考上一篇。Windows下一样可以装Docker,详细步骤可以参考Docker官方文档,其它量化操作不变。
      2.【cam】运行环境准备
      把附件中的文件通过【WINSCP】上传到 【/root/】下然后解压

      tar zxvf /root/cam.tar.gz
      

      首先先安装下NPU的驱动 【aipu.ko】

      cd /root/cam
      
      insmod ./aipu.ko]
      

      已连到串口的【PYTTY】窗口会返回

      23.png

      复制必须的【OPENCV】类库到系统 【lib】下

      cp ./lib/*.* /lib/
      

      运行摄像头实时分类示例

      ./cam ./mbnetv1/aipu.bin signed
      

      24.jpg

      25.jpg

      可以看到可以达到 26FPS ,速度还是很不错的,录了个小视频无法上传,已包含在下面网盘的链接里。后面找时间再分享下R329在【Armbian】下一点使用方面的想法。

      相关文件下载

      本文提到的所有文件,可以从这里下载: cam.tar.gz (提取码: pnb7)

      (文章转载自:极术社区 Aven_)
      (原文链接:https://aijishu.com/a/1060000000231220 )

      发布在 A Series
      q1215200171
      budbool
    • 【全志R329 inside!】小米xiaomi Sound高保真智能音箱拆解报告

      在8月10日,小米“2021雷军年度演讲”成功举行,并同时推出了旗下多款新品。其中,小米首款高端智能音箱xiaomi Sound也正式发布。

      xiaomi Sound智能音箱体积小巧,设计灵感来自于唱片机,外观采用了圆柱型的设计,机身为透明材质。顶部触控板像是唱片机上的黑胶唱片,并设计有CD纹理装饰,四周还设计有环形灯带。整体观感极具简约风格但又不失精致。

      配置上,采用2.25英寸全频单元+2颗无源辐射器,搭配顶部导音锥结构,实现360°全向出音。音质由HARMAN调音,并支持创新的计算音频技术实时动态调音和夜莺算法;其他方面支持两台设备组成立体声,最多8台设备互联;支持UWB音乐接力,实现音乐的无缝传递;搭配上“小爱同学”智能助手和小米强大的IoT生态系统,提供优质的智能音箱体验。

      我爱音频网此前拆解过小米旗下的小米 FlipBuds Pro降噪耳机、小米Air 2 Pro降噪耳机,小米Air2 SE、小米Air2S、小米Air2、红米 AirDots3 Pro 真无线降噪耳机、红米 AirDots 3、红米 AirDots 2、红米AirDots 真无线蓝牙耳机,以及小米小爱随身音箱和小米旗下其他16款蓝牙音箱产品,下面再来看下这款产品的内部结构配置吧~!

      一、xiaomi Sound智能音箱开箱

      640.webp
      xiaomi Sound在包装盒设计上也提升了一个档次。包装盒正面采用黑色背景搭配产品CD纹理和环形灯带,呈现出丰富的光感。上方有产品名称,右下角HARMAN标志和Hi-Res AUDIO认证。

      2.webp
      包装盒背面介绍有产品的多项功能特点,包括全方位声场、哈曼调音、海量声音内容、智能生活管家、UWB互联技术、懂你的小爱同学。

      3.webp

      电源适配器特写,xiaomi Sound智能音箱为有线输入电源。

      4.webp

      DC电源输入接口。

      5.webp

      电源适配器型号:AD-0241200205CN-1,输入:100-240V-50/60Hz 0.7V,输出:12V-2A,制造商:深圳市雅晶源科技有限公司。

      6.webp

      xiaomi Sound高保真智能音箱整体外观一览,圆柱形设计,机身为透明材质。

      7.webp

      机身透明外壳特写。

      8.webp

      xiaomi Sound顶部触控台特写,观感像是悬浮在机身上方。

      9.webp

      顶部触控板设计了CD纹理,有加/减音量和暂停/播放三颗功能按键。

      10.webp

      机身底部整体被防滑垫覆盖,防滑垫中心位置设计有xiaomi和HARMAN品牌LOGO,四周环形信息有中英文的产品型号:L16A,输入:12V-2A,小米通讯技术有限公司 中国制造,让每个人都能享受科技的乐趣。

      11.webp

      DC电源输入接口特写。

      二、xiaomi Sound智能音箱拆解

      看完了开箱,我们对xiaomi Sound高保真智能音箱的外观设计有了详细的了解,下面进入拆解部分,看看内部结构配置~

      12.webp

      机身固定螺丝隐藏在防滑垫下方。

      13.webp

      撕下防滑垫。

      14.webp

      防滑垫内侧特写,采用胶水和定位柱固定。

      15.webp

      卸掉音箱底部盖板的所有螺丝。

      16.webp

      主板USB调试接口。

      17.webp
      卸掉底部盖板可以看到音箱的主板单元。

      18.webp
      盖板内接结构一览。

      19.webp
      主板四周有多个连接器连接内部组件。

      20.webp
      挑开连接器掀开主板,内侧还有导线连接在主板的插座上。

      21.webp

      取掉主板,腔体内部结构一览,还设置有盖板分离主板和内部组件。

      90.webp

      盖板上金属散热片特写。

      22.webp

      扬声器单元连接主板的金属触点。

      23.webp
      主板一侧电路一览。

      24.webp

      主板另外一侧电路一览,左侧有两块屏蔽罩覆盖。

      25.webp

      金属屏蔽罩上设置有散热垫,连接盖板上的金属散热片,降低系统运行时的温度,保障运行的稳定性。

      26.webp

      两颗丝印34K的MOS管。

      27.webp

      丝印9J的稳压IC,实际型号为杰华特JW7805-1.8,是一款1.8V~5.5V/300mA的线性电压调整器,支持固定电压输出有:1.0V, 1.2V, 1.35V, 1.5V, 1.8V, 2.1V, 2.2V, 2.5V, 2.7V, 2.8V, 2.9V, 3.0V, 3.3V, 4.2V, 5.0V。集成过流和过温保护,支持输出放电功能,正负2%输出电压精度,低噪声,静态电流低至6uA,提供 SOT23-5 ,DFN1X1-4封装,潮湿敏感等级为一级(Moisture sensitivity level),已广泛应用于消费电子、存储、网通等类产品。

      28.webp

      杰华特JW7805-1.8详细资料图。

      29.webp

      丝印JWK8J的降压IC,实际型号为杰华特JW5250S(SOT23-5),是一款2.7V~6V/1A的同步降压转换器,1.5MHZ开关频率,静态电流低至40uA,峰值效率高达92%,并且集成输入热插拔保护功能,提供SOT23-5/SOT563封装,潮湿敏感等级为一级(Moisture sensitivity level), 已广泛应用于消费电子、存储、网通,TV,安防等类产品。

      89.webp

      杰华特JW5250S详细资料图。

      31.webp

      丝印JWF5J的降压IC,实际型号为杰华特JW5223(SOT23-5),是一款2.5V~6V/2A的同步降压转换器,1.5MHZ开关频率,静态电流低至40uA,峰值效率高达94%,轻载效率高于85%,并且集成输入热插拔保护功能,支持提供SOT23-5/6(Power Good)封装,潮湿敏感等级为一级(Moisture sensitivity level), 已广泛应用于消费电子、存储、网通,TV,安防等类产品。

      32.webp

      杰华特JW5223详细资料图。

      33.webp

      ESMT晶豪 F59L2G81KA 2Gbit ( 256M X 8 ) 3.3V NAND闪存,用于存储固件文件。

      34.webp

      ESMT晶豪 F59L2G81KA 详细资料图。

      35.webp

      镭雕117ANC的MEMS麦克风,主板四周总共搭载了6颗,组成360度拾音阵列,提升语音交互的准确性。据我爱音频网了解到,6颗麦克风均来自楼氏,型号:SPH0655,是一款带有PDM数字接口的麦克风,此款麦克风具有较高的信噪比为智能音箱的远距离拾音创造必要条件,能容忍较高声压级的音源,使其在智能音箱内部的摆放位置更灵活。

      36.webp

      丝印J5BXI的IC。

      37.webp

      TI德州仪器 TAS5825M 音频放大器,是一款立体声、高性能闭环D类放大器,具有集成的音频处理器和高达192kHz的输入能力。

      38.webp

      TI德州仪器 TAS5825M详细资料图。

      39.webp
      音频放大器输出滤波电感和供电滤波电容。

      40.webp

      连接扬声器单元的两颗金属触点。

      41.webp

      取掉屏蔽罩,内侧同样贴有散热垫,为内部的芯片散热。

      42.webp

      Realtek瑞昱 RTL8733BS WiFi和蓝牙Combo的单芯片解决方案,WiFi规格802.11abgn双频1T1R和蓝牙5.2,是WiFi4 Combo网卡。

      双频能力可在相较干净5G频段提供稳定WiFi吞吐,提供快速联网和无损高保音质音乐传输。在2.4G BT Mesh蓝牙组网应用开启时,例如蓝牙按钮、门铃等智能装置,和5G WiFi分频做完美的共存同时兼用,提升使用者体验。

      蓝牙5.2其中LE Isochronous Channel,俗称LE Audio功能可提供多声道同时互传,实现低延迟立体声及家庭剧院音响模式。

      目前阿里巴巴天猫精灵、百度度秘、喜马拉雅、Sony、Yandex、Mybox、Telefonica、DT等智能音箱无线方案,皆大量采用瑞昱WiFi/蓝牙Combo网卡。

      43.webp

      Allwinner全志 R329 AI语音专用芯,内置双核A53 1.5GHz,双核HIFI4 400MHz(2MB SRAM),Arm中国 Zhouyi 0.256T AIPU ;集成多路音频ADC和音频DAC;内置DDR设计精简,是非常强大具有AIPU的智能语音芯片。全志R329可以为智能音箱、智能家居提供高集成度应用方案。

      44.webp

      Allwinner全志R329详细资料图。

      45.webp

      继续拆解音箱,先取掉外部透明壳。

      46.webp

      透明壳内侧特写。

      47.webp

      内部腔体侧边展示1,DC电源输入接口母座。

      48.webp
      内部腔体侧边展示2,悬挂无源辐射器。

      49.webp

      内部腔体侧边展示3,固定UWB小板。

      50.webp

      内部腔体侧边展示4,固定有WiFi天线。

      51.webp

      底部盖板固定框架特写。

      52.webp

      DC电源输入接口母座特写,焊点套热缩管绝缘,导线泡棉包裹,防止共振产生杂音。

      53.webp

      UWB通信模组特写,模块焊接在排线上。

      54.webp

      无源辐射器特写,尺寸54mm x 44mm,用以提升低频量感。

      55.webp

      贴片WiFi天线特写,来自South Star。

      88.webp

      UWB通信模组正面特写,右侧为天线,左侧UWB芯片通过屏蔽罩覆盖,模块焊接在软排线上。

      57.webp

      背部贴有双面胶,用于固定在音箱机身上。

      58.webp

      UWB天线特写。

      59.webp

      Qorvo DW3210 UWB芯片,是第二代完全集成的脉冲无线电超宽带 (UWB) 无线收发器DW3000系列的一款。

      DW3210 基于 IEEE802.15.4z 标准,实现了增强的安全功能。DW3210 可实现高达 6.8 Mbps 的数据速率,同时在10厘米范围内提供精确定位以进行测距,在5度标准差范围内进行角度测量。在此款产品上用于音箱的UWB音乐接力功能,通过手机靠近音箱,即可实现音乐的无缝传递。

      60.webp
      Qorvo DW3210 详细资料图。

      61.webp

      金属散热片外侧特写。

      62.webp

      金属散热片内侧特写。

      63.webp

      取掉顶部盖板,内侧圆形出音孔盖板特写。

      64.webp

      腔体内部全频喇叭单元特写,纸盆橡胶边,通过四颗螺丝固定。

      65.webp

      取出全频喇叭,腔体内部结构一览。扬声器导线泡棉包裹,导线过孔处大量胶水密封。

      66.webp

      全频喇叭内侧设置有缓冲垫,密封防水和降低腔体共振。

      67.webp

      全频喇叭背部特写,丝印信息ASDPD0003-0301。

      68.webp

      全频喇叭导线连接端子特写。

      69.webp

      出音孔盖板上设置有缓冲橡胶帽。

      70.webp

      缓冲橡胶帽特写。

      71.webp

      出音孔盖板内侧特写,白色贴纸是走线位置,通过双面胶固定。

      72.webp

      外侧覆盖有细密防尘网,防止异物进入腔体。

      73.webp

      顶部触控板背面特写,由两颗螺丝固定盖板,排线穿孔而过。

      74.webp

      卸掉螺丝打开腔体。

      75.webp

      背板内侧整体采用了白色使散射灯光更加均匀,四周边缘位置透光,形成环形灯带。

      76.webp

      顶部盖板内侧特写,中间有圆形小板,两端两个触摸传感器。

      77.webp

      触摸传感器特写。

      78.webp

      主板延伸过来的排线通过连接器连接导线板,贴有胶带加强固定。

      79.webp
      取掉小板,下方还有一片触摸传感器,对应三个触摸按键。

      80.webp

      小板电路一览,四周设置有9颗LED指示灯。

      81.webp

      RGB LED指示灯特写。

      82.webp

      Chipsea芯海 CSA37F71 触摸检测IC,是芯海全新一代压力传感器调理芯片。该芯片较上一代产品CSA37F61的测量精度提升4倍,功耗下降30%。可在更厚的金属板上实现按键功能,为智能家居带来更丰富的人机交互体验。

      83.webp
      Chipsea芯海 CSA37F71详细资料图。

      84.webp

      小米xiaomi Sound高保真智能音箱拆解全家福。

      我爱音频网总结

      xiaomi Sound作为小米首款高端智能音箱,在外观上进行了全新的设计,整体观感极为精致,用料也别出心裁。透明的机身外壳能够融入到各种使用场景,呈现出不同的光泽感;顶部触控板设计搭配环形指示灯带,呈现出类悬浮效果。唯一缺憾是未内置电池,需要考虑电源线的摆放。

      内部结构方面主要分为底部主板单元、中间扬声器单元和顶部的触控单元。整体结构环环相扣,组件之间均通过各种连接器连接,提升了组装的便捷性。

      底部主板上,四周设置有6颗麦克风单元,组成360度拾音阵列,配备全志 R329 AI语音专用芯,实现精准的语音交互功能;主控芯片为瑞昱 RTL8733BS WiFi蓝牙Combo的单芯片解决方案,双频能力可在相较干净5G频段提供稳定WiFi吞吐,提供快速联网和无损高保音质音乐传输;音频放大器为德州仪器 TAS5825M,集成的音频处理器和高达192kHz的输入支持;以及用于存储固件的晶豪 F59L2G81KA NAND闪存,杰华特JW7805、JW5250S、JW5223降压IC等。

      全频喇叭单元和两个无源辐射器固定在内部框架上,四周还固定有WiFi天线,UWB通信模组。UWB通信模组采用了Qorvo DW3210 超宽带芯片,基于IEEE802.15.4z标准,支持高速率传输、精确定位,用于音箱的UWB音乐接力功能;顶部触控单元内部设置有三个触摸传感器,配备了芯海 CSA37F71 触摸检测IC。小板四周设置有9颗LED指示灯,拥有多种不同的色彩,用于语音交互反馈。

      整体来说,xiaomi Sound智能音箱无论是外观设计还是内部结构、做工,相较于以前的产品又有了很大的提升。最新的配置方案,360度全向出音扬声器系统,HARMAN调音,以及创新的计算音频技术,为小巧的机身提供了强悍的音频效果。UWB连接技术的应用还为其带来了更加便捷的使用体验。

      (文章转载自:我爱音频网)
      (原文链接:https://mp.weixin.qq.com/s/xcV2JIk5XHhLHB1ueMoGGg )

      发布在 A Series
      q1215200171
      budbool
    • 回复: 【素材汇总】D1开发板图片素材汇总

      扣好的哪吒

      哪吒.png

      发布在 公告
      q1215200171
      budbool
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 6 / 6