mirror of
https://github.com/pvvx/RTL00MP3.git
synced 2025-07-31 12:41:06 +00:00
add example
This commit is contained in:
parent
0cd01e4dc1
commit
5cd34b0c9f
75 changed files with 6023 additions and 217 deletions
|
|
@ -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 */
|
||||
|
|
@ -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__);
|
||||
}
|
||||
|
|
@ -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__);
|
||||
}
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue