From e929eef26e33ebae246a362008c8c1bfee35419c Mon Sep 17 00:00:00 2001 From: Espressif Systems Date: Mon, 8 Jan 2018 10:26:20 +0800 Subject: [PATCH] feat(example): Add mqtt client demo internal: 6f953538 --- examples/mqtt_demo/Makefile | 123 +++++++++++++++ examples/mqtt_demo/README.md | 12 ++ examples/mqtt_demo/gen_misc.sh | 191 +++++++++++++++++++++++ examples/mqtt_demo/include/user_config.h | 32 ++++ examples/mqtt_demo/user/MQTTEcho.c | 106 +++++++++++++ examples/mqtt_demo/user/Makefile | 44 ++++++ examples/mqtt_demo/user/user_main.c | 122 +++++++++++++++ 7 files changed, 630 insertions(+) create mode 100644 examples/mqtt_demo/Makefile create mode 100644 examples/mqtt_demo/README.md create mode 100755 examples/mqtt_demo/gen_misc.sh create mode 100644 examples/mqtt_demo/include/user_config.h create mode 100755 examples/mqtt_demo/user/MQTTEcho.c create mode 100644 examples/mqtt_demo/user/Makefile create mode 100644 examples/mqtt_demo/user/user_main.c diff --git a/examples/mqtt_demo/Makefile b/examples/mqtt_demo/Makefile new file mode 100644 index 00000000..a1dd8f1a --- /dev/null +++ b/examples/mqtt_demo/Makefile @@ -0,0 +1,123 @@ +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lcirom \ + -lgcc \ + -lhal \ + -lcrypto \ + -lfreertos \ + -llwip \ + -lmain \ + -lnet80211 \ + -lphy \ + -lpp \ + -lmbedtls \ + -lopenssl \ + -lmqtt \ + -lwpa \ + $(DEP_LIBS_eagle.app.v6)\ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +# -DMQTT_TASK: Define MQTT_TASK to enable MQTT start background +# thread for a client. +CONFIGURATION_DEFINES = -DICACHE_FLASH -DMQTT_TASK + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# +INCLUDES := $(INCLUDES) -I $(PDIR)include +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/examples/mqtt_demo/README.md b/examples/mqtt_demo/README.md new file mode 100644 index 00000000..9c9958ec --- /dev/null +++ b/examples/mqtt_demo/README.md @@ -0,0 +1,12 @@ +# Paho MQTT demo + +This example shows how to use the Eclipse Paho MQTT as an example of ESP8266 RTOS SDK. In this demo, the following functions can be realized: MQTT publish, subscribe and ping. + +1. Config SSID and PASSWORD of the Wi-Fi AP to be connected in user_config.h + +2. Config MQTT Broker to be connected in MQTTEcho.c + +3. Export SDK_PATH and BIN_PATH, run gen_misc.sh to compile, then download and run the demo + +4. MQTT client will connect with the MQTT Broker, subscribe to the topic "ESP8266/sample/sub", and will publish messages + to the topic "ESP8266/sample/pub" diff --git a/examples/mqtt_demo/gen_misc.sh b/examples/mqtt_demo/gen_misc.sh new file mode 100755 index 00000000..11bd9d0c --- /dev/null +++ b/examples/mqtt_demo/gen_misc.sh @@ -0,0 +1,191 @@ +#!/bin/bash + +:< + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __USER_CONFIG_H__ +#define __USER_CONFIG_H__ + +#define SSID "TEST001" +#define PASSWORD "1234567890" + +#endif + diff --git a/examples/mqtt_demo/user/MQTTEcho.c b/examples/mqtt_demo/user/MQTTEcho.c new file mode 100755 index 00000000..50fb1b0d --- /dev/null +++ b/examples/mqtt_demo/user/MQTTEcho.c @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "mqtt/MQTTClient.h" + +#define MQTT_CLIENT_THREAD_NAME "mqtt_client_thread" +#define MQTT_CLIENT_THREAD_STACK_WORDS 2048 +#define MQTT_CLIENT_THREAD_PRIO 8 +LOCAL xTaskHandle mqttc_client_handle; + +#define MQTT_BROKER "192.168.1.100" /* Address of the MQTT Broker to be connected*/ + +void messageArrived(MessageData* data) +{ + printf("Message arrived: %s\n", data->message->payload); +} + +static void mqtt_client_thread(void *pvParameters) +{ + printf("mqtt client thread starts\n"); + MQTTClient client; + Network network; + unsigned char sendbuf[80], readbuf[80] = {0}; + int rc = 0, count = 0; + MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer; + + pvParameters = 0; + NetworkInit(&network); + MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf)); + + char* address = MQTT_BROKER; + if ((rc = NetworkConnect(&network, address, 1883)) != 0) + printf("Return code from network connect is %d\n", rc); + +#if defined(MQTT_TASK) + if ((rc = MQTTStartTask(&client)) != pdPASS) + printf("Return code from start tasks is %d\n", rc); + else + printf("Use MQTTStartTask\n"); +#endif + + connectData.MQTTVersion = 3; + connectData.clientID.cstring = "ESP8266_sample"; + + if ((rc = MQTTConnect(&client, &connectData)) != 0) + printf("Return code from MQTT connect is %d\n", rc); + else + printf("MQTT Connected\n"); + + if ((rc = MQTTSubscribe(&client, "ESP8266/sample/sub", 2, messageArrived)) != 0) + printf("Return code from MQTT subscribe is %d\n", rc); + else + printf("MQTT subscribe to topic \"ESP8266/sample/sub\"\n"); + + while (++count) { + MQTTMessage message; + char payload[30]; + + message.qos = QOS2; + message.retained = 0; + message.payload = payload; + sprintf(payload, "message number %d", count); + message.payloadlen = strlen(payload); + + if ((rc = MQTTPublish(&client, "ESP8266/sample/pub", &message)) != 0) + printf("Return code from MQTT publish is %d\n", rc); + else + printf("MQTT publish topic \"ESP8266/sample/pub\", message number is %d\n", count); + + vTaskDelay(100000 / portTICK_RATE_MS); //send every 100 seconds + } + + printf("mqtt_client_thread going to be deleted\n"); + vTaskDelete(NULL); + return; +} + +void user_conn_init(void) +{ + int ret; + ret = xTaskCreate(mqtt_client_thread, + MQTT_CLIENT_THREAD_NAME, + MQTT_CLIENT_THREAD_STACK_WORDS, + NULL, + MQTT_CLIENT_THREAD_PRIO, + &mqttc_client_handle); + if (ret != pdPASS) { + printf("mqtt create client thread %s failed\n", MQTT_CLIENT_THREAD_NAME); + } +} diff --git a/examples/mqtt_demo/user/Makefile b/examples/mqtt_demo/user/Makefile new file mode 100644 index 00000000..dd3837c7 --- /dev/null +++ b/examples/mqtt_demo/user/Makefile @@ -0,0 +1,44 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libuser.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/mqtt_demo/user/user_main.c b/examples/mqtt_demo/user/user_main.c new file mode 100644 index 00000000..3481bbc9 --- /dev/null +++ b/examples/mqtt_demo/user/user_main.c @@ -0,0 +1,122 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "esp_common.h" +#include "user_config.h" + +/****************************************************************************** + * FunctionName : user_rf_cal_sector_set + * Description : SDK just reversed 4 sectors, used for rf init data and paramters. + * We add this function to force users to set rf cal sector, since + * we don't know which sector is free in user's application. + * sector map for last several sectors : ABCCC + * A : rf cal + * B : rf init data + * C : sdk parameters + * Parameters : none + * Returns : rf cal sector +*******************************************************************************/ +uint32 user_rf_cal_sector_set(void) +{ + flash_size_map size_map = system_get_flash_size_map(); + uint32 rf_cal_sec = 0; + + switch (size_map) { + case FLASH_SIZE_4M_MAP_256_256: + rf_cal_sec = 128 - 5; + break; + + case FLASH_SIZE_8M_MAP_512_512: + rf_cal_sec = 256 - 5; + break; + + case FLASH_SIZE_16M_MAP_512_512: + case FLASH_SIZE_16M_MAP_1024_1024: + rf_cal_sec = 512 - 5; + break; + + case FLASH_SIZE_32M_MAP_512_512: + case FLASH_SIZE_32M_MAP_1024_1024: + rf_cal_sec = 1024 - 5; + break; + case FLASH_SIZE_64M_MAP_1024_1024: + rf_cal_sec = 2048 - 5; + break; + case FLASH_SIZE_128M_MAP_1024_1024: + rf_cal_sec = 4096 - 5; + break; + default: + rf_cal_sec = 0; + break; + } + + return rf_cal_sec; +} + +void wifi_event_handler_cb(System_Event_t *event) +{ + if (event == NULL) { + return; + } + + switch (event->event_id) { + case EVENT_STAMODE_GOT_IP: + os_printf("sta got ip ,create task and free heap size is %d\n", system_get_free_heap_size()); + user_conn_init(); + break; + + case EVENT_STAMODE_CONNECTED: + os_printf("sta connected\n"); + break; + + case EVENT_STAMODE_DISCONNECTED: + wifi_station_connect(); + break; + + default: + break; + } +} + +/****************************************************************************** + * FunctionName : user_init + * Description : entry of user application, init user function here + * Parameters : none + * Returns : none +*******************************************************************************/ +void user_init(void) +{ + os_printf("SDK version:%s %d\n", system_get_sdk_version(), system_get_free_heap_size()); + wifi_set_opmode(STATION_MODE); + + struct station_config config; + bzero(&config, sizeof(struct station_config)); + sprintf(config.ssid, SSID); + sprintf(config.password, PASSWORD); + wifi_station_set_config(&config); + + wifi_set_event_handler_cb(wifi_event_handler_cb); + + wifi_station_connect(); +}