文章使用RT-Thread 标准版,版本为5.0.2 。使用野火霸道主板,主控为STM32F103VET6。该文章介绍在RT-Thread studio上正常连接公网后开始添加MY MQTT软件包,并实现mqtt数据交互功能。
1.前提
在msh页面使用ping www.baidu.com 可以ping通,如下
2.添加MY MQTT软件包
搜索mymtqq软件包
打开DFS支持
保存编译,报以下错误
../packages/mymqtt-latest/MQTTClient-C/mqtt_client.c:31:23: fatal error: dfs_posix.h: No such file or directory
compilation terminated.
arm-none-eabi-gcc "../libraries/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c"
arm-none-eabi-gcc "../libraries/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c"
arm-none-eabi-gcc "../libraries/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c"
make: *** [packages/mymqtt-latest/MQTTClient-C/subdir.mk:18: packages/mymqtt-latest/MQTTClient-C/mqtt_client.o] Error 1
make: *** Waiting for unfinished jobs....
"make -j20 all" terminated with exit code 2. Build might be incomplete.
解决方法如下,在mqtt_client.c文件中添加
struct linger {
int l_onoff; /* option on/off */
int l_linger; /* linger time */
};
编译通过
3.编写用户使用文件
以下给定mqtt 用户模板,可直接拷贝使用。在.c文件中主要修改data_cheak()函数中的应用程序。在.h文件中主要修改mqtt服务器的各种参数。
mqtt_app.c文件
#include <mqtt_client.h>
#include <netdev.h>
#include "mqtt_app.h"
#define DBG_TAG "MQTT"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
/*
* 全局变量
*/
rt_thread_t Net_thread = RT_NULL;//mqtt线程
char MQTT_URI_0[50] = {0};//临时存储mqtt ip地址端口号 tcp
static int is_started_user = 0; //mqtt是否第一次配置
static mqtt_client client;//mqtt结构体
char MQTT_CH0_Successfulworking = 0; //连网成功标志位
char get_mqtt_data[256];//暂存拷贝接收到的数据 全局变量
char get_data_flag = 0;//接收到mqtt信息标志位
//接收到mqtt主机下发的信息 回调函数
static void mqtt_sub_callback(mqtt_client *c, message_data *msg_data)
{
#if 1
*((char *)msg_data->message->payload + msg_data->message->payloadlen) = '\0';
LOG_D("mqtt sub callback: %.*s %.*s",
msg_data->topic_name->lenstring.len,
msg_data->topic_name->lenstring.data,
msg_data->message->payloadlen,
(char *)msg_data->message->payload);
LOG_D("get:%s\n",(char *)msg_data->message->payload);
#endif
#if 1
//将mqtt服务器下发的信息拷贝到 get_mqtt_data
get_data_flag = 1;
strncat((char *) get_mqtt_data, (const char *)msg_data->message->payload, msg_data->message->payloadlen);
#endif
}
static void mqtt_sub_default_callback(mqtt_client *c, message_data *msg_data)
{
#if 0
*((char *)msg_data->message->payload + msg_data->message->payloadlen) = '\0';
LOG_D("mqtt sub default callback: %.*s %.*s",
msg_data->topic_name->lenstring.len,
msg_data->topic_name->lenstring.data,
msg_data->message->payloadlen,
(char *)msg_data->message->payload);
#endif
}
//连接回调函数
static void mqtt_connect_callback(mqtt_client *c)
{
LOG_I("inter mqtt_connect_callback!");
}
//连接成功回调函数
static void mqtt_online_callback(mqtt_client *c)
{
LOG_I("inter mqtt_online_callback!");
}
//mqtt离线回调函数
static void mqtt_offline_callback(mqtt_client *c)
{
LOG_I("inter mqtt_offline_callback!");
}
/*
* 主mqtt配置函数
*/
int mqtt_init_user(void)
{
/* init condata param by using MQTTPacket_connectData_initializer */
MQTTPacket_connectData condata = MQTTPacket_connectData_initializer;
static char cid[20] = { 0 };
if (is_started_user)
{
LOG_E("mqtt client is already connected.");
return -1;
}
/* config MQTT context param */
{
client.isconnected = 0;
rt_memcpy(MQTT_URI_0, "\0", sizeof(MQTT_URI_0));
rt_sprintf(MQTT_URI_0, "tcp://%s:%d", MQTT_URL_New,MQTT_PORT_New);//拷贝ip和端口号
LOG_I("MQTT_URI_0:%s", MQTT_URI_0);
client.uri = MQTT_URI_0;
/* generate the random client ID */
rt_snprintf(cid, sizeof(cid), "rtthread%d", rt_tick_get());//连接id
/* config connect param */
memcpy(&client.condata, &condata, sizeof(condata));
client.condata.clientID.cstring = cid;
client.condata.username.cstring = USER_NAME; //mqtt 用户名
client.condata.password.cstring = PASS_WORD; //mqtt 密码
client.condata.keepAliveInterval = 30;
client.condata.cleansession = 1;
/* config MQTT will param. */
client.condata.willFlag = 0;
client.condata.will.qos = 1;
client.condata.will.retained = 0;
client.condata.will.topicName.cstring = will_topic;//遗嘱主题 (无用)
client.condata.will.message.cstring = MQTT_WILLMSG;//遗嘱信息(无用)
/* malloc buffer. */
//修改mqtt内存池 建议修改 可以支持大约4k上报信息 (我实际使用最大3.5k为一包),如果RAM太小可修改该变量
client.buf_size = client.readbuf_size = 4096;
client.buf = rt_calloc(1, client.buf_size);
client.readbuf = rt_calloc(1, client.readbuf_size);
if (!(client.buf && client.readbuf))
{
LOG_E("no memory for MQTT client buffer!");
return -1;
}
/* set event callback function */
client.connect_callback = mqtt_connect_callback;//回调
client.online_callback = mqtt_online_callback;
client.offline_callback = mqtt_offline_callback;
/* set subscribe table and event callback */
client.message_handlers[0].topicFilter = rt_strdup(MQTT_SUBTOPIC);//订阅主题
client.message_handlers[0].callback = mqtt_sub_callback;//订阅回调函数
client.message_handlers[0].qos = QOS1;
/* set default subscribe event callback */
client.default_message_handlers = mqtt_sub_default_callback;
}
{
int value;
uint16_t u16Value;
value = 5;
paho_mqtt_control(&client, MQTT_CTRL_SET_CONN_TIMEO, &value);
value = 5;
paho_mqtt_control(&client, MQTT_CTRL_SET_MSG_TIMEO, &value);
value = 5;
paho_mqtt_control(&client, MQTT_CTRL_SET_RECONN_INTERVAL, &value);
value = 30;
paho_mqtt_control(&client, MQTT_CTRL_SET_KEEPALIVE_INTERVAL, &value);
u16Value = 3;
paho_mqtt_control(&client, MQTT_CTRL_SET_KEEPALIVE_COUNT, &u16Value);
}
/* run mqtt client */
if (PAHO_SUCCESS == paho_mqtt_start(&client, 8196, 20))
is_started_user = 1;
else
is_started_user = 0;
return 0;
}
//需要发布的mqtt信息
char Send_data[1024] = "This is an MQTT instance information";//需要发送的模拟量值4G其他打包使用
//处理mqtt数据函数 用户自定义修改
static void data_cheak(char mode){
if(get_data_flag)
{
get_data_flag = 0;
LOG_I("get data [%s],",get_mqtt_data);
rt_memset(get_mqtt_data, 0, sizeof(get_mqtt_data));
}
//以下是测试上报实例
static uint32_t cun = 0;
if(cun % 1000 == 0)
{
paho_mqtt_publish(&client, QOS0, MQTT_PUBTOPIC, Send_data,strlen(Send_data));
}
cun++;
}
//MQTT主运行函数
static void MQTTNew_entry(void* paremeter){
rt_thread_mdelay(5000);
LOG_I("mqtt run!");
while(1)
{
while (1) //等待网络连接准备好
{
struct netdev *netdev_link = netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);
if (netdev_link)
{
netdev_low_level_set_link_status(netdev_link, 1);
break;
}
rt_thread_mdelay(rt_tick_from_millisecond(RT_TICK_PER_SECOND));
}
rt_thread_mdelay(3000);
mqtt_init_user();
while (!client.isconnected) //等待连接成功
{
LOG_I("Waiting for mqtt0 connection...\n");
rt_thread_delay(1000);
}
MQTT_CH0_Successfulworking = 1;//连接成功
while(client.isconnected)
{
data_cheak(1);
rt_thread_mdelay(100);
}
MQTT_CH0_Successfulworking = 0;//连接失败
rt_thread_mdelay(1000);
}
}
int Client_Net_init(void){
uint8_t result = 0;
Net_thread = rt_thread_create( "LTE_W5",MQTTNew_entry,RT_NULL,LTEW5500_stack,LTE_PRIORITY, 20);
if (Net_thread != RT_NULL){rt_thread_startup(Net_thread);}
else{
LOG_W("MQTT Init err!\n");
result = RT_ERROR;
}
return result;
}
INIT_APP_EXPORT(Client_Net_init);
mqtt_app.h文件,主要包含mqtt服务器各种信息
#ifndef APPLICATIONS_MQTT_APP_H_
#define APPLICATIONS_MQTT_APP_H_
#include <rtthread.h>
//mqtt线程优先级
#define LTE_PRIORITY (RT_MAIN_THREAD_PRIORITY - 4 + 3)
//mqtt堆栈大小
#define LTEW5500_stack (1024+512)
//mqtt 账号
#define USER_NAME "xxxxx"用户自行修改
//mqtt 密码
#define PASS_WORD "xxxxx"用户自行修改
//mqtt ip
#define MQTT_URL_New "xxxxx"用户自行修改
//mqtt 端口号
#define MQTT_PORT_New "xxxxx"用户自行修改
//mqtt 订阅主题
#define MQTT_SUBTOPIC "xxxxx"用户自行修改
//mqtt 发布主题
#define MQTT_PUBTOPIC "xxxxx"用户自行修改
//遗嘱主题
#define will_topic "xxxxx"用户自行修改
//遗嘱信息
#define MQTT_WILLMSG "xxxxx"用户自行修改
#endif /* APPLICATIONS_MQTT_APP_H_ */
移植文件后运行,发现报以下错误
linking...
./packages/mymqtt-latest/MQTTClient-C/mqtt_client.o: In function `mqtt_connect':
E:\Myself\work\A_code\RT-Thread\STM32F103ZET6\10001\Debug/../packages/mymqtt-latest/MQTTClient-C/mqtt_client.c:689: undefined reference to `select'
./packages/mymqtt-latest/MQTTClient-C/mqtt_client.o: In function `mqtt_subscribe':
E:\Myself\work\A_code\RT-Thread\STM32F103ZET6\10001\Debug/../packages/mymqtt-latest/MQTTClient-C/mqtt_client.c:791: undefined reference to `select'
./packages/mymqtt-latest/MQTTClient-C/mqtt_client.o: In function `paho_mqtt_thread':
E:\Myself\work\A_code\RT-Thread\STM32F103ZET6\10001\Debug/../packages/mymqtt-latest/MQTTClient-C/mqtt_client.c:1176: undefined reference to `select'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:81: rtthread.elf] Error 1
"make -j20 all" terminated with exit code 2. Build might be incomplete.
这是一个典型的链接错误,表明MQTT客户端代码中使用了select ()系统调用,但在RT-Thread编译环境中没有提供对应的实现。解决方法如下找到libc/posix/io 添加构建poll文件即可。
重新编译,运行,下载 。
可以看到,设备发布,订阅mqtt成功。
————————————————
版权声明:本文为CSDN博主「BUG_yechiyu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/henan_zhang/article/details/157549119
|
|