add example

This commit is contained in:
pvvx 2017-06-07 23:44:38 +03:00
parent 0cd01e4dc1
commit 5cd34b0c9f
75 changed files with 6023 additions and 217 deletions

View file

@ -0,0 +1,7 @@
#ifndef EXAMPLE_SOCKET_TCP_TRX_H
#define EXAMPLE_SOCKET_TCP_TRX_H
void example_socket_tcp_trx_1(void);
void example_socket_tcp_trx_2(void);
#endif /* EXAMPLE_SOCKET_TCP_TRX_H */

View file

@ -0,0 +1,145 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
//#include <osdep_api.h>
#include <osdep_service.h>
#define SERVER_PORT 80
#define LISTEN_QLEN 2
static int tx_exit = 0, rx_exit = 0;
//static _Sema tcp_tx_rx_sema;
static _sema tcp_tx_rx_sema;
static void tx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
memset(buffer, 1, sizeof(buffer));
printf("\n%s start\n", __FUNCTION__);
while(1) {
int ret = 0;
//RtlDownSema(&tcp_tx_rx_sema);
rtw_down_sema(&tcp_tx_rx_sema);
ret = send(client_fd, buffer, sizeof(buffer), 0);
//RtlUpSema(&tcp_tx_rx_sema);
rtw_up_sema(&tcp_tx_rx_sema);
if(ret <= 0)
goto exit;
vTaskDelay(100);
}
exit:
printf("\n%s exit\n", __FUNCTION__);
tx_exit = 1;
vTaskDelete(NULL);
}
static void rx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
printf("\n%s start\n", __FUNCTION__);
while(1) {
int ret = 0, sock_err = 0;
size_t err_len = sizeof(sock_err);
//RtlDownSema(&tcp_tx_rx_sema);
rtw_down_sema(&tcp_tx_rx_sema);
ret = recv(client_fd, buffer, sizeof(buffer), MSG_DONTWAIT);
getsockopt(client_fd, SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
//RtlUpSema(&tcp_tx_rx_sema);
rtw_up_sema(&tcp_tx_rx_sema);
// ret == -1 and socket error == EAGAIN when no data received for nonblocking
if((ret == -1) && (sock_err == EAGAIN))
continue;
else if(ret <= 0)
goto exit;
vTaskDelay(10);
}
exit:
printf("\n%s exit\n", __FUNCTION__);
rx_exit = 1;
vTaskDelete(NULL);
}
static void example_socket_tcp_trx_thread(void *param)
{
int server_fd = -1, client_fd = -1;
struct sockaddr_in server_addr, client_addr;
size_t client_addr_size;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: socket tx/rx 1\n");
server_fd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("ERROR: bind\n");
goto exit;
}
if(listen(server_fd, LISTEN_QLEN) != 0) {
printf("ERROR: listen\n");
goto exit;
}
while(1) {
client_addr_size = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size);
if(client_fd >= 0) {
tx_exit = 1;
rx_exit = 1;
//RtlInitSema(&tcp_tx_rx_sema, 1);
rtw_init_sema(&tcp_tx_rx_sema, 1);
if(xTaskCreate(tx_thread, ((const char*)"tx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(tx_thread) failed", __FUNCTION__);
else
tx_exit = 0;
vTaskDelay(10);
if(xTaskCreate(rx_thread, ((const char*)"rx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(rx_thread) failed", __FUNCTION__);
else
rx_exit = 0;
while(1) {
if(tx_exit && rx_exit) {
close(client_fd);
break;
}
else
vTaskDelay(1000);
}
//RtlFreeSema(&tcp_tx_rx_sema);
rtw_free_sema(&tcp_tx_rx_sema);
}
}
exit:
close(server_fd);
vTaskDelete(NULL);
}
void example_socket_tcp_trx_1(void)
{
if(xTaskCreate(example_socket_tcp_trx_thread, ((const char*)"example_socket_tcp_trx_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_socket_tcp_trx_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,125 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#define SERVER_PORT 80
#define LISTEN_QLEN 2
#define MAX_RETRY 5
static int tx_exit = 0, rx_exit = 0;
static void tx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
memset(buffer, 1, sizeof(buffer));
printf("\n%s start\n", __FUNCTION__);
while(1) {
int retry = 0;
// retry send if socket busy
for(retry = 0; retry < MAX_RETRY; retry ++) {
if(write(client_fd, buffer, sizeof(buffer)) == -1)
printf("\nwrite retry=%d\n", retry);
else
break;
}
// socket may be closed if max retry reached
if(retry == MAX_RETRY)
goto exit;
vTaskDelay(100);
}
exit:
printf("\n%s exit\n", __FUNCTION__);
tx_exit = 1;
vTaskDelete(NULL);
}
static void rx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
printf("\n%s start\n", __FUNCTION__);
while(1) {
if(read(client_fd, buffer, sizeof(buffer)) <= 0)
goto exit;
}
exit:
printf("\n%s exit\n", __FUNCTION__);
rx_exit = 1;
vTaskDelete(NULL);
}
static void example_socket_tcp_trx_thread(void *param)
{
int server_fd = -1, client_fd = -1;
struct sockaddr_in server_addr, client_addr;
size_t client_addr_size;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: socket tx/rx 2\n");
server_fd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("ERROR: bind\n");
goto exit;
}
if(listen(server_fd, LISTEN_QLEN) != 0) {
printf("ERROR: listen\n");
goto exit;
}
while(1) {
client_addr_size = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size);
if(client_fd >= 0) {
tx_exit = 1;
rx_exit = 1;
if(xTaskCreate(tx_thread, ((const char*)"tx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(tx_thread) failed", __FUNCTION__);
else
tx_exit = 0;
vTaskDelay(10);
if(xTaskCreate(rx_thread, ((const char*)"rx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(rx_thread) failed", __FUNCTION__);
else
rx_exit = 0;
while(1) {
if(tx_exit && rx_exit) {
close(client_fd);
break;
}
else
vTaskDelay(1000);
}
}
}
exit:
close(server_fd);
vTaskDelete(NULL);
}
void example_socket_tcp_trx_2(void)
{
if(xTaskCreate(example_socket_tcp_trx_thread, ((const char*)"example_socket_tcp_trx_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_socket_tcp_trx_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,22 @@
LWIP SOCKET TCP TX/RX EXAMPLE
Description:
Example of TCP bidirectional transmission with use two threads for TCP tx/rx on one socket.
Example 1 uses non-blocking recv and semaphore for TCP send/recv mutex
Example 2 does not use any synchronization mechanism, but can only run correctly on lwip with TCPIP thread msg api patch
Configuration:
Modify SERVER_PORT in example_socket_tcp_trx.c for listen port
[platform_opts.h]
Run example 1 in example_socket_tcp_trx_1.c
#define CONFIG_EXAMPLE_SOCKET_TCP_TRX 1
Run example 2 in example_socket_tcp_trx_2.c
#define CONFIG_EXAMPLE_SOCKET_TCP_TRX 2
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A socket TCP trx example thread will be started automatically when booting.
A TCP server will be started to wait for connection.
Can use a TCP client connecting to this server to start a TCP bidirectional transmission