基於mini2440嵌入式linux上整合一套Domoticz智慧家居系統(七)交叉編譯paho.mqtt.embedded-c庫和嵌入式linux樣例程式
本篇將把paho.mqtt.embedded-c官方的原始碼交叉編譯成資料包封裝庫和應用程式兩部分,並把樣例應用程式在mini2440上執行。
一、首先編譯MQTT協議包封裝庫:
解壓paho.mqtt.embedded-c-master.zip之後,進入目錄,
修改Makefile:
1、修改第70行CC ?=gcc為:
CC ?=arm-linux-gcc
2、第43行SOURCE_FILES_C = $(srcdir)/*.c改為:
SOURCE_FILES_C = $(wildcard $(srcdir)/*.c )
OBJS = $(addsuffix .o,$(basename $( SOURCE_FILES_C)))
這個是把那個目錄下的所有.c檔案都編譯進去,不然,後面引用這個庫的時候會出錯。
3、第95行rm -rf ${blddir}/* 改為:
rm -rf ${blddir}/* $(OBJS) ${srcdir}/../samples/transport.o
4、第110行
${EMBED_MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C}
改為
${EMBED_MQTTLIB_C_TARGET}: $(OBJS) ${HEADERS_C}
第111行
${CC} ${CCFLAGS_SO} -o [email protected] ${SOURCE_FILES_C} ${LDFLAGS_C}
改為:
${CC} ${CCFLAGS_SO} -o [email protected] $(OBJS) ${LDFLAGS_C}
這是把所有的.o檔案都連結到動態庫中。
不然,後面引用動態庫的時候會報錯誤說缺少相關引用。
注意前面都有個tab鍵符
4、在121行nstall: build 下面新增:
-mkdir -p $(DESTDIR)${libdir}
-mkdir -p $(DESTDIR)${includedir}
cp -r $(HEADERS) $(DESTDIR)${includedir}
這是建立安裝目錄、複製標頭檔案。
5、
make
編譯好後:
6、
make install DESTDIR=/usr/local/arm/paho.mqtt.embedded-c prefix=
這裡指定prefix(字首)為空。,不然安裝的時候,會在我們指定的目錄後加入usr/local這個子路徑。
安裝好後如下:
就安裝到了主機的/usr/local/arm/paho.mqtt.embedded-c目錄下了,這個目錄下有兩個子目錄:
1)、include,這個在我們編譯自己的程式的時候需要用到;
2)、lib子目錄:
這個是我們編譯自己的程式需要連結的動態庫,照例,把它複製到arm板根檔案系統的/usr/lib中。
二、嘗試編譯client和樣例程式:
1、進入MQTTClient-C/samples目錄,把linux子目錄複製一份命名為mini2440
cp -r linux mini2440
進入mini2440目錄,編輯build.sh
把裡面的內容都刪掉,改為:
cp ../../src/MQTTClient.c .
cp ../../src/linux/MQTTLinux.c .
cp ../../src/linux/MQTTLinux.h .
sed '/^#include "MQTTPacket.h"/i\\#include "MQTTLinux.h"' ../../src/MQTTClient.h > MQTTClient.h
make
sed ‘/^#include “MQTTPacket.h”/i\#include “MQTTLinux.h”’ ../../src/MQTTClient.h > MQTTClient.h
這句的意思是讀入../../src/MQTTClient.h 檔案,然後搜#include “MQTTPacket.h”,然後在它的下一行插入#include “MQTTLinux.h”
然後把所有內容寫入MQTTClient.h儲存在當前目錄。
因為要引用後面那個標頭檔案,不加入,會出錯。
下面來寫一個Makefile,內容如下:
TOPDIR = ../..
CC=arm-linux-gcc
INCDIR :=-I/usr/local/arm/paho.mqtt.embedded-c/include
COMPILE.c = $(CC) $(CFLAGS) $(INCDIR) -MMD -c
LINK.c = $(CC) $(LDFLAGS) -lpthread -lrt
.PHONY: all
%.o:%.c
$(COMPILE.c) $< -o [email protected]
SRC_FILE := \
MQTTClient.c \
MQTTLinux.c \
stdoutsub.c
OBJS := $(addsuffix .o, $(basename $(SRC_FILE)))
DEPS :=$(OBJS:.o=.d)
all:mqtt
mqtt:$(OBJS)
$(LINK.c) $(OBJS) -lpaho-embed-mqtt3c -L/usr/local/arm/paho.mqtt.embedded-c/lib -o [email protected]
cp [email protected] /work/rootfs/usr/my/
clean:
rm -f $(OBJS) mqtt
distclean:clean
rm -f $(DEPS)
-include $(DEPS)
2、然後修改stdoutsub.c。
第213行 Client c;改為:
MQTTClient c;
第218行NewNetwork(&n);改為:
NetworkInit(&n);
第219行ConnectNetwork(&n, opts.host, opts.port);改為:
NetworkConnect(&n, opts.host, opts.port);
第220行MQTTClient(&c, &n, 1000, buf, 100, readbuf, 100);改為:
MQTTClientInit(&c, &n, 1000, buf, 100, readbuf, 100);
第248行n.disconnect(&n);改為:
NetworkDisconnect(&n);
然後儲存、退出,執行指令碼:
./build.sh
這個指令碼只需要執行一次,後面可以使用make來編譯了。
結果如下:
已經編譯好,並拷貝到arm板的/usr/my目錄中了,可執行檔名字叫mqtt。
下面步驟來驗證這個mqtt程式能否接收到domoticz釋出的訊息。
三、啟動mini2440,在串列埠下,在根目錄下啟動mosquitto和domoticz。
對了,要說一下啟動mosquitto,前面說到用
mosquitto -c /etc/mosquitto/mosquitto.conf -v &
來啟動,因為前面除錯要看列印資訊。
現在不要看這些資訊了,啟動時讓它遮蔽列印資訊,可以用
mosquitto -c /etc/mosquitto/mosquitto.conf -v -d
這一條命令來啟動。
然後:
/etc/init.d/domoticz.sh start &
domoticz已經啟動了。
進入/usr/my目錄,然後執行一下./mqtt可以看到:
Usage: stdoutsub topicname , where options are:
–host (default is localhost)
–port (default is 1883)
–qos (default is 2)
–delimiter (default is \n)
–clientid (default is hostname+timestamp)
–username none
–password none
–showtopics (default is on if the topic has a wildcard, else off)
對應我們的可執行檔案,用法是:
mqtt 主題名 <其他引數>
引數用法是
–host <要連結的主機名> (預設是 localhost)
–port<埠號>(預設是1883)
……
我們現在就可以全部使用預設引數,因為要連線的mosquitto就在本機,其他預設引數都是對應的。
接下來,執行,注意這只是個sub客戶端程式。
對應我們的可執行檔案,用法是:
./mqtt domoticz/out
這就是訂閱 本機的MQTT broker釋出的 domoticz/out主題訊息。
啟動結果如下:
然後點到開關那個選項:
然後點那個燈泡,點亮它。
可以看到mini2440這邊已經收到了訊息。
再關閉:
兩次訊息只有nvalue有變化。
這個就是開關量的值。
Android手機客戶端APP操作,也會得到相同的結果:
到此,paho.mqtt.embedded-c客戶端的程式,基本上得到了驗證。
下一篇就是真正使用客戶端程式來控制mini2440上的LED燈了。