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 += TCPEchoClient_SingleTasks.c
SOURCE_FILES += ${FREERTOS_TCP}/portable/NetworkInterface/MPS2_AN385/ether_lan9118/smsc9220_eth_drv.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 DEFINES := -DprojCOVERAGE_TEST -DQEMU_SOC_MPS2 -DHEAP3
LDFLAGS = -T ./scripts/mps2_m3.ld -specs=nano.specs --specs=rdimon.specs -lc -lrdimon LDFLAGS = -T ./scripts/mps2_m3.ld -specs=nano.specs --specs=rdimon.specs -lc -lrdimon

View file

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

View file

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

View file

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

View file

@ -26,8 +26,7 @@
/* /*
* This project is a cut down version of the project described on the following * 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 * link. Only the TCP echo clients is included in the build:
* included in the build:
* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html
*/ */
@ -44,23 +43,12 @@
/* Demo application includes. */ /* Demo application includes. */
#include "FreeRTOS_IP.h" #include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h" #include "FreeRTOS_Sockets.h"
/*#include "SimpleUDPClientAndServer.h" */
/*#include "SimpleTCPEchoServer.h" */
/*#include "logging.h" */
#include "TCPEchoClient_SingleTasks.h" #include "TCPEchoClient_SingleTasks.h"
/* Simple UDP client and server task parameters. */ /* Echo client 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. */
#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the linux port. */ #define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the linux port. */
#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #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 a name that will be used for LLMNR and NBNS searches. */
#define mainHOST_NAME "RTOSDemo" #define mainHOST_NAME "RTOSDemo"
#define mainDEVICE_NICK_NAME "qemu_demo" #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 * 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 * 1 but a DHCP server could not be contacted. See the online documentation for
* more information. */ * more information. */
static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, static const uint8_t ucIPAddress[ 4 ] =
{
configIP_ADDR0,
configIP_ADDR1, configIP_ADDR1,
configIP_ADDR2, configIP_ADDR2,
configIP_ADDR3 configIP_ADDR3
}; };
static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, static const uint8_t ucNetMask[ 4 ] =
{
configNET_MASK0,
configNET_MASK1, configNET_MASK1,
configNET_MASK2, configNET_MASK2,
configNET_MASK3 configNET_MASK3
}; };
static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, static const uint8_t ucGatewayAddress[ 4 ] =
{
configGATEWAY_ADDR0,
configGATEWAY_ADDR1, configGATEWAY_ADDR1,
configGATEWAY_ADDR2, configGATEWAY_ADDR2,
configGATEWAY_ADDR3 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_ADDR1,
configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR2,
configDNS_SERVER_ADDR3 configDNS_SERVER_ADDR3
}; };
const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, const uint8_t ucMACAddress[ 6 ] =
{
configMAC_ADDR0,
configMAC_ADDR1, configMAC_ADDR1,
configMAC_ADDR2, configMAC_ADDR2,
configMAC_ADDR3, configMAC_ADDR3,
@ -122,16 +120,6 @@ const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0,
configMAC_ADDR5 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. */ /* Use by the pseudo random number generator. */
static UBaseType_t ulNextRand; static UBaseType_t ulNextRand;
@ -183,6 +171,7 @@ void main_tcp_echo_client_tasks( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xTasksAlreadyCreated = pdFALSE; BaseType_t xTasksAlreadyCreated = pdFALSE;
/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect /* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect
* events are only received if implemented in the MAC driver. */ * events are only received if implemented in the MAC driver. */
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )