esp8266自定义工程框架
如何再起官方rtos sdk中规范的建立一个工程了,现在我们基于上一篇博客-esp8266对接阿里云平台做下规范。
首先将user_main.c中mqtt连接部分分离出来,写入user_mqtt.c中,分离是注意头文件包含,及一些全局变量设置。
user_main.c
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
//#include "esp_system.h"
//#include "freertos/FreeRTOS.h"
//#include "freertos/task.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "MQTTClient.h"
#include "user_mqtt.h"
#define DBG_C(...) printf("[%s,%d]",__FUNCTION__,__LINE__);printf(__VA_ARGS__)
/* FreeRTOS event group to signal when we are connected & ready to make a request */
EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
int CONNECTED_BIT = BIT0;
#define MQTT_CLIENT_THREAD_NAME "mqtt_client_thread"
#define MQTT_CLIENT_THREAD_STACK_WORDS 4096
#define MQTT_CLIENT_THREAD_PRIO 8
static const char *TAG = "example";
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
DBG_C("SYSTEM_EVENT_STA_START\n");
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
DBG_C("SYSTEM_EVENT_STA_GOT_IP\n");
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
DBG_C("SYSTEM_EVENT_STA_DISCONNECTED\n");
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
//wifi相关初始化
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
//设备需要连接wifi的ssid password配置
wifi_config_t wifi_config = {
.sta = {
.ssid = "cmcc",
.password = "qwe123456",
},
};
DBG_C("Setting WiFi configuration SSID %s...\n", wifi_config.sta.ssid);
//设置wifi 模式 station模式
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
//开启wif,联网
ESP_ERROR_CHECK(esp_wifi_start());
}
/******************************************************************************
* FunctionName : app_main
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void app_main(void)
{
//modify cdb 2019-12-19
// printf("SDK version:%s\n", esp_get_idf_version());
// Initialize NVS
esp_err_t ret = nvs_flash_init();
int i=0;
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
//初始化wifi,并且联网
initialise_wifi();
//创建mqtt 处理线程
ret = xTaskCreate(&mqtt_client_thread,
MQTT_CLIENT_THREAD_NAME,
MQTT_CLIENT_THREAD_STACK_WORDS,
NULL,
MQTT_CLIENT_THREAD_PRIO,
NULL);
if (ret != pdPASS) {
DBG_C("mqtt create client thread %s failed\n", MQTT_CLIENT_THREAD_NAME);
}
//程序将进入死循环,防止退出,并且打印运行时间log,单位s,也开启rtos任务调度
while(1)
{
DBG_C("the system is runing,runtime:%d\n",i++);
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
user_mqtt.c
#include <stdio.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "MQTTClient.h"
/* FreeRTOS event group to signal when we are connected & ready to make a request */
extern EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
extern int CONNECTED_BIT;
#define DBG_C(...) printf("[%s,%d]",__FUNCTION__,__LINE__);printf(__VA_ARGS__)
//mqtt 相关参数
#define CONFIG_MQTT_PAYLOAD_BUFFER (1*1024)
#define CONFIG_MQTT_BROKER "a1PC1yDIZoi.iot-as-mqtt.cn-shanghai.aliyuncs.com" // "106.15.83.29"//
#define CONFIG_MQTT_PORT 1883
#define CONFIG_MQTT_SUB_TOPIC "/a1PC1yDIZoi/hMdcyQzFeEa86qEwmOhf/user/report"
#define CONFIG_MQTT_PUB_TOPIC "/a1PC1yDIZoi/hMdcyQzFeEa86qEwmOhf/user/data"
static void messageArrived(MessageData *data)
{
char recvbuf[512];
memset(recvbuf,0,512);
strncpy(recvbuf,(char *)data->message->payload,data->message->payloadlen);
DBG_C("Message arrived[%d]:%s\n", data->message->payloadlen, recvbuf);
}
//publish
static int mqtt_client_send(MQTTClient * client)
{
MQTTMessage message;
static uint32_t count = 0;
char payload[512];
int rc=0;
memset(payload,0,512);
message.qos = QOS0;
message.retained = 0;
message.payload = payload;
sprintf(payload, "message number %d", ++count);
message.payloadlen = strlen(payload);
if((count%50) != 10)
return 0;
if ((rc = MQTTPublish(client, CONFIG_MQTT_PUB_TOPIC, &message)) != 0) {
DBG_C("Return code from MQTT publish is %d\n", rc);
} else {
DBG_C("MQTT published topic %s, len:%u heap:%u\n", CONFIG_MQTT_PUB_TOPIC, message.payloadlen, esp_get_free_heap_size());
}
if (rc != 0) {
return -1;
}
return rc;
}
void mqtt_client_thread(void *pvParameters)
{
char *payload = NULL;
MQTTClient client;
Network network;
int rc = 0;
char clientID[32] = {0};
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
//mqtt 网络连接初始化
NetworkInit(&network);
if (MQTTClientInit(&client, &network, 0, NULL, 0, NULL, 0) == false) {
DBG_C("mqtt init err\n");
vTaskDelete(NULL);
}
payload = malloc(CONFIG_MQTT_PAYLOAD_BUFFER);
if (!payload) {
DBG_C("mqtt malloc err\n");
} else {
memset(payload, 0x0, CONFIG_MQTT_PAYLOAD_BUFFER);
}
for (;;) {
DBG_C("wait wifi connect...\n");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
//创建mqtt socket连接,底层就是调用socket connect
if ((rc = NetworkConnect(&network, CONFIG_MQTT_BROKER, CONFIG_MQTT_PORT)) != 0) {
DBG_C("Return code from network connect is %d\n", rc);
continue;
}
connectData.MQTTVersion = 3;
//sprintf(clientID, "%s_%u", CONFIG_MQTT_CLIENT_ID, esp_random());
connectData.clientID.cstring = "a1PC1yDIZoi.hMdcyQzFeEa86qEwmOhf|securemode=3,timestamp=2524608000000,signmethod=hmacsha1,gw=0,ext=0,partner_id=example.demo.partner-id,module_id=example.demo.module-id|";
connectData.keepAliveInterval = 60;
connectData.username.cstring = "hMdcyQzFeEa86qEwmOhf&a1PC1yDIZoi";
connectData.password.cstring = "92ee26a897d43004c78e94065d6209d5f8ba1c65";
connectData.cleansession = 0;
DBG_C("MQTT Connecting\n");
//建立mqtt连接
if ((rc = MQTTConnect(&client, &connectData)) != 0) {
DBG_C("Return code from MQTT connect is %d\n", rc);
network.disconnect(&network);
continue;
}
DBG_C("MQTT Connected\n");
//订阅CONFIG_MQTT_SUB_TOPIC topic
rc = MQTTSubscribe(&client, CONFIG_MQTT_SUB_TOPIC, QOS0, messageArrived);
MQTTYield(&client, 500);
if (rc != 0) {
printf("[%s] Client Subscribed %d\n",__func__, rc);
goto fail;
}
DBG_C("MQTT subscribe to topic %s OK\n", CONFIG_MQTT_SUB_TOPIC);
int timeout_count = 0;
while (timeout_count < 10 ) {
rc = MQTTYield(&client, 500);
if(client.isconnected == 0)
{
printf("[%s]mqtt has disconnect!\n",__func__);
break;
}
if(client.ping_outstanding == 1) //pin失败!
{
timeout_count++;
printf("[%s]rc=%d, c->ping_outstanding=%d\r\n",__func__,rc, client.ping_outstanding);
}else{
timeout_count = 0;
}
// rc = mqtt_client_send(&client);
// if(rc < 0)
// DBG_C("MQTT PUBLISH FAIL\n");
vTaskDelay(100);
}
}
fail:
network.disconnect(&network);
DBG_C("mqtt_client_thread going to be deleted\n");
vTaskDelete(NULL);
return;
}
同时建立一个对应的头文件,user_mqtt.h(user_main,c中包含)
#ifndef _ESP8266_MY_MQTT_H_
#define _ESP8266_MY_MQTT_H_
void mqtt_client_thread(void *pvParameters);
#endif
现在看怎么修改component.mk
首先了解下sdk目录结构
如上图结构,想添加自己的功能模块,如上面方法添加即可。
代码添加完成,如何将起编译进代码呢?
我们需要修改工程目录下的components目录中的component.mk
修改如下:
#
# Component Makefile
#
#添加.c代码
COMPONENT_SRCDIRS := mqtt
#添加头文件
COMPONENT_ADD_INCLUDEDIRS += mqtt/include
看到这里,就能够再自定义工程里随意添加自己的功能了。
注意:这里建立说下修改项目名称
编译
make clean
make
查看结果:
来源:CSDN
作者:雪地里-成长之路
链接:https://blog.csdn.net/qq_38240926/article/details/103613144