Demo: qemu mps2 echo client cleanup (#833)

This commit is contained in:
alfred gedeon 2022-08-03 00:05:14 +02:00 committed by GitHub
parent 9058c39aed
commit 4242c47a8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 386 additions and 399 deletions

View file

@ -47,10 +47,6 @@ SOURCE_FILES += ${FREERTOS_TCP}/portable/NetworkInterface/MPS2_AN385/NetworkInte
SOURCE_FILES += TCPEchoClient_SingleTasks.c
SOURCE_FILES += ${FREERTOS_TCP}/portable/NetworkInterface/MPS2_AN385/ether_lan9118/smsc9220_eth_drv.c
# networking specific cflags
CFLAGS := -DmainCREATE_NETWORKING_DEMO_ONLY=1
CFLAGS += -DmainCREATE_TCP_ECHO_TASKS_SINGLE=1
DEFINES := -DprojCOVERAGE_TEST -DQEMU_SOC_MPS2 -DHEAP3
LDFLAGS = -T ./scripts/mps2_m3.ld -specs=nano.specs --specs=rdimon.specs -lc -lrdimon

View file

@ -54,17 +54,17 @@
#if ( ipconfigUSE_TCP == 1 )
/* The echo tasks create a socket, send out a number of echo requests, listen
for the echo reply, then close the socket again before starting over. This
delay is used between each iteration to ensure the network does not get too
congested. */
* for the echo reply, then close the socket again before starting over. This
* delay is used between each iteration to ensure the network does not get too
* congested. */
#define echoLOOP_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
/* The echo server is assumed to be on port 7, which is the standard echo
protocol port. */
* protocol port. */
#define echoECHO_PORT ( 7 )
/* The size of the buffers is a multiple of the MSS - the length of the data
sent is a pseudo random size between 20 and echoBUFFER_SIZES. */
* sent is a pseudo random size between 20 and echoBUFFER_SIZES. */
#define echoBUFFER_SIZE_MULTIPLIER ( 1 )
#define echoBUFFER_SIZES ( ipconfigTCP_MSS * echoBUFFER_SIZE_MULTIPLIER )
@ -88,7 +88,7 @@ sent is a pseudo random size between 20 and echoBUFFER_SIZES. */
/*-----------------------------------------------------------*/
/* Rx and Tx time outs are used to ensure the sockets do not wait too long for
missing data. */
* missing data. */
static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 );
static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 );
@ -142,8 +142,8 @@ missing data. */
xWinProps.lRxWinSize = 3;
/* This task can be created a number of times. Each instance is numbered
to enable each instance to use a different Rx and Tx buffer. The number is
passed in as the task's parameter. */
* to enable each instance to use a different Rx and Tx buffer. The number is
* passed in as the task's parameter. */
xInstance = ( BaseType_t ) pvParameters;
/* Point to the buffers to be used by this instance of this task. */
@ -151,8 +151,8 @@ missing data. */
pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] );
/* Echo requests are sent to the echo server. The address of the echo
server is configured by the constants configECHO_SERVER_ADDR0 to
configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */
* server is configured by the constants configECHO_SERVER_ADDR0 to
* configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */
xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,
configECHO_SERVER_ADDR1,
@ -166,7 +166,7 @@ missing data. */
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
/* Set a time out so a missing reply does not cause the task to block
indefinitely. */
* indefinitely. */
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
@ -209,10 +209,11 @@ missing data. */
/* Error? */
break;
}
printf( "data send receiving data... \n" );
/* Clear the buffer into which the echoed string will be
placed. */
* placed. */
memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES );
xReceivedBytes = 0;
@ -227,7 +228,7 @@ missing data. */
if( xReturned < 0 )
{
/* Error occurred. Latch it so it can be detected
below. */
* below. */
xReceivedBytes = xReturned;
break;
}
@ -244,8 +245,8 @@ missing data. */
}
/* If an error occurred it will be latched in xReceivedBytes,
otherwise xReceived bytes will be just that - the number of
bytes received from the echo server. */
* otherwise xReceived bytes will be just that - the number of
* bytes received from the echo server. */
if( xReceivedBytes > 0 )
{
/* Compare the transmitted string to the received string. */
@ -259,7 +260,7 @@ missing data. */
else
{
/* The received string did not match the transmitted
string. */
* string. */
ulTxRxFailures[ xInstance ]++;
break;
}
@ -277,11 +278,11 @@ missing data. */
}
/* Finished using the connected socket, initiate a graceful close:
FIN, FIN+ACK, ACK. */
* FIN, FIN+ACK, ACK. */
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );
/* Expect FreeRTOS_recv() to return an error once the shutdown is
complete. */
* complete. */
xTimeOnEntering = xTaskGetTickCount();
do
@ -306,7 +307,7 @@ missing data. */
FreeRTOS_closesocket( xSocket );
/* Pause for a short while to ensure the network is not too
congested. */
* congested. */
vTaskDelay( echoLOOP_DELAY );
}
}
@ -321,7 +322,7 @@ missing data. */
uint32_t ulRandomNumber;
/* Randomise the number of characters that will be sent in the echo
request. */
* request. */
do
{
( void ) xApplicationGetRandomNumber( &ulRandomNumber );
@ -350,7 +351,7 @@ missing data. */
BaseType_t xReturn = pdPASS, x;
/* Return fail is the number of cycles does not increment between
consecutive calls. */
* consecutive calls. */
for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ )
{
if( ulTxRxCycles[ x ] == ulLastEchoSocketCount[ x ] )

View file

@ -46,21 +46,23 @@ __attribute__((optimize("O0")))
__attribute__( ( naked ) )
void Reset_Handler( void )
{
// set stack pointer
/* set stack pointer */
__asm volatile ( "ldr r0, =_estack" );
__asm volatile ( "mov sp, r0" );
// copy .data section from flash to RAM
/* copy .data section from flash to RAM */
for( uint32_t * src = &_sidata, * dest = &_sdata; dest < &_edata; )
{
*dest++ = *src++;
}
// zero out .bss section
/* zero out .bss section */
for( uint32_t * dest = &_sbss; dest < &_ebss; )
{
*dest++ = 0;
}
// jump to board initialisation
/* jump to board initialisation */
void _start( void );
_start();
}
@ -68,9 +70,9 @@ void Reset_Handler(void)
void prvGetRegistersFromStack( uint32_t * pulFaultStackAddress )
{
/* These are volatile to try and prevent the compiler/linker optimising them
away as the variables never actually get used. If the debugger won't show the
values of the variables, make them global my moving their declaration outside
of this function. */
* away as the variables never actually get used. If the debugger won't show the
* values of the variables, make them global my moving their declaration outside
* of this function. */
volatile uint32_t r0;
volatile uint32_t r1;
volatile uint32_t r2;
@ -91,7 +93,9 @@ of this function. */
psr = pulFaultStackAddress[ 7 ];
/* When the following line is hit, the variables contain the register values. */
for( ;; );
for( ; ; )
{
}
}
static void Default_Handler( void ) __attribute__( ( naked ) );
@ -113,7 +117,6 @@ void Default_Handler(void)
static void HardFault_Handler( void ) __attribute__( ( naked ) );
void Default_Handler2( void )
{
__asm volatile
(
" tst lr, #4 \n"
@ -129,56 +132,64 @@ void Default_Handler2(void)
void Default_Handler3( void )
{
for (;;) { }
for( ; ; )
{
}
}
void Default_Handler4( void )
{
for (;;) { }
for( ; ; )
{
}
}
void Default_Handler5( void )
{
for (;;) { }
for( ; ; )
{
}
}
void Default_Handler6( void )
{
for (;;) { }
for( ; ; )
{
}
}
const uint32_t * isr_vector[] __attribute__( ( section( ".isr_vector" ) ) ) =
{
( uint32_t * ) &_estack,
(uint32_t*)&Reset_Handler, // Reset -15
(uint32_t*)&Default_Handler, // NMI_Handler -14
(uint32_t*)&Default_Handler2, // HardFault_Handler -13
(uint32_t*)&Default_Handler3, // MemManage_Handler -12
(uint32_t*)&Default_Handler4, // BusFault_Handler -11
(uint32_t*)&Default_Handler5, // UsageFault_Handler -10
0, // reserved
0, // reserved
0, // reserved
0, // reserved -6
(uint32_t*)&vPortSVCHandler, // SVC_Handler -5
(uint32_t*)&Default_Handler6, // DebugMon_Handler -4
0, // reserved
(uint32_t*)&xPortPendSVHandler, // PendSV handler -2
(uint32_t*)&xPortSysTickHandler, // SysTick_Handler -1
0, // uart0 receive 0
0, // uart0 transmit
0, // uart1 receive
0, // uart1 transmit
0, // uart 2 receive
0, // uart 2 transmit
0, // GPIO 0 combined interrupt
0, // GPIO 2 combined interrupt
0, // Timer 0
0, // Timer 1
0, // Dial Timer
0, // SPI0 SPI1
0, // uart overflow 1 2,3 12
(uint32_t*)&EthernetISR, // Ethernet 13
( uint32_t * ) &Reset_Handler, /* Reset -15 */
( uint32_t * ) &Default_Handler, /* NMI_Handler -14 */
( uint32_t * ) &Default_Handler2, /* HardFault_Handler -13 */
( uint32_t * ) &Default_Handler3, /* MemManage_Handler -12 */
( uint32_t * ) &Default_Handler4, /* BusFault_Handler -11 */
( uint32_t * ) &Default_Handler5, /* UsageFault_Handler -10 */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved -6 */
( uint32_t * ) &vPortSVCHandler, /* SVC_Handler -5 */
( uint32_t * ) &Default_Handler6, /* DebugMon_Handler -4 */
0, /* reserved */
( uint32_t * ) &xPortPendSVHandler, /* PendSV handler -2 */
( uint32_t * ) &xPortSysTickHandler, /* SysTick_Handler -1 */
0, /* uart0 receive 0 */
0, /* uart0 transmit */
0, /* uart1 receive */
0, /* uart1 transmit */
0, /* uart 2 receive */
0, /* uart 2 transmit */
0, /* GPIO 0 combined interrupt */
0, /* GPIO 2 combined interrupt */
0, /* Timer 0 */
0, /* Timer 1 */
0, /* Dial Timer */
0, /* SPI0 SPI1 */
0, /* uart overflow 1 2,3 12 */
( uint32_t * ) &EthernetISR, /* Ethernet 13 */
};
void _start( void )
@ -190,16 +201,15 @@ void _start(void)
__attribute__( ( naked ) ) void exit( int status )
{
// Force qemu to exit using ARM Semihosting
/* Force qemu to exit using ARM Semihosting */
__asm volatile (
"mov r1, r0\n"
"cmp r1, #0\n"
"bne .notclean\n"
"ldr r1, =0x20026\n" // ADP_Stopped_ApplicationExit, a clean exit
"ldr r1, =0x20026\n" /* ADP_Stopped_ApplicationExit, a clean exit */
".notclean:\n"
"movs r0, #0x18\n" // SYS_EXIT
"movs r0, #0x18\n" /* SYS_EXIT */
"bkpt 0xab\n"
"end: b end\n"
);
}

View file

@ -42,17 +42,8 @@ void vApplicationTickHook( void );
extern void initialise_monitor_handles(void);
int main ()
{
#if ( mainCREATE_NETWORKING_DEMO_ONLY == 1 )
{
main_tcp_echo_client_tasks();
}
#else
{
#error "Invalid Selection..." \
"\nPlease Select a Demo application from the main command"
}
#endif
return 0;
}

View file

@ -26,8 +26,7 @@
/*
* This project is a cut down version of the project described on the following
* link. Only the simple UDP client and server and the TCP echo clients are
* included in the build:
* link. Only the TCP echo clients is included in the build:
* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html
*/
@ -44,23 +43,12 @@
/* Demo application includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
/*#include "SimpleUDPClientAndServer.h" */
/*#include "SimpleTCPEchoServer.h" */
/*#include "logging.h" */
#include "TCPEchoClient_SingleTasks.h"
/* Simple UDP client and server task parameters. */
#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL )
/* Echo client task parameters - used for both TCP and UDP echo clients. */
/* Echo client task parameters */
#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the linux port. */
#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* Echo server task parameters. */
#define mainECHO_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the linux port. */
#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* Define a name that will be used for LLMNR and NBNS searches. */
#define mainHOST_NAME "RTOSDemo"
#define mainDEVICE_NICK_NAME "qemu_demo"
@ -94,27 +82,37 @@ static void prvMiscInitialisation( void );
* defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is
* 1 but a DHCP server could not be contacted. See the online documentation for
* more information. */
static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0,
static const uint8_t ucIPAddress[ 4 ] =
{
configIP_ADDR0,
configIP_ADDR1,
configIP_ADDR2,
configIP_ADDR3
};
static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0,
static const uint8_t ucNetMask[ 4 ] =
{
configNET_MASK0,
configNET_MASK1,
configNET_MASK2,
configNET_MASK3
};
static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0,
static const uint8_t ucGatewayAddress[ 4 ] =
{
configGATEWAY_ADDR0,
configGATEWAY_ADDR1,
configGATEWAY_ADDR2,
configGATEWAY_ADDR3
};
static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0,
static const uint8_t ucDNSServerAddress[ 4 ] =
{
configDNS_SERVER_ADDR0,
configDNS_SERVER_ADDR1,
configDNS_SERVER_ADDR2,
configDNS_SERVER_ADDR3
};
const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0,
const uint8_t ucMACAddress[ 6 ] =
{
configMAC_ADDR0,
configMAC_ADDR1,
configMAC_ADDR2,
configMAC_ADDR3,
@ -122,16 +120,6 @@ const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0,
configMAC_ADDR5
};
/* Set the following constant to pdTRUE to log using the method indicated by the
* name of the constant, or pdFALSE to not log using the method indicated by the
* name of the constant. Options include to standard out (xLogToStdout), to a disk
* file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE
* then UDP messages are sent to the IP address configured as the echo server
* address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and
* the port number set by configPRINT_PORT in FreeRTOSConfig.h. */
//const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;
/* Use by the pseudo random number generator. */
static UBaseType_t ulNextRand;
@ -183,6 +171,7 @@ void main_tcp_echo_client_tasks( void )
/*-----------------------------------------------------------*/
BaseType_t xTasksAlreadyCreated = pdFALSE;
/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect
* events are only received if implemented in the MAC driver. */
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )