一个arm开发板的研究笔记
一个arm开发板的研究笔记
最近更新:2020-03-03 17:46 周二
#开发主机系统信息 $ lsb_release -a No LSB modules are available. Distributor ID:Ubuntu Description:Ubuntu 18.04.4 LTS Release:18.04 Codename:bionic $ cat /proc/version Linux version 4.15.0-43-generic (buildd@lgw01-amd64-001) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018
文本编辑工具我用的不是vi而是nano 为了使左侧显示行号,下方提示行号 sudo nano /etc/nanorc 去掉 set linenumbers 前的注释 去掉 set constantshow 前的注释
#交叉编译环境 File: gcc-4.4.4-glibc-2.11.1-multilib-1.0_EasyARM-iMX283.tar.bz2 Size: 163749909 bytes Modified: 2020年2月24日, 23:18:03 MD5: 196AA7CA5A39492CD577D983C9DD1A10 SHA1: 9328B768F87D04504FE524E9DEC5A8409DD69261 CRC32: 7BB9B60F
#开发板内核 File: linux-2.6.35.3-102c9c0.tar.bz2 Size: 74888350 bytes Modified: 2020年2月24日, 23:20:01 MD5: E52CF122EEF2D38E29BBA9D836FD48FD SHA1: C61ADCA4D9A5540569FC0D69A0176BD04C58AE29 CRC32: D1EA1131
#sqlite3数据库工具 File: sqlite-autoconf-3310100.tar.gz Size: 2887243 bytes Modified: 2020年2月28日, 00:36:49 MD5: 2D0A553534C521504E3AC3AD3B90F125 SHA1: 0C30F5B22152A8166AA3BEBB0F4BC1F3E9CC508B CRC32: 25B51AEC
交叉编译环境搭建
安装后续编译可能用到的工具
$sudo apt-get update && apt-get upgrade #先更新下系统 $sudo apt-get install vim tftpd-hpa openssh-server nfs-kernel-server libncurses5-dev lib32z1-dev u-boot-tools autoconf automake libtool
解压编译工具
这里要用到刚下载的 gcc-4.4.4-glibc-2.11.1-multilib-1.0_EasyARM-iMX283.tar.bz2
mkdir /usr/local/arm cd /usr/local/arm tar -xvf ./gcc-4.4.4-glibc-2.11.1-multilib-1.0_EasyARM-iMX283.tar.bz2 #在执行这个命令前,先将这个文件拷贝到当前目录(/usr/local/arm)
设置环境变量
mkdir /xjzy cd /xjzy
新建 setenv.sh 文件
vim setenv.sh
将如下内容输入到 setenv.sh 中
#!/bin/sh echo "[=== Setup ARM Compile Environment ===]" export PATH="$PATH:/usr/local/arm/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin" export ARCH=arm export CROSS_COMPILE=arm-fsl-linux-gnueabi- service tftpd-hpa restart export PS1="\[\e[32;1m\][arm]\[\e[0m\]:\u@\h:\W "
修改 setenv.sh 权限
chmod 777 setenv.sh
以后需要进入交叉编译环境时,在终端中输入如下指令,当然,也可以复制上面export行的指令,粘贴到终端中
. /xjzy/setenv.sh #进入交叉编译环境
编译内核
编译内核应在交叉编译环境下,具体请看 交叉编译环境搭建 章节
将内核文件复制到/xjzy目录下,解压
cd /xjzy tar -xvf linux-2.6.35.3-102c9c0.tar.bz2 cd linux-2.6.35.3
//默认内核是已经配置好的了,若需要再次配置,可执行如下命令
make menuconfig
配置完成后,就可以进行编译了
make uImage
[arm]:root@ubuntu:linux-2.6.35.3 make uImage #make uImage前面的部分我虚拟机的名称等信息 ... #出现如下信息时,说明编译成功 CHK include/linux/version.h CHK include/generated/utsrelease.h make[1]: 'include/generated/mach-types.h' is up to date. CALL scripts/checksyscalls.sh CHK include/generated/compile.h Kernel: arch/arm/boot/Image is ready SHIPPED arch/arm/boot/compressed/lib1funcs.S AS arch/arm/boot/compressed/lib1funcs.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready UIMAGE arch/arm/boot/uImage Image Name: Linux-2.6.35.3-571-gcca29a0 Created: Fri Feb 28 10:49:02 2020 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 2585628 Bytes = 2525.03 KiB = 2.47 MiB Load Address: 40008000 Entry Point: 40008000 Image arch/arm/boot/uImage is ready
生成的uImage文件在如下目录
/xjzy/linux-2.6.35.3/arch/arm/boot/uImage
编译的时候可能会报错,错误的部分代码如下:
372 @val = @{$canned_values{$hz}}; 373 if (!defined(@val)) { 374 @val = compute_values($hz); 375 } 376 output($hz, @val);
将第373行代码修如下:
372 @val = @{$canned_values{$hz}}; 373 if (!@val) { 374 @val = compute_values($hz); 375 } 376 output($hz, @val);
出现这样错误的原因是perl版本升级,因bug原因,将defined(@array)去掉了,可以直接使用数组判断非空
据说官方有说明,但我不知道怎么查找,写这个文档时,我参考的那个页面忘记是哪个了,所以也没再此留下对方的脚印
编译应用程序
以编译hello.c文件作为样例
# arm-fsl-linux-gnueabi-gcc hello.c -o hello.o
hello.c的源码如下
#include <stdio.h> int main(void) { int i; for (i=0; i<5; i++){ printf("Hello world! (%d)\n", i); } return 0; }
写个makefile文件简化编译过程
为了编译方便,可以写一个makefile文件,这样以后编译就可以直接输入make命令了
我没写过这个,方法自己搜索一下吧,不复杂
sqlite3数据库移植
此部分内容参考:DoubleLi的文章成功移植SQLite3到ARM Linux开发板
下载sqlite3源码
官方网站 https://www.sqlite.org/download.html
sqlite-autoconf-3310100.tar.gz下载
将源码包放到linux主机工作目录下
写此笔记时我用的sqlite版本是3310100
编译sqlite不需要使用root权限
$ whoami bootloader #当前登录用户名 $ cd ~ $ pwd /home/bootloader #当前所在位置
解压sqlite3源码包
将下载的sqlite-autoconf-3310100.tar.gz文件放到当前目录
tar zxvf sqlite-autoconf-3310100.tar.gz #解压 cd sqlite-autoconf-3310100 mkdir _install
配置sqlite3编译选项
交叉编译工具路径加入系统环境变量
下面这三个临时环境变量其实就是复制的setenv.sh中的
. /xjzy/setenv.sh #进入交叉编译环境
生成makefile
./configure --host=arm-fsl-linux-gnueabi --prefix=$(pwd)/_install
其中
--host 指定交叉编译工具,我这里使用的是 arm-fsl-linux-gnueabi ,参考教程上说一般是arm-linux、arm-linux-gnueabihf、arm-none-linux-gnueabi等 --prefix 制定安装目录,编译后的文件会全部放在安装目录中,参考教程中说必须是绝对路径,我没测试过相对路径会报什么错
编译安装sqlite3
make make install
压缩生成文件
pwd /home/bootloader/sqlite-autoconf-3310100 arm-fsl-linux-gnueabi-strip _install/lib/libsqlite3.so.0.8.6 arm-fsl-linux-gnueabi-strip _install/bin/sqlite3
复制文件到开发板
后续步骤是在开发板上执行的
将sqlite3复制到/usr/local/bin目录,
将动态库文件复制到/usr/local/lib目录,并对动态库做链接
cd /usr/local/lib ln -s libsqlite3.so.0.8.6 libsqlite3.so.0 ln -s libsqlite3.so.0.8.6 libsqlite3.so
运行sqlite-在开发板上
在开发板上执行sqlite3命令,看到如下信息说明sqlite3移植成功!
sqlite3 SQLite version 3.31.1 2020-01-27 19:55:54 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite>
使用 .help 查看帮助,使用 .quit 退出sqlite命令
libmodbus库移植
官方网站https://libmodbus.org/download/
将源码包放到linux主机工作目录下
写此笔记时我用的libmodbus版本是3310100
编译libmodbus不需要使用root权限
解压libmodbus源码包
tar -zxvf libmodbus-3.1.6.tar.gz cd libmodbus-3.1.6/ mkdir _install
配置libmodbus编译选项
交叉编译工具路径加入系统环境变量
下面这三个临时环境变量其实就是复制的setenv.sh中的
. /xjzy/setenv.sh #进入交叉编译环境
生成makefile
./configure --build=i686 --host=arm-fsl-linux-gnueabi --enable-static --prefix=$(pwd)/_install
--prefix 指定了安装目录,交叉编译make install的内容会在这个目录里,解压源码包时,我创建的_install目录在这里,因此这样设置
编译安装libmodbus
make make install
编译完成后,在_install目录下,会新增如下3个文件夹
bootloader@ubuntu:~/libmodbus-3.1.6/_install$ ls -la ... drwxrwxr-x 3 bootloader bootloader 4096 Feb 28 16:14 include #该目录中是modbus的头文件 drwxrwxr-x 3 bootloader bootloader 4096 Feb 28 16:14 lib #该目录中是modbus动态库文件 drwxrwxr-x 3 bootloader bootloader 4096 Feb 28 16:14 share #这是个空文件夹 bootloader@ubuntu:~/libmodbus-3.1.6/_install$ ls -la include/modbus/ ... -rw-r--r-- 1 bootloader bootloader 11190 Feb 28 16:14 modbus.h -rw-r--r-- 1 bootloader bootloader 1199 Feb 28 16:14 modbus-rtu.h -rw-r--r-- 1 bootloader bootloader 1373 Feb 28 16:14 modbus-tcp.h -rw-r--r-- 1 bootloader bootloader 2124 Feb 28 16:14 modbus-version.h bootloader@ubuntu:~/libmodbus-3.1.6/_install$ ls -la lib/ ... -rw-r--r-- 1 bootloader bootloader 138518 Feb 28 16:14 libmodbus.a -rwxr-xr-x 1 bootloader bootloader 970 Feb 28 16:14 libmodbus.la lrwxrwxrwx 1 bootloader bootloader 18 Feb 28 16:14 libmodbus.so -> libmodbus.so.5.1.0 lrwxrwxrwx 1 bootloader bootloader 18 Feb 28 16:14 libmodbus.so.5 -> libmodbus.so.5.1.0 -rwxr-xr-x 1 bootloader bootloader 113611 Feb 28 16:14 libmodbus.so.5.1.0 drwxrwxr-x 2 bootloader bootloader 4096 Feb 28 16:14 pkgconfig bootloader@ubuntu:~/libmodbus-3.1.6/_install$ ls -la lib/pkgconfig/ ... -rw-r--r-- 1 bootloader bootloader 241 Feb 28 16:14 libmodbus.pc
压缩生成libmodbus
我参考的教程里并没有对生成的文件进行压缩,之所以在这里执行,是参考了sqlite里有这一步,执行此步后,文件小了很多
只压缩了.so文件和.a文件,没有压缩lib文件夹中.la后缀的文件,会提示无法识别的文件格式(File format not recognized)
cd _install arm-fsl-linux-gnueabi-strip lib/libmodbus.so.5.1.0 arm-fsl-linux-gnueabi-strip lib/libmodbus.a ls -la lib/libmodbus.so.5.1.0 -rwxr-xr-x 1 bootloader bootloader 34320 Feb 28 16:23 lib/libmodbus.so.5.1.0 ls -la lib/libmodbus.a -rw-r--r-- 1 bootloader bootloader 27308 Feb 28 16:29 lib/libmodbus.a
上面的库文件中,3个文件libmodbus.so\libmodbus.so.5\libmodbus.so.5.1.0最后是要移值的目标板上的,通常放在/usr/lib目录下.另外在交叉编译时,也要拷贝过去.
后面开发应用软件时,需要用到的头文件和库文件,可以通过手工拷贝的方法将头文件和库文件临时拷贝到应用软件开发的目录下,并在makefile中指定这些库文件的目录.
libmodbus应用软件的开发和编译
cd ~ #返回当前用户根目录 mkdir modbus-test cd modbus-test mkdir -p include/modbus mkdir include mkdir lib touch main.c touch makefile
将上一步make install生成的_install中文件拷贝到当前目录下include/modbus文件夹和lib文件夹下
main.c文件内容如下
#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <pthread.h> #include "modbus.h" #include "modbus-tcp.h" #include "modbus-version.h" #if defined(_WIN32) #include <ws2tcpip.h> #else #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #endif #define NB_CONNECTION 5 //xian quan di zhi ding yi const uint16_t UT_BITS_ADDRESS = 0x13; const uint16_t UT_BITS_NB = 0x25; const uint8_t UT_BITS_TAB[] ={0xCD,0x6B,0xB2,0x0E,0x64}; //li san shu ru ji cun qi const uint16_t UT_INPUT_BITS_ADDRESS=0xC4; const uint16_t UT_INPUT_BITS_NB = 0x16; const uint8_t UT_INPUT_BITS_TAB[]= {0xAC,0xDB,0x64}; //bao chi ji cun qi ding yi const uint16_t UT_REGISTERS_ADDRESS =0x6B; // const uint16_t UT_REGISTERS_ADDRESS_SPECIAL = 0x6C; const uint16_t UT_REGISTERS_NB = 0x03; const uint16_t UT_REGISTERS_TAB[] = {0x022B,0x0001,0x0064}; //SHU RU JI CUN QI DING YI const uint16_t UT_REGISTERS_NB_SPECIAL = 0x02; // const uint16_t UT_INPUT_REGISTERS_ADDRESS =0x08; const uint16_t UT_INPUT_REGISTERS_NB = 0x01; const uint16_t UT_INPUT_REGISTERS_TAB[] = {0x0064}; modbus_t *ctx = NULL; int server_socket; modbus_mapping_t *mb_mapping; static void close_sigint(int dummy) { close(server_socket); modbus_free(ctx); modbus_mapping_free(mb_mapping); exit(dummy); } void *modbus_tcp(void *args) { int master_socket; int rc; fd_set refset; fd_set rdset; int i; int fdmax; int header_length; ctx=modbus_new_tcp("192.168.1.136",508); ////mb_mapping = modbus_mapping_new( //UT_BITS_ADDRESS + UT_BITS_NB, //UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB, //UT_REGISTERS_ADDRESS +UT_REGISTERS_NB, // UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB); // if(mb_mapping == NULL) //{ // fprintf(stderr,"failed to allocater the mapping:%s\n", // modbus_strerror(errno)); // modbus_free(ctx); //return -1; //} // chu shi hua ji cun qi modbus_set_bits_from_bytes(mb_mapping->tab_input_bits,UT_INPUT_BITS_ADDRESS, UT_INPUT_BITS_NB,UT_INPUT_BITS_TAB); for(i=0;i<UT_INPUT_REGISTERS_NB;i++) { mb_mapping->tab_input_registers[UT_INPUT_REGISTERS_NB+i] = UT_INPUT_REGISTERS_TAB[i]; } for(i=0;i<UT_REGISTERS_NB;i++); { mb_mapping->tab_registers[UT_REGISTERS_ADDRESS+i] = UT_REGISTERS_TAB[i]; } server_socket = modbus_tcp_listen(ctx,NB_CONNECTION); signal(SIGINT,close_sigint); FD_ZERO(&refset); FD_SET(server_socket,&refset); fdmax=server_socket; for(;;) { rdset = refset; if(select(fdmax+1,&rdset,NULL,NULL,NULL) == -1) { perror("Server select() failure."); close_sigint(1); } for(master_socket=0;master_socket<=fdmax;master_socket++) { if(FD_ISSET(master_socket,&rdset)) { if(master_socket ==server_socket) { socklen_t addrlen; struct sockaddr_in clientaddr; int newfd; addrlen= sizeof(clientaddr); memset(&clientaddr,0,sizeof(clientaddr)); newfd = accept(server_socket,(struct sockaddr *)&clientaddr,&addrlen); if(newfd == -1) { perror("Server accept() error"); } else { FD_SET(newfd,&refset); if(newfd>fdmax) { fdmax=newfd; } //printf("New connection from %s:%d on socket %d\n",inet_ntor(clientaddr.sin_adr),clientaddr.sin_port,newfd); } } else { uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH]; int data = 0; int address = 0; modbus_set_socket(ctx,master_socket); rc = modbus_receive(ctx,query); address = (query[header_length+1]<<8+query[header_length+2]); if(query[header_length]==0x06) { } if(rc != -1) { modbus_reply(ctx,query,rc,mb_mapping); } else { printf("connection closed on socket %d\n",master_socket); close(master_socket); FD_CLR(master_socket,&refset); if(master_socket == fdmax) { fdmax--; } } } } } // printf("-----------------------------------------------------------\n"); //for(i=0;i<10;i++) //{ // printf("baochijicunqi[%d]:%d\n",i,mb_mapping->tab_registers[i]); //} } } void *modbus_rtu(void *args) { modbus_t *ctx = NULL; ctx = modbus_new_rtu("/dev/ttySP4", 9600, 'N', 8, 1); if (ctx == NULL) { fprintf(stderr, "Unable to allocate libmodbus contex\n"); //return -1; } modbus_set_debug(ctx, 1); modbus_set_slave(ctx, 1); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno)); //return -1; } int i,rc; uint16_t tab_reg[64] = {0}; while (1) { printf("\n----------------\n"); rc = modbus_read_registers(ctx, 0, 10, tab_reg); if (rc == -1) { fprintf(stderr,"%s\n", modbus_strerror(errno)); //return -1; } for (i=0; i<10; i++) { mb_mapping->tab_registers[i]=tab_reg[i]; printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]); } usleep(5000000); } modbus_close(ctx); modbus_free(ctx); } int main(void) { pthread_t t1; pthread_t t2; int i; mb_mapping = modbus_mapping_new( UT_BITS_ADDRESS + UT_BITS_NB, UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB, UT_REGISTERS_ADDRESS +UT_REGISTERS_NB, UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB); if(mb_mapping == NULL) { fprintf(stderr,"failed to allocater the mapping:%s\n", modbus_strerror(errno)); modbus_free(ctx); } pthread_create(&t1,NULL,modbus_tcp,NULL); pthread_create(&t2,NULL,modbus_rtu,NULL); while(1) { //printf("-----------------------------------------------------------\n"); for(i=0;i<10;i++) { //printf("baochijicunqi[%d]:%d\n",i,mb_mapping->tab_registers[i]); } sleep(1); } getchar(); return 0; }
makefile文件内容如下
将编译后的libmodbus复制到开发板
手头没有开发板,暂停了,编译了不知道该怎么测试,所以暂时搁置
goahead移植
此部分内容参考:
GoAhead4.1.0 开发总结一(移植)
GoAhead4.1.0 开发总结二(自定义使用)
goahead源码下载
当前我使用goahead-5.1.1-src,社区版能能下载当前社区版的源码,不能下载以前的版本
goahead交叉编译
解压源码
tar -xvf goahead-5.1.1-src.tar cd goahead-5.1.1
修改Makefile文件
nano Makefile
在Makefile文件开头添加如下信息
#CROSS_COMPILE 在这里指定交叉编译环境所在位置及编译工具前缀 CROSS_COMPILE =/usr/local/arm/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-fsl-linux-gnueabi- AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump ARCH=arm
附我所用的CROSS_COMPILE路径里的信息
ls /usr/local/arm/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/ arm-fsl-linux-gnueabi-addr2line arm-linux-ar arm-none-linux-gnueabi-as arm-fsl-linux-gnueabi-ar arm-linux-as arm-none-linux-gnueabi-c++ arm-fsl-linux-gnueabi-as arm-linux-c++ arm-none-linux-gnueabi-cc arm-fsl-linux-gnueabi-c++ arm-linux-cc arm-none-linux-gnueabi-c++filt arm-fsl-linux-gnueabi-cc arm-linux-c++filt arm-none-linux-gnueabi-cpp arm-fsl-linux-gnueabi-c++filt arm-linux-cpp arm-none-linux-gnueabi-ct-ng.config arm-fsl-linux-gnueabi-cpp arm-linux-ct-ng.config arm-none-linux-gnueabi-g++ arm-fsl-linux-gnueabi-ct-ng.config arm-linux-g++ arm-none-linux-gnueabi-gcc arm-fsl-linux-gnueabi-g++ arm-linux-gcc arm-none-linux-gnueabi-gcc-4.4.4 arm-fsl-linux-gnueabi-gcc arm-linux-gcc-4.4.4 arm-none-linux-gnueabi-gccbug arm-fsl-linux-gnueabi-gcc-4.4.4 arm-linux-gccbug arm-none-linux-gnueabi-gcov arm-fsl-linux-gnueabi-gccbug arm-linux-gcov arm-none-linux-gnueabi-gdb arm-fsl-linux-gnueabi-gcov arm-linux-gdb arm-none-linux-gnueabi-gprof arm-fsl-linux-gnueabi-gdb arm-linux-gprof arm-none-linux-gnueabi-ld arm-fsl-linux-gnueabi-gprof arm-linux-ld arm-none-linux-gnueabi-ldd arm-fsl-linux-gnueabi-ld arm-linux-ldd arm-none-linux-gnueabi-nm arm-fsl-linux-gnueabi-ldd arm-linux-nm arm-none-linux-gnueabi-objcopy arm-fsl-linux-gnueabi-nm arm-linux-objcopy arm-none-linux-gnueabi-objdump arm-fsl-linux-gnueabi-objcopy arm-linux-objdump arm-none-linux-gnueabi-populate arm-fsl-linux-gnueabi-objdump arm-linux-populate arm-none-linux-gnueabi-ranlib arm-fsl-linux-gnueabi-populate arm-linux-ranlib arm-none-linux-gnueabi-readelf arm-fsl-linux-gnueabi-ranlib arm-linux-readelf arm-none-linux-gnueabi-run arm-fsl-linux-gnueabi-readelf arm-linux-run arm-none-linux-gnueabi-size arm-fsl-linux-gnueabi-run arm-linux-size arm-none-linux-gnueabi-strings arm-fsl-linux-gnueabi-size arm-linux-strings arm-none-linux-gnueabi-strip arm-fsl-linux-gnueabi-strings arm-linux-strip elftosb arm-fsl-linux-gnueabi-strip arm-none-linux-gnueabi-addr2line arm-linux-addr2line arm-none-linux-gnueabi-ar
有些教程里有说需要屏蔽掉下面语句,这一句是用来启动SSL matrixssl的,具体参考Webs25GettingStarted.pdf文档中的说明(Page8)
但我在Makefile文件里没找到下面的语句,因此没有理会
matrixsslDir:=$(shell ls -d ../matrixssl-3-1*/)
goahead测试
手头没有开发板,编译了不知道该怎么测试,所以抄了以下代码
将build/linux-arm-default/bin目录中的:libgo.so goahead self.crt self.key auth.txt route.txt移动到开发板中(最后两个文件我就没生成是什么情况,这两个文件可以从源码目录src/文件中取得) 将libgo.so放到/lib或者/usr/lib中 将goahead self.crt self.key auth.txt route.txt放到同一个文件夹中,位置任意我这里放的是/mnt/system中 将任一网页文件放到开发板的/usr/web/目录下,goahead源文件解压后doc/contents/目录下有个index.html文件可供测试 运行如下命令进行测试,ip地址根据自己开发板的地址适当修改 ./goahead -v /usr/web/ 192.168.131.139:80
在主机浏览器输入http://192.168.131.139/
页面如下显示(表示程序运行正常):
Congratulations! The server is up and running.
在电脑上编译运行
tar -xvf goahead-5.1.1-src.tar cd goahead-5.1.1/ make && sudo make install sudo cp src/self.key src/self.crt /etc/goahead/ sudo goahead -v --home /etc/goahead /var/www/goahead #显示结果如下 goahead: 2: Configuration for Embedthis GoAhead Community Edition goahead: 2: --------------------------------------------- goahead: 2: Version: 5.1.1 goahead: 2: BuildType: Debug goahead: 2: CPU: x64 goahead: 2: OS: linux goahead: 2: Host: 127.0.1.1 goahead: 2: Directory: /etc/goahead goahead: 2: Documents: /var/www/goahead goahead: 2: Configure: me -d -q -platform linux-x86-default -configure . -gen make goahead: 2: --------------------------------------------- goahead: 2: Started http://*:80 goahead: 2: Started https://*:443 # 在浏览器中打开浏览器,输入linux主机ip地址,终端中显示如下 goahead: 2: GET /index.html HTTP/1.1 goahead: 2: GET /favicon.ico HTTP/1.1 goahead: 2: Idle connection closed goahead: 2: Idle connection closed
openssl移植
编译mosquitto时需要用到openssl,因此先编译openssl
openssl源码下载
openssl网站 https://www.openssl.org/source/
GitHub仓库 https://github.com/openssl/openssl
openssl交叉编译
. /xjzy/setenv.sh #进入交叉编译环境 tar -zxvf openssl-1.1.1d.tar.gz cd openssl-1.1.1d mkdir _install #新建个文件夹,用于make install存放生成的文件 #./Configure no-shared --prefix=$(pwd)/_install linux-armv4 #no-shared生成静态库,这个和下面生成动态库的命令二选一 ./Configure --prefix=$(pwd)/_install linux-armv4 #生成动态库 --prefix指定生成lib include bin目录的路径 make #编译 #make install #安装,完成后会在刚指定的_install文件夹中生成安装文件 make install_sw install_ssldirs #用此方法不生成doc帮助文档,节省make install时间
编译完成后_install文件夹内容如下
pwd /home/bootloader/openssl-1.1.1d/_install/lib ls -lh ... lrwxrwxrwx 1 bootloader bootloader 16 Mar 3 16:33 libcrypto.so -> libcrypto.so.1.1 -rwxr-xr-x 1 bootloader bootloader 2.6M Mar 3 16:33 libcrypto.so.1.1 lrwxrwxrwx 1 bootloader bootloader 13 Mar 3 16:33 libssl.so -> libssl.so.1.1 -rwxr-xr-x 1 bootloader bootloader 553K Mar 3 16:33 libssl.so.1.1 #以上两个文件是后面项目移植需要放在/usr/lib文件夹下 drwxrwxr-x 2 bootloader bootloader 4.0K Mar 3 16:33 engines-1.1 -rw-r--r-- 1 bootloader bootloader 3.8M Mar 3 16:33 libcrypto.a -rw-r--r-- 1 bootloader bootloader 693K Mar 3 16:33 libssl.a drwxrwxr-x 2 bootloader bootloader 4.0K Mar 3 16:33 pkgconfig
mosquitto移植-MQTT
Eclipse Mosquitto是实现MQTT协议版本5.0、3.1.1和3.1的开源消息代理(经EPL / EDL许可).Mosquitto轻巧,适合在从低功耗单板计算机到完整服务器的所有设备上使用.
此部分内容参考:
mosquitto 使用时出现的一些问题及其解决办法
mosquitto源码下载
Eclipse Mosquitto网站 https://mosquitto.org/
Eclipse Mosquitto下载https://mosquitto.org/download/
可从https://mosquitto.org/files/获得较早的下载
mosquitto交叉编译
. /xjzy/setenv.sh #进入交叉编译环境 tar -zxvf mosquitto-1.6.9.tar.gz cd mosquitto-1.6.9/ mkdir _install #新建个文件夹,用于make install存放生成的文件 make WITH_SRV=no CC=gcc CXX=g++ CFLAGS="-I$(pwd)/../openssl-1.1.1d/_install/include/" LDFLAGS="-L$(pwd)/../openssl-1.1.1d/_install/lib -lssl -lcrypto" #在这个例子中,openssl-1.1.1d文件夹 和 mosquitto-1.6.9文件夹在同级目录下,因此上面的路径我采用$(pwd)/../openssl-1.1.1d/的书写方式,也可以使用绝对路径 make DESTDIR=$(pwd)/_install install #生成安装文件
编译完成后_install文件夹内容如下
[arm]:bootloader@ubuntu:_install tree . ├── etc | └── mosquitto ... ... └── usr └── local ├── bin │ ├── mosquitto_passwd │ ├── mosquitto_pub #测试程序,用于向服务器端推送数据 │ ├── mosquitto_rr │ └── mosquitto_sub #测试程序,用于订阅服务端端 ├── include #开发需要用到的库? ... ... ├── lib │ ├── libmosquittopp.so -> libmosquittopp.so.1 #在开发板上创建软链接 │ ├── libmosquittopp.so.1 #拷贝到开发板/usr/bin目录下 │ ├── libmosquitto.so -> libmosquitto.so.1 #在开发板上创建软链接 │ ├── libmosquitto.so.1 #拷贝到开发板/usr/bin目录下 │ └── pkgconfig │ ├── libmosquitto.pc │ └── libmosquittopp.pc ├── sbin │ └── mosquitto #MQTT服务器端 └── share └── man #这里面的是帮助手册吧! ... ...
mosquitto测试
假设 windows主机ip地址:192.168.131.1 linux主机ip地址 :192.168.131.129 arm开发板ip地址 :192.168.131.200
在windows上安装MQTT测试软件
在<https://mosquitto.org/download/>下载windows客户端mosquitto-1.6.8-install-windows-x64.exe,默认路径安装 C:\Program Files\mosquitto目录下有4个主要exe文件,帮助文档readme.md/readme-windows.txt mosquitto.exe #服务 mosquitto_passwd.exe mosquitto_pub.exe #发布 mosquitto_sub.exe #订阅 在主机命令行下运行mosquitto.exe开启服务 在arm开发板上运行订阅hello mosquitto_sub -v -t hello -h 192.168.131.1 在pc端或开发板中推送 mosquitto_pub -t hello -h 192.168.131.1 -m "world" 开发板会收到消息 hello world 允许同时有多个订阅者
可能会遇到的错误
问题1: mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory mosquitto_pub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory 原因: 共享库安装到了/usr/local/lib(很多开源共享库会安装在这个目录下)或其他非/lib或非/usr/lib文件夹下,因此需要将共享库所在文件夹添加到共享库配置文件/etc/ld.so.conf中,然后执行ldconfig,或将所需要共享库链接到/usr/lib目录,然后执行ldconfig 解决办法入下: 方法1: echo "/usr/local/lib" >> /etc/ld.so.conf #将libmosquitto.so.1所在的路径加入到/etc/ld.so.conf文件中 cat /etc/ld.so.conf #此时应该看到文件最后一行已经添加了路径/etc/ld.so.conf ldconfig # /etc/ld.so.conf 方法2: sudo ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1 ldconfig
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 【.NET】调用本地 Deepseek 模型