From 70ff2dad56fcde63145833a5a245efbd6666852a Mon Sep 17 00:00:00 2001 From: Chen Han Date: Tue, 29 Oct 2019 15:12:36 +0800 Subject: [PATCH] add mqtt demo --- board/Linux_Posix/mqtt_demo/CMakeLists.txt | 57 +++++++++ board/Linux_Posix/mqtt_demo/inc/mqtt_config.h | 17 +++ .../mqtt_demo/inc/socket_wrapper.h | 8 ++ board/Linux_Posix/mqtt_demo/inc/tos_config.h | 46 +++++++ board/Linux_Posix/mqtt_demo/readme.md | 47 +++++++ board/Linux_Posix/mqtt_demo/src/main.c | 104 ++++++++++++++++ .../mqtt_demo/src/socket_wrapper.c | 116 ++++++++++++++++++ 7 files changed, 395 insertions(+) create mode 100644 board/Linux_Posix/mqtt_demo/CMakeLists.txt create mode 100644 board/Linux_Posix/mqtt_demo/inc/mqtt_config.h create mode 100644 board/Linux_Posix/mqtt_demo/inc/socket_wrapper.h create mode 100644 board/Linux_Posix/mqtt_demo/inc/tos_config.h create mode 100644 board/Linux_Posix/mqtt_demo/readme.md create mode 100644 board/Linux_Posix/mqtt_demo/src/main.c create mode 100644 board/Linux_Posix/mqtt_demo/src/socket_wrapper.c diff --git a/board/Linux_Posix/mqtt_demo/CMakeLists.txt b/board/Linux_Posix/mqtt_demo/CMakeLists.txt new file mode 100644 index 00000000..747abae7 --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.8) + +project(mqtt_demo) + +set(CMAKE_BUILD_TYPE "Debug") +set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb") +set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") + +set(TINY_ROOT ../../../) + +## kernel +include_directories(${TINY_ROOT}/osal/cmsis_os) +include_directories(${TINY_ROOT}/kernel/core/include) +include_directories(${TINY_ROOT}/kernel/evtdrv/include) +include_directories(${TINY_ROOT}/kernel/hal/include) +include_directories(${TINY_ROOT}/kernel/pm/include) + +aux_source_directory(${TINY_ROOT}/osal/cmsis_os CMSIS_SRCS) +aux_source_directory(${TINY_ROOT}/kernel/core CORE_SRCS) +aux_source_directory(${TINY_ROOT}/kernel/evtdrv EVTDRV_SRCS) +aux_source_directory(${TINY_ROOT}/kernel/pm PM_SRCS) + +set(KERNEL_SRCS ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS}) + +## net +include_directories(${TINY_ROOT}/components/connectivity/Eclipse-Paho-MQTT/3rdparty/include) +include_directories(${TINY_ROOT}/components/connectivity/Eclipse-Paho-MQTT/wrapper/include) +include_directories(${TINY_ROOT}/net/sal_module_wrapper) + +aux_source_directory(${TINY_ROOT}/components/connectivity/Eclipse-Paho-MQTT/3rdparty/src MQTT_3RD_SRCS) +aux_source_directory(${TINY_ROOT}/components/connectivity/Eclipse-Paho-MQTT/wrapper/src MQTT_SRCS) +aux_source_directory(${TINY_ROOT}/net/sal_module_wrapper SAL_SRCS) + +set(NET_SRCS ${MQTT_3RD_SRCS} ${MQTT_SRCS} ${SAL_SRCS}) + +## arch +set(ARCH_ROOT ${TINY_ROOT}/arch/linux) + +include_directories(${ARCH_ROOT}/common/include) +include_directories(${ARCH_ROOT}/posix/gcc) + +aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS) +aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS) + +set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS}) + +set(TINY_SRCS ${ARCH_SRCS} ${KERNEL_SRCS} ${NET_SRCS}) + +## app +include_directories(./) +include_directories(./inc) + +aux_source_directory(./src APP_SRCS) + +add_executable(mqtt_demo ${APP_SRCS} ${TINY_SRCS}) + +target_link_libraries(mqtt_demo pthread) \ No newline at end of file diff --git a/board/Linux_Posix/mqtt_demo/inc/mqtt_config.h b/board/Linux_Posix/mqtt_demo/inc/mqtt_config.h new file mode 100644 index 00000000..9bde77b5 --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/inc/mqtt_config.h @@ -0,0 +1,17 @@ +#ifndef TOS_MQTT_CONFIG_H +#define TOS_MQTT_CONFIG_H + +#error please replace yourself server configuration +/** + * 1. run python tool + * ``` + * cd tiny/tools/ + * python3 mqtt_config_gen.py + * ``` + * then input your server information + * + * 2. tool will generate `mqtt_config.h` file, copy to replace this file + */ + +#endif + diff --git a/board/Linux_Posix/mqtt_demo/inc/socket_wrapper.h b/board/Linux_Posix/mqtt_demo/inc/socket_wrapper.h new file mode 100644 index 00000000..0df6bc06 --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/inc/socket_wrapper.h @@ -0,0 +1,8 @@ +#ifndef _SOCKET_WRAPPER_ +#define _SOCKET_WRAPPER_ + +#include "sal_module_wrapper.h" + +sal_module_t *get_socket_module(void); + +#endif //_SOCKET_WRAPPER_ \ No newline at end of file diff --git a/board/Linux_Posix/mqtt_demo/inc/tos_config.h b/board/Linux_Posix/mqtt_demo/inc/tos_config.h new file mode 100644 index 00000000..7cd5e2a9 --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/inc/tos_config.h @@ -0,0 +1,46 @@ +#ifndef _TOS_CONFIG_H_ +#define _TOS_CONFIG_H_ + +#include "stddef.h" + +#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量 + +#define TOS_CFG_ROUND_ROBIN_EN 1u // 配置TencentOS tiny的内核是否开启时间片轮转 + +#define TOS_CFG_OBJECT_VERIFY 0u // 配置TencentOS tiny是否校验指针合法 + +#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏 + +#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块 + +#define TOS_CFG_MMHEAP_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小 + +#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小 + +#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块 + +#define TOS_CFG_QUEUE_EN 1u // 配置TencentOS tiny是否开启队列模块 + +#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块 + +#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块 + +#define TOS_CFG_MMBLK_EN 1u + +#if (TOS_CFG_QUEUE_EN > 0u) +#define TOS_CFG_MSG_EN 1u +#else +#define TOS_CFG_MSG_EN 0u +#endif + +#define TOS_CFG_MSG_POOL_SIZE 10u // 配置TencentOS tiny消息队列大小 + +#define TOS_CFG_IDLE_TASK_STK_SIZE 256u // 配置TencentOS tiny空闲任务栈大小 + +#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率 + +#define TOS_CFG_CPU_CLOCK 1000000u // 配置TencentOS tiny CPU频率 + +#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式 + +#endif \ No newline at end of file diff --git a/board/Linux_Posix/mqtt_demo/readme.md b/board/Linux_Posix/mqtt_demo/readme.md new file mode 100644 index 00000000..aefa85de --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/readme.md @@ -0,0 +1,47 @@ +# How to run the demo in linux + +## step1 +make sure your develop environment. ++ `cmake` and version greater than 3.8.2 ++ `gcc` `gdb` `make` is installed + +## step2 +generate `mqtt_config.h` file to replace `./inc/mqtt_config.h` + +cd `tiny/tools/` directory, run python script +```bash +python3 mqtt_config_gen.py +``` + +then input your server configuration, generate `mqtt_config.h` file +copy to `./inc/` replace old file + +## step3 +make `build` directory and compile in `build` + +```bash +mkdir build && cd build +cmake .. +make +``` + +## step4 +run program !! + +```bash +# in build directory +./mqtt_demo +``` + +## other +you can copy this demo to other path, but if you want do it, +you need modify `CMakeLists.txt`. find line + +```cmake +set(TINY_ROOT ../../../) +``` + +and modify `path-to-tinyos` +```cmake +set(TINY_ROOT path-to-tinyos) +``` diff --git a/board/Linux_Posix/mqtt_demo/src/main.c b/board/Linux_Posix/mqtt_demo/src/main.c new file mode 100644 index 00000000..b2c150cf --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/src/main.c @@ -0,0 +1,104 @@ +#include "cmsis_os.h" +#include "socket_wrapper.h" +#include "sal_module_wrapper.h" +#include "mqtt_wrapper.h" +#include "mqtt_config.h" + +#include + +int sock_id = 0; + +//mqtt_publisher +#define MQTT_PUBLISHER_STK_SIZE 1024 +void mqtt_publisher(void *pdata); +osThreadDef(mqtt_publisher, osPriorityNormal, 1, MQTT_PUBLISHER_STK_SIZE); + +//mqtt_reciever +#define MQTT_RECIEVER_STK_SIZE 1024 +void mqtt_reciever(void *pdata); +osThreadDef(mqtt_reciever, osPriorityNormal, 1, MQTT_RECIEVER_STK_SIZE); + +void mqtt_publisher(void *pdata) +{ + mqtt_con_opt_t con_param; + con_param.keep_alive_interval = 2000; + con_param.cleansession = 1; + con_param.username = MQTT_USR_NAME; + con_param.password = MQTT_PASSWORD; + con_param.client_id = MQTT_CLIENT_ID; + + mqtt_pub_opt_t pub_param; + pub_param.dup = 0; + pub_param.qos = 0; + pub_param.retained = 0; + pub_param.id = 0; + pub_param.payload = "hello tencent cloud"; + pub_param.payload_len = 20; + pub_param.topic = MQTT_PUBLISH_TOPIC; + + mqtt_sub_opt_t sub_param; + sub_param.count = 1; + sub_param.dup = 0; + sub_param.id = 0; + sub_param.req_qos = 0; + sub_param.topic = MQTT_SUBSCRIBE_TOPIC; + + printf("start connect\n"); + tos_sal_module_register(get_socket_module()); + tos_sal_module_init(); + + sock_id = tos_mqtt_connect(MQTT_SERVER_IP, MQTT_SERVER_PORT, &con_param); + if (sock_id == -1) + { + printf("connect failed!!!\n"); + return -1; //to exit thread + } + printf("connect success\n"); + + if (tos_mqtt_subscribe(sock_id, &sub_param) != 0) + { + printf("subscribe failed!!!\n"); + }else{ + printf("subscribe success\n"); + } + + osThreadCreate(osThread(mqtt_reciever), NULL); // start receive + + for (;;) + { + printf("\n"); + printf("publish topic-->%s| data-->%s| \n", pub_param.topic, pub_param.payload); + if (tos_mqtt_publish(sock_id, &pub_param) != 0) { + printf("publish failed!!!\n"); + } + osDelay(2000); + } +} + +void mqtt_reciever(void *pdata) +{ + uint8_t read_data[100]; + int8_t topic[30]; + uint32_t read_len; + + for (;;) + { + read_len = tos_mqtt_receive(topic, sizeof(topic), read_data, sizeof(read_data)); + if (read_len >= 0) + { + printf("receive topic-->%s| data-->%s| \n", topic, read_data); + } + osDelay(100); + } +} + +int main(void) +{ + osKernelInitialize(); //TOS Tiny kernel initialize + osThreadCreate(osThread(mqtt_publisher), NULL); // start connect and publish + osKernelStart(); //Start TOS Tiny + + while (1) + { + } +} diff --git a/board/Linux_Posix/mqtt_demo/src/socket_wrapper.c b/board/Linux_Posix/mqtt_demo/src/socket_wrapper.c new file mode 100644 index 00000000..99867790 --- /dev/null +++ b/board/Linux_Posix/mqtt_demo/src/socket_wrapper.c @@ -0,0 +1,116 @@ +#include "socket_wrapper.h" +#include "cmsis_os.h" + +#include +#include +#include +#include +#include + +static osMutexId socket_send_lock, socket_recv_lock; + +osMutexDef(socket_send_lock); +osMutexDef(socket_recv_lock); + +int socket_init(void) +{ + socket_send_lock = osMutexCreate(osMutex(socket_send_lock)); + socket_recv_lock = osMutexCreate(osMutex(socket_recv_lock)); + + return ((socket_recv_lock != NULL) && (socket_send_lock != NULL)); +} + +int socket_connect(const char *ip, const char *port, sal_proto_t proto) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(atoi(port))}; + int socket_proto = 0; + + inet_pton(AF_INET, ip, &addr.sin_addr); + + if (TOS_SAL_PROTO_TCP == proto) + { + socket_proto = IPPROTO_TCP; + } + else if (TOS_SAL_PROTO_UDP == proto) + { + socket_proto = IPPROTO_UDP; + } + else + { + return -1; + } + + int socket_id = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + connect(socket_id, &addr, sizeof(addr)); + return socket_id; +} + +int socket_send(int sock, const void *buf, size_t len) +{ + ssize_t send_len = 0, state; + if (sock < 0) + return -1; + osMutexWait(socket_send_lock, TOS_TIME_FOREVER); + do + { + state = send(sock, (buf + send_len), (len - send_len), MSG_DONTWAIT); + if (state > 0) + { + send_len += state; + } + if (send_len != len) + { + osDelay(5); + } + } while (len != send_len); + osMutexRelease(socket_send_lock); + return send_len; +} + +int socket_recv(int sock, void *buf, size_t len) +{ + ssize_t recv_len = 0, state; + if (sock < 0) + return -1; + osMutexWait(socket_recv_lock, TOS_TIME_FOREVER); + do + { + state = recv(sock, (buf + recv_len), (len - recv_len), MSG_DONTWAIT); + if (state > 0) + { + recv_len += state; + } + if (recv_len != len) + { + osDelay(5); + } + } while (len != recv_len); + osMutexRelease(socket_recv_lock); + return recv_len; +} + +int socket_close(int sock) +{ + close(sock); +} + +static sal_module_t linux_sal = { + .init = socket_init, + .connect = socket_connect, + .send = socket_send, + .recv = socket_recv, + .close = socket_close, + // .sendto = NULL, + // .recv_timeout = NULL, + // .recvfrom = NULL, + // .recvfrom_timeout = NULL, + // .parse_domain = NULL, +}; + +sal_module_t *get_socket_module(void) +{ + return (&linux_sal); +}