keil移植MQTT时GNU语法报错

本文讲述了在STM32F103C8T6上移植KawaiiMQTT库时,遇到GNU语法错误,由于ARMCC不支持匿名结构体。提供了两种解决方法:一是开启keil编译器的GNU模式,二是自定义宏定义以绕过匿名结构体限制。

keil移植MQTT时GNU语法报错

目录

  • keil移植MQTT时GNU语法报错
    • 一、原因分析
    • 二、解决方法
      • 方法1
      • 方法2

背景描述:

STM32F103C8T6+ESP8266 WIFI模块,使用CubeMX生成简单的FreeRTOS代码,调通UART1和UART3,UART3与WIFI模块连接,UART1作为调试串口。

基于源代码移植杰杰的kawaii MQTT,clientmqtt,遇到GNU语法报错:

…\mqttclient\mqttclient\mqttclient.h(79): error: #3093: anonymous structs are only supported in --gnu mode, or when enabled with #pragma anon_unions

在这里插入图片描述

一、原因分析

官方解释:

https://developer.arm.com/documentation/dui0375/latest/Language-Extensions/Anonymous-classes–structures-and-unions

此结构体中存在匿名结构体,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(__n
Keil开发环境中移植MQTT协议,需要通过添加相关源码文件、配置工程设置以及实现必要的接口函数来完成。以下是具体的实现步骤: 1. **获取MQTT源码库** 从开源项目中获取适用于嵌入式平台的MQTT协议源码,例如Paho-MQTT-Embedded-C或MQTTClient-C库。这些库通常包含核心协议实现文件,如`MQTTClient.c`、`MQTTClient.h`,以及用于数据包处理的`MQTTPacket`目录中的文件[^3]。 2. **将源码添加到Keil工程** 打开Keil工程,右键点击项目中的`Source Group`,选择“Add Existing Files to Group”,将`MQTTClient.c`、`MQTTClient.h`以及`MQTTPacket`目录中的所有源文件添加到项目中。确保所有必要的头文件路径已正确配置,以便编译器可以找到这些文件[^2]。 3. **实现定器接口** 创建`MQTTTimer.c`和`MQTTTimer.h`文件,用于实现MQTT协议所需的定器功能。例如,定义`Timer`结构体以及`TimerInit`、`TimerCountdownMS`、`TimerIsExpired`等函数,确保MQTT客户端可以处理超和心跳机制[^2]。 4. **实现网络接口** 根据硬件平台,实现基于TCP或串口连接的网络接口。例如,定义`Network`结构体并实现`NetworkConnect`、`NetworkDisconnect`、`NetworkRead`、`NetworkWrite`等函数,使得MQTT客户端可以通过4G模块或以太网模块与MQTT服务器通信[^2]。 5. **解决编译问题** 在Keil中编译,可能会遇到语法兼容性问题,例如匿名结构体不被支持的错误。可以通过启用`#pragma anon_unions`或修改源码中涉及匿名结构体的部分来解决此类问题[^4]。 6. **测试与验证** 编写主程序,初始化定器和网络接口,并调用MQTT客户端API进行连接、订阅和发布操作。确保工程能够成功编译并通过串口调试信息验证MQTT通信流程是否正常[^1]。 ### 示例代码:MQTT客户端连接与发布消息 ```c #include "MQTTClient.h" #include "MQTTTimer.h" #include "Network.h" void mqtt_publish_example() { Network network; MQTTClient client; MQTTPacket_connectData data = MQTTPacket_connectData_initializer; int rc = 0; NetworkInit(&network); NetworkConnect(&network, "broker_address", 1883); // 替换为实际MQTT Broker地址 MQTTClientInit(&client, &network, 1000, send_buf, sizeof(send_buf), read_buf, sizeof(read_buf)); data.MQTTVersion = 4; // MQTT 3.1.1 data.clientID.cstring = "stm32_client"; data.username.cstring = "username"; data.password.cstring = "password"; rc = MQTTConnect(&client, &data); if (rc != 0) { // 处理连接失败 } MQTTMessage message; message.qos = QOS1; message.payload = (void *)"Hello MQTT"; message.payloadlen = 11; rc = MQTTPublish(&client, "topic/test", &message); if (rc != 0) { // 处理发布失败 } MQTTDisconnect(&client); NetworkDisconnect(&network); } ``` ### 示例代码:定器实现 ```c // MQTTTimer.h typedef struct { uint32_t end_time; } Timer; void TimerInit(Timer* timer); char TimerIsExpired(Timer* timer); void TimerCountdownMS(Timer* timer, unsigned int timeout); ``` ```c // MQTTTimer.c #include "MQTTTimer.h" #include "stm32f4xx_hal.h" // 根据实际平台调整 void TimerInit(Timer* timer) { timer->end_time = 0; } char TimerIsExpired(Timer* timer) { return (HAL_GetTick() >= timer->end_time) ? 1 : 0; } void TimerCountdownMS(Timer* timer, unsigned int timeout) { timer->end_time = HAL_GetTick() + timeout; } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

studyingdda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值