mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-21 02:15:55 +08:00
更新硬件SDK
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
### example_sysdep_api_test.c
|
||||
|
||||
linksdk自带的适配接口测试代码,用于测试接口适配是否有问题
|
||||
|
||||
|
||||
|
||||
### example_mqtt_basic.c
|
||||
|
||||
linksdk自带的连接阿里云服务器mqtt基础功能测试demo
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 在xmake.lua中通过如下两行代码来切换编译demo
|
||||
|
||||
```lua
|
||||
add_files("/src/example_sysdep_api_test.c",{public = true})
|
||||
-- add_files("/src/example_mqtt_basic.c",{public = true})
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
#ifndef __RTE_DEVICE_H
|
||||
#define __RTE_DEVICE_H
|
||||
|
||||
#include "ec618.h"
|
||||
|
||||
/* Peripheral IO Mode Select, Must Configure First !!!
|
||||
Note, when receiver works in DMA_MODE, interrupt is also enabled to transfer tailing bytes.
|
||||
*/
|
||||
|
||||
#define POLLING_MODE 0x1
|
||||
#define DMA_MODE 0x2
|
||||
#define IRQ_MODE 0x3
|
||||
#define UNILOG_MODE 0x4
|
||||
|
||||
#define RTE_UART0_TX_IO_MODE UNILOG_MODE
|
||||
#define RTE_UART0_RX_IO_MODE IRQ_MODE
|
||||
#define USART0_RX_TRIG_LVL (30)
|
||||
|
||||
#define RTE_UART1_TX_IO_MODE DMA_MODE
|
||||
#define RTE_UART1_RX_IO_MODE DMA_MODE
|
||||
|
||||
#define RTE_UART2_TX_IO_MODE POLLING_MODE
|
||||
#define RTE_UART2_RX_IO_MODE DMA_MODE
|
||||
|
||||
#define RTE_SPI0_IO_MODE POLLING_MODE
|
||||
|
||||
#define RTE_SPI1_IO_MODE POLLING_MODE
|
||||
|
||||
#define RTE_I2C0_IO_MODE POLLING_MODE
|
||||
#define RTE_I2C1_IO_MODE POLLING_MODE
|
||||
|
||||
|
||||
// I2C0 (Inter-integrated Circuit Interface) [Driver_I2C0]
|
||||
// Configuration settings for Driver_I2C0 in component ::Drivers:I2C
|
||||
#define RTE_I2C0 1
|
||||
|
||||
// { PAD_PIN28}, // 0 : gpio13 / 2 : I2C0 SCL
|
||||
// { PAD_PIN27}, // 0 : gpio12 / 2 : I2C0 SDA
|
||||
#define RTE_I2C0_SCL_BIT 28 // AUDIO use 28
|
||||
#define RTE_I2C0_SCL_FUNC PAD_MUX_ALT2
|
||||
|
||||
#define RTE_I2C0_SDA_BIT 27 // AUDIO use 27
|
||||
#define RTE_I2C0_SDA_FUNC PAD_MUX_ALT2
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_I2C0_DMA_TX_EN 0
|
||||
#define RTE_I2C0_DMA_TX_REQID DMA_REQUEST_I2C0_TX
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_I2C0_DMA_RX_EN 0
|
||||
#define RTE_I2C0_DMA_RX_REQID DMA_REQUEST_I2C0_RX
|
||||
|
||||
// I2C1 (Inter-integrated Circuit Interface) [Driver_I2C1]
|
||||
// Configuration settings for Driver_I2C1 in component ::Drivers:I2C
|
||||
#define RTE_I2C1 1
|
||||
|
||||
// { PAD_PIN20}, // 0 : gpio5 / 2 : I2C1 SCL
|
||||
// { PAD_PIN19}, // 0 : gpio4 / 2 : I2C1 SDA
|
||||
#define RTE_I2C1_SCL_BIT 20
|
||||
#define RTE_I2C1_SCL_FUNC PAD_MUX_ALT2
|
||||
|
||||
#define RTE_I2C1_SDA_BIT 19
|
||||
#define RTE_I2C1_SDA_FUNC PAD_MUX_ALT2
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_I2C1_DMA_TX_EN 1
|
||||
#define RTE_I2C1_DMA_TX_REQID DMA_REQUEST_I2C1_TX
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_I2C1_DMA_RX_EN 1
|
||||
#define RTE_I2C1_DMA_RX_REQID DMA_REQUEST_I2C1_RX
|
||||
|
||||
|
||||
// UART0 (Universal asynchronous receiver transmitter) [Driver_USART0]
|
||||
// Configuration settings for Driver_USART0 in component ::Drivers:USART
|
||||
#define RTE_UART0_CTS_PIN_EN 0
|
||||
#define RTE_UART0_RTS_PIN_EN 0
|
||||
|
||||
// { PAD_PIN27}, // 0 : gpio12 / 3 : UART0 RTSn
|
||||
// { PAD_PIN28}, // 0 : gpio13 / 3 : UART0 CTSn
|
||||
// { PAD_PIN29}, // 0 : gpio14 / 3 : UART0 RXD
|
||||
// { PAD_PIN30}, // 0 : gpio15 / 3 : UART0 TXD
|
||||
#define RTE_UART0_RTS_BIT 27
|
||||
#define RTE_UART0_RTS_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_UART0_CTS_BIT 28
|
||||
#define RTE_UART0_CTS_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_UART0_RX_BIT 29
|
||||
#define RTE_UART0_RX_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_UART0_TX_BIT 30
|
||||
#define RTE_UART0_TX_FUNC PAD_MUX_ALT3
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_UART0_DMA_TX_REQID DMA_REQUEST_USART0_TX
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_UART0_DMA_RX_REQID DMA_REQUEST_USART0_RX
|
||||
|
||||
// UART1 (Universal asynchronous receiver transmitter) [Driver_USART1]
|
||||
// Configuration settings for Driver_USART1 in component ::Drivers:USART
|
||||
#define RTE_UART1_CTS_PIN_EN 1
|
||||
#define RTE_UART1_RTS_PIN_EN 1
|
||||
|
||||
// { PAD_PIN31}, // 0 : gpio16 / 1 : UART1 RTS
|
||||
// { PAD_PIN32}, // 0 : gpio17 / 1 : UART1 CTS
|
||||
// { PAD_PIN33}, // 0 : gpio18 / 1 : UART1 RXD
|
||||
// { PAD_PIN34}, // 0 : gpio19 / 1 : UART1 TXD
|
||||
#define RTE_UART1_RTS_BIT 31
|
||||
#define RTE_UART1_RTS_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_UART1_CTS_BIT 32
|
||||
#define RTE_UART1_CTS_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_UART1_RX_BIT 33
|
||||
#define RTE_UART1_RX_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_UART1_TX_BIT 34
|
||||
#define RTE_UART1_TX_FUNC PAD_MUX_ALT1
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_UART1_DMA_TX_REQID DMA_REQUEST_USART1_TX
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_UART1_DMA_RX_REQID DMA_REQUEST_USART1_RX
|
||||
|
||||
// UART2 (Universal asynchronous receiver transmitter) [Driver_USART2]
|
||||
// Configuration settings for Driver_USART2 in component ::Drivers:USART
|
||||
#define RTE_UART2_CTS_PIN_EN 0
|
||||
#define RTE_UART2_RTS_PIN_EN 0
|
||||
|
||||
// { PAD_PIN25}, // 0 : gpio10 / 3 : UART2 RXD
|
||||
// { PAD_PIN26}, // 0 : gpio11 / 3 : UART2 TXD
|
||||
#define RTE_UART2_RX_BIT 25
|
||||
#define RTE_UART2_RX_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_UART2_TX_BIT 26
|
||||
#define RTE_UART2_TX_FUNC PAD_MUX_ALT3
|
||||
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_UART2_DMA_TX_REQID DMA_REQUEST_USART2_TX
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_UART2_DMA_RX_REQID DMA_REQUEST_USART2_RX
|
||||
|
||||
// SPI0 (Serial Peripheral Interface) [Driver_SPI0]
|
||||
// Configuration settings for Driver_SPI0 in component ::Drivers:SPI
|
||||
#define RTE_SPI0 1
|
||||
|
||||
// { PAD_PIN21}, // 0 : gpio16 / 1 : UART1 RTS / 2 : SPI0 SSn
|
||||
// { PAD_PIN22}, // 0 : gpio11 / 1 : UART1 CTS / 2 : SPI0 MOSI
|
||||
// { PAD_PIN23}, // 0 : gpio14 / 1 : UART1 RXD / 2 : SPI0 MISO
|
||||
// { PAD_PIN24}, // 0 : gpio15 / 1 : UART1 TXD / 2 : SPI0 SCLK
|
||||
#define RTE_SPI0_SSN_BIT 21
|
||||
#define RTE_SPI0_SSN_FUNC PAD_MUX_ALT2
|
||||
|
||||
#define RTE_SPI0_MOSI_BIT 22
|
||||
#define RTE_SPI0_MOSI_FUNC PAD_MUX_ALT2
|
||||
|
||||
#define RTE_SPI0_MISO_BIT 23
|
||||
#define RTE_SPI0_MISO_FUNC PAD_MUX_ALT2
|
||||
|
||||
#define RTE_SPI0_SCLK_BIT 24
|
||||
#define RTE_SPI0_SCLK_FUNC PAD_MUX_ALT2
|
||||
|
||||
#define RTE_SPI0_SSN_GPIO_INSTANCE 1
|
||||
#define RTE_SPI0_SSN_GPIO_INDEX 0
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_SPI0_DMA_TX_REQID DMA_REQUEST_SPI0_TX
|
||||
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_SPI0_DMA_RX_REQID DMA_REQUEST_SPI0_RX
|
||||
|
||||
// SPI1 (Serial Peripheral Interface) [Driver_SPI1]
|
||||
// Configuration settings for Driver_SPI1 in component ::Drivers:SPI
|
||||
#define RTE_SPI1 1
|
||||
|
||||
// { PAD_PIN13}, // 0 : gpio2 / 1 : UART0 RTSn / 3 : SPI1 SSn
|
||||
// { PAD_PIN14}, // 0 : gpio3 / 1 : UART0 CTSn / 3 : SPI1 MOSI
|
||||
// { PAD_PIN15}, // 0 : gpio4 / 1 : UART0 RXD / 3 : SPI1 MISO
|
||||
// { PAD_PIN16}, // 0 : gpio5 / 1 : UART0 TXD / 3 : SPI1 SCLK
|
||||
#define RTE_SPI1_SSN_BIT 13
|
||||
#define RTE_SPI1_SSN_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_SPI1_MOSI_BIT 14
|
||||
#define RTE_SPI1_MOSI_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_SPI1_MISO_BIT 15
|
||||
#define RTE_SPI1_MISO_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_SPI1_SCLK_BIT 16
|
||||
#define RTE_SPI1_SCLK_FUNC PAD_MUX_ALT3
|
||||
|
||||
#define RTE_SPI1_SSN_GPIO_INSTANCE 0
|
||||
#define RTE_SPI1_SSN_GPIO_INDEX 2
|
||||
|
||||
// DMA
|
||||
// Tx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_SPI1_DMA_TX_REQID DMA_REQUEST_SPI1_TX
|
||||
|
||||
// Rx
|
||||
// Channel <0=>0 <1=>1 <2=>2 <3=>3 <4=>4 <5=>5 <6=>6 <7=>7
|
||||
#define RTE_SPI1_DMA_RX_REQID DMA_REQUEST_SPI1_RX
|
||||
|
||||
|
||||
// PWM0 Controller [Driver_PWM0]
|
||||
// Configuration settings for Driver_PWM0 in component ::Drivers:PWM
|
||||
#define RTE_PWM 1
|
||||
|
||||
#define EFUSE_INIT_MODE POLLING_MODE
|
||||
#define L2CTLS_INIT_MODE POLLING_MODE
|
||||
|
||||
#define FLASH_BARE_RW_MODE 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define RTE_UART0 1
|
||||
#define RTE_UART1 1
|
||||
#define RTE_UART2 1
|
||||
/* to enable external thermal */
|
||||
#define EXTERNAL_NTC_EXIST 0
|
||||
|
||||
|
||||
#if (RTE_UART1 == 1)
|
||||
#define UART1_DTR_PAD_INDEX 26 // GPIO11
|
||||
#define UART1_DTR_GPIO_INSTANCE 0
|
||||
#define UART1_DTR_GPIO_PIN 11
|
||||
|
||||
#define UART1_RI_PAD_INDEX 44 // AONIO 4 = GPIO24
|
||||
#define UART1_RI_GPIO_INSTANCE 1
|
||||
#define UART1_RI_GPIO_PIN 8
|
||||
#define UART1_RI_PWM_INSTANCE 1
|
||||
#define UART1_RI_PWM_CLK_ID FCLK_TIMER1
|
||||
#define UART1_RI_PWM_CLK_SEL FCLK_TIMER1_SEL_26M
|
||||
|
||||
#define UART1_DCD_PAD_INDEX 45 // AONIO 5 = GPIO25
|
||||
#define UART1_DCD_GPIO_INSTANCE 1
|
||||
#define UART1_DCD_GPIO_PIN 9
|
||||
#endif
|
||||
|
||||
#if (RTE_UART2 == 1)
|
||||
#define UART2_DTR_PAD_INDEX 25 // GPIO10
|
||||
#define UART2_DTR_GPIO_INSTANCE 0
|
||||
#define UART2_DTR_GPIO_PIN 10
|
||||
|
||||
#define UART2_RI_PAD_INDEX 43 // AONIO 3 = GPIO23
|
||||
#define UART2_RI_GPIO_INSTANCE 1
|
||||
#define UART2_RI_GPIO_PIN 7
|
||||
#define UART2_RI_PWM_INSTANCE 0
|
||||
#define UART2_RI_PWM_CLK_ID FCLK_TIMER0
|
||||
#define UART2_RI_PWM_CLK_SEL FCLK_TIMER0_SEL_26M
|
||||
|
||||
#define UART2_DCD_PAD_INDEX 47 // AONIO 7 = GPIO27
|
||||
#define UART2_DCD_GPIO_INSTANCE 1
|
||||
#define UART2_DCD_GPIO_PIN 11
|
||||
#endif
|
||||
|
||||
|
||||
#define NETLIGHT_PAD_INDEX 46 // AONIO 6 = GPIO26
|
||||
#define NETLIGHT_PAD_ALT_FUNC PAD_MUX_ALT5
|
||||
#define NETLIGHT_PWM_INSTANCE 3
|
||||
|
||||
//USIM1 OPTION1
|
||||
#define USIM1_URST_OP1_PAD_INDEX 19 // GPIO4
|
||||
#define USIM1_URST_OP1_GPIO_INSTANCE 0
|
||||
#define USIM1_URST_OP1_GPIO_PIN 4
|
||||
#define USIM1_UCLK_OP1_PAD_INDEX 20 // GPIO5
|
||||
#define USIM1_UCLK_OP1_GPIO_INSTANCE 0
|
||||
#define USIM1_UCLK_OP1_GPIO_PIN 5
|
||||
#define USIM1_UIO_OP1_PAD_INDEX 21 // GPIO6
|
||||
#define USIM1_UIO_OP1_GPIO_INSTANCE 0
|
||||
#define USIM1_UIO_OP1_GPIO_PIN 6
|
||||
|
||||
//USIM1 OPTION2
|
||||
#define USIM1_UIO_OP2_PAD_INDEX 27 // GPIO12
|
||||
#define USIM1_UIO_OP2_GPIO_INSTANCE 0
|
||||
#define USIM1_UIO_OP2_GPIO_PIN 12
|
||||
#define USIM1_URST_OP2_PAD_INDEX 28 // GPIO13
|
||||
#define USIM1_URST_OP2_GPIO_INSTANCE 0
|
||||
#define USIM1_URST_OP2_GPIO_PIN 13
|
||||
#define USIM1_UCLK_OP2_PAD_INDEX 29 // GPIO14
|
||||
#define USIM1_UCLK_OP2_GPIO_INSTANCE 0
|
||||
#define USIM1_UCLK_OP2_GPIO_PIN 14
|
||||
|
||||
//USIM1 clock latched by AONIO, for example, use AONIO-6 test on EVB
|
||||
#define AONIO_6_PAD_INDEX 46 // AONIO 6 = GPIO26
|
||||
#define AONIO_6_GPIO_INSTANCE 1
|
||||
#define AONIO_6_GPIO_PIN 10
|
||||
|
||||
#define RTE_CSPI0 0
|
||||
|
||||
#define RTE_CSPI0_MCLK_PAD_ADDR 39
|
||||
#define RTE_CSPI0_MCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI0_PCLK_PAD_ADDR 35
|
||||
#define RTE_CSPI0_PCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI0_CS_PAD_ADDR 36
|
||||
#define RTE_CSPI0_CS_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI0_SDO0_PAD_ADDR 37
|
||||
#define RTE_CSPI0_SDO0_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI0_SDO1_PAD_ADDR 38
|
||||
#define RTE_CSPI0_SDO1_FUNC PAD_MUX_ALT1
|
||||
|
||||
// DMA CSPI0 Request ID
|
||||
#define RTE_CSPI0_DMA_RX_REQID DMA_REQUEST_I2S0_RX
|
||||
|
||||
// CSPI1 Configuration
|
||||
#define RTE_CSPI1 1
|
||||
|
||||
#define RTE_CSPI1_MCLK_PAD_ADDR 18
|
||||
#define RTE_CSPI1_MCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI1_PCLK_PAD_ADDR 19
|
||||
#define RTE_CSPI1_PCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI1_CS_PAD_ADDR 20
|
||||
#define RTE_CSPI1_CS_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI1_SDO0_PAD_ADDR 21
|
||||
#define RTE_CSPI1_SDO0_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_CSPI1_SDO1_PAD_ADDR 22
|
||||
#define RTE_CSPI1_SDO1_FUNC PAD_MUX_ALT1
|
||||
|
||||
// DMA CSPI1 Request ID
|
||||
#define RTE_CSPI1_DMA_RX_REQID DMA_REQUEST_I2S1_RX
|
||||
|
||||
#endif /* __RTE_DEVICE_H */
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* 这个例程适用于`Linux`这类支持task的POSIX设备, 它演示了用SDK配置MQTT参数并建立连接, 之后创建2个线程
|
||||
*
|
||||
* + 一个线程用于保活长连接
|
||||
* + 一个线程用于接收消息, 并在有消息到达时进入默认的数据回调, 在连接状态变化时进入事件回调
|
||||
*
|
||||
* 需要用户关注或修改的部分, 已经用 TODO 在注释中标明
|
||||
*
|
||||
*/
|
||||
#include "common_api.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "aiot_state_api.h"
|
||||
#include "aiot_sysdep_api.h"
|
||||
#include "aiot_mqtt_api.h"
|
||||
#include "luat_mobile.h"
|
||||
#include "luat_rtos.h"
|
||||
#include "luat_debug.h"
|
||||
|
||||
/* TODO: 替换为自己设备的三元组 */
|
||||
char *product_key = "${YourProductKey}";
|
||||
char *device_name = "${YourDeviceName}";
|
||||
char *device_secret = "${YourDeviceSecret}";
|
||||
|
||||
/*
|
||||
TODO: 替换为自己实例的接入点
|
||||
|
||||
对于企业实例, 或者2021年07月30日之后(含当日)开通的物联网平台服务下公共实例
|
||||
mqtt_host的格式为"${YourInstanceId}.mqtt.iothub.aliyuncs.com"
|
||||
其中${YourInstanceId}: 请替换为您企业/公共实例的Id
|
||||
|
||||
对于2021年07月30日之前(不含当日)开通的物联网平台服务下公共实例
|
||||
需要将mqtt_host修改为: mqtt_host = "${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com"
|
||||
其中, ${YourProductKey}:请替换为设备所属产品的ProductKey。可登录物联网平台控制台,在对应实例的设备详情页获取。
|
||||
${YourRegionId}:请替换为您的物联网平台设备所在地域代码, 比如cn-shanghai等
|
||||
该情况下完整mqtt_host举例: a1TTmBPIChA.iot-as-mqtt.cn-shanghai.aliyuncs.com
|
||||
|
||||
详情请见: https://help.aliyun.com/document_detail/147356.html
|
||||
*/
|
||||
char *mqtt_host = "${YourInstanceId}.mqtt.iothub.aliyuncs.com";
|
||||
|
||||
/* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */
|
||||
extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
|
||||
|
||||
/* 位于external/ali_ca_cert.c中的服务器证书 */
|
||||
extern const char *ali_ca_cert;
|
||||
|
||||
static luat_rtos_task_handle g_mqtt_process_thread = NULL;
|
||||
static luat_rtos_task_handle g_mqtt_recv_thread = NULL;
|
||||
static uint8_t g_mqtt_process_thread_running = 0;
|
||||
static uint8_t g_mqtt_recv_thread_running = 0;
|
||||
luat_rtos_semaphore_t net_semaphore_handle;
|
||||
#define NETSTATUS_NORMAL (0x1)
|
||||
|
||||
static luat_rtos_task_handle linksdk_task_handle;
|
||||
|
||||
|
||||
void mobile_event_callback(LUAT_MOBILE_EVENT_E event, uint8_t index, uint8_t status){
|
||||
if (event == LUAT_MOBILE_EVENT_NETIF && status == LUAT_MOBILE_NETIF_LINK_ON){
|
||||
LUAT_DEBUG_PRINT("netif acivated");
|
||||
luat_rtos_semaphore_release(net_semaphore_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: 如果要关闭日志, 就把这个函数实现为空, 如果要减少日志, 可根据code选择不打印
|
||||
*
|
||||
* 例如: [1577589489.033][LK-0317] mqtt_basic_demo&gb80sFmX7yX
|
||||
*
|
||||
* 上面这条日志的code就是0317(十六进制), code值的定义见core/aiot_state_api.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* 日志回调函数, SDK的日志会从这里输出 */
|
||||
int32_t demo_state_logcb(int32_t code, char *message)
|
||||
{
|
||||
LUAT_DEBUG_PRINT("linksdk message: %s", message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MQTT事件回调函数, 当网络连接/重连/断开时被触发, 事件定义见core/aiot_mqtt_api.h */
|
||||
void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata)
|
||||
{
|
||||
switch (event->type) {
|
||||
/* SDK因为用户调用了aiot_mqtt_connect()接口, 与mqtt服务器建立连接已成功 */
|
||||
case AIOT_MQTTEVT_CONNECT: {
|
||||
LUAT_DEBUG_PRINT("AIOT_MQTTEVT_CONNECT\n");
|
||||
/* TODO: 处理SDK建连成功, 不可以在这里调用耗时较长的阻塞函数 */
|
||||
}
|
||||
break;
|
||||
|
||||
/* SDK因为网络状况被动断连后, 自动发起重连已成功 */
|
||||
case AIOT_MQTTEVT_RECONNECT: {
|
||||
LUAT_DEBUG_PRINT("AIOT_MQTTEVT_RECONNECT\n");
|
||||
/* TODO: 处理SDK重连成功, 不可以在这里调用耗时较长的阻塞函数 */
|
||||
}
|
||||
break;
|
||||
|
||||
/* SDK因为网络的状况而被动断开了连接, network是底层读写失败, heartbeat是没有按预期得到服务端心跳应答 */
|
||||
case AIOT_MQTTEVT_DISCONNECT: {
|
||||
char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") :
|
||||
("heartbeat disconnect");
|
||||
LUAT_DEBUG_PRINT("AIOT_MQTTEVT_DISCONNECT: %s\n", cause);
|
||||
/* TODO: 处理SDK被动断连, 不可以在这里调用耗时较长的阻塞函数 */
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* MQTT默认消息处理回调, 当SDK从服务器收到MQTT消息时, 且无对应用户回调处理时被调用 */
|
||||
void demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata)
|
||||
{
|
||||
switch (packet->type) {
|
||||
case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: {
|
||||
LUAT_DEBUG_PRINT("heartbeat response\n");
|
||||
/* TODO: 处理服务器对心跳的回应, 一般不处理 */
|
||||
}
|
||||
break;
|
||||
|
||||
case AIOT_MQTTRECV_SUB_ACK: {
|
||||
LUAT_DEBUG_PRINT("suback, res: -0x%04X, packet id: %d, max qos: %d\n",
|
||||
-packet->data.sub_ack.res, packet->data.sub_ack.packet_id, packet->data.sub_ack.max_qos);
|
||||
/* TODO: 处理服务器对订阅请求的回应, 一般不处理 */
|
||||
}
|
||||
break;
|
||||
|
||||
case AIOT_MQTTRECV_PUB: {
|
||||
LUAT_DEBUG_PRINT("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic);
|
||||
LUAT_DEBUG_PRINT("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload);
|
||||
/* TODO: 处理服务器下发的业务报文 */
|
||||
}
|
||||
break;
|
||||
|
||||
case AIOT_MQTTRECV_PUB_ACK: {
|
||||
LUAT_DEBUG_PRINT("puback, packet id: %d\n", packet->data.pub_ack.packet_id);
|
||||
/* TODO: 处理服务器对QoS1上报消息的回应, 一般不处理 */
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 执行aiot_mqtt_process的线程, 包含心跳发送和QoS1消息重发 */
|
||||
void *demo_mqtt_process_thread(void *args)
|
||||
{
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
while (g_mqtt_process_thread_running) {
|
||||
res = aiot_mqtt_process(args);
|
||||
if (res == STATE_USER_INPUT_EXEC_DISABLED) {
|
||||
break;
|
||||
}
|
||||
luat_rtos_task_sleep(1000);
|
||||
}
|
||||
luat_rtos_task_delete(g_mqtt_process_thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 执行aiot_mqtt_recv的线程, 包含网络自动重连和从服务器收取MQTT消息 */
|
||||
void *demo_mqtt_recv_thread(void *args)
|
||||
{
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
while (g_mqtt_recv_thread_running) {
|
||||
res = aiot_mqtt_recv(args);
|
||||
if (res < STATE_SUCCESS) {
|
||||
if (res == STATE_USER_INPUT_EXEC_DISABLED) {
|
||||
break;
|
||||
}
|
||||
luat_rtos_task_sleep(1);
|
||||
}
|
||||
}
|
||||
luat_rtos_task_delete(g_mqtt_recv_thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int linksdk_mqtt_task(void *param)
|
||||
{
|
||||
int32_t res = STATE_SUCCESS;
|
||||
void *mqtt_handle = NULL;
|
||||
uint16_t port = 443; /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */
|
||||
aiot_sysdep_network_cred_t cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */
|
||||
|
||||
luat_rtos_semaphore_create(&net_semaphore_handle, 1);
|
||||
|
||||
luat_mobile_event_register_handler(mobile_event_callback);
|
||||
|
||||
luat_rtos_semaphore_take(net_semaphore_handle, LUAT_WAIT_FOREVER);
|
||||
/* 配置SDK的底层依赖 */
|
||||
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
|
||||
/* 配置SDK的日志输出 */
|
||||
aiot_state_set_logcb(demo_state_logcb);
|
||||
|
||||
/* 创建SDK的安全凭据, 用于建立TLS连接 */
|
||||
memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
|
||||
cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* 使用RSA证书校验MQTT服务端 */
|
||||
cred.max_tls_fragment = 16384; /* 最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K */
|
||||
cred.sni_enabled = 1; /* TLS建连时, 支持Server Name Indicator */
|
||||
cred.x509_server_cert = ali_ca_cert; /* 用来验证MQTT服务端的RSA根证书 */
|
||||
cred.x509_server_cert_len = strlen(ali_ca_cert); /* 用来验证MQTT服务端的RSA根证书长度 */
|
||||
|
||||
/* 创建1个MQTT客户端实例并内部初始化默认参数 */
|
||||
mqtt_handle = aiot_mqtt_init();
|
||||
if (mqtt_handle == NULL) {
|
||||
LUAT_DEBUG_PRINT("aiot_mqtt_init failed\n");
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: 如果以下代码不被注释, 则例程会用TCP而不是TLS连接云平台 */
|
||||
|
||||
/* {
|
||||
memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
|
||||
cred.option = AIOT_SYSDEP_NETWORK_CRED_NONE;
|
||||
} */
|
||||
|
||||
|
||||
/* 配置MQTT服务器地址 */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)mqtt_host);
|
||||
/* 配置MQTT服务器端口 */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port);
|
||||
/* 配置设备productKey */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);
|
||||
/* 配置设备deviceName */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);
|
||||
/* 配置设备deviceSecret */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);
|
||||
/* 配置网络连接的安全凭据, 上面已经创建好了 */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
|
||||
/* 配置MQTT默认消息接收回调函数 */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler);
|
||||
/* 配置MQTT事件回调函数 */
|
||||
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler);
|
||||
|
||||
/* 与服务器建立MQTT连接 */
|
||||
res = aiot_mqtt_connect(mqtt_handle);
|
||||
if (res < STATE_SUCCESS) {
|
||||
/* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
|
||||
aiot_mqtt_deinit(&mqtt_handle);
|
||||
LUAT_DEBUG_PRINT("aiot_mqtt_connect failed: -0x%04X\n\r\n", -res);
|
||||
LUAT_DEBUG_PRINT("please check variables like mqtt_host, produt_key, device_name, device_secret in demo\r\n");
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* MQTT 订阅topic功能示例, 请根据自己的业务需求进行使用 */
|
||||
/* {
|
||||
char *sub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/+/post_reply";
|
||||
res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL);
|
||||
if (res < 0) {
|
||||
LUAT_DEBUG_PRINT("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
} */
|
||||
|
||||
/* MQTT 发布消息功能示例, 请根据自己的业务需求进行使用 */
|
||||
/* {
|
||||
char *pub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post";
|
||||
char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}";
|
||||
res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0);
|
||||
if (res < 0) {
|
||||
LUAT_DEBUG_PRINT("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
} */
|
||||
|
||||
/* 创建一个单独的线程, 专用于执行aiot_mqtt_process, 它会自动发送心跳保活, 以及重发QoS1的未应答报文 */
|
||||
g_mqtt_process_thread_running = 1;
|
||||
luat_rtos_task_create(&g_mqtt_process_thread, 4096, 20, "", demo_mqtt_process_thread, mqtt_handle, NULL);
|
||||
if (g_mqtt_process_thread == NULL) {
|
||||
LUAT_DEBUG_PRINT("task_create demo_mqtt_process_thread failed: %d\n", res);
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 创建一个单独的线程用于执行aiot_mqtt_recv, 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连 */
|
||||
g_mqtt_recv_thread_running = 1;
|
||||
luat_rtos_task_create(&g_mqtt_recv_thread, 4096, 20, "", demo_mqtt_recv_thread, mqtt_handle, NULL);
|
||||
if (g_mqtt_recv_thread == NULL) {
|
||||
LUAT_DEBUG_PRINT("task_create demo_mqtt_recv_thread failed: %d\n", res);
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 主循环进入休眠 */
|
||||
while (1) {
|
||||
luat_rtos_task_sleep(1000);
|
||||
}
|
||||
|
||||
/* 断开MQTT连接, 一般不会运行到这里 */
|
||||
g_mqtt_process_thread_running = 0;
|
||||
g_mqtt_recv_thread_running = 0;
|
||||
luat_rtos_task_sleep(1);
|
||||
|
||||
res = aiot_mqtt_disconnect(mqtt_handle);
|
||||
if (res < STATE_SUCCESS) {
|
||||
aiot_mqtt_deinit(&mqtt_handle);
|
||||
LUAT_DEBUG_PRINT("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 销毁MQTT实例, 一般不会运行到这里 */
|
||||
res = aiot_mqtt_deinit(&mqtt_handle);
|
||||
if (res < STATE_SUCCESS) {
|
||||
LUAT_DEBUG_PRINT("aiot_mqtt_deinit failed: -0x%04X\n", -res);
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return -1;
|
||||
}
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void task_demo_init(void)
|
||||
{
|
||||
luat_rtos_task_create(&linksdk_task_handle, 4096, 20, "", linksdk_mqtt_task, NULL, NULL);
|
||||
}
|
||||
|
||||
INIT_TASK_EXPORT(task_demo_init, "1");
|
||||
@@ -0,0 +1,872 @@
|
||||
/***************
|
||||
demo_sysdep_api_test
|
||||
****************/
|
||||
|
||||
|
||||
/*
|
||||
* 这个例程用于用户在移植后验证是否移植成功的。
|
||||
* 通过一系列的测试case,验证移植的相关接口是否正常工作;
|
||||
* + 正常结束后会输出TEST SUCCESS,其它会输出TEST ERROR + ERRORCODE
|
||||
* + 如遇长时间卡住也为测试失败
|
||||
*
|
||||
* 该测试工具会使用多线程/多任务的能力,在RTOS下使用需要自行适配任务创建。
|
||||
* 需要用户关注或修改的部分, 已经用 TODO 在注释中标明
|
||||
*
|
||||
*/
|
||||
#include "common_api.h"
|
||||
#include "aiot_sysdep_api.h"
|
||||
#include "aiot_state_api.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "luat_rtos.h"
|
||||
#include "luat_debug.h"
|
||||
|
||||
/* 定义入口函数类型 */
|
||||
typedef void *(*TASK_FUNC)(void* argv);
|
||||
|
||||
/*TODO: 堆最大空间,单位字节 */
|
||||
#define HEAP_MAX ( 20 * 1024 )
|
||||
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TODO END <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
||||
/**
|
||||
* 系统接口测试结果
|
||||
*/
|
||||
typedef enum {
|
||||
TEST_SUCCESS,
|
||||
TEST_ERR_RANDOM,
|
||||
TEST_ERR_MALLOC,
|
||||
TEST_ERR_HEAP,
|
||||
TEST_ERR_SLEEP,
|
||||
TEST_ERR_MUTEX,
|
||||
TEST_ERR_NETWORK,
|
||||
TEST_ERR_GENERIC,
|
||||
} sysdep_test_result_t;
|
||||
|
||||
static const char *result_string[] = {
|
||||
"TEST_SUCCESS",
|
||||
"TEST_ERR_RANDOM",
|
||||
"TEST_ERR_MALLOC",
|
||||
"TEST_ERR_HEAP",
|
||||
"TEST_ERR_SLEEP",
|
||||
"TEST_ERR_MUTEX",
|
||||
"TEST_ERR_NETWORK",
|
||||
"TEST_ERR_GENERIC",
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
aiot_sysdep_portfile_t *sysdep;
|
||||
void* user_data;
|
||||
char* name;
|
||||
} task_handler_input_t;
|
||||
|
||||
/**
|
||||
* sysdep测试入口原型定义
|
||||
*/
|
||||
typedef sysdep_test_result_t (*sysdep_test_func)(aiot_sysdep_portfile_t* sysdep);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total_size;//堆总大小
|
||||
} heap_cfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count;
|
||||
/* 最大重复次数 */
|
||||
uint16_t repeat_cnt_max;
|
||||
} random_cfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t sleep_ms;
|
||||
uint8_t sleep_end;
|
||||
} time_cfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void* mutex;
|
||||
int32_t value;
|
||||
uint32_t timeout_ms;
|
||||
} mutex_cfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* host;
|
||||
uint16_t port;
|
||||
uint32_t connect_timeout_ms;
|
||||
uint32_t recv_timeout_ms;
|
||||
int32_t recv_buf_len;
|
||||
uint32_t send_timeout_ms;
|
||||
uint32_t cycle_test_times;
|
||||
} network_cfg_t;
|
||||
|
||||
static luat_rtos_task_handle sleep_task_handle1;
|
||||
static luat_rtos_task_handle sleep_task_handle2;
|
||||
static luat_rtos_task_handle mutex_task_handle1;
|
||||
static luat_rtos_task_handle mutex_task_handle2;
|
||||
static luat_rtos_task_handle linksdk_task_handle;
|
||||
|
||||
/**
|
||||
* 随机生成随机数列表,重复出现次数不高于指定值
|
||||
*/
|
||||
static sysdep_test_result_t random_repeat_test(aiot_sysdep_portfile_t* sysdep, random_cfg_t* rd)
|
||||
{
|
||||
typedef uint8_t random_value_t;
|
||||
random_value_t *random_values = NULL;
|
||||
int count = 0;
|
||||
random_value_t temp = 0;
|
||||
sysdep_test_result_t ret = TEST_SUCCESS;
|
||||
/* 差值 */
|
||||
int diff = 0;
|
||||
/* 递变标志 */
|
||||
int flag = 0;
|
||||
|
||||
random_values = sysdep->core_sysdep_malloc(sizeof(random_value_t) * rd->count, NULL);
|
||||
if(random_values == NULL){
|
||||
LUAT_DEBUG_PRINT("[linksdk]\r\nmalloc fail");
|
||||
ret = TEST_ERR_MALLOC;
|
||||
goto end;
|
||||
}
|
||||
memset(random_values, 0, sizeof(random_value_t) * rd->count);
|
||||
|
||||
/* 生成随机数,并统计重复次数 计算差值*/
|
||||
for(count = 0; count < rd->count; count++) {
|
||||
sysdep->core_sysdep_rand((uint8_t*)&temp, sizeof(random_value_t));
|
||||
temp %= rd->count;
|
||||
|
||||
/* 检测是否为规律递变 */
|
||||
if(count == 1 ){
|
||||
diff = random_values[count] - random_values[count - 1];
|
||||
}else if (count >= 2){
|
||||
if(diff == random_values[count] - random_values[count - 1]){
|
||||
flag++;
|
||||
}
|
||||
}
|
||||
|
||||
if(random_values[temp] <= rd->repeat_cnt_max) {
|
||||
random_values[temp]++;
|
||||
}
|
||||
else {
|
||||
LUAT_DEBUG_PRINT("[linksdk]randowm value [%d] times [%d] over max counter [%d]", temp, random_values[temp], rd->repeat_cnt_max);
|
||||
ret = TEST_ERR_RANDOM;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
/* 规律递变则返回错误 */
|
||||
if(rd->count >= 3 && flag >= rd->count - 2){
|
||||
LUAT_DEBUG_PRINT("[linksdk]random value error");
|
||||
ret = TEST_ERR_RANDOM;
|
||||
goto end;
|
||||
}
|
||||
ret = TEST_SUCCESS;
|
||||
end:
|
||||
if(random_values != NULL){
|
||||
sysdep->core_sysdep_free(random_values);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机数测试入口
|
||||
*/
|
||||
sysdep_test_result_t random_test(aiot_sysdep_portfile_t* sysdep)
|
||||
{
|
||||
random_cfg_t rd;
|
||||
/* 随机数接口要求生成的随机数按字节随机 */
|
||||
rd.count = 256;
|
||||
/* 随机数重复次数不能超过该值 */
|
||||
rd.repeat_cnt_max = 10;
|
||||
return random_repeat_test(sysdep, &rd);
|
||||
}
|
||||
|
||||
static sysdep_test_result_t heap_malloc_max_test(aiot_sysdep_portfile_t* sysdep, heap_cfg_t* hp)
|
||||
{
|
||||
/**
|
||||
* 最大空间申请、释放
|
||||
*/
|
||||
uint32_t user_malloc_max = hp->total_size - 100;
|
||||
void * ptr = sysdep->core_sysdep_malloc(user_malloc_max, "");
|
||||
if(ptr == NULL) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]malloc error");
|
||||
return TEST_ERR_MALLOC;
|
||||
}
|
||||
/* 空间读写测试 */
|
||||
uint8_t read_value;
|
||||
for(int i = 0; i < user_malloc_max; i++) {
|
||||
((uint8_t*)ptr)[i] = (uint8_t)i;
|
||||
read_value = ((uint8_t*)ptr)[i];
|
||||
if(read_value != (uint8_t)i) {
|
||||
sysdep->core_sysdep_free(ptr);
|
||||
LUAT_DEBUG_PRINT("[linksdk]heap read and write fail");
|
||||
return TEST_ERR_MALLOC;
|
||||
}
|
||||
}
|
||||
sysdep->core_sysdep_free(ptr);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 堆回收测试
|
||||
*/
|
||||
static sysdep_test_result_t heap_recycle_test(aiot_sysdep_portfile_t* sysdep, heap_cfg_t* hp)
|
||||
{
|
||||
/* 待申请的堆空间大小 */
|
||||
const uint32_t size_list[]= {1,2,4,8,16,32,64,128,256,512,1024,10*1024};
|
||||
/* 存储堆指针 */
|
||||
void* malloc_list[sizeof(size_list) / sizeof(uint32_t)] = {NULL};
|
||||
int malloc_list_size = sizeof(size_list) / sizeof(uint32_t);
|
||||
/* 申请空间 */
|
||||
int malloc_cnt = 0;
|
||||
int i = 0;
|
||||
for(i = 0; i < malloc_list_size; i++) {
|
||||
malloc_list[i] = sysdep->core_sysdep_malloc(size_list[i], "");
|
||||
if(malloc_list[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
malloc_cnt = i;
|
||||
/**
|
||||
* 非相邻空间释放
|
||||
*/
|
||||
for(i = 0; i < malloc_cnt; i+=2) {
|
||||
sysdep->core_sysdep_free(malloc_list[i]);
|
||||
}
|
||||
for(i = 1; i < malloc_cnt; i+=2) {
|
||||
sysdep->core_sysdep_free(malloc_list[i]);
|
||||
}
|
||||
/**
|
||||
* 最后申请最大空间
|
||||
*/
|
||||
return heap_malloc_max_test(sysdep, hp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 堆测试入口
|
||||
*/
|
||||
|
||||
sysdep_test_result_t heap_test(aiot_sysdep_portfile_t* sysdep)
|
||||
{
|
||||
sysdep_test_result_t ret = TEST_SUCCESS;
|
||||
heap_cfg_t hp;
|
||||
hp.total_size = HEAP_MAX;
|
||||
ret = heap_malloc_max_test(sysdep,&hp);
|
||||
if(ret != TEST_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
return heap_recycle_test(sysdep, &hp);
|
||||
}
|
||||
|
||||
static sysdep_test_result_t network_tcp_test(aiot_sysdep_portfile_t* sysdep, network_cfg_t* cfg)
|
||||
{
|
||||
void* network_hd = sysdep->core_sysdep_network_init();
|
||||
core_sysdep_socket_type_t type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_SOCKET_TYPE, &type);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_HOST, cfg->host);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_PORT, (void*)&cfg->port);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS, &cfg->connect_timeout_ms);
|
||||
|
||||
/**
|
||||
* 建连测试
|
||||
*/
|
||||
if(0 != sysdep->core_sysdep_network_establish(network_hd)) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network establish test error:%d", TEST_ERR_NETWORK);
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收等待超时测试
|
||||
*/
|
||||
char* buf = sysdep->core_sysdep_malloc(cfg->recv_buf_len + 1, "");
|
||||
if(buf == NULL){
|
||||
LUAT_DEBUG_PRINT("[linksdk]malloc fail");
|
||||
return TEST_ERR_MALLOC;
|
||||
}
|
||||
uint64_t start = sysdep->core_sysdep_time();
|
||||
sysdep->core_sysdep_network_recv(network_hd, (uint8_t*)buf, cfg->recv_buf_len, cfg->recv_timeout_ms, NULL);
|
||||
uint64_t stop = sysdep->core_sysdep_time();
|
||||
if(stop - start < cfg->recv_timeout_ms) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network receive test error:%d, start [%ld], end [%ld]", TEST_ERR_NETWORK, start, stop);
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Http Get请求来验证TCP是否工作正常
|
||||
*/
|
||||
char* http_get = "GET / HTTP/1.1\r\n"\
|
||||
"Host: www.aliyun.com\r\n"\
|
||||
"Connection: keep-alive\r\n"\
|
||||
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36\r\n"\
|
||||
"Origin: https://www.aliyun.com\r\n"\
|
||||
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n"\
|
||||
"\r\n";
|
||||
|
||||
int32_t send_len = strlen(http_get);
|
||||
int32_t send_result = sysdep->core_sysdep_network_send(network_hd, (uint8_t*)http_get, send_len, cfg->send_timeout_ms, NULL);
|
||||
if(send_result != send_len) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network send length test error:%d, send [%d], result [%d]", TEST_ERR_NETWORK, send_len, send_result);
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
|
||||
int32_t buf_len = 0;
|
||||
uint8_t byte_read;
|
||||
int32_t content_len = 0;
|
||||
int32_t ret;
|
||||
char* str_ptr = NULL;
|
||||
char* target_str = "Content-Length:";
|
||||
int state = 0;
|
||||
while(1) {
|
||||
ret = sysdep->core_sysdep_network_recv(network_hd, (uint8_t*)&byte_read, 1, cfg->recv_timeout_ms, NULL);
|
||||
/* 需支持按字节读取 */
|
||||
if(ret == 1) {
|
||||
if(state == 0) {
|
||||
/* 提取一行 */
|
||||
buf[buf_len++] = byte_read;
|
||||
if(byte_read != '\n') {
|
||||
continue;
|
||||
}
|
||||
buf[buf_len] = '\0';
|
||||
/*空行表示header结束*/
|
||||
if(buf_len == 2 && buf[0] == '\r' && buf[1] == '\n') {
|
||||
state = 1;
|
||||
buf_len = 0;
|
||||
continue;
|
||||
}
|
||||
/*搜索应答长度*/
|
||||
str_ptr = strstr(buf,target_str);
|
||||
if(str_ptr == NULL) {
|
||||
buf_len = 0;
|
||||
continue;
|
||||
}
|
||||
str_ptr += strlen(target_str);
|
||||
if(str_ptr >= &buf[buf_len]) {
|
||||
buf_len = 0;
|
||||
continue;
|
||||
}
|
||||
if( 1 == sscanf(str_ptr,"%d",&content_len)) {
|
||||
buf_len = 0;
|
||||
}
|
||||
} else {
|
||||
buf[buf_len++] = byte_read;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sysdep->core_sysdep_network_deinit(&network_hd);
|
||||
sysdep->core_sysdep_free(buf);
|
||||
buf = NULL;
|
||||
if(network_hd != NULL){
|
||||
LUAT_DEBUG_PRINT("[linksdk]network deinit error");
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
/* http的正文长度校验 */
|
||||
if(buf_len == 0 || buf_len != content_len) {
|
||||
LUAT_DEBUG_PRINT("[linksdk][NETWORK_TEST.RECV] test error:%d, send [%d], result [%d]", TEST_ERR_NETWORK, buf_len, content_len);
|
||||
return TEST_ERR_NETWORK;
|
||||
} else {
|
||||
LUAT_DEBUG_PRINT("[linksdk][NETWORK_TEST.RECV] test success");
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
sysdep_test_result_t network_tcp_cycle_test(aiot_sysdep_portfile_t* sysdep, network_cfg_t* cfg)
|
||||
{
|
||||
void* network_hd = NULL;
|
||||
int count = cfg->cycle_test_times;
|
||||
while(count-- > 0) {
|
||||
network_hd = sysdep->core_sysdep_network_init();
|
||||
if(network_hd == NULL) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network tcp init test error");
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
core_sysdep_socket_type_t type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_SOCKET_TYPE, &type);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_HOST, cfg->host);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_PORT, (void*)&cfg->port);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS, &cfg->connect_timeout_ms);
|
||||
|
||||
if(0 != sysdep->core_sysdep_network_establish(network_hd)) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network tcp establish test error:%d", TEST_ERR_NETWORK);
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
sysdep->core_sysdep_network_deinit(&network_hd);
|
||||
}
|
||||
if( TEST_SUCCESS != heap_test(sysdep) ) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network deinit then heap test error:%d", TEST_ERR_NETWORK);
|
||||
return TEST_ERR_NETWORK;
|
||||
} else {
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static sysdep_test_result_t network_tcp_send_length_test(aiot_sysdep_portfile_t* sysdep, network_cfg_t* cfg)
|
||||
{
|
||||
sysdep_test_result_t ret = TEST_SUCCESS;
|
||||
void* network_hd = sysdep->core_sysdep_network_init();
|
||||
|
||||
core_sysdep_socket_type_t type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_SOCKET_TYPE, &type);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_HOST, cfg->host);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_PORT, (void*)&cfg->port);
|
||||
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS, &cfg->connect_timeout_ms);
|
||||
|
||||
/**
|
||||
* 建连测试
|
||||
*/
|
||||
if(0 != sysdep->core_sysdep_network_establish(network_hd)) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network establish test error:%d", TEST_ERR_NETWORK);
|
||||
return TEST_ERR_NETWORK;
|
||||
}
|
||||
/**
|
||||
* 通过Http Get请求来验证TCP发送接口是否具备长包发送能力
|
||||
*/
|
||||
const char* http_get = "GET / HTTP/1.1\r\n"\
|
||||
"Host: www.aliyun.com\r\n"\
|
||||
"Connection: keep-alive\r\n"\
|
||||
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36\r\n"\
|
||||
"Origin: https://www.aliyun.com\r\n"\
|
||||
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n"\
|
||||
"\r\n"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
|
||||
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,";
|
||||
|
||||
int32_t send_len = strlen(http_get);
|
||||
int32_t send_result = sysdep->core_sysdep_network_send(network_hd, (uint8_t*)http_get, send_len, cfg->send_timeout_ms, NULL);
|
||||
if(send_result != send_len) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]network send length test error:%d, send [%d], result [%d]", TEST_ERR_NETWORK, send_len, send_result);
|
||||
ret = TEST_ERR_NETWORK;
|
||||
}
|
||||
sysdep->core_sysdep_network_deinit(&network_hd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
sysdep_test_result_t network_test(aiot_sysdep_portfile_t* sysdep)
|
||||
{
|
||||
sysdep_test_result_t ret;
|
||||
sysdep->core_sysdep_sleep(100);
|
||||
|
||||
network_cfg_t cfg;
|
||||
cfg.host = "www.aliyun.com";
|
||||
cfg.port = 80;
|
||||
cfg.connect_timeout_ms = 5000;
|
||||
cfg.recv_timeout_ms = 5000;
|
||||
cfg.recv_buf_len = 1024;
|
||||
cfg.send_timeout_ms = 5000;
|
||||
cfg.cycle_test_times = 10;
|
||||
|
||||
ret = network_tcp_test(sysdep, &cfg);
|
||||
if(ret != TEST_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = network_tcp_send_length_test(sysdep,&cfg);
|
||||
if(ret != TEST_SUCCESS){
|
||||
return ret;
|
||||
}
|
||||
ret = network_tcp_cycle_test(sysdep, &cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void enter_sleep1(void* user_data)
|
||||
{
|
||||
task_handler_input_t* user = (task_handler_input_t*)user_data;
|
||||
time_cfg_t* tm = user->user_data;
|
||||
|
||||
LUAT_DEBUG_PRINT("[linksdk]%s enter wanna sleep: %ldms", user->name, tm->sleep_ms);
|
||||
user->sysdep->core_sysdep_sleep(tm->sleep_ms);
|
||||
|
||||
tm->sleep_end = 1;
|
||||
luat_rtos_task_delete(sleep_task_handle1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void enter_sleep2(void* user_data)
|
||||
{
|
||||
task_handler_input_t* user = (task_handler_input_t*)user_data;
|
||||
time_cfg_t* tm = user->user_data;
|
||||
|
||||
LUAT_DEBUG_PRINT("[linksdk]%s enter wanna sleep: %ldms", user->name, tm->sleep_ms);
|
||||
user->sysdep->core_sysdep_sleep(tm->sleep_ms);
|
||||
|
||||
tm->sleep_end = 1;
|
||||
luat_rtos_task_delete(sleep_task_handle2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sysdep_test_result_t time_sleep_test(aiot_sysdep_portfile_t* sysdep)
|
||||
{
|
||||
uint64_t start,stop;
|
||||
time_cfg_t time_cfg;
|
||||
sysdep_test_result_t ret= TEST_SUCCESS;
|
||||
time_cfg_t* sleep1 = NULL;
|
||||
time_cfg_t* sleep2 = NULL;
|
||||
task_handler_input_t input1;
|
||||
task_handler_input_t input2;
|
||||
int64_t wait_total;
|
||||
uint64_t temp;
|
||||
|
||||
time_cfg.sleep_ms = 10 * 1000;
|
||||
LUAT_DEBUG_PRINT("[linksdk]sleep %ldms test",time_cfg.sleep_ms);
|
||||
start = sysdep->core_sysdep_time();
|
||||
sysdep->core_sysdep_sleep(time_cfg.sleep_ms);
|
||||
stop = sysdep->core_sysdep_time();
|
||||
LUAT_DEBUG_PRINT("[linksdk]sleep start %ld stop %ld ms test",start,stop);
|
||||
/* 睡眠异常 */
|
||||
if((stop - start) * 1.1 < time_cfg.sleep_ms) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]sleep test error: %d",TEST_ERR_SLEEP);
|
||||
ret = TEST_ERR_SLEEP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* 睡眠时间超过10% */
|
||||
if(stop - start > (uint64_t)(time_cfg.sleep_ms * 1.1)) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]sleep test error: %d",TEST_ERR_SLEEP);
|
||||
ret = TEST_ERR_SLEEP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/**
|
||||
* 并发睡眠测试,两个并发睡眠消耗的时间应小于两次睡眠时间之和
|
||||
*/
|
||||
sleep1 = sysdep->core_sysdep_malloc(sizeof(time_cfg_t),"");
|
||||
sleep2 = sysdep->core_sysdep_malloc(sizeof(time_cfg_t),"");
|
||||
if(sleep1 == NULL || sleep2 == NULL){
|
||||
ret = TEST_ERR_SLEEP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sleep1->sleep_ms = 10 * 1000;
|
||||
sleep1->sleep_end = 0;
|
||||
sleep2->sleep_ms = 10 * 1000;
|
||||
sleep2->sleep_end = 0;
|
||||
|
||||
input1.name = "sleep_test_task_1";
|
||||
input1.sysdep = sysdep;
|
||||
input1.user_data = sleep1;
|
||||
|
||||
input2.name = "sleep_test_task_2";
|
||||
input2.sysdep = sysdep;
|
||||
input2.user_data = sleep2;
|
||||
|
||||
start = sysdep->core_sysdep_time();
|
||||
|
||||
luat_rtos_task_create(&sleep_task_handle1, 1024, 20, "", enter_sleep1, &input1, NULL);
|
||||
luat_rtos_task_create(&sleep_task_handle2, 1024, 20, "", enter_sleep2, &input2, NULL);
|
||||
|
||||
/**
|
||||
* 等待睡眠结束
|
||||
*/
|
||||
wait_total = sleep1->sleep_ms + sleep2->sleep_ms + 100;
|
||||
while((sleep1->sleep_end == 0 || sleep2->sleep_end == 0) && wait_total-- > 0) {
|
||||
sysdep->core_sysdep_sleep(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查所有线程是否都退出
|
||||
*/
|
||||
while (sleep1->sleep_end == 0 || sleep2->sleep_end == 0){
|
||||
sysdep->core_sysdep_sleep(1);
|
||||
}
|
||||
|
||||
/* 两个线程应该在规定时间内退出 */
|
||||
if(wait_total < 0) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]concurrent sleep test error: wait sleep timeout fail");
|
||||
ret = TEST_ERR_SLEEP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* 总睡眠时间应小于各睡眠时间之和 */
|
||||
stop = sysdep->core_sysdep_time();
|
||||
temp = sleep1->sleep_ms + sleep2->sleep_ms;
|
||||
if(stop - start >= temp) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]sleep %ldms start:[%ld] stop:[%ld]\r\n unexpected ", sleep1->sleep_ms, start, stop);
|
||||
ret = TEST_ERR_SLEEP;
|
||||
}
|
||||
else {
|
||||
LUAT_DEBUG_PRINT("[linksdk]sleep %ldms start:[%ld] stop:[%ld] expected ", sleep1->sleep_ms, start, stop);
|
||||
ret = TEST_SUCCESS;
|
||||
}
|
||||
end:
|
||||
if(sleep1 != NULL)
|
||||
sysdep->core_sysdep_free(sleep1);
|
||||
if(sleep2 != NULL)
|
||||
sysdep->core_sysdep_free(sleep2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mutex_synchronize_test1(void* user_data)
|
||||
{
|
||||
task_handler_input_t* input = (task_handler_input_t*)user_data;
|
||||
mutex_cfg_t* cfg = input->user_data;
|
||||
while(1) {
|
||||
input->sysdep->core_sysdep_mutex_lock(cfg->mutex);
|
||||
if(cfg->value < 0) {
|
||||
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
|
||||
break;
|
||||
}
|
||||
cfg->value++;
|
||||
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
|
||||
input->sysdep->core_sysdep_sleep(cfg->timeout_ms);
|
||||
}
|
||||
luat_rtos_task_delete(mutex_task_handle1);
|
||||
return NULL;
|
||||
}
|
||||
static void mutex_synchronize_test2(void* user_data)
|
||||
{
|
||||
task_handler_input_t* input = (task_handler_input_t*)user_data;
|
||||
mutex_cfg_t* cfg = input->user_data;
|
||||
while(1) {
|
||||
input->sysdep->core_sysdep_mutex_lock(cfg->mutex);
|
||||
if(cfg->value < 0) {
|
||||
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
|
||||
break;
|
||||
}
|
||||
cfg->value++;
|
||||
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
|
||||
input->sysdep->core_sysdep_sleep(cfg->timeout_ms);
|
||||
}
|
||||
luat_rtos_task_delete(mutex_task_handle2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 互斥锁测试
|
||||
*/
|
||||
sysdep_test_result_t mutex_test(aiot_sysdep_portfile_t* sysdep)
|
||||
{
|
||||
sysdep_test_result_t ret;
|
||||
void* mutex = NULL;
|
||||
mutex_cfg_t *mutex_cfg_2 = NULL;
|
||||
task_handler_input_t *input_1 = NULL;
|
||||
task_handler_input_t *input_2 = NULL;
|
||||
int32_t wait_ms = 3000;
|
||||
/**
|
||||
* 互斥锁申请释放及内存泄漏测试
|
||||
*/
|
||||
for(int i = 0; i < 1000; i++) {
|
||||
mutex = sysdep->core_sysdep_mutex_init();
|
||||
sysdep->core_sysdep_mutex_lock(mutex);
|
||||
sysdep->core_sysdep_mutex_unlock(mutex);
|
||||
sysdep->core_sysdep_mutex_deinit(&mutex);
|
||||
}
|
||||
if( TEST_SUCCESS != heap_test(sysdep)) {
|
||||
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST.CYCLE] test failed\r\n");
|
||||
return ret = TEST_ERR_MUTEX;
|
||||
}
|
||||
|
||||
/**
|
||||
* 互斥锁功能测试
|
||||
*/
|
||||
mutex_cfg_t *mutex_cfg_1 = sysdep->core_sysdep_malloc(sizeof(mutex_cfg_t), "");
|
||||
if(mutex_cfg_1 == NULL) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]mutex test but malloc fail");
|
||||
ret = TEST_ERR_MUTEX;
|
||||
goto end;
|
||||
}
|
||||
mutex_cfg_1->mutex = sysdep->core_sysdep_mutex_init();
|
||||
if(mutex_cfg_1->mutex == NULL) {
|
||||
ret = TEST_ERR_MALLOC;
|
||||
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST]malloc fail:%d", ret);
|
||||
goto end;
|
||||
}
|
||||
input_1 = sysdep->core_sysdep_malloc(sizeof(task_handler_input_t), "");
|
||||
if(input_1 == NULL){
|
||||
LUAT_DEBUG_PRINT("[linksdk]mutex test but malloc fail");
|
||||
ret = TEST_ERR_MALLOC;
|
||||
goto end;
|
||||
}
|
||||
input_1->name = "mutex_test_task1";
|
||||
input_1->sysdep = sysdep;
|
||||
input_1->user_data = mutex_cfg_1;
|
||||
mutex_cfg_1->timeout_ms = 100;
|
||||
mutex_cfg_1->value = 0;
|
||||
luat_rtos_task_create(&mutex_task_handle1, 1024, 20, "", mutex_synchronize_test1, input_1, NULL);
|
||||
|
||||
mutex_cfg_2 = sysdep->core_sysdep_malloc(sizeof(mutex_cfg_t), "");
|
||||
if(mutex_cfg_2 == NULL) {
|
||||
ret = TEST_ERR_MALLOC;
|
||||
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST]malloc fail:%d", ret);
|
||||
goto end;
|
||||
}
|
||||
mutex_cfg_2->mutex = sysdep->core_sysdep_mutex_init();
|
||||
if(mutex_cfg_2->mutex == NULL) {
|
||||
ret = TEST_ERR_MALLOC;
|
||||
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST]malloc fail:%d", ret);
|
||||
goto end;
|
||||
}
|
||||
input_2 = sysdep->core_sysdep_malloc(sizeof(task_handler_input_t), "");
|
||||
input_2->name = "mutex_test_task2";
|
||||
input_2->sysdep = sysdep;
|
||||
input_2->user_data = mutex_cfg_2;
|
||||
mutex_cfg_2->timeout_ms = 100;
|
||||
mutex_cfg_2->value = 0;
|
||||
luat_rtos_task_create(&mutex_task_handle2, 1024, 20, "", mutex_synchronize_test2, input_2, NULL);
|
||||
|
||||
sysdep->core_sysdep_sleep(wait_ms);
|
||||
/**
|
||||
* 对mutex_cfg_1->mutex加锁,mutex_test_task1会被锁住,mutex_cfg_1->value应该不会发生变化
|
||||
*/
|
||||
int32_t v1,v2;
|
||||
LUAT_DEBUG_PRINT("[linksdk]mutex lock task1, unlock task2 %d ms", wait_ms);
|
||||
sysdep->core_sysdep_mutex_lock(mutex_cfg_1->mutex);
|
||||
|
||||
v1 = mutex_cfg_1->value;
|
||||
v2 = mutex_cfg_2->value;
|
||||
|
||||
sysdep->core_sysdep_sleep(wait_ms);
|
||||
|
||||
int32_t v1_,v2_;
|
||||
v1_ = mutex_cfg_1->value;
|
||||
v2_ = mutex_cfg_2->value;
|
||||
LUAT_DEBUG_PRINT("[linksdk]task1 value [%d --> %d], task2 value [%d --> %d] ", v1, v1_, v2, v2_);
|
||||
if(v1 != v1_ || v2 == v2_) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]mutex test failed ");
|
||||
ret = TEST_ERR_MUTEX;
|
||||
goto end;
|
||||
}
|
||||
sysdep->core_sysdep_mutex_unlock(mutex_cfg_1->mutex);
|
||||
|
||||
|
||||
/**
|
||||
* 对mutex_cfg_2->mutex加锁,mutex_test_task2会被锁住,mutex_cfg_2->value应该不会发生变化
|
||||
*/
|
||||
LUAT_DEBUG_PRINT("[linksdk]unlock task1, lock task2 %d ms", wait_ms);
|
||||
sysdep->core_sysdep_mutex_lock(mutex_cfg_2->mutex);
|
||||
v1 = mutex_cfg_1->value;
|
||||
v2 = mutex_cfg_2->value;
|
||||
|
||||
sysdep->core_sysdep_sleep(wait_ms);
|
||||
|
||||
v1_ = mutex_cfg_1->value;
|
||||
v2_ = mutex_cfg_2->value;
|
||||
|
||||
LUAT_DEBUG_PRINT("[linksdk]task1 value [%d --> %d], task2 value [%d --> %d] ", v1, v1_, v2, v2_);
|
||||
if(v1 == v1_ || v2 != v2_) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]mutex test failed");
|
||||
ret = TEST_ERR_MUTEX;
|
||||
goto end;
|
||||
}
|
||||
sysdep->core_sysdep_mutex_unlock(mutex_cfg_2->mutex);
|
||||
|
||||
/**
|
||||
* mutex_cfg_2->mutex不加锁,mutex_cfg_1->mutex不加锁,对应value应该正常变化
|
||||
*/
|
||||
LUAT_DEBUG_PRINT("[linksdk]unlock task1, lock task2 %d ms\r\n", wait_ms);
|
||||
v1 = mutex_cfg_1->value;
|
||||
v2 = mutex_cfg_2->value;
|
||||
sysdep->core_sysdep_sleep(wait_ms);
|
||||
v1_ = mutex_cfg_1->value;
|
||||
v2_ = mutex_cfg_2->value;
|
||||
LUAT_DEBUG_PRINT("[linksdk]task1 value [%d --> %d], task2 value [%d --> %d]\r\n", v1, v1_, v2, v2_);
|
||||
if(v1 == v1_ || v2 == v2_) {
|
||||
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST.UNLOCK] test failed \r\n");
|
||||
ret = TEST_ERR_MUTEX;
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
/**
|
||||
* 线程退出,回归
|
||||
*/
|
||||
if(mutex_cfg_1 != NULL) {
|
||||
mutex_cfg_1->value = -10;
|
||||
sysdep->core_sysdep_sleep(500);
|
||||
if(mutex_cfg_1->mutex != NULL){
|
||||
sysdep->core_sysdep_mutex_deinit(&(mutex_cfg_1->mutex));
|
||||
}
|
||||
|
||||
sysdep->core_sysdep_free(mutex_cfg_1);
|
||||
}
|
||||
|
||||
if(mutex_cfg_2 != NULL){
|
||||
mutex_cfg_2->value = -10;
|
||||
sysdep->core_sysdep_sleep(500);
|
||||
if(mutex_cfg_2->mutex != NULL){
|
||||
sysdep->core_sysdep_mutex_deinit(&(mutex_cfg_2->mutex));
|
||||
}
|
||||
sysdep->core_sysdep_free(mutex_cfg_2);
|
||||
}
|
||||
|
||||
if(input_1 != NULL){
|
||||
sysdep->core_sysdep_free(input_1);
|
||||
}
|
||||
if(input_2 != NULL){
|
||||
sysdep->core_sysdep_free(input_2);
|
||||
}
|
||||
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
sysdep_test_func func;
|
||||
} sysdep_test_suite;
|
||||
|
||||
/**
|
||||
* 测试项列表
|
||||
*/
|
||||
sysdep_test_suite test_list[]= {
|
||||
{"RANDOM_TEST ", random_test},
|
||||
{"HEAP_TEST ", heap_test},
|
||||
{"TIME_TEST ", time_sleep_test},
|
||||
{"NETWORK_TEST", network_test},
|
||||
{"MUTEX_TEST ", mutex_test},
|
||||
};
|
||||
|
||||
/**
|
||||
* sysdep的接口实现,包含系统时间、内存管理、网络、锁、随机数、等接口实现
|
||||
*/
|
||||
extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
|
||||
|
||||
static void demo_sysdep_api_test(void *param)
|
||||
{
|
||||
luat_rtos_task_sleep(1000);
|
||||
aiot_sysdep_portfile_t *sysdep = &g_aiot_sysdep_portfile;
|
||||
int32_t size = sizeof(test_list) / sizeof(test_list[0]);
|
||||
sysdep_test_result_t ret = TEST_SUCCESS;
|
||||
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
|
||||
LUAT_DEBUG_PRINT("[linksdk]TOTAL TEST START");
|
||||
for(int32_t i = 0; i < size; i++) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]TEST [%d/%d] [%s] .....................................[START]", i + 1, size, test_list[i].name);
|
||||
ret = (test_list[i].func)(sysdep);
|
||||
if(TEST_SUCCESS != ret) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]TEST [%d/%d] [%s] .....................................[FAILED] [%s]", i + 1, size, test_list[i].name, result_string[ret]);
|
||||
break;
|
||||
} else {
|
||||
LUAT_DEBUG_PRINT("[linksdk]TEST [%d/%d] [%s] .....................................[SUCCESS]", i + 1, size, test_list[i].name);
|
||||
}
|
||||
}
|
||||
if(ret == TEST_SUCCESS) {
|
||||
LUAT_DEBUG_PRINT("[linksdk]TOTAL TEST SUCCESS");
|
||||
} else {
|
||||
LUAT_DEBUG_PRINT("[linksdk]TOTAL TEST FAILED %s", result_string[ret]);
|
||||
}
|
||||
luat_rtos_task_delete(linksdk_task_handle);
|
||||
}
|
||||
|
||||
static void task_demo_init(void)
|
||||
{
|
||||
luat_rtos_task_create(&linksdk_task_handle, 4096, 20, "", demo_sysdep_api_test, NULL, NULL);
|
||||
}
|
||||
|
||||
INIT_TASK_EXPORT(task_demo_init, "1");
|
||||
@@ -0,0 +1,26 @@
|
||||
local TARGET_NAME = "example_linksdk"
|
||||
local LIB_DIR = "$(buildir)/".. TARGET_NAME .. "/"
|
||||
local LIB_NAME = "lib" .. TARGET_NAME .. ".a "
|
||||
|
||||
target(TARGET_NAME)
|
||||
set_kind("static")
|
||||
set_targetdir(LIB_DIR)
|
||||
--使用第三方的linksdk
|
||||
includes(SDK_TOP .. "/thirdparty/linksdk")
|
||||
add_deps("linksdk")
|
||||
--加入代码和头文件
|
||||
add_includedirs("./inc",
|
||||
SDK_TOP .. "/thirdparty/linksdk/core",{public = true})
|
||||
add_files("./src/example_sysdep_api_test.c",{public = true})
|
||||
-- add_files("/src/example_mqtt_basic.c",{public = true})
|
||||
|
||||
--路径可以随便写,可以加任意路径的代码,下面代码等效上方代码
|
||||
-- add_includedirs(SDK_TOP .. "project/" .. TARGET_NAME .. "/inc",{public = true})
|
||||
-- add_files(SDK_TOP .. "project/" .. TARGET_NAME .. "/src/*.c",{public = true})
|
||||
|
||||
--可以继续增加add_includedirs和add_files
|
||||
--自动链接c
|
||||
|
||||
LIB_USER = LIB_USER .. SDK_TOP .. LIB_DIR .. LIB_NAME .. " "
|
||||
--甚至可以加入自己的库
|
||||
target_end()
|
||||
Reference in New Issue
Block a user