目录
1、合并源码
- 创建一个运行FreeRTOS的工程这里是先找到任意一个能运行FreeRTOS的工程,其中包含文件如下:
- 添加MQTTClient文件夹并将MQTT相关文件添加进该文件夹 找到MQTT源码文件夹,将下面红框内MQTT编程所需相关文件添加进MQTTclient(MQTT相关文件为MQTT源码压缩包里的相关文件,压缩包放在最后的目录,有需要自取)
2、添加进keil工程
打开FreeRTOS文件的MDK-ARM中的keil工程进行如下操作:
common
添加进MQTTClient总共有5个文件,步骤与上类似,下面直接展示添加的主要.c文件:
mqtt
mqttclient
network
platform
3、解决编译错误问题
合并源码编译常见错误问题:头文件未被找到;数据类型错误;语法错误。
3.1 第一个错误
提示未能找到platform_timer.h,则需要将该文件的路径添加进去即可:
- 找到文件所在路径(这里为自己指定的文件夹)
- 打开keil的C/C++并将路径添加进去
头文件存放位置见如下:
- < > 类头文件一般存在于keil的系统目录或者自己指定的文件中
- " "类头文件一般存在于当前目录、keil的系统目录或者自己指定的文件中
如何查看是否存在于当前目录(用上述例子做演示):
可见当前目录并不存在该头文件(若存在与keil系统目录则应该不会报错),则需要到某些指定文件寻找并添加路径即可。
3.2 第二个错误
提示未能找到networrk.h,则需要将该文件的路径添加进去即可:
- 先看当前目录是否存在可见并不存在Network.h
- 找到文件所在路径(这里为自己指定的文件夹)
- 打开keil的C/C++并将路径添加进去
3.3 第三个错误
提示未能找到头文件中的mqtt_config.h,则需要将该文件的路径添加进去即可:
- 并未能找到该文件
- 直接将该文件注释掉即可
- 注释掉后发现mbedtls/config.h文件未能找到,索性直接注释掉即可
3.4 第四个错误
提示未加括号,属于语法错误,则需要修改对应代码:
- 找到定义的对应位置
- 判断出可能是TickType_t未进行定义,于是做以下修改:
#define configTICK_RATE_HZ 1000//((TickType_t)1000)
- 也可以找到TickType_t定义位置,添加相关代码找到该类型定义的位置,确定为需要添加红框内的.h文件,同时需要添加该.h文件的路径
3.5 第五个错误
提示找不到mqtt_errot.h,则需要将该文件的路径添加进去即可:
- 找到文件所在路径(这里为自己指定的文件夹)
- 打开keil的C/C++并将路径添加进去
3.6 第六个错误
提示找不到MQTTPacket.h,则需要将该文件的路径添加进去即可:
- 找到文件所在路径(这里为自己指定的文件夹)
- 打开keil的C/C++并将路径添加进去
3.7 第七个错误
提示找不到lwip/opt.h,由于在这里可以不使用这些头文件中的功能,所以可以将其注释掉:
#if 0
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include <lwip/sockets.h>
#include "lwip/netdb.h"
#endif
注释完后出现size_t未定义现象,于是通过分析可知nettype_tcp.h中的platform_net_socket.h使用到size_t,而size_t在mqtt_log.h中的stdio.h中被定义,所以应该在nettype_tcp.c中修改两个头文件位置即可:
接下来发现其他文件也调用到platform_net_socket.c也调用到size_t,于是在platform_net_socket.c包含mqtt_log.h即可(注意是在platform_net_socket.h上面):
最后发现socklen_t未被定义,通过查看发现所有函数只是调用socklen_t,并没有进行定义,于是我们在platform_socket.h直接进行定义即可,同时将socklen_t存在位置的代码删掉(为了先编译通过):
全部return 0即可,后续函数的实现我们会进行添加代码。
3.8 第八个错误
提示未能找到plooc_class.h,则需要将该文件的路径添加进去即可:
- 找到文件所在路径(这里为自己指定的文件夹)
- 打开keil的C/C++并将路径添加进去
- 添加完毕提示匿名结构体不支持GNU模式,这属于语法问题(语法不支持):
- 此结构体中存在匿名结构体,keil默认的ARMCC编译工具链不支持匿名结构体,GNU编译工具链支持匿名结构体。
//此结构体中存在匿名结构体,ARMCC不支持,逐步分析: def_class(mqtt_connack_data_t, private_member( uint8_t rc; uint8_t session_present; ) ) //def_class宏定义如下: #define def_class(__name, ...) __def_class(__name, __VA_ARGS__) //private_member宏定义如下: # define private_member(__member) __member //private_member宏定义如下: #define private_member(...) PLOOC_VISIBLE(__VA_ARGS__) //使用增加错误语法编译,查看编译报错方法来看,PLOOC_VISIBLE走的是下面的分支,其中存在一个没有名字的结构体即匿名结构体,AMRCC报错 # if defined(PLOOC_CFG_REMOVE_MEMORY_LAYOUT_BOUNDARY___USE_WITH_CAUTION___)//第一个分支 # define PLOOC_VISIBLE(...) __VA_ARGS__ # else//第二个分支 # define PLOOC_VISIBLE(...) \ struct { \ __VA_ARGS__ \ }PLOOC_ALIGN(PLOOC_ALIGNOF_STRUCT(__VA_ARGS__)); # endif
- 解决方法一:在keil编译器中增加
--gnu
,解决编译报错问题 - 解决方法二:在上述结构体展开文件plooc_class.h中定义PLOOC_CFG_REMOVE_MEMORY_LAYOUT_BOUNDARY___USE_WITH_CAUTION___即可解决编译报错问题
附录
MQTT源码链接:https://github.com/jiejieTop/mqttclient