当前位置:   article > 正文

基于ARM开发板搭建物联网服务器_armbian搭建物联网平台

armbian搭建物联网平台

一、项目需求

1.1设备需求

1.嵌入式开发板:	
		(1)可以接入网络:目的是为了MQTT的订阅端
		(2)能够运行最小Linux系统:为了移植MQTT、SQLite3、Boa应用
2.PC:
		(1)虚拟机安装Linux系统:本人使用的是Ubuntu 20.04版本 对版本没有要求
	    (2)MQTT测试工具
	    (3)HyperTerminal串口通讯工具
3.服务器
		本人使用的是阿里云服务器作为MQTT的broker
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.2知识需求

	1.对嵌入式开发板有一定了解,能够移植相关应用
	2.了解数据库的基本使用
	3.了解MQTT传输原理
	4.了解HTML+CSS+JavaScript+AJAX基本原理
	5.了解Boa+CGI作用
  • 1
  • 2
  • 3
  • 4
  • 5

1.3项目介绍

项目过程:
1.通过获取MQTT订阅服务器某一主题获取到消息如下:

{
	"Devaddr":1,
	"temp":23.56
}
  • 1
  • 2
  • 3
  • 4

2.嵌入式开发板通过mosquitto+JSON获取到JSON数据并将其解析出来
3.解析成功后写入SQLITE3数据库中
4.由BOA搭建的网页通过JS+AJAX+CGI调用C函数
5.数据库部分数据的打印到网页上
6.最终实现局域网下的物联网数据展示系统

二、开发环境搭建

2.1阿里云服务器配置

在这里插入图片描述

这里我使用的是FinalShell接入我的阿里云服务器
连接成功如图所示
  • 1
  • 2

在这里插入图片描述

apt-get install mosquitto
  • 1

安装mqtt服务器

在这里插入图片描述
安装完成之后
打开mosuitto服务并查看服务状态

service mosquitto start
service mosquitto status
  • 1
  • 2

我们测试mqtt服务器是否有效
打开MQTT.fx
找到设置-添加阿里云服务器IP 端口号1883 点击OK退出
在这里插入图片描述
点击connect 发现灯变绿了
(按顺序)
1.在subscribe填写主题test 点击subscribe
2.在publish前的空白处 填写主题test
3.在publish窗口输入发送内容 点击publish

在这里插入图片描述
在这里插入图片描述
订阅端成功收到数据 hello mqtt!
服务器配置完成!

2.2虚拟机交叉编译环境搭建

1.下载交叉编译环境文件
这里我用的最新的2014.05-29版本

2.为什么要使用交叉编译工具链
因为我们使用的电脑一般为x86的芯片架构,x86上编译程序不能在arm架构上运行,
需要交叉编译工具链才能够生成arm能够运行的程序。
x86:
在这里插入图片描述
arm:
在这里插入图片描述

3.交叉编译环境的搭建
在有交叉编译工具链的文件夹中

sudo tar -xvf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
  • 1

方便使用mv 修改文件夹名字
移动文件到 /usr/local/文件夹下

mv  arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu arm-2014.05.29
cp -r  arm-2014.05.29 /usr/local/arm-linux
  • 1
  • 2

修改路径

vi /etc/profile
  • 1

在最后一行添加

export PATH=$PATH:/usr/local/arm-2014.05.29/bin
  • 1

退出后

source /etc/profile
  • 1

然后再输入arm 双击 tab 就会出现如下图所示命令 表示为安装成功
在这里插入图片描述

2.3下载相关应用压缩文件

本文下载的主要有六个文件
1.mosquitto(mqtt订阅/发布工具)
2.libuuid(mosquitto依赖库)
3.openssl(mosquitto依赖库)
4.boa(能够在开发板运行网站)
5.sqlite3(数据库)
6.ntpclient(时间校正应用)

三、应用移植

准备好移植文件
本人移植准备的应用如下
在这里插入图片描述

3.1MQTT移植

创建一个新文件夹备用
这里我创建的是mqtt-arm
在这里插入图片描述

在/opt下创建一个mosquitto-arm文件夹备用(无视mosquitto-x86)
在这里插入图片描述

(1)libuuid移植

1.输入指令解压

tar -xvf libuuid-1.0.3.tar.gz 
cd libuuid-1.0.3/
  • 1
  • 2

2.输入指令

./configure --prefix=/opt/mosquitto-arm/ CC=arm-none-linux-gnueabi-gcc --host=arm-linux
make -j8
sudo make install
  • 1
  • 2
  • 3

完成第一步移植

(2)openssl移植

OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。
1.输入指令解压

tar -xvf openssl-1.1.0i.tar.gz 
cd openssl-1.1.0i/
  • 1
  • 2

2.输入指令

setarch i386 ./config no-asm shared --prefix=/opt/mosquitto-arm/openssl/
  • 1

解释:
setarch i386:声明生成的是 32 位 CPU,如果是 64 位 CPU 则去除该部分
no-asm: 是在交叉编译过程中不使用汇编代码代码加速编译过程,原因是它的汇编代码是对arm格式不支持的。
shared :生成动态连接库。
–prefix :指定make install后生成目录的路径,不修改此项则默认为OPENSSLDIR目录(/usr/local/ssl)。

3.打开Makefile文件修改

vi Makefile
CROSS_COMPILE=arm-linux-none-gnueabi- 
  • 1
  • 2

在这里插入图片描述
4.保存编译

make
  • 1

如果出现错误option “-m32”
则在Makefiile中的CFLAGS与LIB_LDFLAGS行去除 -m32选项即可

5.再次

sudo make 
sudo makeinstall
  • 1
  • 2

这里可能会出现
arm-none-linux-gnueabi-ranlib: command not found
指令未找到的错误
原因是我们在root下没有安装交叉编译工具链又使用的root环境导致的
所以我们需要在root环境下安装工具链或者将mosquitto-arm文件移植用户文件下
这样就不会导致权限引起的问题

6.最后在 /opt/mosquitto-arm/下生成openssl文件夹
在这里插入图片描述
第二步完成

(3)Mosquitto移植

输入指令解压

tar -xvf mosquitto-1.5.tar.gz 
cd mosquitto-1.5/
  • 1
  • 2

执行编译命令

make WITH_SRV=no CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CFLAGS="-I /opt/mosquitto-arm/openssl/include -I /opt/mosquitto-arm/libuuid-1.0.3/include -I /opt/mosquitto-arm/openssl/lib -I /opt/mosquit/to-arm/libuuid-1.0.3/lib" LDFLAGS="-L /opt/mosquitto-arm/openssl/lib -L /opt/mosquitto-arm/libuuid-1.0.3/lib -lssl -lcrypto -luuid"
  • 1

注意,如果这里安装 libuuid 和 openssl 的库的时候路径和我的不一致,要把-I 和-L 指定的库和头文件的路径修改成自己对应安装 uuid 和 openssl 库的路径,否则编译不过去。

make DESTDIR=/opt/mosquitto-arm/mosquitto-1.5 install
  • 1

最终生成mosquitto-1.5/

(4)文件移植

在这里插入图片描述
至此三个文件夹都完成了
接着就是文件的移植
现在进入我们一开始创建的mqtt-arm文件夹

cd ~/mqtt-arm
  • 1

主要库要复制进来
1.二进制文件以及配置文件

	cp /etc/mosquitto/mosquitto.conf.example .
	cp /opt/mosquitto-arm/mosquitto-1.5/usr/local/bin/* .
	cp /opt/mosquitto-arm/mosquitto-1.5/usr/local/sbin/mosquitto .
  • 1
  • 2
  • 3

这三部分别是移植配置文件,移植订阅、发布文件,移植作为服务器的文件
2./opt/mosquitto-arm 目录下复制 libuuid与openssl与mosquitto 到 mqtt-arm

	cp /opt/mosquitto-arm/* . -r
  • 1

最终文件夹如下图所示
在这里插入图片描述
打包文件

	cd ../
	tar -czf mqtt-arm.tar.gz mqtt-arm/
  • 1
  • 2

最终得到一个mqtt-arm.tar.gz压缩文件
在这里插入图片描述
我们把mqtt-arm.tar.gz移动到开发板中并解压出来
在这里插入图片描述

进入mqtt-arm把libuuid-1.0.3/ mosquitto-1.5/ openssl/三个文件下的 lib 下
的库全部放到开发板的/lib 下面

	cd mqtt-arm
	cp libuuid-1.0.3/lib/* /lib/ -r
	cp openssl/lib/* /lib/ -r 
	cp mosquitto-1.5/usr/local/lib/* /lib -r
  • 1
  • 2
  • 3
  • 4

再移动到二进制可运行文件到/bin目录下

	mv mosquitto mosquitto_* /bin
  • 1

验证:
在这里插入图片描述
输入mos 按键Tab自动补全发现有命令则移植成功

备注:如果想要再X86平台下运行直接安装mosquitto即可使用

	sudo apt-get install mosquitto
  • 1
(5)验证

在服务器开启mqtt服务器的前提下
我们使用虚拟机用于订阅mqtt消息,开发板用于发布消息作为自测试。
虚拟机:(149.xxx.xx.xx为本人服务器)

	mosquitto_sub -h 149.xxx.xx.xx -t “mqtt” -v
  • 1

开发板:

	mosquitto_pub -h 149.xxx.xx.xx -t “mqtt” -m "Hello Mqtt"
  • 1

测试成功!
在这里插入图片描述
如果没有服务器也可以以虚拟机作为服务器:相关网址点我

3.2BOA移植

BOA简介

其可执行代码只有大约60KB左右,Boa是一个单任务的HTTP服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求。Boa支持CGI。
Boa的设计目标是速度和安全。(CGI只是一个进程,用来提供接口),自动目录生成和自动文件枪支进行拼接。
Boa的主要设计目标是速度和安全性。安全性在“不能被恶意用户破坏”的意义上,不是“细粒度访问控制和加密通信”。

特点:可靠性和可移植性,Boa不是作为功能强大的服务器。
开发平台:GNU / Linux是目前的开发平台。

解压BOA文件 并运行配置文件

	tar -xvf tar -xvf boa-0.94.13.tar.gz 
	cd boa-0.94.13/src/
	./config
  • 1
  • 2
  • 3

1.我们修改一下 src下的 compat.h文件 120行 去掉foo后的##
在这里插入图片描述
2.还有boa.c 225行注释掉 if(setuid(0) != -1)…
在这里插入图片描述
3.修改一下编译器

	vi Makefile
  • 1

修改CC 与 CPP如下图所示
在这里插入图片描述

保存退出执行

	make
  • 1

生成了一个二进制boa文件
在这里插入图片描述
此时我们还要给他瘦身

	arm-none-linux-gnueabi-strip boa
  • 1

在这里插入图片描述
对比发现由原来的 244195byte->60588byte 为原来的四分之一左右
紧接着还需要配置一下 boa-0.94.13/boa.conf 配置文件

	vi ../boa.conf
  • 1

附件:配置详解
(1)Group的修改

修改 Group nogroup

为 Group 0

(2)user的修改

修改 User nobody

为 User 0

(3)ScriptAlias的修改

修改ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

为 ScriptAlias /cgi-bin/ /var/www/cgi-bin/

(5)DoucmentRoot的修改

DoucmentRoot /var/www

(6)ServerName的设置

修改#ServerName www.your.org.here

为 ServerName www.your.org.here

否则会出现错误“gethostbyname::No such file or directory”

(7)AccessLog修改

修改AccessLog /var/log/boa/access_log

为#AccessLog /var/log/boa/access_log

否则会出现错误提示:“unable to dup2 the error log: Bad file descriptor”

(8)以下配置和boa.conf的配置有关,都是在ARM根文件系统中创建

以下步骤在开发板上进行:

创建目录/etc/boa并且把boa 和 boa.conf拷贝到这个目录下

mkdir /etc/boa
  • 1

创建HTML文档的主目录/www

mkdir /www/cgi-bin
  • 1

CGI脚本所在录 /www/cgi-bin

以下步骤在ubuntu下进行:

将boa.conf拷贝到开发板根文件系统的/etc/boa下

将boa拷贝到开发板根文件系统的/bin下

将ubuntu下/etc/mime.types拷贝到开发板根文件系统的/etc下

	cp /etc/mime.types /etc
  • 1

将你的主页index.html拷贝到 /var/www 目录下

最后我们测试一下
首先在开发板上运行 ./boa
然后创建一个 index.html
文件内容如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My First HTML</title>
</head>

<body>
    <h1>Hello BOA!</h1>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

复制index.html 到开发板的 /www/文件下
然后打开浏览器 连接开发板的IP
最后成功如下所示
在这里插入图片描述
至此BOA移植成功!

3.3sqlite3数据库移植

本文讲述sqlite3数据库的嵌入式设备移植过程并结合小例子说明如何使用sqlite3的库进行编程。数据库在程序开发过程中起到举足轻重的作用,肩负着用户和系统设置数据的保存、查找、增删等操作,是程序运行的“粮食“。数据库的提供商有很多,诸如oracle、candence、mysql、sqlite等。但是sqlite3作为一款高可靠性且小巧玲珑的数据库工具,以及它的跨平台特性使得它十分适合在嵌入式领域使用。本文以ITop-4412系列嵌入式平台为目标,实现sqlite3的嵌入式移植,并使平台具有数据库开发的能力,方便保存用户信息及音视频配置信息。

解压sqlite3

	tar -xvf sqlite-autoconf-3340100.tar.gz 
	cd sqlite-autoconf-3340100/
	./configure CC=arm-none-linux-gnueabi-gcc --host=arm-linux --prefix=/home/sqlite3-arm/
	make
	make install
  • 1
  • 2
  • 3
  • 4
  • 5

生成文件如下
在这里插入图片描述
把bin下的sqlite3拷贝到开发板/bin下
把lib下所有库拷贝到开办板/lib下
至此开发板能够运行sqlite3命令即移植完成
在这里插入图片描述
移植成功!

3.4ntpclient移植

Ntpclient是时间服务提供程序。用于校准开发板系统时间,这样在使用sqlite3数据库导入时间时不会出错。

1.解压文件

	tar -xvf ntpclient_2015_365.tar.gz
	cd ntpclient_2015_365/
	vi Makefile +5
  • 1
  • 2
  • 3

2.修改第五行如图所示在这里插入图片描述
3.保存退出编译

	make
  • 1

4.生成ntpclient文件拷贝到开发板/bin目录下
5.使用指令校准时间

	ntpclient -s -d -c 1 -i 5 -h 223.113.120.195
	date
  • 1
  • 2

在这里插入图片描述

6.显示时间同步成功 移植成功!
至此6个应用库都移植完成!

四、MQTT+C的使用

4.1MQTT介绍

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
在这里插入图片描述
简单了解之后知道我们需要的是一个订阅端,一个发布端和一个服务器,由于服务器环境已经在第二章搭建完成,我们现在只需要知道服务器IP和端口号即可,这里我的服务器IP为149.xxx.xxx.xxx 端口号默认为1883。

4.2订阅与发布

由于我们服务器以及搭建完毕,Mosquittto(MQTT应用程序)也移植到了开发板上,我们在虚拟机上进行mosquitto指令测试,熟悉mqtt通信方式。
首先我们有了一个IP+端口号,除此之外我们还需要一个Topic主题才能进行消息的订阅以及发送。因此我们在虚拟机下的Linux系统中打开两个Terminal测试服务器以及mosquitto是否正常。
1.第一个窗口输入

	mosquitto_sub -h 149.xxx.xxx.xxx -t "mqtt" -v
  • 1

2.第二个窗口输入

	mosquitto_pub -h 149.xxx.xxx.xxx -t “mqtt” -m "Hello Mqtt"
  • 1

在这里插入图片描述
如图中左边为订阅端,右边为发布端
在订阅端中

-h IP //后面跟随的是IP地址
-t "topic" //topic部分填写的是发送的主题
-v 在收到的信息前打印主题"mqtt"
  • 1
  • 2
  • 3

在发布端中

-h IP //后面跟随的是IP地址
-t "topic" //topic部分填写的是发送的主题
-m "message" //message部分填写的是需要发送的信息
  • 1
  • 2
  • 3

明白简单的MQTT通信之后我们就可以引用msqtuitto.h库文件来写程序啦

4.3基于Linux+C的MQTT通信程序

mosquitto.h代码介绍

4.3.1Publish端代码分析
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include <mosquitto.h>



void mqtt_log_callback(struct mosquitto *mqtt, void *ubuf, int level, const char *str)
{
   
	printf("[log] level=%d str=%s ubuf=%s\n", level, str, (char *)ubuf);
}

void mqtt_connect_callback(struct mosquitto *mqtt, void *ubuf, int result)
{
   
	int i;
	printf("[connect] level=%d\n", result);

	if(!result){
   
		/* Subscribe to broker information topics on successful connect. */
		mosquitto_subscribe(mqtt, NULL, "mqtt", 2);
	}else{
   
		fprintf(stderr, "Connect failed\n");
	}
	
}

void mqtt_message_callback(struct mosquitto *mqtt, void *ubuf, const struct mosquitto_message *message)
{
   
	if(message->payloadlen){
   
		printf("%s %s\n", message->topic, (char *)message->payload);
	}else{
   
		printf("%s (null)\n", message->topic);
	}
	fflush(stdout);
}

void mqtt_disconnect_callback(struct mosquitto *mosq, void *obj, int result)
{
   
	printf("mqtt disconnect\n");
}

void mqtt_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
   
      printf("mqtt_publish_callback\n");
}


int main(int argc, char *argv[])
{
   
	int ret;
	int session = true;	
	char buf[1024];
	char name[] = "mqtt_pub";
	
	
	struct mosquitto *mosquitto_pub = NULL;

	mosquitto_lib_init();   

	mosquitto_pub = mosquitto_new(name, session, NULL);
	if(!mosquitto_pub){
   
		printf("mqtt new client error\n"
  • 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
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/282363
推荐阅读
相关标签
  

闽ICP备14008679号