更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,354 @@
#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 0
#define RTE_UART1_RTS_PIN_EN 0
// { 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_PIN23}, // 0 : gpio8 / 1 : SPI0 SSn
// { PAD_PIN24}, // 0 : gpio9 / 1 : SPI0 MOSI
// { PAD_PIN25}, // 0 : gpio10 / 1 : SPI0 MISO
// { PAD_PIN26}, // 0 : gpio11 / 1 : SPI0 SCLK
#define RTE_SPI0_SSN_BIT 23
#define RTE_SPI0_SSN_FUNC PAD_MUX_ALT1
#define RTE_SPI0_MOSI_BIT 24
#define RTE_SPI0_MOSI_FUNC PAD_MUX_ALT1
#define RTE_SPI0_MISO_BIT 25
#define RTE_SPI0_MISO_FUNC PAD_MUX_ALT1
#define RTE_SPI0_SCLK_BIT 26
#define RTE_SPI0_SCLK_FUNC PAD_MUX_ALT1
#define RTE_SPI0_SSN_GPIO_INSTANCE 0
#define RTE_SPI0_SSN_GPIO_INDEX 8
// 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 0
// { PAD_PIN27}, // 0 : gpio12 / 1 : SPI1 SSn
// { PAD_PIN28}, // 0 : gpio13 / 1 : SPI1 MOSI
// { PAD_PIN29}, // 0 : gpio14 / 1 : SPI1 MISO
// { PAD_PIN30}, // 0 : gpio15 / 1 : SPI1 SCLK
// { PAD_PIN31}, // 0 : gpio16 / 4 : SPI1 SSn1
#define RTE_SPI1_SSN_BIT 27
#define RTE_SPI1_SSN_FUNC PAD_MUX_ALT1
#define RTE_SPI1_MOSI_BIT 28
#define RTE_SPI1_MOSI_FUNC PAD_MUX_ALT1
#define RTE_SPI1_MISO_BIT 29
#define RTE_SPI1_MISO_FUNC PAD_MUX_ALT1
#define RTE_SPI1_SCLK_BIT 30
#define RTE_SPI1_SCLK_FUNC PAD_MUX_ALT1
#define RTE_SPI1_SSN_GPIO_INSTANCE 0
#define RTE_SPI1_SSN_GPIO_INDEX 12
#define RTE_SPI1_SSN1_BIT 31
#define RTE_SPI1_SSN1_FUNC PAD_MUX_ALT4
// 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 0
/* 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 */

View File

@@ -0,0 +1,9 @@
#ifndef NETWORK_SERVICE_H
#define NETWORK_SERVICE_H
#include "stdlib.h"
void network_service_init(void);
uint8_t network_service_is_ready(void);
#endif

View File

@@ -0,0 +1,15 @@
#ifndef SOCKET_SERVICE_H
#define SOCKET_SERVICE_H
//result0成功1 socket未连接其余错误值是lwip send接口返回的错误原因值
typedef void (*socket_service_send_data_callback_t)(int result, uint32_t callback_param);
void socket_service_init(void);
void socket_service_set_remote_port(int port);
//同步插入队列结果通过返回值判断0成功其他失败
//插入成功后异步发送结果通过callback_func(int result, void *callback_param)中的result判断0成功其他失败
int socket_service_send_data(const char *data, uint32_t len, socket_service_send_data_callback_t callback_func, uint32_t callback_param);
#endif

View File

@@ -0,0 +1,6 @@
#ifndef USB_SERVICE_H
#define USB_SERVICE_H
void usb_service_init(void);
#endif

View File

@@ -0,0 +1,12 @@
#include "common_api.h"
#include "network_service.h"
#include "socket_service.h"
#include "usb_service.h"
extern void test_service_init(void);
INIT_TASK_EXPORT(network_service_init, "0");
INIT_TASK_EXPORT(socket_service_init, "1");
INIT_TASK_EXPORT(usb_service_init, "2");
INIT_TASK_EXPORT(test_service_init, "2");

View File

@@ -0,0 +1,85 @@
#include "luat_debug.h"
#include "luat_rtos.h"
#include "luat_mobile.h"
/*
功能模块名称IP网络监测
本功能模块监测IP层网络链路状态
外部功能模块通过调用network_service_is_ready接口可以获取状态1表示IP网络就绪0表示IP网络未准备就绪
IP网络准备就绪之后外部功能模块才能正常使用socket、http、mqtt等去连接服务器进行收发数据
*/
static uint8_t g_s_is_link_up;
uint8_t network_service_is_ready(void)
{
return g_s_is_link_up;
}
static void mobile_event_cb(LUAT_MOBILE_EVENT_E event, uint8_t index, uint8_t status)
{
switch(event)
{
case LUAT_MOBILE_EVENT_CFUN:
LUAT_DEBUG_PRINT("cfun event,status %d", status);
break;
case LUAT_MOBILE_EVENT_SIM:
switch(status)
{
case LUAT_MOBILE_SIM_READY:
LUAT_DEBUG_PRINT("sim event ready");
break;
case LUAT_MOBILE_NO_SIM:
LUAT_DEBUG_PRINT("sim event not insert");
break;
case LUAT_MOBILE_SIM_NEED_PIN:
LUAT_DEBUG_PRINT("sim event need pin");
break;
}
break;
case LUAT_MOBILE_EVENT_REGISTER_STATUS:
LUAT_DEBUG_PRINT("register event, status %d", status);
break;
case LUAT_MOBILE_EVENT_CELL_INFO:
switch(status)
{
case LUAT_MOBILE_CELL_INFO_UPDATE:
break;
case LUAT_MOBILE_SIGNAL_UPDATE:
break;
}
break;
case LUAT_MOBILE_EVENT_PDP:
LUAT_DEBUG_PRINT("pdp event, cid %d, status %d", index, status);
break;
case LUAT_MOBILE_EVENT_NETIF:
switch (status)
{
case LUAT_MOBILE_NETIF_LINK_ON:
LUAT_DEBUG_PRINT("netif link on event");
g_s_is_link_up = 1;
break;
default:
LUAT_DEBUG_PRINT("netif link off event");
g_s_is_link_up = 0;
break;
}
break;
case LUAT_MOBILE_EVENT_TIME_SYNC:
LUAT_DEBUG_PRINT("time sync event");
break;
case LUAT_MOBILE_EVENT_CSCON:
LUAT_DEBUG_PRINT("rrc event, status %d", status);
break;
default:
break;
}
}
void network_service_init(void)
{
luat_mobile_event_register_handler(mobile_event_cb);
}

View File

@@ -0,0 +1,370 @@
#include "sockets.h"
#include "dns.h"
#include "lwip/ip4_addr.h"
#include "netdb.h"
#include "luat_debug.h"
#include "luat_rtos.h"
#include "luat_mem.h"
#include "network_service.h"
#include "socket_service.h"
/*
功能模块名称socket长连接、数据收发框架
主体业务逻辑为:
1、上电开机后启动一个task等待network_service功能模块中检测到IP网络准备就绪
然后通过tcp去连接地址为REMOTE_SERVER_ADDRESS、端口为g_s_remote_server_port的服务器
2、服务器连接成功后创建一个数据发送的tasktcp_send_task_proc
在这个task中从存储待发送数据的队列中读取每条数据依次发送到服务器
3、服务器连接成功后创建一个数据接收的tasktcp_recv_task_proc
在这个task中使用select机制监听可读和异常事件
4、在数据发送和数据接收的task中出现任何异常都会主动断开socket连接5秒钟之后再去重连
用户如果没有自己的测试服务器可以访问https://netlab.luatos.com/打开一个TCP服务TCP服务的端口号随机分配
端口号确定好之后直接修改本文件中的g_s_remote_server_port变量值
也可以不修改直接烧录本example设备运行起来之后通过usb_service功能模块和PC端串口工具通信来动态修改端口号
*/
typedef struct socket_service_send_data
{
char *data;
uint32_t len;
socket_service_send_data_callback_t callback_func;
uint32_t callback_param;
}socket_service_send_data_t;
#define REMOTE_SERVER_ADDRESS "112.125.89.8"
// #define REMOTE_SERVER_PORT 34410
static int g_s_remote_server_port = 37954;
static luat_rtos_task_handle g_s_tcp_connect_task_handle, g_s_tcp_send_task_handle, g_s_tcp_recv_task_handle;
static luat_rtos_semaphore_t g_s_connect_ok_semaphore;
//socket id、连接状态、连接task存在状态
static int g_s_socket_id = -1;
static uint8_t g_s_is_connected = 0;
static uint8_t g_s_is_tcp_connect_task_exist = 0;
//socket数据发送task mailbox长度
#define TCP_SEND_TASK_MAILBOX_EVENT_MAX_SIZE 50
void socket_service_set_remote_port(int port)
{
g_s_remote_server_port = port;
}
static void close_socket(void)
{
LUAT_DEBUG_PRINT("enter");
close(g_s_socket_id);
g_s_socket_id = -1;
g_s_is_connected = 0;
}
#define RECV_BUF_LEN 1024
static void tcp_recv_task_proc(void *arg)
{
fd_set read_set, error_set;
struct timeval timeout;
int ret, read_len;
char * recv_buf = NULL;
LUAT_DEBUG_PRINT("enter");
while(1)
{
if(g_s_is_connected)
{
luat_rtos_semaphore_take(g_s_connect_ok_semaphore, LUAT_NO_WAIT);
if(NULL == recv_buf)
{
recv_buf = (char *)LUAT_MEM_MALLOC(RECV_BUF_LEN);
LUAT_DEBUG_ASSERT(recv_buf != NULL,"malloc recv_buf fail");
}
timeout.tv_sec = 60;
timeout.tv_usec = 0;
while(1)
{
FD_ZERO(&read_set);
FD_ZERO(&error_set);
FD_SET(g_s_socket_id,&read_set);
FD_SET(g_s_socket_id,&error_set);
LUAT_DEBUG_PRINT("before select");
ret = select(g_s_socket_id+1, &read_set, NULL, &error_set, &timeout);
if(ret < 0)
{
//失败
LUAT_DEBUG_PRINT("select fail, ret %d",ret);
break;
}
else if(ret == 0)
{
//超时
LUAT_DEBUG_PRINT("select timeout");
}
else
{
if(FD_ISSET(g_s_socket_id, &error_set))
{
//出错
LUAT_DEBUG_PRINT("select error event");
break;
}
else if(FD_ISSET(g_s_socket_id, &read_set))
{
LUAT_DEBUG_PRINT("select read event");
read_len = recv(g_s_socket_id, recv_buf, RECV_BUF_LEN, 0);
//read event后第一次读不到数据表示出错
//实测在select时服务器主动断开连接会走到这里
if(read_len <= 0)
{
LUAT_DEBUG_PRINT("select read event error");
break;
}
else
{
do
{
LUAT_DEBUG_PRINT("recv %d bytes data from server",read_len);
if(read_len > 0)
{
//读到了数据在recv_buf中长度为read_len
}
read_len = recv(g_s_socket_id, recv_buf, RECV_BUF_LEN, 0);
}while(read_len > 0);
}
}
else
{
LUAT_DEBUG_PRINT("select other socket event");
}
}
}
close_socket();
luat_rtos_task_sleep(5000);
socket_service_init();
}
else
{
//等待connect ok
LUAT_DEBUG_PRINT("wait connect ok semaphore");
luat_rtos_semaphore_take(g_s_connect_ok_semaphore, 1000);
}
}
}
//同步插入队列结果通过返回值判断0成功其他失败
//插入成功后异步发送结果通过callback_func(int result, void *callback_param)中的result判断0成功其他失败
int socket_service_send_data(const char *data, uint32_t len, socket_service_send_data_callback_t callback_func, uint32_t callback_param)
{
if(data==NULL || len==0)
{
return -1;
}
socket_service_send_data_t *data_item = (socket_service_send_data_t *)LUAT_MEM_MALLOC(sizeof(socket_service_send_data_t));
LUAT_DEBUG_ASSERT(data_item != NULL,"malloc data_item fail");;
data_item->data = LUAT_MEM_MALLOC(len);
LUAT_DEBUG_ASSERT(data_item->data != NULL, "malloc data_item.data fail");
memcpy(data_item->data, data, len);
data_item->len = len;
data_item->callback_func = callback_func;
data_item->callback_param = callback_param;
int ret = luat_rtos_message_send(g_s_tcp_send_task_handle, 0, data_item);
if(ret != 0)
{
LUAT_MEM_FREE(data_item->data);
data_item->data = NULL;
LUAT_MEM_FREE(data_item);
data_item = NULL;
}
return ret;
}
static void tcp_send_task_proc(void *arg)
{
uint32_t message_id;
socket_service_send_data_t *data_item;
int ret = -1;
uint32_t sent_len = 0;
while(1)
{
if(luat_rtos_message_recv(g_s_tcp_send_task_handle, &message_id, (void **)&data_item, LUAT_WAIT_FOREVER) == 0)
{
if(g_s_is_connected)
{
sent_len = 0;
// LUAT_DEBUG_PRINT("total len %d, sent len %d", data_item->len, sent_len);
while (sent_len < data_item->len)
{
ret = send(g_s_socket_id, data_item->data+sent_len, data_item->len-sent_len, 0);
if (ret >= 0)
{
LUAT_DEBUG_PRINT("send %d bytes", ret);
sent_len += ret;
if (sent_len >= data_item->len)
{
if(data_item->callback_func)
{
data_item->callback_func(0, data_item->callback_param);
}
}
}
else
{
if (errno == EWOULDBLOCK)
{
LUAT_DEBUG_PRINT("block, wait send buffer ok");
luat_rtos_task_sleep(1000);
}
else
{
close_socket();
if(data_item->callback_func)
{
data_item->callback_func(ret, data_item->callback_param);
}
luat_rtos_task_sleep(5000);
socket_service_init();
break;
}
}
}
}
else
{
if(data_item->callback_func)
{
data_item->callback_func(1, data_item->callback_param);
}
}
LUAT_MEM_FREE(data_item->data);
data_item->data = NULL;
LUAT_MEM_FREE(data_item);
data_item = NULL;
}
}
}
static void tcp_connect_task_proc(void *arg)
{
ip_addr_t remote_ip;
struct sockaddr_in name;
socklen_t sockaddr_t_size = sizeof(name);
int ret, h_errnop;
struct hostent dns_result;
struct hostent *p_result;
LUAT_DEBUG_PRINT("enter");
while(1)
{
//检查网络是否准备就绪如果尚未就绪等待1秒后循环重试
while(!network_service_is_ready())
{
LUAT_DEBUG_PRINT("wait network_service_is_ready");
luat_rtos_task_sleep(1000);
}
//执行DNS如果失败等待1秒后返回检查网络逻辑重试
char buf[128] = {0};
ret = lwip_gethostbyname_r(REMOTE_SERVER_ADDRESS, &dns_result, buf, sizeof(buf), &p_result, &h_errnop);
if(ret == 0)
{
remote_ip = *((ip_addr_t *)dns_result.h_addr_list[0]);
}
else
{
luat_rtos_task_sleep(1000);
LUAT_DEBUG_PRINT("dns fail");
continue;
}
//创建套接字如果创建失败等待3秒后循环重试
g_s_socket_id = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
while(g_s_socket_id < 0)
{
LUAT_DEBUG_PRINT("create socket fail");
luat_rtos_task_sleep(3000);
}
//连接服务器如果失败关闭套接字等待5秒后返回检查网络逻辑重试
name.sin_family = AF_INET;
name.sin_addr.s_addr = remote_ip.u_addr.ip4.addr;
name.sin_port = htons(g_s_remote_server_port);
ret = connect(g_s_socket_id, (const struct sockaddr *)&name, sockaddr_t_size);
if(ret < 0)
{
LUAT_DEBUG_PRINT("connect fail, ret %d",ret);
close_socket();
luat_rtos_task_sleep(5000);
continue;
}
LUAT_DEBUG_PRINT("connect ok");
g_s_is_connected = 1;
fcntl(g_s_socket_id, F_SETFL, O_NONBLOCK);
if (NULL == g_s_connect_ok_semaphore)
{
luat_rtos_semaphore_create(&g_s_connect_ok_semaphore, 1);
}
luat_rtos_semaphore_release(g_s_connect_ok_semaphore);
if(g_s_tcp_send_task_handle == NULL)
{
luat_rtos_task_create(&g_s_tcp_send_task_handle, 2048, 20, "tcp_send", tcp_send_task_proc, NULL, TCP_SEND_TASK_MAILBOX_EVENT_MAX_SIZE);
}
if(g_s_tcp_recv_task_handle == NULL)
{
luat_rtos_task_create(&g_s_tcp_recv_task_handle, 2048, 20, "tcp_recv", tcp_recv_task_proc, NULL, 0);
}
break;
}
// 打印出来该任务自启动起来最小剩余栈空间大小
//然后我们就可以计算出最大使用的大小一般可以再乘以1.5左右作为最终分配的值必须是4的倍数
// LUAT_DEBUG_PRINT("before luat_rtos_task_delete, %d", luat_rtos_task_get_high_water_mark());
LUAT_DEBUG_PRINT("exit");
g_s_is_tcp_connect_task_exist = 0;
luat_rtos_task_delete(g_s_tcp_connect_task_handle);
}
void socket_service_init(void)
{
if(!g_s_is_tcp_connect_task_exist)
{
g_s_is_tcp_connect_task_exist = (luat_rtos_task_create(&g_s_tcp_connect_task_handle, 2560, 30, "tcp_connect", tcp_connect_task_proc, NULL, 0)==0);
}
}

View File

@@ -0,0 +1,109 @@
#include "luat_debug.h"
#include "luat_rtos.h"
#include "socket_service.h"
/*
功能模块名称:数据发送和模拟断网测试;
数据发送测试主体逻辑如下:
1、上电开机后启动一个task在task内部每隔3秒调用一次socket_service_send_data接口发送数据"send data from test task"到服务器;
发送结果通过回调函数send_data_from_task_callback通知本功能模块
2、上电开机后启动一个定时器3秒后调用一次socket_service_send_data接口发送数据"send data from test timer"到服务器;
发送结果通过回调函数send_data_from_timer_callback通知本功能模块之后再启动一个3秒的定时器发送数据如此循环
模拟断网测试主体逻辑如下(此功能默认关闭,如需打开,请参考本文件末尾几行代码注释):
1、上电开机后启动一个task在task内部进入飞行模式5秒后然后退出飞行模式30秒后再进入飞行模式如此循环
*/
#define SEND_DATA_FROM_TASK "send data from test task"
#define SEND_DATA_FROM_TIMER "send data from test timer"
static luat_rtos_semaphore_t g_s_send_data_from_task_semaphore_handle;
static luat_rtos_timer_t g_s_send_data_timer;
//result0成功1 socket未连接其余错误值是lwip send接口返回的错误原因值
static void send_data_from_task_callback(int result, uint32_t callback_param)
{
LUAT_DEBUG_PRINT("async result %d, callback_param %d", result, callback_param);
luat_rtos_semaphore_release(g_s_send_data_from_task_semaphore_handle);
}
static void test_send_data_task_proc(void *arg)
{
int result;
luat_rtos_semaphore_create(&g_s_send_data_from_task_semaphore_handle, 1);
while (1)
{
LUAT_DEBUG_PRINT("send request");
result = socket_service_send_data(SEND_DATA_FROM_TASK, strlen(SEND_DATA_FROM_TASK), send_data_from_task_callback, 0);
if (0 == result)
{
luat_rtos_semaphore_take(g_s_send_data_from_task_semaphore_handle, LUAT_WAIT_FOREVER);
}
else
{
LUAT_DEBUG_PRINT("sync result %d", result);
}
luat_rtos_task_sleep(3000);
}
}
static void send_data_timer_callback(void);
//result0成功1 socket未连接其余错误值是lwip send接口返回的错误原因值
static void send_data_from_timer_callback(int result, uint32_t callback_param)
{
LUAT_DEBUG_PRINT("async result %d, callback_param %d", result, callback_param);
luat_rtos_timer_start(g_s_send_data_timer, 3000, 0, send_data_timer_callback, NULL);
}
static void send_data_timer_callback(void)
{
LUAT_DEBUG_PRINT("send request");
int result = socket_service_send_data(SEND_DATA_FROM_TIMER, strlen(SEND_DATA_FROM_TIMER), send_data_from_timer_callback, 0);
if (0 != result)
{
LUAT_DEBUG_PRINT("sync result %d", result);
luat_rtos_timer_start(g_s_send_data_timer, 3000, 0, send_data_timer_callback, NULL);
}
}
static void flymode_task_proc(void *arg)
{
luat_rtos_task_sleep(5000);
LUAT_DEBUG_PRINT("entry");
while (1)
{
luat_rtos_task_sleep(30000);
LUAT_DEBUG_PRINT("enter flymode");
luat_mobile_set_flymode(0,1);
luat_rtos_task_sleep(5000);
luat_mobile_set_flymode(0,0);
LUAT_DEBUG_PRINT("exit flymode");
}
}
void test_service_init(void)
{
luat_rtos_task_handle test_send_data_task_handle;
luat_rtos_task_create(&test_send_data_task_handle, 2048, 30, "test_send_data", test_send_data_task_proc, NULL, 0);
luat_rtos_timer_create(&g_s_send_data_timer);
luat_rtos_timer_start(g_s_send_data_timer, 3000, 0, send_data_timer_callback, NULL);
// 此task通过不断的进入和退出飞行模式来模拟断网场景
// 仅用模拟测试使用,有需要可以自行打开
// luat_rtos_task_handle flymode_task_handle;
// luat_rtos_task_create(&flymode_task_handle, 2048, 20, "flymode", flymode_task_proc, NULL, NULL);
}

View File

@@ -0,0 +1,84 @@
#include "luat_rtos.h"
#include "luat_debug.h"
#include "luat_uart.h"
#include "luat_mem.h"
#include "socket_service.h"
/*
功能模块名称usb和上位机通信
主体业务逻辑为:
1、设备上电开机后在电脑端会枚举出三个端口使用第3个端口可以和PC端的串口工具进行数据通信
2、PC端串口工具发送port,<%d>\r\n命令来修改socket_service功能模块中的服务器端口号
例如port,1234\r\n表示修改要连接的服务器端口号为1234
*/
// static luat_rtos_task_handle usb_task_handle;
//usb在电脑上枚举出的第3个口为数据通信口
//此端口的ID为4
#define USB_DATA_PORT_ID 4
//仅仅测试使用,写的不够健壮
#define USB_RECV_BUFFER_SIZE 256
static uint8_t g_s_recv_buff[USB_RECV_BUFFER_SIZE+1];
static uint32_t g_s_recved_len = 0;
static void parse_recv_data(char* data, uint32_t len)
{
if(len > (USB_RECV_BUFFER_SIZE-g_s_recved_len))
{
LUAT_DEBUG_PRINT("recv len exceed max size, error");
goto exit;
}
memcpy(g_s_recv_buff+g_s_recved_len, data, len);
g_s_recved_len += len;
*(g_s_recv_buff+len) = 0;
if(strstr((const char *)g_s_recv_buff, "\r\n"))
{
int port;
if(sscanf(g_s_recv_buff, "port,%d", &port))
{
socket_service_set_remote_port(port);
luat_uart_write(USB_DATA_PORT_ID, "\r\nOK\r\n", 6);
}
else
{
luat_uart_write(USB_DATA_PORT_ID, "\r\nERROR\r\n", 9);
}
goto exit;
}
else
{
return;
}
exit:
memset(g_s_recv_buff, 0, sizeof(g_s_recv_buff));
g_s_recved_len = 0;
return;
}
static void usb_recv_cb(int uart_id, uint32_t data_len){
char* data_buff = LUAT_MEM_MALLOC(data_len+1);
memset(data_buff,0,data_len+1);
luat_uart_read(uart_id, data_buff, data_len);
LUAT_DEBUG_PRINT("uart_id:%d data:%s data_len:%d",uart_id,data_buff,data_len);
parse_recv_data(data_buff, data_len);
LUAT_MEM_FREE(data_buff);
}
void usb_service_init(void)
{
luat_uart_t uart = {
.id = USB_DATA_PORT_ID,
};
luat_uart_setup(&uart);
luat_uart_ctrl(USB_DATA_PORT_ID, LUAT_UART_SET_RECV_CALLBACK, usb_recv_cb);
}

View File

@@ -0,0 +1,21 @@
local TARGET_NAME = "example_socket_single"
local LIB_DIR = "$(buildir)/".. TARGET_NAME .. "/"
local LIB_NAME = "lib" .. TARGET_NAME .. ".a "
target(TARGET_NAME)
set_kind("static")
set_targetdir(LIB_DIR)
--加入代码和头文件
add_includedirs("./inc",{public = true})
add_files("./src/*.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
--自动链接
LIB_USER = LIB_USER .. SDK_TOP .. LIB_DIR .. LIB_NAME .. " "
--甚至可以加入自己的库
target_end()