Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

FreeRTOS+TCP logs: crc swap: 0000

Posted by yanvasilij on January 27, 2017

Hello,

I use FreeRTOS+TCP on my STM32F429. I created project with modbus TCP slave and start to poll data from my PC. Sometimes I get modbus errors (time out). I turned on FreeRTOS+TCP logs and found there the follows:

usGenerateProtocolChecksum[TCP]: crc swap: 0000

What does mean this logs?

Regards, Vasilij


FreeRTOS+TCP logs: crc swap: 0000

Posted by rtel on January 27, 2017

I think that is telling you a TCP checksum was correct (worked out to be 0). Not sure that is an error.


FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on January 28, 2017

Do you think that the modbus errors occur at the moment that the TCP checksum equals to zero?

Beside logging, the code says:

~~~~ if( usChecksum == 0u ) { usChecksum = ipCORRECTCRC; /* which is equal to 0xffff. */ } else { usChecksum = FreeRTOShtons( usChecksum ); } ~~~~


FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on January 29, 2017

The reason that 0x0 was transmitted as 0xffff is because of the UDP rule, see rfc768 :

If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care)

But if I'm not mistaken, for other protocols this should not apply and thus:

~~~~ if( ( usChecksum == 0u ) && ( ucProtocol == ( uint8t ) ipPROTOCOLUDP ) ) { #if( ipconfigHASDEBUGPRINTF != 0 ) { if( xOutgoingPacket != pdFALSE ) { FreeRTOSdebugprintf( ( "usGenerateProtocolChecksum[%s]: crc swap: %04Xn", pcType, usChecksum ) ); } } #endif /* ipconfigHASDEBUGPRINTF != 0 / / In case of UDP, a calculated checksum of 0x0000 is transmitted as 0xffff. A value of zero would mean that the checksum is not used. */ usChecksum = ( uint16t )0xffffu; } else { usChecksum = FreeRTOShtons( usChecksum ); } ~~~~

Does that stop the modbus errors?


FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on January 30, 2017

I did test the above change but I forgot that my board is calculating all checksums in hardware :-(

The change to usGenerateProtocolChecksum() is a bit more complex than in the sketch here above. The translation from 0x0 to 0xffff should take place in two cases:

● When checking a CRC on an incoming packet. ● When the CRC of an UDP packet turns out to be zero

Please find attached 'protocol_checksum.c' which contains the entire function usGenerateProtocolChecksum().

Regards.

Attachments

protocol_checksum.c (5087 bytes)

FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on February 1, 2017

Hi Vasilij,

I just tried out the original CRC method for TCP-packets which have a CRC of zero and trigger this message:

~~~~ usGenerateProtocolChecksum[TCP]: crc swap: 0000

~~~~ so the CRC's are sent as 0xFFFF.

It was not a fatal error, but it did trigger a warning in Wireshark: "TCP CHECKSUM 0xFFFF". I sent the TCP packets to both my Linux machine and a Windows-10 laptop. The packet were accepted by both OS's.

Do you have any news? If you still get stuck, if you want, send me your current NetworkInterface.c for STM32F429.


FreeRTOS+TCP logs: crc swap: 0000

Posted by yanvasilij on February 1, 2017

Hello Hein Tibosch,

I still have a problem. I figured out the follows: sometimes (about once in 2-4 minutes) tcp-response for request comes with big delay (it can be 100 ms, once a had delya 1500 ms!). Because of that reason ModbusPoll gets timeout error occurs, but tcp response comes. I turned off all task except freertos+tcp and network driver. Here my NetworkInterface.c.

Attachments

NetworkInterface.c (18062 bytes)

FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on February 1, 2017

Hi Vasilij, Would it also be possible that you send a PCAP of the communication? If the data is not to be made publicly, you may also send a PCAP to my email asdress (h point tibosch at freertos point org). I would like to see the packets from the beginning of a connection (SYN), if possible.


FreeRTOS+TCP logs: crc swap: 0000

Posted by yanvasilij on February 1, 2017

Here it is:

Attachments

pcap.pcap (5678937 bytes)

FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on February 1, 2017

Hi Vasilij,

When I download your PCAP, it stops after 5,678,937 bytes. Is that the actual size? I wouldn't mind if you compress it next time :-)

Within this PCAP, I don't see any delays yet?

Within a TCP/Modbus connection, is it really necessary to poll so often? Why doesn't the client report when it has some news? Or at least report zero's after a longer period of time?


FreeRTOS+TCP logs: crc swap: 0000

Posted by yanvasilij on February 3, 2017

Hello Hein Tibosch,

Sorry for big pcap - my fault. I promise to compress next time )).

There is difficult to see time-outs in pcap because there is too much request. There is about one 100 ms time-out in about 100k-200k requests/response pairs. So I wrote simple python script that sends modbus request to my modbus slave and measures delay between request and response. If delay is bigger than 50 ms it write delay value to text file (delay value in seconds). So the log in attachments.

Within a TCP/Modbus connection, is it really necessary to poll so often?

Yes it is. There is nothing I can do with it.

By the way. Here code with socket processing. May something wrong there:

~~~

static void createSockets (void * eMBRegInputCB, void * eMBRegHoldingCB, void * eMBRegCoilsCB, void * eMBRegDiscreteCB) { mbPollActivate = xSemaphoreCreateBinary(); /* task for all sockets are created and never deleted. * They just blocks when sokets are closed / for (u32 i = 0; i < NUMOFSOCKETS; i++) { socketTaskParams[i].queue = xQueueCreate (1, sizeof(Sockett)); modbusTcp[i].eMBRegInputCB = (RegInputCBType)eMBRegInputCB; modbusTcp[i].eMBRegHoldingCB = (RegHoldingCBType)eMBRegHoldingCB; modbusTcp[i].eMBRegCoilsCB = (RegCoilsCBType)eMBRegCoilsCB; modbusTcp[i].eMBRegDiscreteCB = (RegDiscreteCBType)eMBRegDiscreteCB; socketTaskParams[i].modbusTcp = &modbusTcp[i]; socketTaskParams[i].modbusTcp->port.buf = socketTaskParams[i].buf; socketTaskParams[i].isOppened = 0; socketTaskParams[i].socketNum = i; DEBUGLOG(("creating socket task %drn", socketTaskParams[i].socketNum )); xTaskCreate( socketTask, "socketTask", configMINIMALSTACKSIZE10, &socketTaskParams[i], 2, &socketTaskHandle[i]); } }

/* sockets processing task / static void socketTask (void *p) { static const TickTypet xReceiveTimeOut = pdMSTOTICKS( 5000 ); static const TickTypet xSendTimeOut = pdMSTOTICKS( 5000 ); int32t inlen; Sockett socket; SocketTaskParams * params; params = (SocketTaskParams)p; u8 connectionIsOppened = 0; DEBUGLOG(("socket %d task statedrn", params->socketNum)); for(;;) { xQueueReceive(params->queue, &socket, portMAXDELAY); FreeRTOSsetsockopt( socket, 0, FREERTOSSORCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); FreeRTOSsetsockopt( socket, 0, FREERTOSSOSNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) ); DEBUGLOG(("Socket %d oppened!rn", params->socketNum)); connectionIsOppened = 1; while (connectionIsOppened) { params->modbusTcp->port.tcpInit(MBTCPPORT); params->modbusTcp->port.addTcpSocket(socket); inlen = FreeRTOSrecv(socket, params->modbusTcp->port.buf, MAXMODBUSTCPFRAMELEN, 0); if (inlen) { params->modbusTcp->port.bufLen = inlen; params->modbusTcp->event.post( EVFRAMERECEIVED ); u8 tmp[50]; memset(tmp, 0, 50); // I just emulate response for 20 holding register request (so here no modbus stack processing at all) tmp[0] = params->modbusTcp->port.buf[0]; tmp[1] = params->modbusTcp->port.buf[1]; tmp[2] = 0x00; tmp[3] = 0x00; tmp[4] = 0x00; tmp[5] = 0x2B; tmp[6] = 0x01; tmp[7] = 0x03; tmp[8] = 0x28; FreeRTOSsend( socket, tmp, 49, 0); } if (inlen < 0) { connectionIsOppened = 0; break; } } FreeRTOSshutdown( socket, FREERTOSSHUTRDWR ); do { if(FreeRTOSrecv(socket, params->modbusTcp->port.buf, MAXMODBUSTCPFRAMELEN, 0)<0) break; } while( 1 ); FreeRTOSclosesocket( socket ); params->isOppened = 0; DEBUG_LOG(("Socket %d closed!rn", params->socketNum)); } }

/* listenning task */ static void listeningTask (void *p) { static const TickTypet timeOut = portMAXDELAY; struct freertossockaddr bindAddress, clientParams; Sockett listenSocket, connectedSocket; socklen_t clientParamsSize = sizeof( clientParams );

WinProperties_t xWinProps;
/* Fill in the buffer and window sizes that will be used by the socket. */
xWinProps.lTxBufSize = 300;
xWinProps.lTxWinSize = 2;
xWinProps.lRxBufSize = 300;
xWinProps.lRxWinSize = 2;


listenSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM,
	   	FREERTOS_IPPROTO_TCP);

FreeRTOS_setsockopt( listenSocket, 0,
	   	FREERTOS_SO_RCVTIMEO, &timeOut, sizeof(timeOut) );

FreeRTOS_setsockopt( listenSocket, 0, FREERTOS_SO_WIN_PROPERTIES,
	   	( void * ) &xWinProps, sizeof( xWinProps ) );

bindAddress.sin_port = MB_TCP_PORT;
bindAddress.sin_port = FreeRTOS_htons( bindAddress.sin_port );
FreeRTOS_bind( listenSocket, &bindAddress, sizeof( bindAddress ) );

/* When connection established corresponding task is unblocked */
FreeRTOS_listen( listenSocket, NUM_OF_SOCKETS );

for (;;)
{
	connectedSocket = FreeRTOS_accept (listenSocket, &clientParams,
		   	&clientParamsSize);
	runSocketTask (connectedSocket);
	taskYIELD();
}

}

void initModbusTcpTask (void * eMBRegInputCB, void * eMBRegHoldingCB, void * eMBRegCoilsCB, void * eMBRegDiscreteCB) { createSockets (eMBRegInputCB, eMBRegHoldingCB, eMBRegCoilsCB, eMBRegDiscreteCB); xTaskCreate( listeningTask, "listeningTask", configMINIMALSTACKSIZE*10, NULL, 1, NULL); }

~~~

Attachments

timeLogError.zip (44076 bytes)

FreeRTOS+TCP logs: crc swap: 0000

Posted by heinbali01 on February 5, 2017

Hi Vasilij,

Your code looks OK now.

Only two thing:

  • When an API returns negative, you can look-up this value in errno.h. A return value of -pdFREERTOS_ERRNO_EAGAIN is not fatail.
  • You write the TCP server and you will never actively close a connection. Therefore you never have to call shutdown().

~~~~ - if (inlen < 0) + if ((inlen < 0) && (inlen != pdFREERTOSERRNOEAGAIN)) { connectionIsOppened = 0; break; } } - FreeRTOSshutdown( socket, FREERTOSSHUTRDWR ); - do - { - if(FreeRTOSrecv(socket, params->modbusTcp->port.buf, MAXMODBUSTCPFRAMELEN, 0)<0) - break; - } while( 1 ); ~~~~

Now about the time-outs:

I would think of missing or dropped packets. Please keep on checking uxGetMinimumFreeNetworkBuffers() : it should not drop below e.g. 3. It can be useful to study the time-outs: see if there were many other messages. See if those messages were broadcasts. Did the EMAC complain about overflows? Was there a temporary shortage of DMA descriptors?

The speed of polling can not be the problem: every 15 ms should be easy. Even if you have several simultaneous connections like this.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists