导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. miumiu
    3. 帖子
    • 资料
    • 关注 0
    • 粉丝 1
    • 我的积分 1035
    • 主题 20
    • 帖子 20
    • 最佳 4
    • 群组 0

    miumiu 发布的帖子

    • 安利一本书:《RISC-V 手册》

      作者:Hello小崔
      链接:https://zhuanlan.zhihu.com/p/148284839
      来源:知乎

      在A国封杀中国相关科技公司的大环境下,操作系统和芯片成为大家讨论很火的事情了。ARM公司受限A国法律限制,开始对HW明令禁止提供ARM架构芯片(当然也包括最近比较火的台积电不再接受HW芯片订单),国人又开始讨论如何打破芯片壁垒,是夹缝生存还是寻求突破?(额...其实没那么复杂,就是听说RISC-V能替代ARM和X86架构,并且社区比较火,觉得要与时俱进学习下)。

      学习新的架构(比如ARM或X86)有多种学习方法,比如通过阅读相关书籍著作了解学习,或是报名课程学习,或者查看官网资料。无论是哪种方式,最终都将回归到查看官网提供的芯片手册这条路,因为手册最准确,也最权威。

      RISC-V英文手册其实还好,相比ARMv8的6666页来说...如果有点吃力,就看下《RISC-V 手册》吧,下载地址:
      RISC-V-Reader-Chinese-v2p1.pdf

      为什么安利这本书,因为这本书对于想要了解RISC-V或者学习RISC-V指令,都比较适用。全书无论是介绍RISC-V还是相关指令,都说明为什么这样设计,有什么优点等等(现在X86为什么不好),让人容易理解和记住,总比上来就说架构寄存器多少个,都有什么功能等等,然后开始死记硬背好得多(恩,x86和arm都是这种感觉)。以下节选《RISC-V 手册》,算是对RISC-V和这本书有个印象。

      RISC-V是什么RISC-V(“RISC five”)的目标是成为一个通用的指令集架构(ISA):

      • 它要能适应包括从最袖珍的嵌入式控制器,到最快的高性能计算机等各种规模的处理器。

      • 它应该能兼容各种流行的软件栈和编程语言。

      • 它应该适应所有实现技术,包括现场可编程门阵列(FPGA)、 专用集成电路(ASIC)、 全定制芯片, 甚至未来的设备技术。

      • 它应该对所有微体系结构样式都有效:例如微编码或硬连线控制;顺序或乱序执行流水线; 单发射或超标量等等。

      • 它应该支持广泛的专业化,成为定制加速器的基础,因为随着摩尔定律的消退,加速器的重要性日益提高。

      • 它应该是稳定的,基础的指令集架构不应该改变。

        更重要的是,它不能像以前的专有指令集架构一样被弃用,例如AMD Am29000、 Digital Alpha、 Digital VAX、Hewlett Packard PA-RISC、 Intel i860、 Intel i960、 Motorola 88000、以及ZilogZ8000。

      RISC-V的不同寻常不仅在于它是一个最近诞生的指令集架构(它诞生于最近十年,而大多数其他指令集都诞生于20世纪70到80年代),而且在于它是一个开源的指令集架构。

      与几乎所有的旧架构不同,它的未来不受任何单一公司的浮沉或一时兴起的决定的影响(这一点让许多过去的指令集架构都遭了殃)。

      它属于一个开放的,非营利性质的基金会。 RISC-V基金会的目标是保持RISC-V的稳定性,仅仅出于技术原因缓慢而谨慎地发展它,并力图让它之于硬件如同Linux之于操作系统一样受欢迎。

      计算机体系结构的传统方法是增量ISA,新处理器不仅必须实现新的ISA扩展,还必须实现过去的所有扩展。

      目的是为了保持向后的二进制兼容性,这样几十年前程序的二进制版本仍然可以在最新的处理器上正确运行。

      这一要求与来自于同时发布新指令和新处理器的营销上的诱惑共同导致了ISA的体量随时间大幅增长。例如,图1.2显示了当今主导ISA80x86的指令数量增长过程。这个指令集架构的历史可以追溯到1978年,在它的漫长生涯中,它平均每个月增加了大约三条指令。

      这个传统意味着x86-32(我们用它表示32位地址版本的x86)的每个实现必须实现过去的扩展中的错误设计,即便它们不再有意义。例如, 图1.3描述了x86的ASCII Adjust afterAddition(aaa)指令,该指令早已失效。

      作为一个类比,假设一家餐馆只提供固定价格的餐点,最初只是一顿包含汉堡和奶昔的小餐。 随着时间的推移,它会加入薯条,然后是冰淇淋圣代,然后是沙拉,馅饼,葡萄酒,素食意大利面,牛排,啤酒,无穷无尽,直到它成为一顿大餐。食客可以在那家餐厅找到他们过去吃过的东西,尽管总的来说这样做可能没什么意义。这样做的坏处是,用餐者为每次晚餐支付的宴会费用不断增加。

      RISC-V的不同寻常之处,除了在于它是最近诞生的和开源的以外,还在于:和几乎所有以往的ISA不同,它是模块化的。它的核心是一个名为RV32I的基础ISA,运行一个完整的软件栈。

      RV32I是固定的,永远不会改变。这为编译器编写者,操作系统开发人员和汇编语言程序员提供了稳定的目标。模块化来源于可选的标准扩展,根据应用程序的需要,硬件可以包含或不包含这些扩展。

      这种模块化特性使得RISC-V具有了袖珍化、低能耗的特点,而这对于嵌入式应用可能至关重要。 RISC-V编译器得知当前硬件包含哪些扩展后,便可以生成当前硬件条件下的最佳代码。

      惯例是把代表扩展的字母附加到指令集名称之后作为指示。例如, RV32IMFD将乘法(RV32M),单精度浮点(RV32F)和双精度浮点(RV32D)的扩展添加到了基础指令集(RV32I)中。继续用我们刚才的类比来说, RISC-V提供的是菜单,而不是一顿应有尽有的自助餐。

      主厨只需要烹饪顾客需要的东西(而不是每次都做出一顿盛宴),顾客只需要按他们的订单付费。 RISC-V无需仅仅为了市场吸引力而添加指令。

      RISC-V基金会会决定什么时候在菜单里添加新的选项,而他们只会出于技术原因这样做,而且要在由软硬件专家组成的委员会进行专门的公开讨论以后才会添加。即使那些新选择出现在了菜单上,它们仍是可选的,不会像在增量ISA中那样成为未来所有实现的必要组成部分。

      很通俗易懂,为什么设计RISC-V,因为x86的又老又复杂,并且臃肿(很多用不到的指令)。RISC-V希望吸取前人经验和结合现在的实际情况,开发一种通用的指令集架构。

      发布在 灌水区
      miumiu
      WOW
    • 国内的中文Spec可以跟着看看,在这个网址下面都有

      https://cnrv.io/resource

      发布在 灌水区
      miumiu
      WOW
    • 了解RISC-V的指令架构,建议入手看官方的Spec

      riscv-spec-v2.2.pdf

      发布在 灌水区
      miumiu
      WOW
    • 中国开放指令生态(RISC-V)联盟发布的开放指令集与开源芯片发展报告:

      OpenISA-OpenSourceChip-Report.pdf

      发布在 灌水区
      miumiu
      WOW
    • 为什么RISC-V将超越ARM?

      作者:Morris.Zhang
      链接:https://www.zhihu.com/question/450092365/answer/1799057546
      来源:知乎

      近几年间在中/美走访过一些RISC-V基金会和创业项目。从厂商的视角推测,假想差不多10年左右的技术迭代期限,RISC-V技术代际不会挑战Intel,但有可能会挑战ARM M-core,应不会挑战到A-core。

      商业模式上: IP授权才是效益池。以RISC-V的血统,形成稳定传承的公版家族和发展公版生态十分重要的,这是避免IP碎片化和避免芯片产品无法赚钱的关键因素,也是流片成本摊薄并形成普遍经济效益的重要因素。

      RISC-V在这方面的短板是显而易见的:低成本自由授权+厂商随意定义指令的模式使得公版延续无法得到保护,软件和编译器生态所依仗的长期兼容性同样不稳固,碎片化不可避免,MIPS在个别方面亦有前车之鉴。

      与之相对比,RISC家族里的产品化实力和经济效益都很好的当然是ARM,质优+量足+门槛低+大规模流片应用的信誉,收敛了大量公版IP授权案例,比如Qcom虽然自己做CPU,也逐渐转向ARM公版,多快好省;而其严格管控的Architectural-license更是通过ARM design services驱动大厂投入ARM设计,进一步验证和发扬了ARM指令架构和IPs的信誉,同时经历大量workloads的洗礼验证;此外,ARM又十分重视拥抱商业EDA生态以及Fab合作,输出了大量设计工具和IP。

      而反观RISC-V,当下全球有一个百亿级晶体管密度的商用案例么?- 技术生态上: 如今RISC-V的声音不小,当然,RISC-V能够大幅简化电路,但对复杂应用拆解要么增加操作数牺牲性能,要么增加指令集又把系统复杂化,比如其SIMD指令就没有真正堪用的,唯一可用的Hwacha向量指令集(开源)本质上还是协处理器,连乱序执行流水线都整合不进去,更不用说做编译器层优化了;而进一步讲,所谓的复杂指令集实际是在电路层给这些操作建立shortcuts,需要经年累月的设计积累和workload验证,都是有晶圆面积代价的。

      这种情形下,就会限制芯片用途的想象力了,DSA的碎片化和软件生态会成为掣肘,而做通用芯片尤其是CPU的短期市场侵彻可能性是微小的。以及,提一句EDA库,稍大型的商用设计都需要大调RTL,毕竟RISC-V的应用实例少,参考工具不多,很多不能拿来直接用,需要适配经典IP以及开发出新的IP族,这也需要漫长演进以及牺牲晶圆面积代价,最终究竟是在通用领域或是专精领域沉淀出成果还未可知,但至少要形成自己的公版授权生态和装机量,才不至于IP碎片化而带来的窄赛道和低经济效益。

      此处不妨回顾一下历史:ARM有今天成绩,DEC功不可没,老DEC真是有不少财宝的,INTC凭借那次收购StrongARM的IP资源、设计经验积累以及door keeper级别的人才才稳步攻入服务器市场的,而ARM的真正商用也受益于DEC遗产;想象一下,RISC起源的时期有诸多大鲸:IBM Power, SPARC, ALPHA …最终仅有ARM一骑绝尘,倘若没有DEC,ARM也会遇到今天RISC-V的满地碎片局面。

      未来几年,RISC-V会有一些消费侧IoT的小实例,但由于IP碎片化而不容易赚钱,很难挑战ARM-M,不会挑战到A,更不会挑战x86版图。而另一个掣肘是,目前可见开发RISC-V芯片项目有三种方式,一是购买商用IP,二是参考开源代码,三是理想化的从零自研(总不会从第1个管子开始画起)。

      而若从美国的RISC-V商用IP厂商购买IP,则会受EAR管制,比如不能出售IP及提供服务给华为;若采用开源代码或自行开发,目前看不受管制,但需要避免被标准组织终止会员资格,以及美国社区仍可能做出限制。

      引用一句戴伟民先生的讲话:Intel X86和ARM的IP授权虽然给中国带来了繁荣,但却是不自主和不可控的。而架构授权虽然不自主,但是可控且可以繁荣的。基于M-Core、MIPS Alpha的CPU则是自主、可控但不繁荣的。希望中国的CPU可借助RISC-V做到自主、可控、繁荣,并且持续性创新。

      发布在 灌水区
      miumiu
      WOW
    • Linux Poll 使用方法和实现

      转载自:https://blog.csdn.net/zhuxiaoping54532/article/details/51701549

      Linux socket之四:使用POLL机制处理多连接

      使用select函数可以处理socket多连接的问题(select的用法参见:http://blog.csdn.net/zhandoushi1982/article/details/5070107),使用POLL也可以实现同样的功能,且调用方式更加简单。原型是:

      [cpp] view plain copy
      struct pollfd {
      int fd; //文件描述符
      short events; //要求查询的事件掩码
      short revents; //返回的事件掩码
      };
      int poll(struct pollfd *ufds, unsigned int nfds, int timeout);

      poll函数使用pollfd类型的结构来监控一组文件句柄,ufds是要监控的文件句柄集合,nfds是监控的文件句柄数量,timeout是等待的毫秒数,这段时间内无论I/O是否准备好,poll都会返回。

      timeout为负数表示无线等待,timeout为0表示调用后立即返回。

      执行结果:为0表示超时前没有任何事件发生;-1表示失败;

      成功则返回结构体中revents不为0的文件描述符个数。pollfd结构监控的事件类型如下:

      [cpp] view plain copy
      #define POLLIN 0x0001
      #define POLLPRI 0x0002
      #define POLLOUT 0x0004
      #define POLLERR 0x0008
      #define POLLHUP 0x0010
      #define POLLNVAL 0x0020

      #define POLLRDNORM 0x0040
      #define POLLRDBAND 0x0080
      #define POLLWRNORM 0x0100
      #define POLLWRBAND 0x0200
      #define POLLMSG 0x0400
      #define POLLREMOVE 0x1000
      #define POLLRDHUP 0x2000

      如上是events事件掩码的值域,POLLIN|POLLPRI类似于select的读事件,POLLOUT|POLLWRBAND类似于select的写事件。当events属性为POLLIN|POLLOUT,表示监控是否可读或可写。

      在poll返回时,即可通过检查revents变量对应的标志位与events是否相同,比如revents中POLLIN事件标志位被设置,则表示文件描述符可以被读取。代码段示例:

      [cpp] view plain copy
      int sockfd; //套接字句柄
      struct pollfd pollfds;
      int timeout;

      timeout = 5000;
      pollfds.fd = sockfd; //设置监控sockfd
      pollfds.events = POLLIN|POLLPRI; //设置监控的事件

      for(;;){
      switch(poll(&pollfds,1,timeout)){ //开始监控
      case -1: //函数调用出错
      printf("poll error \r\n");
      break;
      case 0:
      printf("time out \r\n");
      break;
      default: //得到数据返回
      printf("sockfd have some event \r\n");
      printf("event value is 0x%x",pollfds.revents);
      break;
      }
      }
      原文:http://blog.csdn.net/zhandoushi1982/article/details/7738424

      Linux poll()解析
      poll()函数:这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,下面是这个函数的声明:
      #include <poll.h>

      int poll(struct pollfd fds[], nfds_t nfds, int timeout);

      参数说明:

      fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;

      每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;

      特别是对于 socket连接比较多的情况下,在一定程度上可以提高处理的效率;

      这一点与select()函数不同,调用select()函数之后,select() 函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;

      因 此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;

      nfds:nfds_t类型的参数,用于标记数组fds中的结构体元素的总数量;

      timeout:是poll函数调用阻塞的时间,单位:毫秒;

      返回值:

      0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;

      ==0:数组fds中没有任何socket描述符准备好读、写,或出错;此时poll超时,超时时间是timeout毫秒;换句话说,如果所检测的 socket描述符上没有任何事件发生的话,那么poll()函数会阻塞timeout所指定的毫秒时间长度之后返回,如果timeout==0,那么 poll() 函数立即返回而不阻塞,如果timeout==INFTIM,那么poll() 函数会一直阻塞下去,直到所检测的socket描述符上的感兴趣的事件发 生是才返回,如果感兴趣的事件永远不发生,那么poll()就会永远阻塞下去;

      -1: poll函数调用失败,同时会自动设置全局变量errno;

      如果待检测的socket描述符为负值,则对这个描述符的检测就会被忽略,也就是不会对成员变量events进行检测,在events上注册的事件也会被忽略,poll()函数返回的时候,会把成员变量revents设置为0,表示没有事件发生;

      另外,poll() 函数不会受到socket描述符上的O_NDELAY标记和O_NONBLOCK标记的影响和制约,也就是说,不管socket是阻塞的还是非阻塞 的,poll()函数都不会收到影响;而select()函数则不同,select()函数会受到O_NDELAY标记和O_NONBLOCK标记的影 响,如果socket是阻塞的socket,则调用select()跟不调用select()时的效果是一样的,socket仍然是阻塞式TCP通讯,相 反,如果socket是非阻塞的socket,那么调用select()时就可以实现非阻塞式TCP通讯;

      所以poll() 函数的功能和返回值的含义与 select() 函数的功能和返回值的含义是完全一样的,两者之间的差别就是内部实现方式不一样,select()函数基本上可以在所有支持文件描述符操作的系统平台上运 行(如:Linux 、Unix 、Windows、MacOS等),可移植性好,而poll()函数则只有个别的的操作系统提供支持(如:SunOS、Solaris、AIX、HP提供 支持,但是Linux不提供支持),可移植性差;

      strust pollfd结构说明:

      typedef struct pollfd {
      int fd; /* 需要被检测或选择的文件描述符*/
      short events; /* 对文件描述符fd上感兴趣的事件 /
      short revents; /
      文件描述符fd上当前实际发生的事件*/
      } pollfd_t;

      typedef unsigned long nfds_t;

      经常检测的事件标记: POLLIN/POLLRDNORM(可读)、POLLOUT/POLLWRNORM(可写)、POLLERR(出错)

      如果是对一个描述符上的多个事件感兴趣的话,可以把这些常量标记之间进行按位或运算就可以了;

      比如:对socket描述符fd上的读、写、异常事件感兴趣,就可以这样做:struct pollfd fds;

      fds[nIndex].events=POLLIN | POLLOUT | POLLERR;

      当 poll()函数返回时,要判断所检测的socket描述符上发生的事件,可以这样做: struct pollfd fds;

      检测可读TCP连接请求:

      if((fds[nIndex].revents & POLLIN) == POLLIN){//接收数据/调用accept()接收连接请求}

      检测可写:

      if((fds[nIndex].revents & POLLOUT) == POLLOUT){//发送数据}

      检测异常:

      if((fds[nIndex].revents & POLLERR) == POLLERR){//异常处理}

      每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域。

      revents域是文件描述符的操作结果事件掩码。内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。合法的事件

      如下:
      POLLIN
      有数据可读。

      POLLRDNORM
      有普通数据可读。

      POLLRDBAND
      有优先数据可读。

      POLLPRI
      有紧迫数据可读。

      POLLOUT
      写数据不会导致阻塞。

      POLLWRNORM
      写普通数据不会导致阻塞。

      POLLWRBAND
      写优先数据不会导致阻塞。

      POLLMSG
      SIGPOLL 消息可用。
      此外,revents域中还可能返回下列事件:

      POLLER
      指定的文件描述符发生错误。

      POLLHUP
      指定的文件描述符挂起事件。

      POLLNVAL
      指定的文件描述符非法。

      这些事件在events域中无意义,因为它们在合适的时候总是会从revents中返回。使用poll()和select()不一样,你不需要显式地请求异常情况报告。

      POLLIN | POLLPRI等价于select()的读事件,POLLOUT |POLLWRBAND等价于select()的写事件。POLLIN等价于POLLRDNORM |POLLRDBAND,而POLLOUT则等价于POLLWRNORM。

      例如,要同时监视一个文件描述符是否可读和可写,我们可以设置 events为POLLIN |POLLOUT。在poll返回时,我们可以检查revents中的标志,对应于文件描述符请求的events结构体。

      如果POLLIN事件被设置,则文件描述符可以被读取而不阻塞。

      如果POLLOUT被设置,则文件描述符可以写入而不导致阻塞。

      这些标志并不是互斥的:它们可能被同时设置,表示这个文件描述符的读取和写入操作都会正常返回而不阻塞。

      timeout参数指定等待的毫秒数,无论I/O是否准备好,poll都会返回。

      timeout指定为负数值表示无限超时;timeout为0指示poll调用立即返回并列出准备好I/O的文件描述符,但并不等待其它的事件。这种情况下,poll()就像它的名字那样,一旦选举出来,立即返回。

      返回值和错误代码
      成功时,poll()返回结构体中revents域不为0的文件描述符个数;如果在超时前没有任何事件发生,poll()返回0;失败时,poll()返回-1,并设置errno为下列值之一:

      EBADF
      一个或多个结构体中指定的文件描述符无效。

      EFAULT
      fds指针指向的地址超出进程的地址空间。

      EINTR
      请求的事件之前产生一个信号,调用可以重新发起。

      EINVAL
      nfds参数超出PLIMIT_NOFILE值。

      ENOMEM
      可用内存不足,无法完成请求。


      linux的poll机制
      Poll就是监控文件是否可读的一种机制,作用与select一样。
      应用程序的调用函数如下:

      int poll(struct pollfd *fds,nfds_t nfds, int timeout);

      Poll机制会判断fds中的文件是否可读,如果可读则会立即返回,返回的值就是可读fd的数量,如果不可读,那么就进程就会休眠timeout这么长的时间,然后再来判断是否有文件可读,如果有,返回fd的数量,如果没有,则返回0.

      内核实现流程:

      当应用程序调用poll函数的时候,会调用到系统调用sys_poll函数,该函数最终调用do_poll函数,do_poll函数中有一个死循 环,

      在里面又会利用do_pollfd函数去调用驱动中的poll函数(fds中每个成员的字符驱动程序都会被扫描到),驱动程序中的Poll函数的工作 有两个,

      一个就是调用poll_wait 函数,把进程挂到等待队列中去(这个是必须的,你要睡眠,必须要在一个等待队列上面,否则到哪里去唤醒你呢??),

      另一个是确定相关的fd是否有内容可 读,如果可读,就返回1,否则返回0,如果返回1 ,do_poll函数中的count++,

      然后 do_poll函数然后判断三个条件(if (count ||!timeout || signal_pending(current)))如果成立就直接跳出,如果不成立,

      就睡眠timeout个jiffes这么长的时间(调用schedule_timeout实现睡眠),如果在这段时间内没有其他进程去唤醒它,

      那么第二次执行判断的时候就会跳出死循环。如果在这段时间内有其他进程唤醒它,那么也可以跳出死循环返回

      (例如我们可以利用中断处理函数去唤醒它,这样的话一有数据可读,就可以让它立即返回)。

      1.  sys_poll函数位于fs/select.c文件中,代码如下:
        

      asmlinkagelong sys_poll(struct pollfd __user *ufds, unsigned int nfds, long timeout_msecs)

      {

      s64 timeout_jiffies;

           if (timeout_msecs > 0) {
      

      #ifHZ > 1000

               /* We can only overflow if HZ >1000 */
      
               if (timeout_msecs / 1000 >(s64)0x7fffffffffffffffULL / (s64)HZ)
      
                   timeout_jiffies = -1;
      
               else
      

      #endif

                   timeout_jiffies =msecs_to_jiffies(timeout_msecs);
      
           } 
      

      else

      {
      /* Infinite (< 0) or no (0)timeout */

               timeout_jiffies = timeout_msecs;
      
           } 
      
           return do_sys_poll(ufds,nfds, &timeout_jiffies);
      

      }

      它对超时参数稍作处理后,直接调用do_sys_poll。

      1.  do_sys_poll函数也位于位于fs/select.c文件中,我们忽略其他代码:
        

      intdo_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)

      {
      ……

      poll_initwait(&table);

      ……

           fdcount = do_poll(nfds, head,&table, timeout);
      

      ……

      }

      poll_initwait函数非常简单,它初始化一个poll_wqueues变量table:

      poll_initwait> init_poll_funcptr(&pwq->pt, __pollwait); > pt->qproc = qproc;

      即table->pt->qproc= __pollwait,__pollwait将在驱动的poll函数里用到。

      1.  do_sys_poll函数位于fs/select.c文件中,代码如下:
        

      static int do_poll(unsigned int nfds, struct poll_list *list, struct poll_wqueues *wait, s64 *timeout)

      {
      01 ……

      02 for (;;){
      03 ……

      04 if(do_pollfd(pfd, pt)) {
      05 count++;

      06 pt = NULL;

      07 }

      08 ……

      09 if(count || !*timeout || signal_pending(current))

      10 break;

      11 count= wait->error;

      12 if(count)

      13 break;14

      15 if(*timeout < 0) {
      16 /*Wait indefinitely */

      17 __timeout= MAX_SCHEDULE_TIMEOUT;

      18 }else if (unlikely(timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {
      19 /

      20 * Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in

      21 * a loop

      22 */

      23 __timeout= MAX_SCHEDULE_TIMEOUT - 1;

      24 *timeout-= __timeout;

      25 }else {
      26 __timeout= *timeout;

      27 *timeout= 0;

      28 }29

      30 __timeout= schedule_timeout(__timeout); // 休眠时间由应用提供

      31 if(*timeout >= 0)

      32 *timeout+= __timeout;

      33 }

      34 __set_current_state(TASK_RUNNING);

      35 returncount;

      36 }

      分析其中的代码,可以发现,它的作用如下:

      ① 从02行可以知道,这是个循环,它退出的条件为:

      a. 09行的3个条件之一(count非0,超时、有信号等待处理)

      count顺0表示04行的do_pollfd至少有一个成功。

      b. 11、12行:发生错误

      ② 重点在do_pollfd函数,后面再分析

      ③ 第30行,让本进程休眠一段时间,注意:应用程序执行poll调用后,如果①②的条件不满足,进程就会进入休眠。那么,谁唤醒呢?除了休眠到指定时间被系统唤醒外,还可以被驱动程序唤醒──记住这点,这就是为什么驱动的poll里要调用poll_wait的原因,后面分析。

      1.  do_pollfd函数位于fs/select.c文件中,代码如下:
        

      static inline unsigned int do_pollfd(struct pollfd*pollfd, poll_table *pwait)

      {
      ……

               if(file->f_op && file->f_op->poll)
      
                       mask= file->f_op->poll(file, pwait);
      

      ……

      }

      可见,它就是调用我们的驱动程序里注册的poll函数。

      二、驱动程序:

      驱动程序里与poll相关的地方有两处:一是构造file_operation结构时,要定义自己的poll函数。二是通过poll_wait来调用上面说到的__pollwait函数,pollwait的代码如下:

      staticinline void poll_wait(struct file * filp, wait_queue_head_t * wait_address,poll_table *p)

      {
      if (p && wait_address)

               p->qproc(filp, wait_address, p);
      

      }

      p->qproc就是__pollwait函数,从它的代码可知,它只是把当前进程挂入我们驱动程序里定义的一个队列里而已。它的代码如下:

      staticvoid __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)

      {
      struct poll_table_entry *entry =poll_get_entry(p);

           if (!entry)
      
               return;
      
           get_file(filp);
      
           entry->filp = filp;
      
           entry->wait_address = wait_address;
      
           init_waitqueue_entry(&entry->wait,current);
      
           add_wait_queue(wait_address,&entry->wait);
      

      }

      执行到驱动程序的poll_wait函数时,进程并没有休眠,我们的驱动程序里实现的poll函数是不会引起休眠的。让进程进入休眠,是前面分析的do_sys_poll函数的30行“__timeout = schedule_timeout(__timeout)”。

      poll_wait只是把本进程挂入某个队列,应用程序调用poll > sys_poll> do_sys_poll > poll_initwait,do_poll > do_pollfd > 我们自己写的poll函数后,再调用schedule_timeout进入休眠。

      如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。可见,poll_wait的作用,只是为了让驱动程序能找到要唤醒的进程。即使不用poll_wait,我们的程序也有机会被唤醒:

      chedule_timeout(__timeout),只是休眠__time_out这段时间。

      现在来总结一下poll机制:

      1. poll > sys_poll > do_sys_poll >poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。

      2. 接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数

        它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;

        它还判断一下设备是否就绪。

      3. 如果设备未就绪,do_sys_poll里会让进程休眠一定时间,这个时间是应用提供的“超时时间”

      4. 进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。

      5. 如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作1次,直到应用程序给定的时间, 然后返回。

      驱动的poll函数编写模板如下:

      static DECLARE_WAIT_QUEUE_HEAD(my_waitq); //休眠要挂的等待队列
      static unsigned drv_poll(struct file *file, poll_table *wait)
      {
      unsigned int mask = 0;
      poll_wait(file, &my_waitq, wait); // 不会立即休眠
      if (有数据)
      mask |= POLLIN | POLLRDNORM;
      return mask;
      }

      发布在 Linux
      miumiu
      WOW
    • 精通 Git

      转载自:http://whycan.com/t_4495.html

      目录
      许可证 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
      Scott Chacon 序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
      Ben Straub 序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
      献辞 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
      贡献者 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
      引言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
      起步 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
      关于版本控制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
      Git 简史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
      Git 是什么? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
      命令行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
      安装 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
      初次运行 Git 前的配置. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
      获取帮助 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
      Git 基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
      获取 Git 仓库. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
      记录每次更新到仓库 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
      查看提交历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
      撤消操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
      远程仓库的使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
      打标签 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
      Git 别名 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
      Git 分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
      分支简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
      分支的新建与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
      分支管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
      分支开发工作流 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
      远程分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
      变基 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
      服务器上的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
      协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
      在服务器上搭建 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
      生成 SSH 公钥 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
      配置服务器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
      Git 守护进程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
      Smart HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
      GitWeb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
      GitLab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
      第三方托管的选择 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
      分布式 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
      分布式工作流程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
      向一个项目贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
      维护项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
      GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
      账户的创建和配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
      对项目做出贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
      维护项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
      管理组织 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
      脚本 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
      Git 工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
      选择修订版本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
      交互式暂存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
      贮藏与清理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
      签署工作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
      搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
      重写历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
      重置揭密 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
      高级合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
      Rerere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
      使用 Git 调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
      子模块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
      打包 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
      替换 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
      凭证存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
      自定义 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
      配置 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
      Git 属性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
      Git 钩子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
      使用强制策略的一个例子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
      Git 与其他系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
      作为客户端的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
      迁移到 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
      Git 内部原理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
      底层命令与上层命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
      Git 对象 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
      Git 引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
      包文件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
      引用规范 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
      传输协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
      维护与数据恢复 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
      环境变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
      附录 A: 在其它环境中使用 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
      图形界面 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
      Visual Studio 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
      Git in Visual Studio Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
      Eclipse 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
      Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
      Git in Sublime Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
      Bash 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
      Zsh 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
      Git 在 PowerShell 中使用 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
      附录 B: 在你的应用中嵌入 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      命令行 Git 方式. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      Libgit2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      JGit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
      go-git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
      Dulwich. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
      附录 😄 Git 命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
      设置与配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
      获取与创建项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
      快照基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
      分支与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
      项目分享与更新 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
      检查与比较 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
      调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
      补丁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
      邮件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
      外部系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
      管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
      底层命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
      索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509

      资料下载:progit_v2_1_36.pdf

      发布在 Linux
      miumiu
      WOW
    • Linux命令行获取本机外网地址

      转载自:http://whycan.com/t_5187.html (出处:哇酷开发者社区)

      sudo apt-get install curl -y
      以下任意一个命令行均可以:

      curl checkip.amazonaws.com
      curl ifconfig.me
      curl icanhazip.com
      curl ipecho.net/plain
      curl ifconfig.co

      参考: https://www.cyberciti.biz/faq/how-to-find-my-public-ip-address-from-command-line-on-a-linux/

      发布在 Linux
      miumiu
      WOW
    • Linux 工具快速教程

      转载自:http://whycan.com/t_4494.html (出处:哇酷开发者社区)

      致谢
      README
      Linux基础

      1. 学会使用命令帮助
      2. 文件及目录管理
      3. 文本处理
      4. 磁盘管理
      5. 进程管理工具
      6. 性能监控
      7. 网络工具
      8. 用户管理工具
      9. 系统管理及IPC资源管理
        Linux工具进阶
      10. 程序构建
      11. 程序调试
      12. 性能优化
        工具参考篇
      13. gdb 调试利器
      14. ldd 查看程序依赖库
      15. lsof 一切皆文件
      16. ps 进程查看器
      17. pstack 跟踪进程栈
      18. strace 跟踪进程中的系统调用
      19. ipcs 查询进程间通信状态
      20. top linux下的任务管理器
      21. free 查询可用内存
      22. vmstat 监视内存使用情况
      23. iostat 监视I/O子系统
      24. sar 找出系统瓶颈的利器
      25. readelf elf文件格式分析
      26. objdump 二进制文件分析
      27. nm 目标文件格式分析
      28. size 查看程序内存映像大小
      29. wget 文件下载
      30. scp 跨机远程拷贝
      31. crontab 定时任务

      Linux工具快速教程.pdf

      发布在 Linux
      miumiu
      WOW
    • 嵌入式 Linux 知识库

      转载自:http://whycan.com/t_4493.html(哇酷开发者社区)

      致谢
      当前文档 《嵌入式 Linux 知识库 (eLinux.org)》 由 进击的皇虫 使用 书栈
      (BookStack.CN) 进行构建,生成于 2018-02-21。
      书栈(BookStack.CN) 仅提供文档编写、整理、归类等功能,以及对文档内容的生成和导出工
      具。
      文档内容由网友们编写和整理,书栈(BookStack.CN) 难以确认文档内容知识点是否错漏。如
      果您在阅读文档获取知识的时候,发现文档内容有不恰当的地方,请向我们反馈,让我们共同携手,
      将知识准确、高效且有效地传递给每一个人。
      同时,如果您在日常生活、工作和学习中遇到有价值有营养的知识文档,欢迎分享到 书栈
      (BookStack.CN) ,为知识的传承献上您的一份力量!
      如果当前文档生成时间太久,请到 书栈(BookStack.CN) 获取最新的文档,以跟上知识更新换
      代的步伐。
      文档地址:http://www.bookstack.cn/books/tinyclub-elinux
      书栈官网:http://www.bookstack.cn
      书栈开源:https://github.com/TruthHun
      分享,让知识传承更久远! 感谢知识的创造者,感谢知识的分享者,也感谢每一位阅读到此处的
      读者,因为我们都将成为知识的传承者。

      嵌入式 Linux 知识库 (eLinux.org)
      Embedded Linux Wiki 采用 MediaWiki 系统,由 CE Linux Forum 创建。
      基于上述 Mediawiki 版本,这里的 GitBook 版本由 eLinux.org 中文翻译组 创建,目的是为
      了更好地通过网络协作把它翻译成其他语言,而副产品是该知识库可以作为可打印和可阅读的免费书
      籍下载而且支持 pdf,epub 或者 mobi 格式。
      项目首页: http://www.tinylab.org/elinux
      Git 仓库: https://github.com/tinyclub/elinux
      在线阅读: http://tinylab.gitbooks.io/elinux
      实验云台:在线学 Linux,Linux 0.11,汇编,Shell,C ...

      介绍
      欢迎访问 eLinux 知识库!
      本知识库的目标是保存和呈现各类信息,既涉及使用 Linux 进行嵌入式系统开发,也涵盖与通用嵌
      入式开发相关的开源项目和工具。
      点击左侧的导航菜单,即可开启本知识库之旅!
      该站主要带来各类资源列表和信息收集,可用于解决特定领域的问题。例如,如果碰到嵌入式 Linux
      系统启动时间有关问题,则可以阅读启动时间。

      固件
      固件

      安全
      安全
      目录
      简介
      技术/项目主页
      Linux Kernel 中的安全子系统
      SELinux
      Tomoyo
      SMACK
      陈旧的信息 ( 2005 年,CELF 调查的相关信息)
      文档
      关键需求与相关技术点
      资源
      安全框架
      安全组件
      安全特性
      其他资源
      安全活动
      邮件列表
      会议
      安全相关的文章
      论文
      实例和开源代码
      原文:eLinux.org
      翻译:@lzz5235
      校订:@lzufalcon
      安全
      目录
      2 简介
      3 技术/项目主页
      4 Linux Kernel 中的安全子系统
      4.1 SELinux
      4.2 Tomoyo
      4.3 SMACK
      安全
      5 陈旧的信息 ( 2005 年,CELF 调查的相关信息)
      5.1 文档
      5.2 关键需求与相关技术点
      5.3 资源
      5.3.1 安全框架
      5.3.2 安全组件
      5.3.3 安全特性
      5.3.4 其他资源
      5.3.4.1 安全活动
      5.3.4.2 邮件列表
      5.3.4.3 会议
      5.3.4.4 安全相关的文章
      5.3.4.5 论文
      5.3.4.6 实例和开源代码

      实时
      实时
      简介
      实时领域 Wiki
      软件项目
      硬件实现
      文档
      更多开源项目

      启动时间
      启动时间
      目录
      简介
      技术/项目主页
      测量启动时间
      减少启动时间的技术和技巧
      引导程序(Bootloader)加速
      内核加速
      文件系统方面的问题
      用户空间和应用程序加速
      系统休眠相关的改进
      杂项
      一些未经验证的想法
      文章和演讲稿
      案例研究
      其他的项目/邮件列表/资源
      SysV ‘init’ 的替代品
      busybox init
      upstart
      Android init
      systemd
      Kexec
      启动画面(Splash Screen)项目
      其他
      正在从事快速启动的公司、个人或者项目
      启动时间检查清单

      网络
      网络
      目录
      简介
      嵌入式 Linux 网络

      多媒体
      多媒体
      目录
      简介
      CELF 2.0 AVG 规范
      音、视频工作组
      DirectFB 研究
      什么是 DirectFB,DirectFB 如何工作
      嵌入式 Linux 平台上 DirectFB 示例实现
      嵌入式 Linux 平台上一些 DirectFB 基准测试结果
      相关项目
      图形/视频输出
      Framebuffer/帧缓冲
      DirectFB
      V4L2
      X11
      NanoX
      OpenGL (OpenML)
      SDL
      Cairo
      Clutter
      Enlightenment Foundation Libraries ( EFL )
      Qt
      演示图板套件 (演示图板设计师/引擎,来自 Crank Software)
      GStreamer
      Xine
      MPlayer
      文档
      Video in
      V4L[2]
      OpenML
      LinuxTV (DVB API)
      音频输入/输出
      OSS
      ALSA
      OpenAL
      PulseAudio
      AVG 标准的使用者
      Video Lan
      Freevo
      多媒体
      LinuxTV
      MythTV
      DVR
      OpenPVR
      Morphine.TV
      其他
      ARIB 架构(一个数字广播系统标准)
      启动画面
      数字家庭工作组
      Disko 框架
      Free Type(软件字体引擎)
      UPnP
      TV Anytime 论坛
      TV Linux 联盟

      系统裁剪
      系统裁剪
      介绍
      减少系统尺寸的技术
      内核尺寸缩减
      配置选项
      Linux-tiny 补丁集
      “dietnet”
      减少内核尺寸相关的编译选项
      垃圾回收补丁集
      运行时内核大小
      内核栈大小
      自动裁剪
      PRINTK 消息压缩
      裁剪的一些想法和近期的工作
      文件系统压缩
      应用裁剪
      程序大小相关编译选项
      缩减你的程序
      手动优化程序大小
      库尺寸裁剪技术
      使用更小的 libc
      静态链接
      库裁剪
      延时加载库
      就地执行(XIP)
      内核 XIP
      应用 XIP
      原地数据读取 (DRIP)
      尺寸测量的技术和相关工具
      内核尺寸测量数据
      怎样计算内核镜像的大小
      怎样动态计算内存使用情况
      Linux 内核 从 2.4 到 2.6 的尺寸增加
      GCC 代码大小基准测试
      案例研究
      uClinux
      微型处理器上的 Linux (这里是在 M3 上)
      发行版本的尺寸缩减相关尝试
      杂项
      系统裁剪
      内核内存溢出检测
      系统的大小是怎样影响性能的
      缩减桌面发行版本的文件系统
      极小系统

      文件系统
      文件系统
      目录
      简介
      MTD
      UBI
      分区
      eMMC and UFS
      嵌入式文件系统
      AXFS
      Btrfs
      CramFS
      F2FS
      InitRAMFS
      JFFS2
      LogFS
      NFS
      PRAMFS
      Romfs
      SquashFS
      UBIFS
      YAFFS2
      挂载文件系统
      在 PC 上用 mtdram 挂载 JFFS2 镜像
      在 PC 上用 nandsim 挂载 UBI 镜像
      在嵌入式中使用通用文件系统的问题
      MMC/sdcard 卡特性
      专用文件系统
      ABISS
      分层的文件系统
      UnionFS
      aufs
      mini_fo
      性能和基准测试
      性能评测工具
      闪存文件系统比较
      Cogent Embedded 公司的测试 (2013)
      Free Electrons 公司的测试 (2011)
      其他项目
      多媒体文件系统
      文件系统
      维基百科文件系统
      维基文件系统

      电源管理
      目录
      简介
      电源管理技术与项目网页
      Linux 电源管理迷你峰会
      峰会记录
      CE Linux 论坛的需求标准
      资料文档
      开源项目/邮件列表

      内存管理
      目录
      感兴趣的领域
      内存检测和分析
      巨页/大页/超级页
      页缓存压缩
      启动时预留和访问高地址内存
      OOM 处理机制的优化/改进
      Cgroups (控制组)中的 OOM 通知
      mem_notify 补丁
      谷歌 cgroup (控制组) OOM 处理方法
      诺基亚对 OOM 的改进
      基于 LSM 的低内存通知
      基于类型的内存分配(老旧的方法)
      附加资源/邮件列表
      关于缓存的文章

      资源管理
      目录
      开源项目
      CKRM/RG
      UBC/Beancounters
      其他

      设备驱动
      使用手册
      样例驱动
      资源

      设备树
      目录
      前言
      扁平设备树是
      扁平设备树不是
      历史
      未来
      优势
      对于内核发行
      对于片上系统(SoC)供应商
      对于主板设计者
      对于嵌入式 Linux 生态系统
      对于固件或 bootloader 开发者
      其他的优势
      竞品的解决方案
      板子相关特性的数据结构
      ACPI(高级配置与电源接口)
      UEFI(统一的可扩展固件接口)
      Open FirmWare
      关于竞品的解决方案的一些注解
      资源
      Wiki 和内核中的参考资料
      FAQ,小贴士和最佳范例
      演示文稿,论文和文章
      各种子系统的设备树描述的笔记
      较老的材料
      工具
      调试
      设备树 irc (互联网中继聊天)
      设备树邮件列表

      玩转硬件
      目录
      工程设备
      官方支持的设备
      汽车
      工业
      迷你集群
      硬件工具和信息
      软件工具和信息

      开发平台
      目录
      最受欢迎的设备
      ARM
      AVR32
      Blackfin
      MIPS
      PowerPC
      SuperH
      i386 及其兼容平台
      未分类

      贡献内核补丁(Kernel Mainlining)
      目录
      通用资源
      相关演讲
      演讲列表
      训练,指导和挑战
      具体项目
      最佳行动说明
      来自 Andrew Morton
      来自 Deepak Saxena
      来自 Jonathan Corbet
      来自 Arnd Bergmann
      来自 David Arlie
      克服 Mainlining 遇到的障碍

      法律问题
      嵌入式中使用 Linux 的法律问题
      内核只被 GPL V2 许可
      署名行 (signed-off-by) 和原创开发者证书 (DCO)
      有关法律分析和合规的资源
      EXPORT_SYMBOL_GPL
      针对内核 USB API 的 EXPORT_SYMBOL_GPL
      二进制专有的内核模块
      在用户空间中使用内核头文件
      其它链接

      事件/会议
      目录
      即将举办会议
      2015 年
      2015 年 10 月
      已举办的事件
      2015 年
      2015 年 6 月
      2015 年 3 月
      2014 年
      2014 年 10 月
      2014 年 9 月
      2014 年 5 月
      2014 年 4 月
      2013 年
      2013 年 10 月
      2013年5月
      2013 年 2 月
      2012 年
      2012 年 11 月
      2012 年 9 月
      2012 年 8 月
      2012 年 7 月
      2012 年 6 月
      2012 年 4 月
      2012 年 2 月
      2011 年
      2010 年
      2009 年
      2008 年
      2007 年
      2006 年
      2005 年
      2004 年
      来自其他事件的论文集
      内核峰会上的演讲稿
      事件计划
      嵌入式 Linux 会议演讲稿

      术语表
      高频主题术语表
      A
      B
      C
      D
      E
      F
      G
      H
      I
      J
      K
      L
      M
      N
      O
      P
      Q
      R
      S
      T
      U
      V
      W
      X
      Y
      Z

      处理器
      Processors
      Contents
      ARC
      ARM
      MIPS
      SuperH
      Renesas SuperH Overview
      Devices
      PowerPC
      Processors
      Tools
      RT Patches
      Documents
      XScale
      x86
      AVR32
      Blackfin
      m68k
      Further reading

      社区
      Community
      Contents
      Netiquette
      Community sites
      General Portals
      Hardware-Specific Communities
      Software-Specific Communities
      Communities for beginners
      People
      Linux kernel
      Important kernel figures
      Kernel arch maintainers
      Feature developers/maintainers
      Other People
      Interview candidates
      Foundations and Forums
      Linux User Groups
      Development Model
      Reasons for contributing to open source
      Community-building ideas
      Quality Assurance
      Certificate of Origin

      发布在 Linux
      miumiu
      WOW
    • 修改WiFi/BT模组—R329智能语音开发板入门

      **转载自:**https://aijishu.com/a/1060000000191899

      本节以修改WiFi/BT模组为例,演示修改替换一个模块的方法。

      在部分版本的的R329 Tina中(如全志官方对外release的v0.5版本R329 Tina),EVB5方案配置的Realtek 8723D无线模组。如果我们要替换成全志的XR829无线模组要怎么做呢?大概需要如下几步:

      修改内核配置

      首先,我们先获取环境变量,选好方案:

      source build/envsetup.sh
      lunch
      然后make kernel_menuconfig配置内核:

      make kernel_menuconfig

      进行无线模组配置选项:

      Device Drivers > Network device support > Wireless LAN
      可以看到当前选择的模组是Realtek 8723D

      b711b669-95c8-481d-991f-1f2d3bf555e4-image.png

      表示编译成模块,可以在启动的时候实用启动脚本加载,<>表示编译到内核。

      我们将Realtek 8723D反选,并选上XR829:
      5bbd9a56-19ee-4d51-bd1c-8003daac1a8c-image.png

      修改Tina配置
      make menuconfig
      Firmware
      进入Firmware目录,反选r8723ds-firmware,并选上xr829-firmware和xr829 with 40M sdd。xr829 with 40M sdd意思是XR829采用40MHz的外挂晶振。

      <> xr829-firmware..................................... Xradio xr829 firmware
      [
      ] xr829 with 40M sdd

      6001a796-ff59-400f-a657-e1d1b00d916f-image.png

      Wireless Driver
      进入Kernel modules > Wireless Driver,反选kmod-net-rtl8723ds,并选上kmod-net-xr829和kmod-net-xrbtlpm,意思是启动的时候加载xr829模块。

      bb1e929a-fa2b-4869-89ad-6c3719f6ca3d-image.png

      重新编译打包烧写固件
      make -j32
      pack
      烧写固件后,使用wifi扫描demo测试,就可以扫描到附近的wifi信号:

      root@TinaLinux:/# wifi_scan_results_test


      Start scan!


      bssid / frequency / signal level / flags / ssid
      64:6e:97:5a:5a:e4 2462 -55 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      66:6e:97:1a:5a:e4 2462 -55 [WPA2-PSK-CCMP][ESS] AWTest
      7e:b5:9b:2d:e1:63 2437 -56 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] AW-IT-Test
      66:6e:97:1b:14:42 2462 -56 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] AWTest
      7c:b5:9b:fd:e1:bd 2437 -58 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      7c:b5:9b:fd:e1:63 2437 -58 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      7e:b5:9b:1d:e1:63 2437 -58 [WPA2-PSK-CCMP][ESS] AWTest
      7e:b5:9b:1d:e1:bd 2437 -61 [WPA2-PSK-CCMP][ESS] AWTest
      88:d7:f6:88:8b:c0 2412 -37 [WPA2-PSK-CCMP][WPS][ESS] AW-PDC-PD4-316Test
      90:67:1c:f8:11:ac 2437 -36 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS] AW-PDC-RTOS-MUSIC
      00:6b:8e:4e:c0:08 2412 -45 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] AW-PDC-PD4-315test
      c8:4c:75:40:86:ff 2452 -54 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP-preauth][ESS] Allwinner
      c4:f0:81:63:9d:31 2437 -59 [WPA2-PSK-CCMP][ESS] \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
      f0:c9:d1:b3:15:49 2412 -55 [WPA-PSK-TKIP][WPA2-PSK-CCMP][ESS] AP-XRADIO
      64:6e:97:5b:14:42 2462 -64 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      bc:46:99:d6:62:7c 2462 -60 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] SochipR3
      38:1c:1a:2e:b3:52 2437 -63 [WPA2-PSK-CCMP][ESS] AWTest
      ec:6c:9f:af:89:79 2447 -63 [WPA2-PSK-CCMP][ESS] AW-APD-GMSipv6
      74:a5:28:9a:fc:d4 2432 -65 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS] AW-PTD-HK
      04:d4:c4:b9:b9:f8 2437 -65 [WPA2-PSK-CCMP][WPS][ESS] ipv6
      ac:e3:42:9c:7f:79 2437 -68 [WPA2-PSK-CCMP][WPS][ESS]
      00:1c:a3:14:6a:de 2422 -73 [WPA2-PSK-CCMP][ESS] AW-PD4-R818
      8c:be:be:24:6f:ff 2422 -70 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS] AW-PTD-TEST
      7e:b5:9b:1d:e1:a3 2462 -75 [WPA2-PSK-CCMP][ESS] AWTest
      80:e8:6f:d9:fd:a1 2412 -73 [WPA-EAP-CCMP][WPA2-EAP-CCMP][ESS] AWOffice
      80:e8:6f:d9:fd:a2 2412 -73 [WPA2-PSK-CCMP][ESS] AWTest
      80:8f:1d:8a:36:76 2452 -60 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] AW-PDC-PD2-TEST
      38:1c:1a:2e:b3:51 2437 -63 [WPA-EAP-CCMP][WPA2-EAP-CCMP][ESS] AWOffice
      b8:55:10:94:90:b4 2427 -74 [WPA-PSK-CCMP][WPA2-PSK-CCMP][WPS][ESS] AW-ANC-TOTOLINK-N600RV2#34
      80:e8:6f:d9:5d:62 2412 -75 [WPA2-PSK-CCMP][ESS] AWTest
      80:e8:6f:d9:5d:61 2412 -76 [WPA-EAP-CCMP][WPA2-EAP-CCMP][ESS] AWOffice


      Wifi get_scan_results: Success!


      如果固件的模组不对应,使用wifi相关demo时会提示wifi打开失败:

      root@TinaLinux:/# wifi_scan_results_test
      connect wpa_supplicant failed,please check wifi driver!
      wifi on failed
      修改蓝牙配置
      以上修改只是完成了模组wifi部分,bt部分这时候测试是会打开失败的:

      root@TinaLinux:/# bt_test
      root@TinaLinux:/# 58279.055755: [bt_manager_init:212]: enable default profile from bt config.
      58279.055900: [bt_manager_enable:400]: bt manager version:Version:3.0.1.202012201630,builed time:Dec 29 2020-02:46:30
      58279.055915: [bt_test_sta[ 144.123489] sunxi-bt soc@03000000:bt: block state already is 1
      tus_cb:71]: bt is turnning on.
      [ 145.135907] sunxi-bt soc@03000000:bt: set block: 0
      58290.178476: [btmg_device_on:56]: detect hci0......
      58293.179028: [btmg_device_on:56]: detect hci0......
      58296.179372: [btmg_device_on:56]: detect hci0......
      ^C
      root@TinaLinux:/# 58299.179802: [btmg_device_on:56]: detect hci0......
      58302.180339: [btmg_device_on:56]: detect hci0......
      58305.180866: [btmg_device_on:56]: detect hci0......
      58308.181398: [btmg_device_on:61]: hci0 device available
      58308.181471: [bt_test_status_cb:59]: BT is off
      58308.181500: [bt_test_adapter_power_state_cb:43]: Failed to turn on bt
      58308.181530: [bt_manager_enable:436]: init HCI device failed!
      58308.181561: [bt_manager_gap_set_io_capability:1084]: Bt is off, This should not be called!

      (process:1559): GLib-GIO-CRITICAL **: g_dbus_connection_send_message_with_reply_sync: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

      (process:1559): GLib-GIO-CRITICAL **: g_dbus_connection_send_message_with_reply_sync: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

      bt部分还需要修改相关配置文件 target/allwinner/r329-evb5/base-files/etc/bluetooth/bt_init.sh

      !/bin/sh
      bt_hciattach="hciattach"

      start_hci_attach()
      {
      h=`ps | grep "$bt_hciattach" | grep -v grep`
      [ -n "$h" ] && {
      killall "$bt_hciattach"
      sleep 1
      }

      8723ds h5 init
      echo 0 > /sys/class/rfkill/rfkill0/state;
      sleep 1
      echo 1 > /sys/class/rfkill/rfkill0/state;
      sleep 1

      "$bt_hciattach" -n ttyS1 xradio >/dev/null 2>&1 &
      sleep 1

      wait_hci0_count=0
      while true
      do
      [ -d /sys/class/bluetooth/hci0 ] && break
      sleep 1
      let wait_hci0_count++
      [ $wait_hci0_count -eq 8 ] && {
      echo "bring up hci0 failed"
      exit 1
      }
      done
      }

      start() {

      hcidump_xr=$(ps | grep "hcidump_xr" | grep -v grep | awk '{print $1}')
      if [ -n "$hcidump_xr" ] ;then
      echo "hcidump_xr existed"
      else
      echo "hcidump_xr start"
      hcidump_xr &
      fi

      if [ -d "/sys/class/bluetooth/hci0" ];then
      echo "Bluetooth init has been completed!!"
      else
      start_hci_attach
      fi

      d=`ps | grep bluetoothd | grep -v grep`
      [ -z "$d" ] && {
      /etc/bluetooth/bluetoothd start
      sleep 1
      }
      }

      ble_start() {
      if [ -d "/sys/class/bluetooth/hci0" ];then
      echo "Bluetooth init has been completed!!"
      else
      start_hci_attach
      fi

      hci_is_up=`hciconfig hci0 | grep RUNNING`
      [ -z "$hci_is_up" ] && {
      hciconfig hci0 up
      }

      MAC_STR=`hciconfig | grep "BD Address" | awk '{print $3}'`
      LE_MAC=${MAC_STR/2/C}
      OLD_LE_MAC_T=`cat /sys/kernel/debug/bluetooth/hci0/random_address`
      OLD_LE_MAC=$(echo $OLD_LE_MAC_T | tr [a-z] [A-Z])
      if [ -n "$LE_MAC" ];then
      if [ "$LE_MAC" != "$OLD_LE_MAC" ];then
      hciconfig hci0 lerandaddr $LE_MAC
      else
      echo "the ble random_address has been set."
      fi
      fi
      }

      stop() {
      echo "nothing to do."
      }

      case "$1" in
      start|"")
      start
      ;;
      stop)
      stop
      ;;
      ble_start)
      ble_start
      ;;
      *)
      echo "Usage: $0 {start|stop}"
      exit 1
      esac

      R329 EVB5 XR829 bt_init.sh文件下载连接:bt_init.sh

      make kernel_menuconfig内核配置选上:

      Networking support > Bluetooth subsystem support > Bluetooth device drivers
      <> Xradio Bluetooth sleep driver support
      <
      > Xradio Bluetooth farmware debug interface support
      [*] Xradio Bluetooth sleep driver support for bluedriod

      865c40d0-3629-46e4-97b9-5cae6d5704f0-image.png

      重新编译打包烧录固件,用BT demo,成功打开蓝牙会有如下打印:

      root@TinaLinux:/# bt_test
      root@TinaLinux:/# 3407.938316: [bt_manager_init:212]: enable default profile from bt config.
      3407.938454: [bt_manager_enable:400]: bt manager version:Version:3.0.1.202012201630,builed time:Dec 29 2020-02:46:30
      3407.938468: [bt_test_status_cb:71]: bt is turnning on.
      hcidump_xr start
      Bluetooth init has been completed!!
      /etc/bluetooth/bt_init.sh: line 99: hcidump_xr: not found
      3408.306362: [bt_profile_global_init:356]: start bluealsa :1 times
      3408.845050: [bt_test_adapter_power_state_cb:41]: Turn on bt successfully
      3409.308667: [bt_test_status_cb:61]: BT is ON
      [ 66.468094] [BH_WRN] miss interrupt!
      以上,一个无线模组就修改好了。

      *rtl8723ds和XR829模组是pin to pin的,所以无需修改引脚配置。

      **温馨tips:**如想了解更多R329相关开发信息,点击查看
      全志科技R329智能语音开发板详细资料https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • 录音和播放—R329智能语音开发板入门

      转发自:https://aijishu.com/a/1060000000191888

      R329 EVB5开发板背面贴了3颗麦克风,可组成麦克风阵列,
      配合降噪算法调试语音识别类产品。

      496f13ca-d17e-45e2-af65-b5d68a499ec4-image.png

      同时接出了SPK L/R,可以接喇叭进行音频相关的调试。
      c1f851e9-784a-491b-b3ae-609979cb2b4b-image.png

      *另需注意图中所示的跳线帽需要接上,否则喇叭播放会不出声音

      录音
      Tina Linux中的音频子系统采用ALSA架构实现。ALSA全称 Advanced Linux Sound Architecture,是目前主流的Linux音频体系结构。

      ALSA在内核设备驱动层提供了驱动框架alsa-driver,同时在应用层提供了音频接口库alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。

      内置的固件中,已经封装好了音频相关模块,可以直接使用demo录音和播放。

      root@TinaLinux:/# arecord test.wav
      [ 53.158988] sunxi-codec-machine sndcodec: sunxi_hifi_sndcodec_startup
      [ 53.166483] sunxi-codec-machine sndcodec: sunxi_hifi_sndcodec_hw_params
      [ 53.173967] sunxi-internal-cpudai cpudai: ======== hw_params ========
      [ 53.181212] sunxi-internal-cpudai cpudai: pcm_params->format:2
      [ 53.187771] sunxi-internal-cpudai cpudai: pcm_params->channels:5
      [ 53.194529] sunxi-internal-cpudai cpudai: pcm_params->rate:16000
      [ 53.201281] sunxi-internal-cpudai cpudai: pcm_params->period_size:1024
      [ 53.208622] sunxi-internal-cpudai cpudai: pcm_params->periods:4
      [ 53.215276] sunxi-internal-cpudai cpudai: pcm_params->pcm_frames:1024
      [ 53.222513] sunxi-internal-cpudai cpudai: pcm_params->buffer_size:4096
      [ 53.229849] sunxi-internal-cpudai cpudai: ===========================
      [ 53.253756] sunxi-internal-cpudai cpudai: sunxi_hifi_pcm_hw_params
      Recording WAVE 'test.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
      ^CAborted by signal Interrupt...
      [ 64.045853] sunxi-internal-cpudai cpudai: sunxi_hifi_pcm_hw_free
      arecord: pcm_read:2072: read error: Interrupted system call
      [ 64.090576] sunxi-codec-machine sndcodec: sunxi_hifi_sndcodec_shutdown
      root@TinaLinux:/# ls
      44100-mono-s16_le-10s.wav rdinit
      base rom
      bin root
      dev sbin
      etc sys
      lib test.wav
      lib64 tmp
      mnt usr
      overlay var
      proc www

      19289140-12a0-4f31-a78a-b7503b34532c-image.png

      播放
      使用命令aplay +音频文件即可播放该文件,如:

      root@TinaLinux:/# aplay test.wav
      [ 125.270510] sunxi-codec-machine sndcodec: sunxi_hifi_sndcodec_startup
      [ 125.278025] sunxi-codec-machine sndcodec: sunxi_hifi_sndcodec_hw_params
      [ 125.285477] sunxi-internal-cpudai cpudai: ======== hw_params ========
      [ 125.292722] sunxi-internal-cpudai cpudai: pcm_params->format:2
      [ 125.299283] sunxi-internal-cpudai cpudai: pcm_params->channels:2
      [ 125.306043] sunxi-internal-cpudai cpudai: pcm_params->rate:48000
      [ 125.312797] sunxi-internal-cpudai cpudai: pcm_params->period_size:1024
      [ 125.320138] sunxi-internal-cpudai cpudai: pcm_params->periods:4
      [ 125.326795] sunxi-internal-cpudai cpudai: pcm_params->pcm_frames:1024
      [ 125.334034] sunxi-internal-cpudai cpudai: pcm_params->buffer_size:4096
      [ 125.341369] sunxi-internal-cpudai cpudai: ===========================
      [ 125.490383] sunxi-internal-cpudai cpudai: sunxi_hifi_pcm_hw_params
      Playing WAVE 'test.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
      [ 136.190698] sunxi-internal-cpudai cpudai: sunxi_hifi_pcm_hw_free
      [ 136.370445] sunxi-codec-machine sndcodec: sunxi_hifi_sndcodec_shutdown

      6d19d303-8611-458b-9881-5a0284507dfe-image.png

      查看音频文件
      把文件拉到电脑上
      我们可以通过adb将音频文件拉到电脑上查看。

      adb pull test.wav
      51964461-ae17-4451-8212-039766580f91-image.png

      Audacity
      查看音频文件可以使用音频处理软件,如Audacity。

      这是一个常用的音频处理软件,免费,开源,遵循GNU协议,可以到网上搜索下载。Windows和Ubuntu版本均有。

      3946401c-4d8d-47b5-a091-2a8b4fae2385-image.png

      上图就是我们用Audacity打开刚刚录下的音频文件的样子。图中只有一个声道,如果是用三麦克风的阵列录得声音,我们可以看到有三个音轨。如果还有一路或者两路回路(AEC),我们一根可以看到四个或者五个音轨。

      录三个声道
      录三个声道可以使用命令:
      ”-D:”代表设备,“-f”代表格式(采样深度和大小端),“-c”代表声道数。这里我们录了3个声道,如果3个声道的麦克风都是好的,拉到电脑用Audacity上查看可以看到如图所示的三个音轨:

      fc7bb804-e375-4932-b6ec-a005762e7301-image.png

      温馨tips:如想了解更多R329相关开发信息,点击查看 全志科技R329智能语音开发板详细资料
      https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • WiFi连网—R329智能语音开发板入门

      转载自:https://aijishu.com/a/1060000000191884

      R329 EVB5开发板上集成了全志自研的XR829无线芯片,支持2.4G wifi 和BT功能。
      Tina Linux系统对无线功能进行集成,可以直接使用内置DEMO连接wiff、BT。
      这里主要演示wifi demo 。

      首先需要确保开发板上贴上了天线,否则会因为信号强度过弱连接失败。
      R329 EVB5开发板标准装中随盒附赠了一根天线。

      86a3b288-b9c5-4182-8bd2-23e8faf72cd3-image.png

      WiFi 命令
      在终端输入命令行 wifi 然后按 TAB键 补全,会看到系统下内置了大量wifi相关的命令,包括打开、关闭、扫描、连接、中文连接、移除等。

      root@TinaLinux:/# wifi_
      wifi_connect_ap_test wifi_off_test
      wifi_connect_ap_with_netid_test wifi_on_off_test
      wifi_connect_chinese_ap_test wifi_on_test
      wifi_disconnect_ap_test wifi_reconnect_ap_test
      wifi_get_connection_info_test wifi_remove_all_networks_test
      wifi_get_netid_test wifi_remove_network_test
      wifi_list_networks_test wifi_scan.sh
      wifi_longtime_scan_test wifi_scan_results_test
      wifi_longtime_test wifi_wps_pbc_test

      246ad28c-ba18-4e31-ad8b-141f85e6cda6-image.png

      搜索附近WiFi
      输入 wifi_scan_results_test ,即可搜索到附近的wifi信号,会显示bssid、频率、信号强度、加密方式和SSID等信息:

      root@TinaLinux:/# wifi_scan_results_test


      Start scan!


      bssid / frequency / signal level / flags / ssid
      7e:b5:9b:1d:e1:bd 2437 -52 [WPA2-PSK-CCMP][ESS] AWTest
      7c:b5:9b:fd:e1:bd 2437 -54 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      88:d7:f6:88:8b:c0 2412 -40 [WPA2-PSK-CCMP][WPS][ESS] AW-PDC-PD4-316Test
      90:67:1c:f8:11:ac 2437 -44 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS] AW-PDC-RTOS-MUSIC
      36:a1:d4💿10:72 2417 -53 [WPA2-PSK-CCMP][ESS] Mi 10 Pro_zxnn\xe2\x80\x8b
      c4:f0:81:63:9d:30 2462 -57 [WPA2-PSK-CCMP][WPS][ESS] AW-PTD-H-test
      00:6b:8e:4e:c0:08 2462 -58 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] AW-PDC-PD4-315test
      c4:f0:81:63:9d:31 2462 -58 [WPA2-PSK-CCMP][ESS] \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
      ec:6c:9f:af:89:79 2447 -61 [WPA2-PSK-CCMP][ESS] AW-APD-GMSipv6
      c8:4c:75:40:86:ff 2452 -62 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP-preauth][ESS] Allwinner
      08:10:79:a4:78:84 2417 -67 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] AW-PD4-NETTEST
      64:6e:97:5b:14:42 2462 -67 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      7c:b5:9b:fd:e1:63 2412 -68 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      7e:b5:9b:1d:e1:63 2412 -68 [WPA2-PSK-CCMP][ESS] AWTest
      7e:b5:9b:2d:e1:63 2412 -68 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] AW-IT-Test
      66:6e:97:1b:14:42 2462 -69 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] AWTest
      64:6e:97:5a:5a:e4 2462 -70 [WPA-EAP-CCMP+TKIP][WPA2-EAP-CCMP+TKIP][ESS] AWOffice
      38:1c:1a:2e:b3:51 2437 -66 [WPA-EAP-CCMP][WPA2-EAP-CCMP][ESS] AWOffice
      66:6e:97:1a:5a:e4 2462 -71 [WPA2-PSK-CCMP][ESS] AWTest
      ba:8c:21:2e:d1:6c 2412 -73 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] AW-ANC-TPLINK_D16B#170
      74:a5:28:9a:fc:d4 2452 -69 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS] AW-PTD-HK
      80:e8:6f:d9:5d:61 2412 -76 [WPA-EAP-CCMP][WPA2-EAP-CCMP][ESS] AWOffice
      80:e8:6f:d9:5d:62 2412 -76 [WPA2-PSK-CCMP][ESS] AWTest
      ac:07:5f:7d:c3:b9 2412 -79 [WPA2-PSK-CCMP][ESS] \x00\x00\x00\x00\x00\x00\x00\x00


      Wifi get_scan_results: Success!


      7515b06a-e2dc-48c2-9fa6-ef6d6a0c188c-image.png

      连接一个WiFi
      输入wifi_connect_ap_test +wifi ssid(wifi名)+密码,即可连接该wifi ,如连接ssid为AWTest 、密码为 12345678 的wifi:

      root@TinaLinux:/# wifi_connect_ap_test AWTest 12345678
      Connecting to the network(AWTest)......
      [ 196.862383] [STA_WRN] Freq 2437 (wsm ch: 6) prev: 3.
      [ 196.867990] wlan0: authenticate with 7e:b5:9b:1d:e1:bd (try 1)
      [ 196.875266] [STA_WRN] [HT40][xradio_join_work][bss_ht_info]:
      [ 196.875266] [primary_chan :0x00000006]
      [ 196.875266] [ht_param :0x00000007]
      [ 196.875266] [operation_mode:0x00000000]
      [ 196.875266] [stbc_param :0x00000000]
      [ 196.875266] [basic_set[0] :0x00000000]
      [ 196.903079] [STA_WRN] [HT40][xradio_join_work][PhyModeCfg:0x0027]
      [ 196.903079] [ModemFlags :0x00000007]
      [ 196.903079] [ChWidthCfg :0x00000002]
      [ 196.903079] [PriChCfg :0x00000000]
      [ 196.903079] [BandCfg :0x00000000]
      [ 196.903079] [STBC_Enable :0x00000000]
      [ 196.903079] [PreambleCfg :0x00000000]
      [ 196.903079] [SGI_Enable :0x00000000]
      [ 196.903079] GF_Enable :0x00000000]
      [ 196.984781] wlan0: authenticated
      [ 196.988606] [STA_WRN] Freq 2422 (wsm ch: 3) prev: 6.
      [ 196.994393] [STA_WRN] Freq 2437 (wsm ch: 6) prev: 3.
      [ 196.999993] wlan0: associate with 7e:b5:9b:1d:e1:bd (try 1)
      [ 197.021251] wlan0: RX AssocResp from 7e:b5:9b:1d:e1:bd (capab=0x1411 status=0 aid=2)
      [ 197.029988] wlan0: associated
      [ 197.038283] [AP_WRN] [STA] ASSOC HTCAP 11N 58
      [ 197.043207] [AP_WRN] [HT40][xradio_bss_info_changed][ht_prot:0x00000002][HtProtMode:0x0000][Green:0x0004]
      [ 197.053998] [AP_WRN] [HT40][xradio_bss_info_changed][PhyModeCfg:0x4027]
      [ 197.053998] [ModemFlags :0x00000007]
      [ 197.053998] [ChWidthCfg :0x00000002]
      [ 197.053998] [PriChCfg :0x00000000]
      [ 197.053998] [BandCfg :0x00000000]
      [ 197.053998] [STBC_Enable :0x00000000]
      [ 197.053998] [PreambleCfg :0x00000000]
      [ 197.053998] [SGI_Enable :0x00000001]
      [ 197.053998] [GF_Enable :0x00000000]
      [ 197.143876] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
      Connected to the AP(AWTest)
      Getting ip address(AWTest)......
      [ 199.128130] [TXRX_WRN] drop=1759, fctl=0x00d0.
      Wifi connect ap : Success!

      root@TinaLinux:/# [ 199.845392] [TXRX_WRN] drop=1759, fctl=0x00d0.

      如果显示 Wifi connect ap : Success! 即为连接成功了。

      32558d81-9f23-4909-89e9-9532bdccc677-image.png

      Ping通一个网站
      Tina系统已经将协议层等相关配置都配置好,可以直接ping通互联网上的网址,如ping百度:

      root@TinaLinux:/# ping baidu.com
      PING baidu.com (220.181.38.148): 56 data bytes
      64 bytes from 220.181.38.148: seq=0 ttl=52 time=50.064 ms
      64 bytes from 220.181.38.148: seq=1 ttl=52 time=45.933 ms
      64 bytes from 220.181.38.148: seq=2 ttl=52 time=50.558 ms
      64 bytes from 220.181.38.148: seq=3 ttl=52 time=61.543 ms
      64 bytes from 220.181.38.148: seq=4 ttl=52 time=65.560 ms
      64 bytes from 220.181.38.148: seq=6 ttl=52 time=167.182 ms
      64 bytes from 220.181.38.148: seq=7 ttl=52 time=59.301 ms
      64 bytes from 220.181.38.148: seq=8 ttl=52 time=54.295 ms
      ^C
      --- baidu.com ping statistics ---
      10 packets transmitted, 8 packets received, 20% packet loss
      round-trip min/avg/max = 45.933/69.304/167.182 ms
      如果看到这些打印,那么恭喜你,你拥有了使用开发板和世界握手的能力!
      Across the Great Wall we can reach every corner in the world!

      温馨tips:如想了解更多R329相关开发信息,点击查看 全志科技R329智能语音开发板详细资料
      https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • 点灯—R329智能语音开发板入门

      转载自:https://aijishu.com/a/1060000000191874
      等成功用串口或者ADB连接开发板之后,就可以通过终端命令对开发板进行控制了。

      接下来会介绍Tina Linux系统封装几个模块,您可以通过命令启动这几个模块的demo,操控终端几个模块的软硬件。首先是我们大学单片机课程中的必修课:点灯

      R329支持LEDC,LEDC全称 “Light Emitting Diode Controller”,是借助Linux LED标准子系统实现的LED控制模块,可以对LED灯进行点亮、亮度调节、闪烁、阵列控制等操作。LEDC模块在无屏幕智能音箱上用得很多,比如在等待配对、唤醒、音乐播放等场景,LED灯会以不同的效果表示当前状态。

      内置固件已经编译好了LEDC模块,可以直接对LED节点进行控制从而点亮LED灯。

      进入LED灯路径
      首先,我们可以进入LED节点的位置查看一个LED灯三个颜色的节点(R G B):

      root@TinaLinux:/# cd /sys/class/leds/
      root@TinaLinux:/sys/class/leds# ls
      sunxi_led0b sunxi_led0g sunxi_led0r

      24e3d48d-c0fb-4698-bbad-6de58979f78a-image.png

      查看LED灯的配置
      三个节点分别代三个颜色,我们可以进入一个颜色节点,比如红色(R):

      root@TinaLinux:/sys/class/leds# cd sunxi_led0r/
      root@TinaLinux:/sys/devices/platform/soc/ledc/leds/sunxi_led0r# ls
      brightness device subsystem
      delay_off max_brightness trigger
      delay_on power uevent

      6503f945-c86c-41d1-a239-3abe05d7f770-image.png

      可以看到LEDC已经做好了很多LEDC的基本操作,包括亮度调节、闪烁、延时等。

      点亮一个灯
      如果我们要点亮其中一个颜色,可以把亮度值写到 brightness 里,亮度值最高为255:

      root@TinaLinux:/sys/devices/platform/soc/ledc/leds/sunxi_led0r# echo 255 > brightness
      此时LED灯会被点亮

      54b88b6b-a8dd-425c-9b14-ab7e295fcae2-image.png

      调节亮度
      如果要调节亮度值的话,只需调节写到 brightness 的值即可,亮度值范围为0~255,0代表熄灭,255代表最亮:

      root@TinaLinux:/sys/devices/platform/soc/ledc/leds/sunxi_led0r# echo 255 > brightness
      root@TinaLinux:/sys/devices/platform/soc/ledc/leds/sunxi_led0r# echo 100 > brightness
      root@TinaLinux:/sys/devices/platform/soc/ledc/leds/sunxi_led0r# echo 10 > brightness
      root@TinaLinux:/sys/devices/platform/soc/ledc/leds/sunxi_led0r# echo 0 > brightness

      af72cbe4-c1be-480d-aa2e-7443c4fb2ba8-image.png

      4bbdf1d8-2b50-4fb7-944e-9d697006c6f5-image.png

      点亮其它颜色的灯
      如果要点亮其它颜色的灯 ,只需要参照红灯,将亮度值写到绿灯和蓝灯的 brightness 里即可:

      root@TinaLinux:/sys/class/leds# echo 255 > sunxi_led0g/brightness
      root@TinaLinux:/sys/class/leds# echo 0 > sunxi_led0g/brightness
      root@TinaLinux:/sys/class/leds# echo 255 > sunxi_led0b/brightness
      root@TinaLinux:/sys/class/leds# echo 0 > sunxi_led0b/brightness

      6c9ef336-6d3f-46d3-ade6-14cfe8e8f733-image.png

      bdc23a46-5c7e-442b-940f-26d383a569e5-image.png

      闪烁
      如果要实现LED灯闪烁的效果,把 timer 写到 trigger 即可:

      root@TinaLinux:/sys/class/leds# echo timer > sunxi_led0r/trigger
      如果你看到灯亮了,那么恭喜你,它将照亮你嵌入式开发学习的路。

      LED灯阵列操作、模块配置、源码结构、内外部接口等进阶操作请见开发文档《Tina Linux LED开发指南》:《Tina Linux LED开发指南》下载

      同时,还可以使用三个PWM接口对LED的三色灯进行控制,但需要占用较多的引脚和资源。

      温馨tips:如想了解更多R329相关开发信息
      点击查看 全志科技R329智能语音开发板详细资料
      https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • 编译和烧写—R329智能语音开发板入门

      转载自:https://aijishu.com/a/1060000000191869
      完整下载到源码之后,即可对源码进行编译。

      *源码下载方式见:SDK源码获取

      编译打包
      编译打包命令如下:

      source build/envsetup.sh
      lunch r329_evb5-tina
      make -j32
      pack

      其中:
      source build/envsetup.sh :获取环境变量
      lunch r329_evb5-tina 选择 lunch r329_evb5-tina 方案,也可以不加参数直接lunch,这样会有选项可以选择,其中 lunch r329_evb5-tina 是 r329_evb5-tina的标准方案,lunch r329_evb5_min-tina 是只能让系统跑起来的最小系统方案。
      make -j32 :编译,其中-j后面的数字参数为编译用的线程数,可根据开发者编译用的PC实际情况选择。
      pack : 打包,将编译好的固件打包成一个.img格式的固件,固件路径 /out/r329-ev5/tina_r329-evb5_uart0.img

      6afb4c37-09bd-46a4-9c43-d0ce0badcdb8-image.png

      每次打开一个ubuntu终端只需要做一次获取环境变量和选择方案的操作,在这个终端多次编译的时候不需要再做前两步操作,直接 make -j 即可。

      烧写
      烧写,即将编译打包好的固件下载到设备

      烧写方式简介
      全志平台为开发者提供了多种多样的烧写方式和烧写工具:

      (1) PhoenixSuit:基于Windows的系统的烧写工具,是最常用的烧写工具,通过数据线将PC和开发板连接,把固件烧到开发板上,支持分区烧写,适用于开发和小规模生产使用。建议开发者开发时使用该工具进行固件升级。

      (2)LiveSuit:基于Ubuntu的系统的烧写工具,通过数据线将PC和开发板连接,把固件烧到开发板上,即Ubuntu版的PhoenixSuit,适用于Ubuntu系统开发者进行开发烧写。

      (3)PhoenixUSBpro:基于Windows的系统的烧写工具,通过数据线将PC和开发板连接,把固件烧到开发板上,一台PC可同时连接8台设备,分别控制其进行烧写,适用于产线批量生产。(如下图)

      (4)PhoenixCard:基于Windows的系统的量产SD卡制作工具,可以将普通的.img固件制作成SD卡量产固件,生产时在设备端插入量产SD卡即会自动烧写固件,适用于带SD卡卡槽的设备大规模量产。

      (5)存储期间批量烧写生产:用专有设备将提前将固件烧写到未贴片的存储器件(如emmc、nand、nor等)上,再上机贴片,可提高设备生产效率,需要拉通存储器件前才原厂和全志原厂定制设备联调,适用于超大规模产品的量产。

      7f3f9d0e-6cb7-45e9-952b-d729f424ef9e-image.png

      PhoenixSuit使用简介
      下面主要介绍用PhoenixSuit烧写的方法,LiveSuit和PhoenixUSBpro烧写的方法类似。

      PhoenixSuit下载地址:固件烧写工具PhoenixSuit

      同时需安装全志USB驱动,下载链接:全志USB驱动

      *企业开发者在安装APST的同时也会安装全志USB驱动,无需单独再安装

      具体步骤如下:

      (1)打开PhoenixSuit,当设备上电启动并插入USB与PC相连的时,PhoenixSuit会提示识别到设备;
      (2)点击 一键刷机-浏览选择要烧写的固件;
      (3)点击 立即升级,此时会通过USB给设备发送重启命令,设备会带着烧写标识重启,并在重启阶段进入烧写模式;
      (4)设备重新到boot的时候会自动进行烧写,可以看到PhoenixSuit的进度条在动;
      (5)烧写成功,设备重启。

      02feaf30-8319-4ca2-a168-8178233078d6-image.png

      空设备烧写
      当设备第一次烧写时(即设备内没有系统),PC打开烧写工具,设备插入USB,烧写工具工具会自动弹出烧写提示,此时按YES按钮即可进行烧写(需提前在固件处选好要烧写的固件)。

      已有设备固件烧写
      对于已经烧过固件的设备,在开发过程中,可以在串口或ADB终端输入烧写重启命令 reboot efex重启设备,此时设备会重启并在启动过程中自动进入烧写模式,后续烧写过程同上 PhoenixSuit使用简介 .

      *串口及ADB调试方法见: 连接开发板

      异常设备的烧写
      在开发过程中,可能会出现设备烧写了配置错误的固件导致设备启动异常的情况,这个时候无法按照正常启动设备,也就无法正常控制设备烧写,这就需要强制让设备进入烧写模式。常用的方法有两种:

      按住PC键盘的“2”键
      设备上电过程中,在串口终端按住PC键盘的“2”不停地输入“2”,设备启动的时候如果检查到“2”的输入,则会自动跳到烧写模式。如图(是真的按住键盘的“2”,很多新开发者不理解这个隐藏操作):

      6e443687-96db-48c7-9853-b066850f300e-image.png
      短接Nand
      设备上电过程中,用镊子或者杜邦线短接Nand的供电脚,这样设备在启动过程中,就会检查不到Nand的存在,误以为这是一片空片,这样设备就会按照空片启动的流程,自动进入烧写模式。如图:
      77af0c9e-0631-4414-bbb6-85d631812548-image.png
      进阶编译操作
      如果不需要完整编译整个系统,也可以对部分模块进行编译,如单独编译boot0、单独编译uboot、单独编译内核和单独编译某个包等,Tina环境都提供了相应的快捷命令

      单独编译boot0和uboot:mboot,可在Tina任意目录下使用
      单独编译boot0:mboot0,可在Tina任意目录下使用
      单独编译uboot:muboot,可在Tina任意目录下使用
      单独编译内核:mkernel,可在Tina任意目录下使用
      单独编译某个包:mm,只能在编译的包路径下操作,如包路径为 tina/package/utils/rwcheck,则需要进入到 tina/package/utils/rwcheck路径下再输入 mm 命令,编译出来对应的安装包的路径在 tina/out/r329-evb5/packages/base下
      在根目录下编译某个软件包:make <应用包的路径>/install,需要在根目录下操作,如 make package/utils/rwcheck/install
      在根目录下清空应用包临时文件:make <应用包的路径>/clean,需要在根目录下操作,如 make package/utils/rwcheck/clean

      温馨tips:如想了解更多R329相关开发信息,点击查看 全志科技R329智能语音开发板详细资料https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • 连接开发板—R329智能语音开发板入门

      R329 EVB5开发板在出厂时已经烧写了系统固件,支持Linux4.9内核的Tina Linux系统,您可以直接用于调试。

      R329 EVB5提供了两种设备调试的方法,分别是串口和ADB。

      首先,您需要配置电脑端的调试工具,串口及ADB的电脑配置方法见:开发工具

      串口连接:设备上电并连接电脑
      插上电源,串口线连接开发板和电脑USB,如图:
      07fedb84-8565-4998-b8e0-3b8bf8195d95-image.png

      *图中右上角的屏幕为左下角笔记本的HDMI拓展

      串口线线序如图:

      692e4dc0-c9bd-481a-a3f5-a379e0b37230-image.png

      线序:黑-GND,红-3.5V,绿-RX,白-TX

      *TX-发送(Transport),即开发板往电脑发数据的线,发出的打印会显示到串口终端上;RX-接收(Receive),即开发板接收电脑发过来数据的线,开发板会接收这个命令并执行

      安装串口驱动
      插入USB串口线后Windos系统会提示安装驱动,部分型号的串口线会自动搜索驱动安装,但有些型号的串口线驱动会搜索不到安装失败,随盒提供的串口线为CH341SER,驱动下载:CH341SER串口线驱动

      打开串口软件
      打开串口软件MobaXterm,点击左上角的Session-Serial,如果此时串口USB线已经插入,会在Serial port里显示识别到的串口CMO5 (USB-SERIAL CH340(COM5),选择该串口并将波特率设置为115200,点击确定,即会打开一个串口终端。

      bd78d7ad-eecd-4791-83c5-a1cc90e7a5ab-image.png

      您也可以根据自己的喜好选择喜欢串口软件,如Putty、Ubuntu的Minicom等

      输入第一条命令
      在终端输入第一条命令

      ls
      此时可以看到根目录下的路径及文件:

      root@TinaLinux:/# ls
      44100-mono-s16_le-10s.wav rdinit
      base rom
      bin root
      dev sbin
      etc sys
      lib test.wav
      lib64 tmp
      mnt usr
      overlay var
      proc www

      097c9f28-8005-48c5-81d1-9c6c41ced5f5-image.png

      如果看到这些,那么恭喜你,你已经拥有了操控了这个开发板的能力,现在,开始驾驭它在嵌入式的世界里遨游吧!
      ADB连接
      ADB全称Android debug bridge,顾名思义,即连接安卓的桥梁,原来是通过USB连接PC和Android设备的调试工具,现也被移植到全志Tina Linux系统上,会在系统启动时自动在后台运行,当电脑连接开发板时,即可和开发板进行通信。

      相比串口,ADB有更高的传输速率,除了终端命令控制,还可以通过ADB往开发板里推拉文件。同时,全志提供的一些生产测试工具,如DragonMAT等,也是通过ADB和开发板进行通信的。

      b76c63ad-6e01-40d8-9640-047177fb06ec-image.png

      安装和使用方法
      将adb.exe文件放到任意目录下,建议是比较浅的路径,如D:\adb.exe,然后将该路径添加到系统环境变量中,即可在cmd下直接进行adb操作。详细方法和高阶操作在互联上有大量介绍,可自行搜索学习。

      启动路径:Windows系统开始-cmd-命令行终端-ADB
      15acaae1-b462-4300-ab02-34cf44ed810a-image.png

      示例
      把test.wav文件电脑推到开发板的根目录下:

      C:\Users\kunyao>adb push test.wav ./.
      test.wav: 1 file pushed. 1.6 MB/s (35884 bytes in 0.022s)
      再把开发板里的test.wav文件拉回来:

      C:\Users\kunyao>adb pull ./test.wav ./.
      ./test.wav: 1 file pulled. 1.4 MB/s (35884 bytes in 0.024s)

      aad26730-b676-435b-8a73-b0f5c297222d-image.png

      温馨tips:如想了解更多R329相关开发信息,点击查看 全志科技R329智能语音开发板详细资料
      https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • Tina Linux 系统介绍—R329智能语音开发板入门

      转载自:https://aijishu.com/a/1060000000191853

      R329 evb5开发板默认自带Tina Linux系统

      26f04f58-81ba-4944-a4f2-4f090ddd3966-image.png

      Tina Linux是全志科技基于Linux内核开发的针对智能硬件类产品的嵌入式软件系统。Tina Linux基于openwrt-14.07 版本的软件开发包,包含了 Linux 系统开发用到的内核源码、驱动、工具、系统中间件与应用程序包。

      *openwrt 是知名的开源嵌入式 Linux 系统自动构建框架,是由 Makefile 脚本和 Kconfig 配置文件构成的。使得用户可以通过 menuconfig配置,编译出一个完整的可以直接烧写到机器上运行的 Linux 系统软件。

      系统框图

      1050500e-007f-44bc-bf1e-580ba2b38cc1-image.png

      Tina系统软件架构如图所示。从下至上分别为Kernel && Driver、Libraries、System Services、Applications 四层。

      Kernel && Driver
      Kernel&&Driver 层主要提供 Linux Kernel 的标准实现。Tina 平台的 Linux Kernel 采用 Linux3.4、Linux3.10、Linux4.4、Linux4.9、Linux5.4 等内核,不同硬件平台使用不同内核版本,提供安全性、内存管理、进程管理、网络协议栈等基础支持,并通过 Linux 内核管理设备硬件资源,如 CPU 调度、缓存、内存、I/O 等。 其中R329主要使用Linux 4.9。

      Libraries
      Libraries 层对应一般嵌入式系统,相当于中间件层次。其包含了各种系统基础库、第三方开源程序库支持,为应用层提供 API 接口,系统定制者和应用开发者可以基于 Libraries 层的API 开发新的系统服务和应用程序。

      System Services
      System Services 层对应系统服务层,包含系统启动管理、配置管理、热插拔管理、存储管理、多媒体中间件等。

      Applications
      Applications 层主要是实现具体的产品功能及交互逻辑,开发者可以开发实现自己的应用程序,提供系统各种能力给到终端用户。

      开发环境
      目前Tina Linux SDK基于Ubuntu14.04系统进行开发和调试,因此我们推荐使用该版本系统进行开发,其它版本系统可能存在兼容问题,需开发者自己针对系统进行适配。

      编译环境需要的工具
      编译环境需要依赖的工具有:

      gcc,binutils,bzip2,flex,python,perl,make,ia32-libs,find,grep,diff,unzip,gawk,getopt,subversion,libz-dev,libc headers
      Ubuntu环境下可直接执行如下命令安装这些工具:

      sudo apt-get install build-essential subversion git-core libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip ia32-libs lib32z1 lib32z1-dev lib32stdc++6 libstdc++6 -y
      对于 Ubuntu 16.04 以上版本,部分软件包已不再提供或者采用了其他的包,执行上述命令时, 安装失败的包可先忽略,进一步执行以下命令:

      sudo apt-get install libc6:i386 libstdc++6:i386 lib32ncurses5 lib32z1
      Tina SDK获取:详见SDK源码获取 https://aijishu.com/a/1060000000191843

      SDK结构
      Tina Linux SDK 主要由构建系统、配置工具、工具链、host 工具包、目标设备应用程序、文档、脚本、linux 内核、bootloader 部分组成,下面是Tina主目录包含的文件和目录。

      Tina-SDK/
      ├── build
      ├── config
      ├── Config.in
      ├── device
      ├── dl
      ├── lichee
      ├── Makefile
      ├── out
      ├── package
      ├── prebuilt
      ├── rules.mk
      ├── scripts
      ├── target
      ├── tmp
      ├── toolchain
      └── tools
      以下将对主要目录中包含的内容进行简单介绍。

      build 目录
      build 目录存放 Tina Linux 的构建系统文件,此目录结构下主要是一系列基于 Makefile 规格编写的 .mk 文件,主要的功能有:

      (1)检测当前的编译环境是否满足 Tina Linux 的构建需求;
      (2)生成 host 包编译规则;
      (3)生成工具链的编译规则;
      (4)生成 target 包的编译规则;
      (5)生成 linux kernel 的编译规则;
      (6)生成系统固件的生成规则。

      config 目录
      config 目录主要存放 Tina Linux 中配置菜单的界面以及一些固定的配置项,该配置菜单基于内核的 mconf 规格编写。

      device 目标
      devices 目录用于存放方案的配置文件,包括内核配置、env 配置、分区表配置、sys_config.fex(全志定制板级配置文件)、

      board.dts(linux标准设备树文件) 等。

      *这些配置在旧版本Tina(Tina3.0以前)上是保存于 target 目录下,现新版本均移到了 device 目录下,但defconfig仍保存在 target 目录下

      lichee 目录
      lichee 目录主要存放 bootloader、linux内核、DSP等代码,其中DSP代码及编译环境因涉及DSP供应商科声讯版权,需单独申请。lichee目录下结构如下:

      Tina-SDK
      ├── brandy-2.0
      │ ├── build.sh
      │ ├── tools
      │ └── u-boot-2018
      └── linux-4.9
      package 目录
      package 目录存放Tina系统支持的软件包源码和编译规则,目录按照目标软件包的功能进行分类,该目录包含了Tina系统全平台(包括全志R/H/F/V/T系列)的软件包,但是并不是所有软件包都适配了R329方案,部分软件包需要开发者自行适配。

      prebuild 目录
      prebuild 目录存放预编译用的交叉编译器,主要包括aarch64的glibc和musl以及arm的glibc和musl。prebuild目录下结构如下:

      Tina-SDK
      └── linux-x86
      ├── aarch64
      │ ├── aarch64-toolchain.txt
      │ ├── toolchain-sunxi-glibc
      │ └── toolchain-sunxi-musl
      ├── arm
      │ ├── arm-toolchain.txt
      │ ├── toolchain-sunxi-glibc
      │ └── toolchain-sunxi-musl
      └── host
      └── host-toolchain.txt

      scripts 目录
      scripts 目录用于存放设备开发中用到的一些脚本。

      target 目录
      target目录用于存放开发板相关的配置以及sdk和toolchain生产的规格。

      toolchain 目录
      toolchain 目录用于存放交叉工具链构建配置、规则。

      tools 目录
      tools 目录用于存放 host 端工具的编译规则。

      out 目录
      out 目录用于保存编译相关的临时文件和最终镜像文件,编译后自动生成此目录,并生成对应的

      方案out目录,如开发板对应的R329-evb5方案目录结构如下:

      Tina-SDK/out
      ├── host
      └── r329-evb5
      ├── boot.img
      ├── compile_dir
      ├── image
      ├── md5sums
      ├── packages
      ├── r329-evb5-boot.img
      ├── r329-evb5-Image.gz
      ├── r329-evb5-uImage
      ├── rootfs.img
      ├── sha256sums
      ├── staging_dir
      └── tina_r329-evb5_uart0.img

      其中 :

      (1)tina_r329-evb5_uart0.img 就是编译打包后生成的最终烧写到开发板上的固件;
      (2)boot.img 为最终烧写到系统 boot 分区的数据;
      (3)rootfs.img 为最终烧写到系统 rootfs 分区的数据;
      (4)r329-evb5-uImage为内核的 uImage 格式镜像,若配置为 uImage 格式,则会拷贝成 boot.img;
      (5)r329-evb5-boot.img为内核的 boot.img 格式镜像,若配置为 boot.img 格式,则会拷贝成 boot.img
      (6)compile_dir 为 sdk 编译 host、target 和 toolchain 的临时文件目录,存有各个软件包的源码;
      (7)packages 目录保存的是最终生成的 ipk 软件包。

      另外 out 目录下的 host 目录用于存放 host 端的工具以及一些开发相关的文件。

      编译和烧写
      详见编译和烧写 https://aijishu.com/a/1060000000191869

      发布在 A Series
      miumiu
      WOW
    • SDK源码获取—R329智能语音开发板入门

      转载自:https://aijishu.com/a/1060000000191843

      您可以到全志客户服务平台获取相关源码,具体步骤如下。

      登录全志客户服务平台官网
      全志客户服务平台官网:全志客户服务平台

      dfb0beb5-988a-4532-8cd3-b4a364c01e5a-image.png

      注册账号:
      点击 **“立即注册” ** 进行注册,注册表示同意全志科技相关用户协议。
      f4d0d7ee-6bf3-4686-866a-b00c8beab674-image.png

      发布在 A Series
      miumiu
      WOW
    • 「全志科技R329智能语音开发板」简介

      2020年4月,全志科技发布了搭载“ARM中国 周易AIPU”的智能语音专用处理器——R329,产品发布以来,受到了业界的广泛关注,我们听到,有不少开发者/学生朋友希望能有更多机会试用我们的产品,今天就来向大家介绍一下**「全志科技R329智能语音开发板」**相关信息^_^

      76884c45-9a46-43fc-9811-a0e87d02c57f-image.png

      「全志科技R329芯片规格」介绍

      • 列表集成双路AUDIO DSP HIFI4,硬件支持32位浮点的高精度前端、后端数字信号处理算力;

      • 列表集成Arm中国“周易”AIPU,支持160 MACs,语音识别专用深度学习算力超过200GOPS;

      • 列表集成双核CortexA53 1.5GHZ,提供生态配套成熟、完善的用于系统、应用和网络连接开发的高效算力;

      • 列表集成高达2MB的SRAM,搭配HIFI4实现50毫瓦双麦远场格可唤醒的超低功耗;

      • 列表集成高达256MB的DDR3,为LOCAL ASR、LOCAL NLP、LOCAL TTS等语音识别深度学习

      • 列表算法提供充裕的高容量、高带宽的内存支持。

      「全志科技R329智能语音开发板」介绍

      R329-EVB5开发板是基于全志R329芯片的全功能基础开发板,引出了R329几乎所有功能引脚,可用于内部研发调试、开发者学习、方案评估、项目预研、产品功能预开发等。

      「全志科技R329智能语音开发板套件」包括:

      R329智能语音开发板 *1
      5V 2A 电源适配器 *1
      Micro USB线 *1
      串口线 *1

      6e586baa-a383-4538-9dd3-60bc9eb554bc-image.png

      「全志科技R329智能语音开发板」硬件参数:

      主控:R329-N4(BGA封装),内置256MB ddr3

      PCB板层数:2层

      PCB板框大小:120mm*126mm

      供电:5V-2A适配器,板载AXP 2585电源管理芯片,可外接锂电池

      建议调试方式:UART串口,USB-ADB(TinaLinux系统内置adb调试功能)

      存储:128MB spi-nand

      无线模组:XR829,支持2.4G wifi/BT

      有线网络:板载千兆网口;

      音频:3.5mm Line in/out;spdif in/out;板载3路麦克风阵列,板最多可支持8路麦克风阵列;SPK L/R

      视频:板载可接SPI排线槽,可支持触控

      SD卡:板载SD卡卡槽,最高支持128G SD卡

      其它:PWM LED1;LEDCO LED1;LRADC KEY5;microUSB1;DSP debug调试口*2;
      (开发板出厂已内置全志Tina Linux系统)

      13fb78fd-6493-407d-a9e6-7122a3efff49-image.png

      「全志科技R329智能语音开发板」入门教程
      **请点击进入获取详细资料 :**https://r329.docs.allwinnertech.com/zh_CN/latest/

      发布在 A Series
      miumiu
      WOW
    • 探游·R329·AI部署实战(一)

      原文链接:https://aijishu.com/a/1060000000190639

      1. 先提个纲
      今天上手一块板子:R329 EVB板。

      R329来自国产芯片厂商全志科技,定位是智能语音芯片。
      其上一代产品是R328,19年用在了很多智能语音产品上,比如天猫精灵、百度语音助手等。
      为什么能用进去?大致可以认为是功耗低、价格低、性能够用、产品阔以(绝不不是因为前东家所以才夸~)。

      在2020年,全志推出了新一代的R329,主打的是更优功耗,更高性能,更高性价比,其次的亮点是里面的Arm china 0.256T AIPU,双核DSP HIFI,这我刚拿到了开发板r329_evb5_v1,就迫不及待地上手了~

      上手之前我稍微构思了下,觉得应该做成系列记录教程,由浅入深地记录我的开发过程,让工程能力偏弱的算法工程师也能跟着一步步看懂,然后上手部署实践。

      于是我就想着以我朋友(接近新手)的视角来玩这块板子,分为三个阶段,上手阶段,应用阶段,魔改阶段。

      上手阶段:
      就是从一开始的板子上电,接线,搭开发环境、看文档、配置编译内核等等,总之是板子跑起来,为后续的开发做准备;

      应用阶段:
      我们尝试交叉编译过程,移植深度学习推理框架(如NCNN,TNN等),使用zhouyi AIPU跑深度学习模型,使用双核DSP做回声消除等等,最终的目的是跑一个语音模型实现关键词唤醒,跑yolo实现目标检测功能,咱先实现功能,性能、精度调优留到第三步。

      魔改阶段:
      这个阶段,我们越过应用者视角,进入精英开发者视角,就NPU、CPU的硬件特点进行深入hack,了解分析底层的硬件原理,知道每一条指令跑在硬件的哪个部分,知道在任一时刻,该指令出现在哪个地方哪个阶段;深入的剖析AI模型部署的方方面面,比如AI算法优化啊、量化分析啊,算子性能优化啊,性能分析啊等等,总之我觉得这部分是最有意思的。

      2. 上手篇·新手级记录过程
      首先,你得拿到板子对吧,怎么拿?

      要么淘宝买,要么申请试用(下阶段的试用申请可以私信我了解哟)!

      板子拿到了,我相信你跟我朋友(没接触过嵌入式有AI基本了解的某一线大厂算法工程师,简称朋友)一样有这样的疑问?

      “这块板子能干啥?”

      我想了下,这么回的:

      “你用过智能音箱没?百度的小度、小米的小爱,阿里的天猫精灵等等,你语音一叫它就答应,还能语音互动;你去吃海底捞的时候,会发现一个端菜的机器人对吧,这种机器人可以分辨行人、桌子、菜品,你挡住它道了还会跟你battle;刚刚所说的那些产品 那些功能都是这样的板子实现的,具体来说就是在板子上跑了深度学习语音模型、图像模型比如KWS,YOLO啊啥的。”

      解决了朋友的能干啥的疑问之后,我问了下朋友:

      “从你的角度来看,你觉得应该要有哪些资源以及知识才可把板子跑起来?然后把AI模型部署上去实现上面说的那些功能?”

      朋友回答说:

      “。。。我还是之前在大学的时候接触过嵌入式,现在基本都忘了,我也不太清楚了呀,你突然这么一问,现在完全是懵的呀~”

      也对,其实也理解,边缘嵌入式端模型工程部署是伴随着AI的发展而蓬勃兴起的,17年左右开始发展,在19年到达顶峰,目前已趋于平缓;而原来学校阶段基本教的都是嵌入式的基础知识,毕竟那时候AI还没火起来呢,现在相当于在原来的嵌入式基础上加入了AI的相关属性,因此 一部分的嵌入式工程师学习深度学习的知识,或者新晋的深度学习算法工程师学习嵌入式知识,从而就衍生了边缘端部署优化工程师的岗位,属于一个偏小众的领域。

      这一顿battle之后,就得吃中饭了,先去吃饭先~好好做个干饭人~拜拜~

      俺回来啦~开整开整~~~~~~睡午觉~

      。。。。。。

      (下次再也不能在周末睡午觉了,比较费钱,刚吃完午饭又得吃晚饭了。。。)

      好在不饿,先开个箱吧~
      05536354-a42c-4191-8fa9-6fa05f209fc9-image.png

      c78166f0-b545-4157-9d5e-cccb46031047-image.png

      fdacdecc-fb47-4dae-a375-c4c0cd0d8490-image.png

      375fda22-4f76-41a4-b740-58395276639a-image.png
      上电后,灯亮了,就知道硬件没啥大问题了,接下来开始准备软件环境。

      板子的通信接口有两种一种是adb连接,一种是串口连接,我们作为开发者,两个都得配好。

      第一步先装驱动,在http://netstorage.allwinnertech.com:5000/sharing/dsn8IbX8s链接下载驱动,然后在压缩包路径:
      6d4bbf40-ec5b-491b-ade8-80f8b21b87a4-image.png

      分别安装驱动,安装完后记得重启哟~

      按照官网的教程(https://r329.docs.allwinnertech.com/zh_CN/latest/devboardstudy/r329evb5compile/)来配置啥问题也没有,

      e0c849a6-e326-4395-a4ee-03afe132c959-image.png

      556a8f71-8e53-4765-8701-9dd3d6a81bf8-image.png
      好了,到此可以知道板子是好的了,而且也知道板子是预先烧录好了固件的。

      此时我们按照教程去点灯也没啥问题:
      6c9d4343-c36b-4e88-8ecf-9401bd1ccb80-image.png

      于是去测一下麦克风,在板子上测得数据,然后adb pull到电脑上听一下效果,一开始用arecord指令出来很大电流声,指定参数如下图所示就声音正常了。

      18c8292f-2516-4195-aaca-15e0d2f5ade4-image.png

      可以看到,在三通道下是ok的,听上去也挺清晰的。
      82af9545-c985-40ad-bdd2-5d61caf987d6-image.png

      对应的单通道下也是ok的(低音沉~高音丽~![狗头])
      e58dd234-3d19-4729-a27a-7c9bc8445f28-image.png

      2. 编译固件和烧写固件部分
      我们要烧录固件,得先有源码,于是先去搞源码。

      此时你得去全志的客户服务平台(https://open.allwinnertech.com/#/dashboard?menuID=1)申请一个账号,然后让官方给你开通代码权限,开好后就会发个邮件给你:
      2540e168-07fd-409a-93d3-3df50a61cc6a-image.png

      此时按照SDK下载方法一步步执行就好啦~

      然后你可以开始下代码啦,但此时你发现不知道宿主环境是啥?

      找到文档《Tina Linux 系统软件 开发指南》
      1f83c7ab-8853-4daf-ae5d-35ff9a8f31df-image.png

      于是知道了要在ubuntu14.04中进行开发,于是我便弄了个虚拟机跑ubuntu 14.04,这其中也碰到了一次问题,就是我下错版本了,下的是32bit版本,因此按照文档进行环境包安装的时候就进行不下去了,最后换为64bit系统就好了,这点也是文档没有明确指出的。

      好了,下载ubuntu.14.04 64bit系统镜像-->下载虚拟机Vmware-->安装ubuntu-->按照文档(《Tina Linux 系统软件 开发指南》)安装环境。。。。。

      然后终于可以下代码啦~按照服务指导手册的提醒,一步步开始下代码啦~

      ~~~~~~~~~~~~~~~
      ································
      打个盹的功夫~
      ································
      ~~~~~~~~~~~~~~~

      好的,现在代码下载好了。

      我们接下来试一下编译固件烧录固件的流程:

      官网链接在这:https://r329.docs.allwinnertech.com/zh_CN/latest/devboardstudy/r329evb5compile/

      ceb78869-5b0f-4943-b6e9-889c923444af-image.png 14.jpg

      直接按照官网的流程来(行文此时正在编译中),编完后烧录一下看有没有什么问题。。。。。

      A few years later……

      f31b977f-a3d1-434b-a4fd-76f4b7a4d1ae-image.png
      快了快了~
      。
      。
      。
      Finally~

      然后我们烧录下:
      2e5729a1-a692-44a2-a43f-56df5f24d7ab-image.png
      然后上电,完美~

      72aab13f-9f93-4918-b05e-27d806d45b62-image.png

      当然,上述过程中假如我们要编译内核支持AIPU驱动可以kernel_menuconfig 进行配置:
      42d86709-e959-45f7-b53b-d62b4697ac92-image.png
      可以看到AIPU是默认驱动支持了的,但是在软件包配置部分:
      5ace472c-83c1-447a-bff9-88d254f56c5f-image.png
      并没有提供支持,也就是说我们用不了哇,据了解是知识产权属于ARM china,全志这边并不能直接使用,需要原IP厂自己开放了;
      其次HIFI双核DSP部分也是不能直接使用的,因为版权属于科声讯,因此作为发烧开发者的我们,可玩性大大降低了!因此期待尽快释放AIPU、DSP部分资源出来呀~

      ok,此时整个流程都算走了一遍了,可以得到阶段性的结论: 板子是ok的,基本环境已搭建好~

      3. 交叉编译工具
      这个时候我们下一步的探索就是交叉编译环境的确认了,我们只需要造个最简单的hello world函数,交叉编译后能在开发板上运行,

      我要在开发板上运行怎么弄呢?

      这个时候就是交叉编译 工具链出场了!啥?你问我啥叫交叉编译?为什么要有这个?

      嗯,我简单说,你开发机器是虚拟机里面的ubuntu,这里编译的代码只能在虚拟机ubuntu里面跑,但是现在我要移植到目标板R329的tina中去,因此新加一个中间层,我编译的时候选择某个特定的编译器,生成的代码可以直接在R329-tina中跑,这个特定的编译器就是交叉编译器。

      为什么要有这个?因为宿主机中开发方便很多啊~你要是开发板性能强到跟电脑主机一样了,各种环境也很完善了,那就不需要这么麻烦了呀,直接开发板上开发就完事了~

      好了,现在到实操了,官方文档这部分不是很详细,我把摸索的过程详尽写出来,希望能帮到后来者:

      第一步在宿主机造一个简单的helloworld.c
      7967d22b-0cde-424d-81da-fc01bfbbe646-image.png

      确保宿主机能正常运行。
      60a775cd-077b-4ffa-868f-a8fae50babf4-image.png

      第二步找到交叉编译工具,最新的在线文档,https://r329.docs.allwinnertech.com/zh_CN/latest/devboardstudy/r329evb5tina/#_4
      7a999db0-4c73-43b1-9947-4e1d264a2902-image.png
      我们的目标平台是arm,因此选择arm目录;
      目录内有glibc跟musl两套库,我咨询官方得知是musl库,于是我一路先择到:

      在该目录下编译hellworld.c函数,得到嵌入式平台下的目标文件helloworld22,经vmhgfs共享文件,再通过adb push helloworld22 /home/,送到板子上,此时运行发现:
      0c1c5559-591d-420f-acc3-43558d46daec-image.png
      推测可能是:

      编译器版本的问题,编译内核的跟应用的而不一致,
      也有可能是因为宿主机是64bit的,而我们目标板的程序是32bit的(试了下aarch64也不行)。
      因此我们先用static编译顶一下:
      54873fa3-d35e-4061-bb1b-6d11091ece93-image.png

      哇~久违的hello world啊~(我们技术渣就是这样的啦,一点点东西就很开心了~)
      400493ed-a383-4765-af20-55f7696c0574-image.png
      至此,整个流程算是跑通啦~

      小结一下:

      文档还是有一些盲区的,对于一些新手朋友不是很友好,建议直接上docker啊,这样我就完全不用管环境配置问题啦~

      主要的玩点在于HIFI双核DSP跟0.25TOPs的AIPU核,但是这两个目前都没法用啊,这部分希望尽快解决呀~后面的语音+图像模型部署还等着上呢~我总不能跑在算力10几个GFLOPs的A53核上 吧~

      文档开放的不够全面,比如AIPU的一系列开发文档(手动狗头)。
      呼~ 开篇总算水完啦~我这次是带着朋友一边做一边写的,根据朋友的建议,特意把某些地方写的很繁琐,希望大家不要嫌弃呀~下次见,掰掰~

      发布在 A Series
      miumiu
      WOW
    • 1 / 1