1. 程式人生 > >基於mini2440嵌入式linux上整合一套Domoticz智慧家居系統(七)交叉編譯paho.mqtt.embedded-c庫和嵌入式linux樣例程式

基於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燈了。