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 )
@ -77,18 +77,18 @@ sent is a pseudo random size between 20 and echoBUFFER_SIZES. */
* Uses a socket to send data to, then receive data from, the standard echo
* port number 7.
*/
static void prvEchoClientTask( void *pvParameters );
static void prvEchoClientTask( void * pvParameters );
/*
* Creates a pseudo random sized buffer of data to send to the echo server.
*/
static BaseType_t prvCreateTxData( char *ucBuffer,
static BaseType_t prvCreateTxData( char * ucBuffer,
uint32_t ulBufferLength );
/*-----------------------------------------------------------*/
/* 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 );
@ -121,7 +121,7 @@ missing data. */
}
/*-----------------------------------------------------------*/
static void prvEchoClientTask( void *pvParameters )
static void prvEchoClientTask( void * pvParameters )
{
Socket_t xSocket;
struct freertos_sockaddr xEchoServerAddress;
@ -130,7 +130,7 @@ missing data. */
volatile uint32_t ulTxCount = 0UL;
BaseType_t xReceivedBytes, xReturned, xInstance;
BaseType_t lTransmitted, lStringLength;
char *pcTransmittedString, *pcReceivedString;
char * pcTransmittedString, * pcReceivedString;
WinProperties_t xWinProps;
TickType_t xTimeOnEntering;
BaseType_t ret;
@ -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 ) );
@ -195,24 +195,25 @@ missing data. */
printf( "sending data to the echo server size %d original %d\n",
lStringLength,
echoBUFFER_SIZES);
echoBUFFER_SIZES );
/* Send the string to the socket. */
lTransmitted = FreeRTOS_send( xSocket, /* The socket being sent to. */
( void * ) pcTransmittedString, /* The data being sent. */
lStringLength, /* The length of the data being sent. */
0 ); /* No flags. */
printf("FreeRTOS_send returned...transmitted %d\n",
lTransmitted);
printf( "FreeRTOS_send returned...transmitted %d\n",
lTransmitted );
if( lTransmitted < 0 )
{
/* Error? */
break;
}
printf("data send receiving data... \n");
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,13 +307,13 @@ missing data. */
FreeRTOS_closesocket( xSocket );
/* Pause for a short while to ensure the network is not too
congested. */
* congested. */
vTaskDelay( echoLOOP_DELAY );
}
}
/*-----------------------------------------------------------*/
static BaseType_t prvCreateTxData( char *cBuffer,
static BaseType_t prvCreateTxData( char * cBuffer,
uint32_t ulBufferLength )
{
BaseType_t lCharactersToAdd, lCharacter;
@ -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

@ -37,40 +37,42 @@ extern void xPortSysTickHandler( void );
extern void uart_init();
extern int main();
void __attribute__((weak)) EthernetISR (void);
void __attribute__( ( weak ) ) EthernetISR( void );
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;
/* Prevent optimization so gcc does not replace code with memcpy */
__attribute__((optimize("O0")))
__attribute__((naked))
void Reset_Handler(void)
{
// set stack pointer
__asm volatile ("ldr r0, =_estack");
__asm volatile ("mov sp, r0");
// copy .data section from flash to RAM
for (uint32_t *src = &_sidata, *dest = &_sdata; dest < &_edata;)
__attribute__( ( optimize( "O0" ) ) )
__attribute__( ( naked ) )
void Reset_Handler( void )
{
/* set stack pointer */
__asm volatile ( "ldr r0, =_estack" );
__asm volatile ( "mov sp, r0" );
/* copy .data section from flash to RAM */
for( uint32_t * src = &_sidata, * dest = &_sdata; dest < &_edata; )
{
*dest++ = *src++;
}
// zero out .bss section
for (uint32_t *dest = &_sbss; dest < &_ebss;)
/* zero out .bss section */
for( uint32_t * dest = &_sbss; dest < &_ebss; )
{
*dest++ = 0;
}
// jump to board initialisation
void _start(void);
/* jump to board initialisation */
void _start( void );
_start();
}
void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )
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;
@ -78,7 +80,7 @@ of this function. */
volatile uint32_t r12;
volatile uint32_t lr; /* Link register. */
volatile uint32_t pc; /* Program counter. */
volatile uint32_t psr;/* Program status register. */
volatile uint32_t psr; /* Program status register. */
r0 = pulFaultStackAddress[ 0 ];
r1 = pulFaultStackAddress[ 1 ];
@ -91,11 +93,13 @@ 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 ) );
void Default_Handler(void)
void Default_Handler( void )
{
__asm volatile
(
@ -111,9 +115,8 @@ void Default_Handler(void)
);
}
static void HardFault_Handler( void ) __attribute__( ( naked ) );
void Default_Handler2(void)
void Default_Handler2( void )
{
__asm volatile
(
" tst lr, #4 \n"
@ -127,79 +130,86 @@ 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*)&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 * ) &_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 */
};
void _start(void)
void _start( void )
{
uart_init();
main(0, 0);
exit(0);
main( 0, 0 );
exit( 0 );
}
__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 (
"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

@ -43,16 +43,7 @@ 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,43 +82,43 @@ 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,
configMAC_ADDR4,
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;
@ -182,7 +170,8 @@ 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
* events are only received if implemented in the MAC driver. */
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
@ -231,7 +220,7 @@ void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
}
else
{
FreeRTOS_printf( ("Application idle hook network down\n") );
FreeRTOS_printf( ( "Application idle hook network down\n" ) );
}
}
/*-----------------------------------------------------------*/