0%

CROSS COMPILERS

ARM交叉编译工具有多个版本,注意区分。

  • abi(application binary interface): 二进制程序接口
  • eabi(embedded): 嵌入式二进制程序接口
  • arm-none-eabi: 无操作系统,不支持系统调用的函数,如fork等。其使用专用于嵌入式开发的C程序库。
  • arm-none-linux-eabi: 用于linux,使用glibc。

GCC编译器

  • arm-none-eabi-gcc: 编译裸机程序或系统,适用于ARM7/Cortex-M/Cortex-R,可调用newlib库。
  • arm-none-linux-gnueabi-gcc: 编译ARM架构的Linux程序,有uboot/linux kernel/linux应用,适用于ARM9/ARM11/Cortex-A。
  • arm-linux-gnueabi-gcc: 适用于armel架构(与armhf有浮点运算间的差异)。
  • arm-linux-gnueabihf-gcc: 适用于armhf架构。
  • arm-eabi-gcc: android编译器。
  • armcc: 功能同arm-none-eabi-gcc,Keil MDK内置,收费。

DEBUG AND FLASH

DEBUG

STM32支持ISPJTAG/SWD两种调试方式。

In-System Programmability,即在线系统编程。使用时需要先设置 BOOT0BOOT1 两脚,然后通过串口 1进行程序烧写,烧写的软件为Flash_Loader_Demonstrator。此方法的好处是,可以无需外加编程口,但是只可以烧写程序,无法进行在线仿真。

JTAG,全称为Joint Test Action Group,联合测试工作组。是一种国际标准测试协议 (IEEE 1149.1兼容), 主要用于芯片内部测试,早在ARM7上面就已经使用了JTAG作为调试和下载口。

而SWD模式比JTAG 在高速模式下面更加可靠。 在大数据量的情况下面JTAG下载程序会失败, 但是SWD 发生的几率会小很多。基本使用JTAG仿真模式的情况下是可以直接使用SWD模式的。

与 ISP 相比,SWD接口可以与大多数IDE完美兼容,比如IAR,并且可以通过IAR和调试器,进行程序的在线调试,这种调试方法可以直接追踪到当前代码处的各变量状态,寄存器状态等等。

FLASH

  • J-Link是SEGGER公司为支持仿真ARM内核芯片推出的仿真调试工具,支持JTAG和SWD两种模式进行调试。

  • ULINK是由Keil推出的ARM芯片仿真调试工具,是Keil下默认的调试工具,缺点是不支持IAR。ULINK官方提供电路图等资料(半开源资料),可以自行制作仿真调试电路工具。

  • ST-LINK是由意法半导体开发的仿真调试工具。 (ST-LINKV2)适用于STM32与STM8。与STM32连接时支持JTAG与SWD模式,与STM8连接时支持SWIM模式。

ARM IDE

参考材料

  1. 意法半导体
  2. 提问+J-LINK、U-LINK和ST-LINK有什么区别?
  3. JTAG与JLink有啥不同?看完这个你就知道了

为了让大家能在博文下评论两句也是费了老大劲儿了,各种搜评论系统和倒腾。 本篇博文在Hexo静态博客系统的基础上添加评论系统。

博客评论系统

现在知道的博客评论系统也不多,有所了解的是:Disqus和Valine。目前也就只掌握了Disqus系统,下次有空学了其他评论系统的部署之后再来编辑吧。

Disqus

Disqus因为是国外的评论系统,因此最好是常在国外的人使用,好像支持匿名评论。跟我国互联网的相关法规相违背,因此在国内使用的话,会加载不出来,因为被屏蔽了。当然,如果都是墙外的人,那就无所谓了。

注意

首先确认一下你的博客主题本身已经默认支持Disqus评论系统了,否则你可能会因为不懂js语言而被折腾得半死。至于怎么确认是否支持呢?主题文件夹中的readme.md文件或者_config.yml,看看里面是否有disqus支持字样及相关说明,确认完支持之后请继续下列步骤。

对了,如果打不开Disqus官网可以考虑换valine评论系统。

注册账号

  1. 打开Disqus主页, 并点选GET STARTEDDisqus主页
  2. 根据提示注册。 Disqus账号注册

Shortname获取

  1. 注册完之后,点选I want to install Disqus on my site网站会提示你输入Website Name。 后续我们会用到一个Shortname,区别于Website Name,Shortname是用来确保后续hexo部署的时候能够准确跟你的账户连接上的。(我当时好像没填Shortname,应该是自动生成的吧~)

  2. 找到Disqus右上角头像处,Install on Site选项。然后在左侧SITE栏目中找到General选项。从这里可以看到要找到Shortname。(下图中被圈中的马赛克部分就是你的Shortname)

_config.yml设置

找到你的博客主题/themes/hexo-theme-XXXXX-master/下的_config.yml文件,然后修改或添加如下语句:(下列语句中,XXXXX为你的Shortname)

1
disqus_shortname: XXXXX

commont.ejs编辑

  1. 找到与_config.yml文件同级目录底下的layout/_partial/post/中的comment.ejs文件。先复制一份到别处,做备份之用,修改坏了也不着急。然后讲源文件下的所有语句删除,复制以下语句并粘贴(没错,要复制粘贴的这段代码只有两行,因为等下要复制粘贴另外一段代码到这两行代码中间,表示”在非主页的时候执行评论系统“):
    1
    2
    3
    4
    5
    <% if(!index){ %>



    <% } %>
  2. 找到步骤2.2中的第2步骤里的页面,同为左侧SITE栏目中的Installation,下图所示: 接着在刚刚的文件中,粘贴到那两行代码中间,完成后如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <% if(!index){ %>
    <div id="disqus_thread"></div>
    <script>

    /**
    * RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
    * LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/
    /*
    var disqus_config = function () {
    this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
    this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
    };
    */
    (function() { // DON'T EDIT BELOW THIS LINE
    var d = document, s = d.createElement('script');
    s.src = 'https://blog-liewzheng-cn.disqus.com/embed.js';
    s.setAttribute('data-timestamp', +new Date());
    (d.head || d.body).appendChild(s);
    })();
    </script>
    <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>

    <script id="dsq-count-scr" src="//blog-liewzheng-cn.disqus.com/count.js" async></script>
    <% } %>

执行

全部保存,重新运行以下语句便可进行网页预览啦!

1
2
3
hexo clean
hexo g
hexo s

参考资料

  1. 为 Hexo 主题添加评论模块 — Disqus, 多说, 友言
  2. 快速开始
  3. Hexo Next 主题点击加载 Disqus 和来必力双评论系统
  4. Hexo搭建博客系列:(六)Hexo添加Disqus评论

以下术语解释为本人在学习FreeRTOS途中的整理,大多直接引用了官网的原解释,部分用自己的话进行描述。

1. Task

Task is used to process a serial of things. A task must be declared as void type and have a void-type pointer parameter , like: void BLE_TASK(void * pvParameters);

And when used, it’s used in the function xTaskCreate() with 6 parameters, like: xTaskCreate(BLE_TASK, “BEL_TASK”,4000, NULL, 5, NULL);

  • The 1st parameter should be the task you defined, and it only need the name of your task function.
  • The 2nd parameter is the custom string you made in order to recognize it in the tasks list.
  • The 3rd parameter is task stack memory it need. MEMORY = STACK DEPTH * STACK WIDTH
  • The 4th parameter is passed to the the task when it need, and it used to be NULL.
  • The 5th parameter is the priority of the task, the lowest priority is 0, the highest priority is 32. But it always advisable to keep it at the minimum necessary.
  • The 6th parameter is the return value: pdPASS or pdFAIL.

2. Scheduler

Scheduler is used to manage the tasks. It runs in the tick interrupt and select the highest priority task and bring it into RUNNING-STATE.

3. IDLE Task

IDLE Task is automatically created by the scheduler when vTaskStartScheduler() is called and it is always able to run.

4. Task State

All the task has two big states: RUNNING-STATE or NOT-RUNNING-STATE. BLOCKED-STATE, SUSPENDED-STATE and SUSPENDED-STATE are NON-RUNNING-STATE.

Task State

4.1 RUNNING-STATE

When the task is running, it is in the RUNNING-STATE.

4.2 BLOCKED-STATE

BLOCKED-STATE is a sub-state of NOT-RUNNING STATE. Tasks can enter the BLOCKED-STATE to wait for two different types of event: Temporal Event & Synchronization Events. While in this state, tasks are not able to run, so cannot be selected by the scheduler.

4.3 SUSPENDED-STATE

SUSPENDED-STATE is a sub-state of NOT-RUNNING STATE.

4.4 READY-STATE

READY-STATE is a sub-state of NOT-RUNNING STATE.

5. Event

Event is also called Interrupt. It is originated by the environment and force the embedded system to take action in response to it.

6. Event-drive task

Event-drive task has work after the event that triggers it, and is not able to enter the RUNNING-STATE before that event has occurred.

7. Semaphore(s)

  1. Binary Semaphore
  2. Counting Semaphore

8. Queue(s)

Queue provides a task-to-task, task-to-interrupt, interrupt-to-task communication mechanism.

9. Event Group(s)

Event groups are another feature of FreeRTOS that allow events to be communicated to tasks.

10. ISR

Interrupt Service Routine. It is a software process invoked by an interrupt request from a hardware device. It handles the request and sends it to the CPU, interrupting the active process. When the ISR is complete, the process is resumed.

11. Task & Event(Interrupt)

A task is a software feature that is unrelated to the hardware on which FreeRTOS is running. The priority of a task is assigned in software by the application writer, and a software algorithm (the scheduler) decides which task will be in the Running state.

Although written in software, an interrupt service routine is a hardware feature because the hardware controls which interrupt service routine will run, and when it will run. Tasks will only run when there are no ISRs running, so the lowest priority interrupt will interrupt the highest priority task, and there is no way for a task to pre-empt an ISR.

Reference

  1. <FreeRTOS Documentation>
  2. <API>

原文出处:《十进制数转为十六进制字符串

本文修改了以上原文的代码,修正了[0-16]区间的10进制数转换成16进制数时无法正确转换的问题。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<stdio.h>
#include<stdlib.h>

char Hexadecimal_Code[]="0123456789ABCDEF";
char str_Temp[10];

char *Decimal_To_Hexadecimal_String(int Decimal_Data)
{
int High,Low,i=0;
if(Decimal_Data <= 0 || Decimal_Data > 255)
exit(0);

High=Decimal_Data >> 4;
Low=Decimal_Data & 15;

str_Temp[i++]=Hexadecimal_Code[High];
str_Temp[i++]=Hexadecimal_Code[Low];
str_Temp[i]='\0';

return str_Temp;
}

int main()
{
printf("%s\n",Decimal_To_Hexadecimal_String(5));

return 0;
}

以下为本人在学习开发途中的一些关于版本控制的资料整理。

版本控制

版本控制(Revision control)是维护工程蓝图的标准作法,能追踪工程蓝图从诞生一直到定案的过程。此外,版本控制也是一种软件工程技巧,借此能在软件开发的过程中,确保由不同人所编辑的同一程序文件都得到同步。

基线(Baseline)

基线是软件文档或源码(或其它产出物)的一个稳定版本,它是进一步开发的基础。[1]

文件库(Repository)

存储文件的新版本还有历史数据的地方,通常是在服务器上。有时候也叫Depot(像是在SVK、AccuRev还有Perforce中)

工作复本(Working copy)

从文件库中取出一个本地端(客户端)的复制,针对一个特定的时间或是版本。所有在文件库中的文件更动,都是从一个工作版本中修改而来的,这也是这名称的由来。观念上,这是一个沙盒。

提交(Commit)

将本地端的修改送回档案库。(由版本控制软件处理“跟上次更动相比,哪个文件又被更动”的事)

变更(Change)

对一份文件作的特定更动。

变更记录(Change List)

取出(Check-Out)

从文件库取出文件到本地端(客户端)。

更新(Update)

将文件库的修改送到本地端(与提交相反)

合并(Merge / Integration)

合并各个改变。

版次(Revision)

一个revision或version指的是一系列版本变迁的其中之一。

导入(Import)

导出(Export)

冲突(Conflict)

当两方更动同一份文件会发生冲突。

以下为本人在学习ESP32开发的途中的一些资料整理。

GPIO

General-purpose input/output,通用型输入输出。其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。 既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电位的高低 ;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电位或者低电位;对于其他特殊功能,则有另外的寄存器来控制它们。

Xtensa

Xtensa 是Tensilica公司的处理器。

OpenOCD

OpenOCD(Open On-Chip Debugger)开源片上调试器,是一款开源软件,最初是由Dominic Rath同学还在大学期间发起的(2005年)项目。OpenOCD旨在提供针对嵌入式设备的调试、系统编程和边界扫描功能。

OpenOCD的功能是在仿真器的辅助下完成的,仿真器是能够提供调试目标的电信号的小型硬件单元。仿真器是必须的,因为调试主机(运行OpenOCD的主机)通常不具备这种电信号的直接解析功能。

仿真器支持一个或多个传输协议,每个协议涉及不同的电信号,且使用不同的协议栈进行消息传递。市面上有很多种仿真器,并且这些仿真器的命名没有统一的规律。

仿真器有时候会被封装成独立的加密狗,这种称为硬件接口加密狗。一些开发板上面直接集成了硬件接口加密狗,这样可以使开发板通过USB直接连到主机上进行调试。

例如,JTAG仿真器支持JTAG协议的信号,可以用来进行TAPs和目标板子之间符合JTAG协议(IEEE 1149.1)的通讯。TAP(Test Access Port)是处理特殊指令和数据的单元。TAPs在芯片与板子之间和之内以菊花链的形式进行连接。JTAG支持调试和边界扫描。

还有SWD仿真器,这种仿真器支持使用SWD(Serial Wire Debug)信号与一些比较新的ARM芯片进行通讯,而且还可以作为那些同时支持JTAG和SWD的芯片的仿真器。不过SWD仅支持调试,不支持边检扫描。

对于一些芯片,还有专门的编程下载器,这些下载器仅支持擦写FLASH的功能,不支持调试和边界扫描。对于此类专用下载器,OpenOCD暂时并不支持。

加密狗

OpenOCD目前支持多种类型的硬件加密狗:基于USB的,基于并行端口的,以及其他在内部运行OpenOCD的独立盒子。 请参见第2章[仿真器硬件],第5页。

GDB调试

它允许ARM7(ARM7TDMI和ARM720t),ARM9(ARM920T,ARM922T,ARM926EJ-S,ARM966E-S),XScale(PXA25x,IXP42x),Cortex-M3(Stellaris LM3,ST STM32和Energy Micro EFM32)和基于Intel Quark(x10xx)的内核使用GDB协议进行调试。

Flash编程

擦写FLASH支持外部CFI兼容NOR闪存(Intel和AMD / Spansion命令集)和几个内部闪存(LPC1700,LPC1800,LPC2000,LPC4300,AT91SAM7,AT91SAM3U,STR7x,STR9x,LM3,STM32x和EFM32)。包括各种NAND闪存控制器(LPC3180,Orion,S3C24xx等)的初步支持。

AT指令

即Attention,AT指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(Data Terminal Equipment,DTE)向终端适配器(Terminal Adapter, TA)或数据电路终端设备AT(Data Circuit Terminal Equipment,DCE)发送的。通过TA,TE发送AT指令来控制移动台(Mobile Station,MS)的功能,与GSM 网络业务进行交互。用户可以通过AT指令进行呼叫、短信、电话本、数据业务、传真等方面的控制。

Measured Power

之所以所有文档都将Measure_Power变量的值定为C5,是因为此处C5为RSSI 在 1m时强度大小。见(RSSI @ 1m [ RSSI at 1 meter ] )文档《Active Beacon Packet 170512.pdf》。

iBeacon Format

Measure Power 是Beacon距离测量设备1m时的信号强度(0xC5,要求反码)。实际过程中,根据接收到的RSSI值与0xC5(-59dbm)做对比得出当前设备距离,算法由厂商提供,iOS自带算法。

Measure Power

参考文献

  1. AT指令介绍及用法,AT 指令集合
  2. How do iBeacons work?
  3. GPIO

原文:《Shell脚本编程30分钟入门

首先要安装一个wget插件

1
2
3
yum install -y wget
yum install -y setup
yum install -y perl

一、Shell脚本

1. 脚本示例

1
2
3
4
5
6
7
8
#!/bin/sh
cd ~
mkdir shell_tut
cd shell_tut

for ((i=0; i<10; i++)); do
touch test_$i.txt
done

2. 代码解释

  • 第1行:指定脚本解释器,这里是用/bin/sh做解释器的
  • 第2行:切换到当前用户的home目录
  • 第3行:创建一个目录shell_tut
  • 第4行:切换到shell_tut目录
  • 第6行:循环条件,一共循环10次
  • 第7行:创建一个test_0…9.txt文件
  • 第8行:循环体结束

mkdir, touch都是系统自带的程序,一般在/bin或者/usr/bin目录下。for, do, done是sh脚本语言的关键字。

二、Shell相关概念

1. 基础概念

shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务,Windows Explorer是一个典型的图形界面Shell。

shell脚本 ,shell script,是一种为shell编写的脚本程序。业界所说的shell通常都是指shell脚本。shell和shell script是两个不同的概念。由于习惯的原因,简洁起见,本文出现的“shell编程”都是指shell脚本编程,不是指开发shell自身(如Windows Explorer扩展开发)。

sh命令 是shell命令语言解释器,执行命令从标准输入读取或从一个文件中读取。通过用户输入命令,和内核进行沟通。

2. Shell类型

如果要查看某一个用户使用的是什么 shell 可以通过 finger [USERNAME]命令来查看。 (kt)sh,Ken Thompson Shell,历史上第一个Unix shell,1971年由肯·汤普逊写作出第一版并加入UNIX之中。它是一个简单的命令行解释器,但不能被用来运行 指令稿(Shell script)。它的许多特征影响了以后命令行界面的发展。至Version 7 Unix之后,被Bourne shell取代。

sh,Bourne Shell,是Version 7 Unix默认的Unix shell,替代执行文件同为.sh的Thompson shell。

bash ,Bourne Again Shell,Unix shell的一种,在1987年由布莱恩·福克斯为了GNU计划而编写,与Bourne Shell兼容,还继承了C Shell、Korn Shell等优点。

zsh, Z shell是一款可用作交互式登录的shell及脚本编写的命令解释器。Zsh对Bourne shell做出了大量改进,同时加入了Bash、ksh及tcsh的某些功能。

3. Shell模式

3.1 login shell 和 no-login shell

login shell 代表用户登入, 比如使用 su - 命令, 或者用 ssh 连接到某一个服务器上, 都会使用该用户默认 shell 启动 login shell 模式。

该模式下的 shell 会去自动执行 /etc/profile~/.profile 文件, 但不会执行任何的 bashrc 文件, 所以一般在 /etc/profile 或者 ~/.profile 里我们会手动去 source bashrc 文件。

no-login shell 的情况是我们在终端下直接输入 bash 或者 bash -c “CMD” 来启动的 shell。

该模式下是不会自动去运行任何的 profile 文件。

3.2 interactive shell 和 non-interactive shell

interactive shell 是交互式shell, 顾名思义就是用来和用户交互的, 提供了命令提示符可以输入命令。

该模式下会存在一个叫 PS1 的环境变量, 如果还不是 login shell 的则会去 source /etc/bash.bashrc~/.bashrc 文件。

non-interactive shell 则一般是通过 bash -c “CMD” 来执行的bash。

该模式下不会执行任何的 rc 文件 (不过还存在一种特殊情况这个我之后详细讲述)

4. profile和bashrc

profile用于交互式login shell,bashrc用于交互式non-login shell。系统中存在许多bashrc和profile文件。 /etc/profile~/.profile分别对应 所有用户单个用户(bashrc同理)。

4.1 profile

profile 是用户唯一的用来设置环境变量的地方, 因为用户可以有多个 shell 比如 bash, sh, zsh 之类的, 但像环境变量这种其实只需要在统一的一个地方初始化就可以了, 而这就是 profile。/etc/profile中设定的变量(全局)的可以作用于任何用户,profile文件是在用户登录的时候进行初始化的。

4.2 bashrc

bashrc 是专门用来给 bash 做初始化的比如用来初始化 bash 的设置, bash 的代码补全, bash 的别名, bash 的颜色. 以此类推也就还会有 shrc, zshrc 这样的文件存在了, 只是 bash 太常用了而已。~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系。(此句话待考究!!!!)

三、环境

shell编程跟java、php编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

1. OS

当前主流的操作系统都支持shell编程,本文档所述的shell编程是指Linux下的shell,讲的基本都是POSIX标准下的功能,所以,也适用于Unix及BSD(如Mac OS)。

Linux默认安装就带了shell解释器。Mac OS不仅带了sh、bash这两个最基础的解释器,还内置了ksh、csh、zsh等不常用的解释器。windows出厂时没有内置shell解释器,需要自行安装,为了同时能用grep, awk, curl等工具,最好装一个cygwin或者mingw来模拟linux环境。

2. 脚本解释器

2.1 sh

即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。

本文讲的是sh,如果你使用其它语言用作shell编程,请自行参考相应语言的文档。

2.2 bash

Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。业界通常混用bash、sh、和shell,比如你会经常在招聘运维工程师的文案中见到:熟悉Linux Bash编程,精通Shell编程。

在CentOS里,/bin/sh是一个指向/bin/bash的符号链接:

1
2
3
4
[root@centosraw ~]# ls -l /bin/*sh
-rwxr-xr-x. 1 root root 903272 Feb 22 05:09 /bin/bash
-rwxr-xr-x. 1 root root 106216 Oct 17 2012 /bin/dash
lrwxrwxrwx. 1 root root 4 Mar 22 10:22 /bin/sh -> bash

但在Mac OS上不是,/bin/sh和/bin/bash是两个不同的文件,尽管它们的大小只相差100字节左右:

1
2
3
4
5
6
7
iMac:~ wuxiao$ ls -l /bin/*sh
-r-xr-xr-x 1 root wheel 1371648 6 Nov 16:52 /bin/bash
-rwxr-xr-x 2 root wheel 772992 6 Nov 16:52 /bin/csh
-r-xr-xr-x 1 root wheel 2180736 6 Nov 16:52 /bin/ksh
-r-xr-xr-x 1 root wheel 1371712 6 Nov 16:52 /bin/sh
-rwxr-xr-x 2 root wheel 772992 6 Nov 16:52 /bin/tcsh
-rwxr-xr-x 1 root wheel 1103984 6 Nov 16:52 /bin/zsh

2.3 高级编程语言

理论上讲,只要一门语言提供了解释器(而不仅是编译器),这门语言就可以胜任脚本编程,常见的解释型语言都是可以用作脚本编程的,如:Perl、Tcl、Python、PHP、Ruby。Perl是最老牌的脚本编程语言了,Python这些年也成了一些linux发行版的预置解释器。

编译型语言,只要有解释器,也可以用作脚本编程,如C shell是内置的(/bin/csh),Java有第三方解释器Jshell,Ada有收费的解释器AdaScript。

如下是一个PHP Shell Script示例(假设文件名叫test.php):

1
2
3
4
#!/usr/bin/php
<?php
for ($i=0; $i < 10; $i++)
echo $i . "\n";

执行:

1
/usr/bin/php test.php

或者:

1
2
chmod +x test.php
./test.php
chmod命令用来变更文件或目录的权限

四、选择Shell编程语言

1. 熟悉 vs 陌生

如果你已经掌握了一门编程语言(如PHP、Python、Java、JavaScript),建议你就直接使用这门语言编写脚本程序,虽然某些地方会有点啰嗦,但你能利用在这门语言领域里的经验(单元测试、单步调试、IDE、第三方类库)。

新增的学习成本很小,只要学会怎么使用shell解释器(Jshell、AdaScript)就可以了。 ## 2. 简单 vs 高级 如果你觉得自己熟悉的语言(如Java、C)写shell脚本实在太啰嗦,你只是想做一些备份文件、安装软件、下载数据之类的事情,学着使用sh,bash会是一个好主意。

shell只定义了一个非常简单的编程语言,所以,如果你的脚本程序复杂度较高,或者要操作的数据结构比较复杂,那么还是应该使用Python、Perl这样的脚本语言,或者是你本来就已经很擅长的高级语言。因为sh和bash在这方面很弱,比如说:

  • 它的函数只能返回字串,无法返回数组
  • 它不支持面向对象,你无法实现一些优雅的设计模式
  • 它是解释型的,一边解释一边执行,连PHP那种预编译都不是,如果你的脚本包含错误(例如调用了不存在的函数),只要没执行到这一行,就不会报错

3. 环境兼容性

如果你的脚本是提供给别的用户使用,使用sh或者bash,你的脚本将具有最好的环境兼容性,perl很早就是linux标配了,python这些年也成了一些linux发行版的标配,至于mac os,它默认安装了perl、python、ruby、php、java等主流编程语言。

五、 第一个Shell脚本

1. 编写

打开文本编辑器,新建一个文件,扩展名为.sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用.php好了。

输入一些代码,第一行一般是这样:

1
2
#!/bin/bash
#!/usr/bin/php
“#!”是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行。

2. 运行

运行Shell脚本有两种方法: ### 2.1 作为可执行程序

1
2
chmod +x test.sh
./test.sh
注意 一定要写成./test.sh,而不是test.sh,运行其它 二进制的程序 也一样,直接写test.sh,linux系统会去PATH里寻找有没有叫test.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里,你的当前目录通常不在PATH里,所以写成test.sh是会找不到命令的,要用./test.sh告诉系统说,就在当前目录找。 ./表示当前目录。

通过这种方式运行bash脚本,第一行一定要写对,好让系统查找到正确的解释器。

这里的"系统",其实就是shell这个应用程序(想象一下Windows Explorer),但我故意写成系统,是方便理解,既然这个系统就是指shell,那么一个使用/bin/sh作为解释器的脚本是不是可以省去第一行呢?是的。

2.2 作为解释器参数

这种运行方式是,直接运行解释器,其参数就是shell脚本的文件名,如:

1
2
/bin/sh test.sh
/bin/php test.php
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

参考链接

  1. chmod命令
  2. Thompson shell
  3. Bourne shell
  4. bash
  5. 理解 bashrc 和 profile

本文将直接摘抄和引用ESPRESSIF官网文档对ESP32 SDK配置的描述,并对具体执行步骤加一些自己的备注和注意事项。

本文中以Ubuntu为Linux系统的代表,在所有安装步骤apt-get install及涉及到其他读写cpmkdirrm的操作中,如遇到Permission denied等权限不够的问题,请在命令开头添加sudo或直接另起一行输入sudo -s,然后输入密码(有些命令不需要输入密码)获取 root 权限。

Eclipse的使用可以在三大平台上进行,但是用.bin文件烧录到开发板的过程目前仅在Windows平台找得到烧录工具,望悉知。

为方便描述,本文定义终端为MSYS2及Terminal的统称,XXXXX为你电脑的用户名,*为你的端口号数字。

本文分为三部分: - 工具及SDK的下载及配置 - 使用终端运行工程 - 使用Eclipse运行工程

一、工具及SDK的下载及配置

本节共有五部分: - 工具(MSYS2和Git) - ESP-IDF - Xtensa - 环境变量设置 - python依赖包

1. 工具

此部分在官方文档里面称为“设置工具链”。

1.1 MSYS2(for Windows only)

跟Git Bash Shell同理,直接从MSYS2官网下载和安装到C盘根目录C:/下即可。或者直接下载ESPRESSIF提供的.zip文件,解压到C:/

能不能放到其他盘,暂时没有试验过,对于使用MSYS2的开发者而言,最好是到C:\msys32\mingw32.exe文件属性中设置好管理员权限。

本下载仅用于windows平台,对于Mac及Linux平台而言,可以直接调用Terminal进行后续步骤。

1.2 Git(for Mac & Linux)

此步骤要在Terminal中进行,便于将ESPRESSIF保存在Github的ESP-IDF下载到本地。

运行以下命令安装(Debian/Ubuntu):

1
apt-get install git
以及(Mac):Git下载

ESP-IDF 是ESP32设备的SDK,另外,MSYS2自带Git工具。如果已经安装过Git工具了,可以使用gitgit version语句进行查看。

2. ESP-IDF

在创建文件夹esp的过程中,确保自己没有使用到root权限来创建文件夹,查看的方法是打开Files应用,看看esp文件夹上面是否有个锁的图表。因为后续添加的环境变量局限于 XXXXX 用户,而执行文件因为在创建的过程中就属于 root 用户了,就不能够识别个人用户创建的环境变量IDF_PATH。为ESP-IDF的获取创建好文件夹,运行以下命令:

1
2
3
cd ~/
mkdir -p esp
cd esp
如果使用了 root 权限来创建esp文件夹,请使用命令rm -d -f ~/esp来删除 空的esp文件夹 或 使用命令rm -r -f ~/esp非空的esp文件夹。然后重启终端,使用普通用户权限再次创建。

msys2-terminal-window 然后运行下面语句,ESP-IDF 将会被下载到 ~/esp/esp-idf 目录下。

1
git clone --recursive https://github.com/espressif/esp-idf.git

注意: 上面克隆仓库的语句中有个 --recursive 选项。如果你克隆 ESP-IDF 时 没有带这个选项 ,你还需要运行额外的命令(如下)来获取子模块:

1
2
cd esp-idf
git submodule update --init

3. Xtensa(for MAC & Linux only)

Windows平台因为使用MSYS2的原因,自带了Xtensa,因此可以忽略此步骤。

Linux平台 Xtensa-Linux-64bit下载解压。 执行如下命令:

1
2
cd ~/esp
tar -xzf ~/Downloads/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz

MAC平台 Xtensa-MAC

1
2
cd ~/esp
tar -xzf ~/Downloads/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz

4. 环境变量设置

Windows平台: 寻找到路径C:/msys32/etc/profile.d/,然后使用记事本或其他文本工具新建一个名为export_idf_path.sh的文件,然后将你的esp-idf路径写入文件中,如:

1
export IDF_PATH="C:/msys32/home/XXXXX/esp/esp-idf"

安装vim工具或使用其他文本工具,打开~/.profile文件。使用vim工具的话,单击i健进行插入,鼠标点击粘贴以下代码后,按ESC键,然后输入:w进行保存,再次输入:q推出vim工具,ubuntu平台的vim工具安装命令:

1
apt-get install vim

Linux平台

1
2
export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
export IDF_PATH=~/esp/esp-idf

MAC平台

1
2
export PATH=$HOME/esp/xtensa-esp32-elf/bin:$PATH
export IDF_PATH=~/esp/esp-idf

完成修改后重启终端,并在终端中输入以下命令可以查看是否设置成功,如果不成功或者后续步骤中出现No such file or directory的错误提示,请尝试重启系统。

1
2
printenv IDF_PATH
printenv PATH

Environment_Setting_PATH

5. python依赖包安装

直接输入以下命令,安装依赖于Python的软件包:

1
python -m pip install --user -r $IDF_PATH/requirements.txt

注意 在终端输入python可查看版本,如果你的电脑安装的是不同版本的Python,则调用不同的语句进行安装,如python2 python2.7Tools_Downloads_Python

1
python2.7 -m pip install --user -r $IDF_PATH/requirements.txt

如果在此步骤出现/usr/bin/python2.7: No module named pip的问题,则输入以下命令进行pip module安装:

1
apt-get install python-pip

二、使用终端运行工程

本节共有四部分: - 工程样例复制 - 开发板连接 - 工程参数设置 - 命令行烧录

1. 工程样例复制

C:/msys32/home/XXXXX/esp/esp-idf/examples/下面会有很多ESP-IDF自带的工程样例,按照用途分类。本节将使用/get-started/hello_world作为示范。

拷贝样例:

1
2
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world .

要注意的是,拷贝样例的语句中,那个点.必不可少,且和前面的路径中有个空格

2. 开发板连接

将 ESP32 开发板连接到 PC,然后检查串口号,看看它能否正常通信。 ### 2.1 驱动 以下是乐鑫 ESP32 开发板驱动程序的链接:

ESP32-PICO-KIT 和 ESP32-DevKitC - CP210x USB to UART Bridge VCP Drivers ESP32-WROVER-KIT 和 ESP32 Demo Board - FTDI Virtual COM Port Drivers

装完驱动之后,Windows平台的设备管理器中是如下显示的: esp32-devkitc-in-device-manager1

2.2 端口号

Windows平台:设备管理器中查看端口并记录下其设备尾部标注的端口号COM*esp32-devkitc-in-device-manager1

Linux和Mac的平台: 在终端里面,分别运行查看端口命令两次,一次是在插入开发板前,一次是在插入开发板后。 Linux:

1
ls /dev/tty*
Mac:
1
ls /dev/cu.*
另外,Linux平台还需要为登录用户添加串口读写权限:
1
sudo usermod -a -G dialout $XXXXX

Putty工具 下载和使用Putty工具对开发板进行串口连接确认。

运行终端,设置串口:波特率 = 115200,数据位 = 8,停止位 = 1,奇偶校验 = N。

以下是设置串口和在 Windows 和 Linux 上传输参数(如 115200-8-1-N)的一些截屏示例。注意选择上述步骤中确认的串口进行设置。

putty-settings-windows1 putty-settings-linux1

3. 工程参数设置

在终端窗口中,输入cd ~/esp/hello_world进入hello_world所在目录,然后启动工程配置工具:

1
make menuconfig
project-configuration1

在菜单中,进入Serial flasher config>Default serial port输入之前记录下来的串口号(/dev/tty*/dev/cu.*/COM*),工程会加载到该串口上。输入回车确认选择,选择< Save >保存配置,然后选择< Exit >退出应用程序。

以下是menuconfig的使用小技巧: 1. 使用 up & down 组合键在菜单中上下移动 2. 使用 Enter 键进入一个子菜单,Escape 键退出子菜单或退出整个菜单 3. 输入 ? 查看帮助信息,Enter 键退出帮助屏幕 4. 使用空格键或 YN 键来使能 (Yes) 和禁止 (No) 带有复选框 “[*]” 的配置项 5. 当光标在某个配置项上面高亮时,输入 ? 可以直接查看该项的帮助信息 6. 输入 / 搜索配置项

注意 如果再此步骤出现<command-line>:0:12: fatal error: curses.h: No such file or directory的错误提示,则

4. 命令行烧录

4.1 烧录

这条命令会编译应用程序和所有的 ESP-IDF 组件,生成 bootloader、分区表和应用程序 bin 文件,并将这些 bin 文件烧写到 ESP32 板子上。

1
make flash
烧写成功的话,板子将会复位,应用程序 “hello_world” 开始启动,在终端显示如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
esptool.py v2.0-beta2
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000)...
esptool.py v2.0-beta2
Connecting........___
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Attaching SPI flash...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 11616 bytes to 6695...
Wrote 11616 bytes (6695 compressed) at 0x00001000 in 0.1 seconds (effective 920.5 kbit/s)...
Hash of data verified.
Compressed 408096 bytes to 171625...
Wrote 408096 bytes (171625 compressed) at 0x00010000 in 3.9 seconds (effective 847.3 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 82...
Wrote 3072 bytes (82 compressed) at 0x00008000 in 0.0 seconds (effective 8297.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting...

4.2 端口监控

如果要查看 “hello_world” 程序是否真的在运行,输入命令 make monitor。这个命令会启动 IDF Monitor 程序(ESP-IDF自带工具),也可以使用其他串口助手进行查看。

1
make monitor
串口启动时,在终端显示如下:
1
2
3
4
5
6
7
8
9
$ make monitor
MONITOR
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun 8 2016 00:22:57
...
开发板输出到串口的信息,在终端显示如下:
1
2
3
4
5
6
7
...
Hello world!
Restarting in 10 seconds...
I (211) cpu_start: Starting scheduler on APP CPU.
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...

三、 使用Eclipse运行工程

本节共有四部分: - JRE & Eclipse - Eclipse项目运行 - Build Project - Flash tools烧录

1. JRE & Eclipse

1.1 JRE安装

JRE(Java Runtime Environment)要在Eclipse之前安装,并在终端使用如下命令验证是否安装成功并查看版本:

1
java -version

1.2 Eclipse安装

Eclipse IDE 是一个可视化的集成开发环境,可用于编写、编译和调试 ESP-IDF 项目。

下载相应的Eclipse并安装到电脑:eclipse.org,在安装的过程中记得要选择Eclipse for C/C++ Development(有的版本也可能显示为 CDT)。

2. Eclipse项目运行

2.1 导入工程样例

  1. 运行 Eclipse,选择 File -> Import…

  2. 弹出的对话框中选择 C/C++ -> Existing Code as Makefile Project,然后点击 Next

  3. 在下个界面中 Existing Code Location 位置输入您的 IDF 项目的路径(如:C:/msys32/home/XXXXX/esp/hello_world)。 注意:这里应输入 ESP-IDF 项目的路径,而非 ESP-IDF 本身的路径。

  4. 在本界面,找到 Toolchain for Indexer Settings,选择 Cross GCC,最后点击 Finish

2.2 设置工程项目属性

Eclipse_Project_Properties

在本小节中,会 添加或修改三个主要的环境变量BTACH_BUILDIDF_PATHPATH。这些变量可以只在 项目属性 中修改,也可以直接到 系统环境变量 中修改。(添加到系统环境变量中的方法本文无讲解)

Eclipse_Project_Properties_Environment_Value
  1. 新项目将出现在Eclipse左侧的 Project Explorer 选项卡中。选择导入的项目,在右键菜单中选择 Properties

  2. 点击 C/C++ Build 下的 Environment 属性页,点击 Add… 按钮,输入 BATCH_BUILD1

  3. 点击 Add…,输入 IDF_PATH 中输入 ESP-IDF 所在的完整安装路径 C:/msys32/home/XXXXX/esp/esp-idf 。Linux及MAC平台的安装路径 /home/XXXXX/esp/esp-idf .

  4. 选择 PATH 环境变量,不要改变默认值。

Windows 用户:C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin;C:\msys32\usr\bi 添加到 PATH 环境变量的靠前位置(如果您将 msys32 安装到了其它目录,则需要更改对应的路径以匹配您的本地环境)。

  1. 在 macOS 平台上,增加一个 PYTHONPATH 环境变量,并将其设置为 /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages, 保证系统中预先安装的 Python (需安装 pyserial 模块)可以覆盖 Eclipse 内置的任何 Python。
Eclipse_Project_Properties_Preprocessor_Include
  1. 前往 C/C++ General -> Preprocessor Include Paths 属性页面,点击 Providers 选项卡:

选择 CDT Cross GCC Built-in Compiler Settings,将 Command to get compiler specs 修改为 xtensa-esp32-elf-gcc ${FLAGS} -std=c++11 -E -P -v -dD "${INPUTS}"

选择 “CDT GCC Build Output Parser,将 Compiler command pattern 修改为 xtensa-esp32-elf-(gcc|g\+\+|c\+\+|cc|cpp|clang)

Eclipse_Project_Properties_Indexer
  1. 前往 C/C++ General -> Indexer 属性页面,选择 Enable project specific settings 以启用本页上的其他设置。然后去除 Allow heuristic resolution of includes 勾选,因为启用此选项时,Eclipse 有时无法找到正确的头文件目录。
Eclipse_Project_Properties_Build_Behavior
  1. 点击 C/C++ Build -> Behavior 属性页,选中 Enable parallel build 以启用多任务并行构建。

  2. 保存项目属性并退出属性设置界面。

3. Build Project

选择菜单栏中的 Project -> Build Project。在此步骤中,将会调用ESP-IDF生成三个文件:bootloader.binpartition_singleapp.binhello_world.bin。分别对应的是启动程序、分区程序和应用主程序。

成功构建工程项目之后,Eclipse下方的 Console 选项卡将会显示如下: build_successfully

4. Flash tools烧录

Flash tools(仅在ESPRESSIF官网上找到Windows版本)下载并解压到相应位置,打开后进行如下配置。 正确配置后便可成功烧录,要注意的是,bootloader.bin对应放在地址0x1000的位置,partition_singleapp.bin对应放在地址0x8000的位置,helloworld.bin对应放在地址0x10000的位置。 flash_download

参考链接

  1. ubuntu下文件拷贝命令cp命令
  2. ubuntu rm命令
  3. mkdir命令

原文中的URIBeacon已被Google Eddystone替代,因此本文并非完全由原文转载,有小幅度更改。

蓝牙低功耗(BLE)信标

有几种类型(Eddystone,AltBeacon,iBeacon),每种类型都有自己的标准和优势。有些是开放和免费的,有些是封闭的,需要花钱。本文将介绍可用信标的三种主要类型,它们的优点,缺点,衍生物以及有关信标如何工作的一些低级实现细节。确保查看所有可用作BLE信标的已启用mbed的BLE平台。

概观

蓝牙低功耗(BLE)能够以两种状态之一交换数据:连接和广告模式。连接模式使用通用属性(GATT)层以一对一的方式传输数据。广告模式使用通用访问配置文件(GAP)层向正在收听的任何人广播数据。广告模式是一对多转移,无法保证数据的一致性。

BLE Beacons利用GAP广告模式以定期的,特殊格式的广告包广播数据。每种类型的信标都使用自定义规范来对广告数据进行分区,从而赋予其意义。我将看看三种现有类型的信标,URI Beacons,iBeacons和AltBeacons。mbed BLE团队页面支持所有信标类型,如果您想尝试它们,请提供包含文档的示例项目。

iBeacon

Apple的iBeacon是第一款出现的BLE Beacon技术,因此大多数信标都从iBeacon数据格式中获取灵感。iBeacons在几个Apple SDK中启用,可以从任何支持BLE的iDevice读取和广播。iBeacon是一种专有的封闭式标准。iBeacons有一个庞大的生态系统,并为开发人员提供了大量资源,但您必须成为Apple开发人员社区的一员。

数据规格

iBeacons播放了四条信息: 1. 标识信标的UUID。 2. 标识大组中信标子集的主要编号。 3. 标识特定信标的次要编号。 4. TX功率电平为2的补码,表示距设备一米的信号强度。必须由用户或制造商为每个设备校准此编号。

扫描应用程序读取UUID,主要编号和次要编号,并针对数据库引用它们以获取有关信标的信息; 信标本身不包含描述性信息 - 它要求此外部数据库有用。TX功率字段与测量的信号强度一起使用以确定信标距智能电话的距离。请注意,用户必须在信标的基础上校准TxPower才能准确。

iBeacon-Diagramredo

iBeacon前缀包含十六进制数据:0x02 01 06 1A FF 00 4C 02 15。这分解如下:

  • 0x020106将广告包定义为BLE General Discoverable和BR / EDR高速不兼容。实际上它说它只是广播,而不是连接。
  • 0x1AFF表示以下数据长度为26个字节,并且是制造商特定数据。
  • 0x004C是Apple的蓝牙Sig ID,是该规范的一部分,使其依赖于Apple。
  • 0x02是表示邻近信标的辅助ID,由所有iBeacons使用。
  • 0x15将剩余长度定义为21个字节(16 + 2 + 2 + 1)。

其余的字段相当自我解释。邻近UUID是标准的16byte / 128bit BLE UUID,通常是公司独有的。主要和次要数字用于表示UUID内的资产; 常见用途是主要数字是商店(因此可能有65,536个商店),其中次要数字是商店内的单个标签(每个商店还有65,536个可能的标签)。

例子

  1. 一家咖啡店在一个咖啡架和一个寄存器上放置了iBeacons。当顾客走进咖啡店足够近时,智能手机应用程序会看到iBeacon,搜索咖啡店的iBeacon数据库,将iBeacon识别为属于coffeeShop X,然后看到咖啡有效的优惠券,并通知优惠券的用户。
  2. iDevices可以广播iBeacon。这可用于在活动中自动登记并跟踪整个场地的移动。
  3. 请参阅mbed iBeacon设备页面上的嵌入式设备代码。

这是如何设置iBeacon设备以使用mbed BLE_API广播具有主要和次要号码的UUID的示例。请注意,tx功率水平应根据设备的1米测量用户校准。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "mbed.h"
#include "iBeaconService.h"
...
BLEDevice ble;
const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, // 16Byte UUID
0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61
};
uint16_t majorNumber = 1122; // 2 byte major number
uint16_t minorNumber = 3344; // 2 byte minor number
uint16_t txPower = 0xC8; // 1 byte tx power level
...
int main(void){
...
iBeaconService ibeacon(ble, uuid, majorNumber, minorNumber, txPower);
....
while(1){
ble.waitForEvent();
}
}

思考

iBeacons非常酷,得到广泛支持,因为它们是Apple产品,所以每个人都在与它们合作,生态系统尽可能健壮。唯一的限制是需要数据库来为iBeacon数据赋予意义。没有数据库,UUID就毫无意义。你可以在这里找到mbed iBeacon的例子。

衍生品

一个流行的衍生产品是用不同的公司代码替换0x004C代码,例如分配给Nordic Semiconductor的0x0059。该NRF烽火台应用和nrf51822蓝牙智能灯塔套件就是这样的例子。 一些公司提供的示例未明确使用iBeacon规范。

AltBeacon

AltBeacons是Radius Networks提供的开放式免费信标设计。它似乎正在获得一些动力。AltBeacon规范似乎是对Apple正在使用的闭源iBeacon规范的直接反应; 它涵盖了与iBeacon相同的功能,但不是公司特定的。也就是说,它尚未获得广泛支持。

值得注意的是,虽然iBeacons有20个27字节可用于用户数据(UUID + Major + Minor),但AltBeacons有28个28字节可用(MFG ID,BeaconCode,BeaconID,MFG RSVD)。这意味着每条消息可以传送更多数据。

数据规格

所述AltBeacon规格是28bytes(26B是用户可修改的)。AltBeacon的前两个字节不是用户可修改的,而是由BLE堆栈设置的。ADV长度为0x1B,ADV类型为0xFF; 这些将分别指定广告数据包的长度和类型作为制造数据。之后,一切都由用户决定,可以推送到广告制造商数据字段。请注意,在大多数情况下,MFG ID将与Bluetooth Sig分配的号码文档相关联。

altbeacon-spec-exploded-view

例子

用于iBeacons的相同示例适用于AltBeacons,具有以下修改:

  1. 具有不同制造商ID的能力。
  2. 具有不同信标码的能力。
  3. 最后保留数据的一个字节,用于保存特定的制造商信息。

使用AltBeacon,可以使用特定于应用程序的UUID而不是特定于公司的UUID,从而可以更改公司ID。虽然目前没有任何东西正在利用这一点,但我可以想象信标广播UUID用于信标服务,比如温度服务,然后提供制造公司的信息和温度,这样提供任何人的温度值。步行可以查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "mbed.h"
#include "AltBeaconService.h"
...
BLEDevice ble;
uint8_t beaconID[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, // 16B of UUID + 4B subdivided as needed.
0x10,0x11,0x12,0x13,0x14,0x15,0x00,0x01,0x00,0x02 };
uint16_t manufacturerID = 0x5900; //Nordic SIG ID
int8_t rssi = -122;
...
int main(void){
...
AltBeaconService altbeacon(ble, manufacturerID, beaconID, rssi); // Add AltBeacon service to BLE object
...
while(1){
ble.waitForEvent();
}
}

思考

AltBeacons有很大的可能性。它们充分利用了它们所拥有的空间,或多或少地向后兼容iBeacons,并且是开源的。这说它是一个非常新的规范,几乎没有人使用它,并且它与iBeacons的市场渗透作斗争是一场艰苦的战斗。我认为,越来越多的人会使用AltBeacons,因为他们可以携带更多的数据并拥有更广泛的用例 - 这是开放式蛋糕上的一个樱桃。您可以在此处找到mbed AltBeacon示例代码。

Eddystone

Eddystone前身为URIBeacon(发音为YUR-ee-BEE-kun)

Eddystone是由Google开发的开放式信标格式,其设计考虑了透明度和稳健性。Android和iOS设备都可以检测到Eddystone。Eddystone格式建立在现有部署中与行业合作伙伴合作的经验教训的基础上,以及更广泛的灯塔社区。帧格式中可以包含几种不同类型的有效载荷,包括:

  • Eddystone-UID:一个唯一的静态ID,带有一个10字节的命名空间组件和一个6字节的实例组件。
  • Eddystone-URL:经过解析和解压缩后,可由客户端直接使用的压缩URL。
  • Eddystone-TLM:信标状态数据,可用于信标队维护,并为Google Proximity Beacon API的诊断端点提供支持。-TLM应与识别帧交错,例如Eddystone-UID或Eddystone-EID(加密的eTLM版本保留安全性)。
  • Eddystone-EID:时变信标帧,可通过链接解析器(例如Proximity Beacon API)解析为稳定标识符。

此外,Eddystone还包括配置服务和品牌材料。为确保您的部署完全支持Google信标平台,您应该使用Eddystone-UID或-EID设置信标,并可选择添加-URL和-TLM。