阡陌 发布的文章

阡陌

MQTT 学习笔记

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输) 是 IBM 开发的一个即时通信协议。它是一种使用发布/订阅(publish/subscribe)模型的轻量级二进制通信协议,这使得它很适合 M2M(machine to machine)的消息传递,比如低功耗传感器或移动通信设备。 参与角色 由于是基于 publish/subscribe 模型的,所以必定存在消息的发布者和消息的订阅者两个角色,此外还应具有消息代理者(message broker),也就是服务器这一角色。 动作 发布者需要将消息推送至服务器,订阅者要有订阅的动作,然后服务器需要将消息推送给订阅者。 话题 消息以话题为归集(分类),话题将发布者与订阅者的兴趣点牵连了起来。话题就是一个 UTF-8 的字符串,可以使用斜杠(/)表示多个层级关系。话题不需要创建,直接使用就可以。 QoS QoS(Quality of Service,服务质量) 共有 3 级: 0: The broker/client will deliver the message once, with no confirmation. 1: The broker/client will deliver the message at least once, with confirmation required. 2: The broker/client will deliver the message exactly once by using a four step handshake. 通配符 + 与 # 以下带通配符的字符串可以匹配主题 a/b/c/d +/b/c/d a/+/c/d a/+/+/d +/+/+/+ # a/# a/b/# a/b/c/# +/b/c/# 只允许使用通配符订阅话题,不允许使用通配符发布消息。 消息类型 MQTT 拥有 14 种不同的消息类型: CONNECT:客户端连接到 MQTT 代理 CONNACK:连接确认 PUBLISH:新发布消息 PUBACK:新发布消息确认,是 QoS 1 给 PUBLISH 消息的回复 PUBREC:QoS 2 消息流的第一部分,表示消息发布已记录 PUBREL:QoS 2 消息流的第二部分,表示消息发布已释放 PUBCOMP:QoS 2 消息流的第三部分,表示消息发布完成 SUBSCRIBE:客户端订阅某个主题 SUBACK:对于 SUBSCRIBE 消息的确认 UNSUBSCRIBE:客户端终止订阅的消息 UNSUBACK:对于 UNSUBSCRIBE 消息的确认 PINGREQ:心跳 PINGRESP:确认心跳 DISCONNECT:客户端终止连接前优雅地通知 MQTT 代理 相关软件 当前流行的开源代理服务器(MQTT Broker)的实现有:mosquitto, HiveMQ, Apache ActiveMQ, RabbitMQ, mosca 等,MQTT 客户端也有不同操作系统和编程语言下的实现,流行的客户端库(MQTT ClientLibraries)有:Eclipse Paho(支持 C,C++, Java, JavaScript, Python, Go, C#), M2MQTT(C#), Fusesource MQTTClient(Java), MQTT.js(javascript), libmosquitto(c/c++)等等,通过以上库而开发出的 MQTT 客户端应用程序有:mosquitto_pub/mosquitto_sub(可运行于 Linux, Windows, MacOSX 操作系统),HiveMQWebsocket Client(Web browser),MyMQTT(Android),MQTTLens(Google Chrome)等等。 Mosquitto Eclipse Mosquitto™ 是一款实现了 MQTT 3.1 和 3.1.1 版本的开源消息代理软件(C 语言)。 官方网站:https://mosquitto.org/ 测试: wget http://mosquitto.org/files/source/mosquitto-1.4.13.tar.gz tar -zxvf mosquitto-1.4.13.tar.gz cd mosquitto-1.4.13 make(编译过程需要以下三个库:libssl-dev、libc-ares-dev、uuid-dev) sudo make install 编译生成的文件主要是: /usr/local/sbin/mosquitto 代理服务器主程序 /usr/local/bin/mosquitto_pub 用于发布消息的命令行客户端测试程序 /usr/local/bin/mosquitto_sub 用于订阅消息的命令行客户端测试程序 编译时可能出现的错误及解决办法: (1)./mosquitto_internal.h:27:27: fatal error: openssl/ssl.h: 没有那个文件或目录 sudo apt-get install libssl-dev libssl-dev 是将 OpenSSL 用于开发时使用的库文件、头文件等(Debian、Ubuntu) (2)./mosquitto_internal.h:40:20: fatal error: ares.h: 没有那个文件或目录 安装 libc-ares-dev sudo apt-get install libc-ares-dev libc-ares-dev 是 c-ares 的开发库,用于异步域名解析。 (3)read_handle_server.c:31:25: fatal error: uuid/uuid.h: 没有那个文件或目录 sudo apt-get install uuid-dev 它是用于生成 UUID(xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx (8-4-4-4-12))的库 测试: 终端 1: mosquitto -v 1499668521: mosquitto version 1.4.13 (build date 2017-07-10 11:52:05+0800) starting 1499668521: Using default config. 1499668521: Opening ipv4 listen socket on port 1883. 1499668521: Opening ipv6 listen socket on port 1883. 1499668525: New connection from ::1 on port 1883. 1499668525: New client connected from ::1 as mosqsub|1739-debian (c1, k60). 1499668525: Sending CONNACK to mosqsub|1739-debian (0, 0) 1499668525: Received SUBSCRIBE from mosqsub|1739-debian 1499668525: sensors/devicename/temperature (QoS 0) 1499668525: mosqsub|1739-debian 0 sensors/devicename/temperature 1499668525: Sending SUBACK to mosqsub|1739-debian 1499668529: New connection from ::1 on port 1883. 1499668529: New client connected from ::1 as mosqpub|1740-debian (c1, k60). 1499668529: Sending CONNACK to mosqpub|1740-debian (0, 0) 1499668529: Received PUBLISH from mosqpub|1740-debian (d0, q0, r0, m0, 'sensors/devicename/temperature', ... (5 bytes)) 1499668529: Sending PUBLISH to mosqsub|1739-debian (d0, q0, r0, m0, 'sensors/devicename/temperature', ... (5 bytes)) 1499668529: Received DISCONNECT from mosqpub|1740-debian 1499668529: Client mosqpub|1740-debian disconnected. 终端 2: mosquitto_sub -d -t sensors/devicename/temperature Client mosqsub|1739-debian sending CONNECT Client mosqsub|1739-debian received CONNACK Client mosqsub|1739-debian sending SUBSCRIBE (Mid: 1, Topic: sensors/devicename/temperature, QoS: 0) Client mosqsub|1739-debian received SUBACK Subscribed (mid: 1): 0 Client mosqsub|1739-debian received PUBLISH (d0, q0, r0, m0, 'sensors/devicename/temperature', ... (5 bytes)) 31deg 终端 3: mosquitto_pub -d -t sensors/devicename/temperature -m 31deg Client mosqpub|1740-debian sending CONNECT Client mosqpub|1740-debian received CONNACK Client mosqpub|1740-debian sending PUBLISH (d0, q0, r0, m1, 'sensors/devicename/temperature', ... (5 bytes)) Client mosqpub|1740-debian sending DISCONNECT 运行时可能遇到的问题及解决办法: (1)mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory 解决办法: sudo ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1 Eclipse Paho The Eclipse Paho project provides open-source client implementations of MQTT and MQTT-SN messaging protocols aimed at new, existing, and emerging applications for the Internet of Things (IoT). 项目包含了多种语言的 MQTT 客户端库。 EMQ EMQ 杭州小莉科技 EMQ 2.0 完整支持 MQTT V3.1/V3.1.1 版本协议规范,并扩展支持 WebSocket、Stomp、CoAP、MQTT-SN 或私有 TCP 协议。EMQ 2.0 消息服务器支持单节点 100 万连接与多节点分布式集群。 VerneMQ VerneMQ is a high-performance, distributed MQTT broker. It scales horizontally and vertically on commodity hardware to support a high number of concurrent publishers and consumers while maintaining low latency and fault tolerance. VerneMQ is the reliable message hub for your IoT platform or smart products.VerneMQ is based on Erlang OTP, the best technology currently available to build highly scalable messaging systems. This enables VerneMQ to scale horizontally and vertically by fully utilizing multicore architectures....

交叉编译器 gnueabi、none-eabi、arm-eabi、gnueabihf、gnueabi 的区别

命名规则 交叉编译工具链的命名规则为:arch-vendor-os-(gnu)eabi arch - 体系架构,如 ARM,MIPS vendor - 工具链提供商 os - 目标操作系统 eabi - 嵌入式应用二进制接口(Embedded Application Binary Interface) 根据对操作系统的支持与否,ARM GCC 可分为支持和不支持操作系统,如: arm-none-eabi:这个是没有操作系统的,自然不可能支持那些跟操作系统关系密切的函数,比如 fork。它使用的是 newlib 这个专用于嵌入式系统的 C 库。 arm-none-linux-eabi:用于 Linux 的,使用 Glibc 命名实例 1. arm-none-eabi-gcc (ARM architecture,no vendor,not target an operating system,complies with the ARM EABI) 用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,不适用编译 Linux 应用 Application),一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数,比如 fork,他使用的是 newlib 这个专用于嵌入式系统的 C 库。 2. arm-none-linux-gnueabi-gcc (ARM architecture, no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI) 主要用于基于 ARM 架构的 Linux 系统,可用于编译 ARM 架构的 u-boot、Linux 内核、Linux 应用等。arm-none-linux-gnueabi 基于GCC,使用 Glibc 库,经过 Codesourcery 公司优化过推出的编译器。arm-none-linux-gnueabi-xxx 交叉编译工具的浮点运算非常优秀。一般 ARM9、ARM11、Cortex-A 内核,带有 Linux 操作系统的会用到。 3. arm-eabi-gcc Android ARM 编译器。 4. armcc ARM 公司推出的编译工具,功能和 arm-none-eabi 类似,可以编译裸机程序(u-boot、kernel),但是不能编译 Linux 应用程序。armcc 一般和 ARM 开发工具一起,Keil MDK、ADS、RVDS 和 DS-5 中的编译器都是 armcc,所以 armcc 编译器都是收费的。 5. arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc arm-none-uclinuxeabi 用于 uCLinux,使用 Glibc。 arm-none-symbianelf 用于 Symbian,没用过,不知道 C 库是什么 。 ABI 和 EABI ABI:二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。 EABI:嵌入式 ABI。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的编译器生成的汇编语言的接口。 两者主要区别是,ABI 是计算机上的,EABI 是嵌入式平台上(如 ARM,MIPS 等)。 arm-linux-gnueabi-gcc 与 arm-linux-gnueabihf-gcc 两个交叉编译器分别适用于 armel 和 armhf 两个不同的架构,armel 和 armhf 这两种架构在对待浮点运算采取了不同的策略(有 FPU 的 ARM 才能支持这两种浮点运算策略)。 其实这两个交叉编译器只不过是 gcc 的选项 -mfloat-abi 的默认值不同。gcc 的选项 -mfloat-abi 有三种值 soft、softfp、hard(其中后两者都要求 ARM 里有 FPU 浮点运算单元,soft 与后两者是兼容的,但 softfp 和 hard 两种模式互不兼容): soft: 不用 FPU 进行浮点计算,即使有 FPU 浮点运算单元也不用,而是使用软件模式。 softfp: armel 架构(对应的编译器为 arm-linux-gnueabi-gcc)采用的默认值,用 FPU 计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。 hard: armhf 架构(对应的编译器 arm-linux-gnueabihf-gcc)采用的默认值,用 FPU 计算,传参数也用 FPU 中的浮点寄存器传,省去了转换,性能最好,但是中断负荷高。 把以下测试使用的 C 文件内容保存成 mfloat.c: #include <stdio.h> int main(void) { double a, b, c; a = 23.543; b = 323.234; c = b / a; printf("the 13/2 = %f\n", c); printf("hello world !\n"); return 0; } 1、使用 arm-linux-gnueabihf-gcc 编译,使用 -v 选项以获取更详细的信息: # arm-linux-gnueabihf-gcc mfloat.c -v ... COLLECT_GCC_OPTIONS='-v' '-mfloat-abi=hard' '-mtls-dialect=gnu' '-mthumb' '-mlibarch=armv7-a+fp' '-march=armv7-a+fp' '-dumpdir' 'a.' 可看出使用了 hard 硬件浮点模式。 2、使用 arm-linux-gnueabi-gcc 编译: # arm-linux-gnueabi-gcc -v mfloat.c -mfloat-abi=softfp ... COLLECT_GCC_OPTIONS='-v' '-mfloat-abi=softfp' '-mtls-dialect=gnu' '-marm' '-mlibarch=armv5t' '-march=armv5t' '-dumpdir' 'a.' 可看出使用 softfp 模式。 我测试用的 GCC 版本是 11.4.0,arm-linux-gnueabihf-gcc 只支持 -mfloat-abi=hard,而 arm-linux-gnueabi-gcc 则支持 -mfloat-abi=soft 与 -mfloat-abi=softfp 两种模...

ARM 交叉编译工具链

交叉编译 交叉编译通俗地讲就是在一种平台上编译出能运行在体系结构不同的另一种平台上的程序,比如在 PC 平台(X86 CPU)上编译出能运行在以 ARM 为内核的 CPU 平台上的程序,编译得到的程序在 X86 CPU 平台上是不能运行的,必须放到 ARM CPU 平台上才能运行,虽然两个平台用的都是 Linux 系统。 交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由 binutils、gcc 和 glibc 三个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc,例如 uClibc、dietlibc 和 newlib。建立交叉编译工具链是一个相当复杂的过程,如果不想自己经历复杂繁琐的编译过程,网上有一些编译好的可用的交叉编译工具链可以下载,但就以 学习为目的来说读者有必要学习自己制作一个交叉编译工具链(目前来看,对于初学者没有太大必要自己交叉编译一个工具链)。 分类和说明 从授权上,分为免费授权版和付费授权版。 免费版目前有三大主流工具商提供,第一是 GNU(提供源码,自行编译制作),第二是 Codesourcery,第三是 Linora。 arm-none-linux-gnueabi-gcc:是 Codesourcery 公司(目前已经被 Mentor 收购)基于 GCC 推出的的 ARM 交叉编译工具。可用于交叉编译 ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem 和 App 应用程序。 arm-linux-gnueabihf-gcc:是由 Linaro 公司基于 GCC 推出的的 ARM 交叉编译工具。可用于交叉编译 ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem 和 App 应用程序。 aarch64-linux-gnu-gcc:是由 Linaro 公司基于 GCC 推出的的 ARM 交叉编译工具。可用于交叉编译 ARMv8 64 位目标中的裸机程序、u-boot、Linux kernel、filesystem 和 App 应用程序。 arm-none-elf-gcc:是 Codesourcery 公司(目前已经被 Mentor 收购)基于 GCC 推出的的 ARM 交叉编译工具。可用于交叉编译ARM MCU(32位)芯片,如 ARM7、ARM9、Cortex-M/R 芯片程序。 arm-none-eabi-gcc:是 GNU 推出的的ARM交叉编译工具。可用于交叉编译 ARM MCU(32位)芯片,如 ARM7、ARM9、Cortex-M/R 芯片程序。 收费版有 ARM 原厂提供的 armcc、IAR 提供的编译器等等,因为这些价格都比较昂贵,不适合学习用户使用,所以不做讲...

Qt 5.9 静态编译笔记

静态编译 使用 Windows 系统 1、安装环境要求: Supported compiler (Visual Studio 2012 or later, MinGW-builds gcc 4.9 or later) Perl version 5.12 or later http://www.activestate.com/activeperl/ Python version 2.7 or later http://www.activestate.com/activepython/ Ruby version 1.9.3 or later http://rubyinstaller.org/ 2、确保环境变量 Path 中已经加入 Python 、Per、Ruby、D:\Qt\Qt5.9.0\Tools\mingw530_32\bin 的路径。 配置 configure -opensource -confirm-license -static -release \ -platform win32-g++ \ -prefix "D:\Qt\qt_5.9.0_mingw32_static_kits" \ -no-opengl \ -no-openssl \ -nomake tools \ -nomake examples \ -nomake tests \ -qt-freetype \ -qt-libpng \ -qt-libjpeg \ -qt-sqlite \ -qt-pcre \ -qt-zlib \ -skip qt3d \ -skip qtactiveqt \ -skip qtandroidextras \ -skip qtcanvas3d \ -skip qtcharts \ -skip qtconnectivity \ -skip qtdatavis3d \ -skip qtdeclarative \ -skip qtdoc \ -skip qtgamepad \ -skip qtgraphicaleffects \ -skip qtimageformats \ -skip qtlocation \ -skip qtmacextras \ -skip qtmultimedia \ -skip qtnetworkauth \ -skip qtpurchasing \ -skip qtquickcontrols \ -skip qtquickcontrols2 \ -skip qtremoteobjects \ -skip qtscript \ -skip qtscxml \ -skip qtsensors \ -skip qtspeech \ -skip qtsvg \ -skip qttools \ -skip qttranslations \ -skip qtvirtualkeyboard \ -skip qtwebchannel \ -skip qtwebengine \ -skip qtwebsockets \ -skip qtwebview \ -skip qtwinextras \ -skip qtx11extras \ -skip qtxmlpatterns \ -no-feature-dbus -skip 选项可以排除 Qt 标准库(standard repository)之外的子模组(Git Submodule),子模组名就是源码目录中对应的目录名。有些子模组会包含多个模块(Qt modules),比如说 qtconnectivity 子模组就包含了 Qt NFC 模块和 Qt Bluetooth 模块。 -feature-<feature> and -no-feature-<feature> 选项用于包含与排除 Qt 基础库(qtbase 库)的特征。qtbase/src/corelib/global/qfeatures.txt 文件中列出了所有的特征。 -qt-<library>、-system-、-no-<library> 选项用于选择使用源码中自带的还是系统提供的第三方库(third-party libraries),或者都不使用。这些第三方库位于 qtbase/src/3rdparty 编译 mingw32-make -j 4 安装 mingw32-make install 修改连接选项 D:\Qt\qt_5.9.0_mingw32_static_kits\mkspecs\win32-g++\qmake.conf 加入 QMAKE_LFLAGS = -static 或 修改 QMAKE_LFLAGS_RELEASE = -Wl,-s 为 QMAKE_LFLAGS_RELEASE = -Wl,-s -static 或 在工程文件中加入 QMAKE_LFLAGS = -static 通过实验来看应该不用修改 QMAKE_LFLAGS_DLL 的值为 -static,暂时还不了解 QMAKE_LFLAGS_DLL 的用途(估计是指链接生成 dll 文件时用的)。 有些时候还需要配置 qt.conf 如果编译好的 Qt 库的存放位置发生了变化(与 -prefix 参数所指定的不同),则 Qt Versions 提示“Qt没有被正确安装,请运行make install”,解决方法使在 qmake.exe 目录创建 qt.conf,内容为: [paths] prefix = D:/Qt/qt_5.9.0_mingw32_static_kits #当前的实际路径 在 Qt Creator 中配置 注意事项 从 Qt 5.7 开始,已经不支持 Windows XP 平台了,运行程序会提示找不到 dwmapi.dll 。如果编译后的程序需要在 XP 系统上使用,需要使用 Qt 5.6 编...

BusyBox inittab 文件介绍

除了基本的命令之外,BusyBox 还支持 init 功能,如同其它的 init 一样,BusyBox 的 init 也是完成系统的初始化工作,关机前的工作等等,我们知道在 Linux 的内核被载入之后,机器就把控制权转交给内核,内核启之后做了一些工作,然后找到根文件系统里面的 init 程序,并执行它。init 进程会依次进行以下工作: 为 init 设置信号处理过程; 初始化控制台; 剖析 /etc/inittab 文件; 执行系统初始化命令行,缺省情况下会使用 /etc/init.d/rcS; 执行所有导致 init 暂停的 inittab 命令(动作类型:wait); 执行所有仅执行一次的 inittab命令(动作类型:once); 一旦完成以上工作,init 进程便会循环执行以下进程: 执行所有终止时必须重新启动的 inittab 命令(动作类型:respawn) 执行所有终止时必须重新启动但启动前必须询问用户的 inittab 命令(动作类型:askfirst) 初始化控制台之后,BusyBox 会检查 /etc/inittab 文件是否存在,如果此文件不存在,BusyBox 会使用缺省的 inittab 配置,它主要为系统重引导,系统挂起以及 init 重启动设置缺省的动作,此外它还会为四个虚拟控制台(tty1 到 tty4)设置启动 shell 的动作。如果未建立这些设备文件,BusyBox 会报错。 Busybox 的 init 进程在初始化的时候会查看是否有 /etc/inittab 文件,如果有则解析它。 inittab 文件中每一行的格式如下所示: id:runlevel_ignored:action:command id:对 BusyBox 而言,id 用来指定启动进程的控制终端。如果省略,则使用与 init 进程一样的控制终端。 runlevel_ignored:对于 Busybox init 程序,这个字段没有意义,可以省略。 action:表示 init 程序如何控制这个子进程: action 说明 sysinit 为 init 提供初始化命令脚本的路径 wait 告诉 init 必须等到相应的进程完成之后才能继续执行 once 仅执行相应的进程一次,而且不会等待它执行完成 respawn 每当 init 进程监测到该进程终止时,重新启动该它 askfirst 与 respawn 类似,不过 init 进程先输出 “Please press Enter to actvie this console”,等用户输入回车键之后才启动子进程 shutdown 当系统关机(halt/reboot)时,执行相应的进程 restart 当 init 重新启动时(restart init when a QUIT is received),执行相应的进程,通常此处所执行的进程就是 init 本身 ctrlaltdel 当按下 Ctrl + Alt + Delete 组合键时,执行相应的进程 process:要执行的程序,它可以是可执行程序,也可以是脚本 实例: # Note: BusyBox init works just fine without an inittab. If no inittab is # found, it has the following default behavior: # ::sysinit:/etc/init.d/rcS # ::askfirst:/bin/sh # ::ctrlaltdel:/sbin/reboot # ::shutdown:/sbin/swapoff -a # ::shutdown:/bin/umount -a -r # ::restart:/sbin/init # tty2::askfirst:/bin/sh # tty3::askfirst:/bin/sh # tty4::askfirst:/bin/sh # # Boot-time system configuration/initialization script. # This is run first except when booting in single-user mode. # ::sysinit:/etc/init.d/rcS # /bin/sh invocations on selected ttys # # Note below that we prefix the shell commands with a "-" to indicate to the # shell that it is supposed to be a login shell. Normally this is handled by # login, but since we are bypassing login in this case, BusyBox lets you do # this yourself... # # Start an "askfirst" shell on the console (whatever that may be) ::askfirst:-/bin/sh # Start an "askfirst" shell on /dev/tty2-4 tty2::askfirst:-/bin/sh tty3::askfirst:-/bin/sh tty4::askfirst:-/bin/sh # /sbin/getty invocations for selected ttys tty4::respawn:/sbin/getty 38400 tty5 tty5::respawn:/sbin/getty 38400 tty6 # Example of how to put a getty on a serial line (for a terminal) #::respawn:/sbin/getty -L ttyS0 9600 vt100 #::respawn:/sbin/getty -L ttyS1 9600 vt100 # # Example how to put a getty on a modem line. #::respawn:/sbin/getty 57600 ttyS2 # Stuff to do when restarting the init process ::restart:/sbin/init # Stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -...

调制指数

调制指数(modulation index,modulation depth) 表示调制变量在载波未经调制时的值的附近的变化程度,在不同的调制类型中有不同的定义。 振幅调制指数(amplitude modulation index) $h=\dfrac{M}{A}=\dfrac{U_{max}-U_{min}}{U_{max}+U_{min}}$ h:调幅指数 M:调制信号幅度(峰值) A:载波信号幅度 $U_{max}$:调幅波包络的最大值 $U_{min}$ :调幅波包络的最小值 h 表明载波振幅受调制控制的程度,一般要求 0 ≤ h ≤ 1,以便调幅波的包络能正确地表现出调制信号的变化。h > 1 的情况称为过调制。 频率调制指数(frequency modulation index) $h=\dfrac{\Delta f}{f_m}$ $\Delta f$ :最大载波频率偏移 $f_m$ :调制信号的最高频率成分 NFM 小于 0.5,WFM 大于 0.5。 相位调制指数(phase modulation index) $h=\Delta \theta$ △θ:信号调制过程中出现的最大相位差 在无线电传输中,频率调制 FM 的优点是它具有较大的信噪比,因此比等功率振幅调制(AM)信号能更好地抑制射频干扰。频率调制和相位调制是角调制的两种互补的主要方法。相位调制常作为实现调频的中间环节。ASK 属于线性变换,PSK 和 FSK 属于非线性变换,非线性变换有更高的抗干扰能...

HTTP 协议知识点

目前 HTTP 协议使用的最多的是 1.1 版本。 HTTP 1.0 与 HTTP 1.1 的区别 1、HTTP 1.1 支持长连接和请求流水线 1.0 只能使用短连接,每次请求完成后断开连接,新的请求需要重建新的连接。而 1.1 则支持长连接(持久连接,Persistent Connection),所以可以在一个连接中传送多个请求和响应,并且可以同时进行。 2、HTTP 1.1 增加 Host 字段 由于 HTTP 1.0 不支持 Host 请求头字段,浏览器无法使用主机头名来明确表示要访问服务器上的哪个 WEB 站点,这样就无法使用 WEB 服务器在同一个 IP 地址和端口号上配置多个虚拟 WEB 站点。1.1 则解决了这个问题。 3、HTTP 1.1 增加了一些新的状态代码,如 100(Continue)、101(Switching Protocols)等 4、HTTP 1.1 新增了 RANGE:bytes,用于断点续传。 5、HTTP 1.1 还提供了与身份认证、状态管理和 Cache 缓存等机制相关的请求头和响应头。 请求 标准协议支持六种请求方法:GET、HEAD、PUT、DELETE、POST、OPTIONS,与 CRUD 的对应关系是:PUT-->CREATE,GET-->READ,POST-->UPDATE,DELETE-->DELETE。 GET 可以直接写 URL 地址处传递数据,因为它没有消息体,需要传输的数据参数只能通过 URL 地址传递。 POST 可以插入消息体,所以客服端向服务端传递数据时可以通过这个消息体传递。 状态消息 当浏览器从 web 服务器请求服务时,服务器会返回状态消息,主要有几类: 1xx(信息)、2xx(成功)、3xx(重定向)、4xx(客户端错误)、5xx(服务器错误)。 HTTP 请求消息的结构 包括请求行、消息头、空行、消息体。 请求行只能通过一行发送,如:GET /index.html HTTP/1.1 消息头一般包括浏览器信息、用户认证等附加信息 空行用于在有消息体时与消息头分开; 消息体中装有客户端向服务端传输的数据,GET 没有消息体,POST 有消息体。 HTTP 响应消息的结构 包括状态行、消息头、空行、消息体。 状态行包含客服端请求的处理结...

实现复位后不清零单片机内部 SRAM 的方法

通常情况下单片机复位后会自动清零 SRAM 中的一些变量,本文以 ARM 单片机为例来说一说如何实现不清零。 在默认情况下,定义一个未初始化的数组: uint8_t hardfault_info[256]; 它会被分配到ZI段中去。什么是ZI段? ZI(.bss) 即 zero-initialized ,它是在代码中未作初始化的需要在运行时被初始化为零的变量的集合。类似地还有 XO(execute-only )、RO(read-only,.text)只读的常量、RW(read-write,.data)在编译时被初始化了的可读写变...

9G25 使用 Buildroot 创建 rootfs

tar -jxvf buildroot-2017.02.tar.bz2 make at91sam9g20dfc_defconfig make menuconfig Target options ---> Enable VFP extension support Build options ---> Mirrors and Download locations ---> 修改几处源为国内的源,以加快下载速度 │ │ () Primary download site │ │ │ │ (http://sources.buildroot.net) Backup download site │ │ │ │ (http://mirrors.ustc.edu.cn/kernel.org) Kernel.org mirror │ │ │ │ (http://mirrors.ustc.edu.cn/gnu) GNU Software mirror │ │ │ │ (http://rocks.moonscript.org) LuaRocks mirror │ │ │ │ (http://mirrors.ustc.edu.cn/CPAN) CPAN mirror (Perl packages) 工具链配置 Toolchain ---> Toolchain type (Buildroot toolchain) (buildroot) custom toolchain vendor name C library (glibc) Kernel Headers (Linux 3.2.x kernel headers) 版本至少与实际使用的内核的版本一样老才可以,否则启动的时候会提示: FATAL: kernel too old Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00 查看 busybox 支持的 Linux 版本:file busybox | grep Linux glibc version (2.23) Binutils Version (binutils 2.26.1) GCC compiler Version (gcc 5.x) Enable C++ support 注:在使用 Buildroot 自己编译的 toolchian 之前我使用过 gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabi 作为外部 Toolchain,但是遇到了问题,编译的 rootfs 在启动的时候报错: Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004 网上说问题可能是 Kernel 与 rootfs 在编译的时候没有同时开启 EABI,但我检查(readelf -hA vmlinux busybox)的结果是都开启了。会不会是浮点数的问题?配置的都是 soft float,也没问题。最后发现是 rootfs 指令集用的是 ARMv7-a,而 CPU 是 AT91SAM9G25(ARM926EJ-S(ARM9)),支持的指令集是 ARMv5t。单 buildroot 中没找到向外部 GCC 传递 CFLAGS(-march=armv5t)的配置,于是放弃使用外部工具链。 System configuration ---> /dev management (Dynamic using devtmpfs + eudev) 不选 Run a getty (login prompt) after boot (具体行为后续再 inittab 中改) (eth0) Network interface to configure through DHCP Kernel ---> 不选择编译 Kernel Target packages ---> Show packages that are also provided by busybox Shell and utilities ---> bash Debugging, profiling and benchmark ---> gdb Compressors and decompressors ---> bzip2 gzip Networking applications ---> pppd Bootloaders ---> 不选 如果需要额外配置 busybox,使用:make busybox-menuconfig ,这里使用默认配置 编译系统: make -j4 会在 dl 文件夹放置下载到的源码,在 output/image 中生成 rootfs.tar mkdir rootfs sudo tar -xvf rootfs.tar -C rootfs 添加 10_usbkey.rules 到 /etc/udev/rules.d /etc/profile export LD_LIBRARY_PATH=/qtlib /etc/inittab ttyS0::respawn:/bin/login -f root /etc/init.d/S10udev 修改 udevadm trigger --type=devices --action=add 为 udevadm trigger --type=devices 创建 /qtlib 把 QT 的部分动态库库放进去。 将 linux-ppp-scripts_v1.2 的文件放到相应的位置 sudo ./mkubifsimage rootfs/ ubifs.img 发现的问题: 在启动初始化时,执行 init.d/S10udev 中的 udevadm trigger --type=devices --action=add 时,会出现错误信息: UBI error: ubi_open_volume: cannot open device 0, volume 0, error -16 (估计是操作 /dev/mtd8 时出现的错误,因为 cat /dev/mtd8 时会出现同样的错误信息) cat /proc/mtd dev: size erasesize name mtd0: 00040000 00020000 "bootstrap" mtd1: 00080000 00020000 "uboot" mtd2: 00040000 00020000 "env" mtd3: 00040000 00020000 "env_redundant" mtd4: 00040000 00020000 "spare" mtd5: 00080000 00020000 "dtb" mtd6: 00600000 00020000 "kernel" mtd7: 0f800000 00020000 "rootfs" mtd8: 0eb68000 0001f000 "rootfs" 为什么会有两个 rootfs 呢?mtd8 是怎么来的,留待以后研究。 暂时的解决对策是: 去掉此行中的 --action=a...

把 qt 库加入 rootfs 并制作 UBIFS 镜像

解压 rootfs: sudo tar -zxvf rootfs.tar.gz -C rootfs 添加 10_usbkey.rules到 /etc/udev/rules.d(自动挂载,非必须) 编辑 /etc/profile,加入: export LD_LIBRARY_PATH=/qtlib 编辑 /etc/inittab,加入: ttyO0::respawn:/bin/login -f root 实现自动登陆(非必要) 创建 /qtlib 把 QT 的部分动态库库放进去。 制作镜像: sudo ./mkfs.ubifs -F -r rootfs -m 2048 -e 126976 -c 1866 -o ubifs.img ./ubinize -o ubi.img -m 2048 -p 128KiB -s 2048 -O 2048 ubinize-256M.cf...