Hi guys,
I'm developing a huge project on the Concerto controller and it's mostly working fine, I2C, Ethernet, serial, EEPROM, analogue inputs, ePWMs, etc.
But I'm starting to reach some funnel on so many communications operating in parallel and not sure if there are tricks I could do optimize it, so I came to ask the experts.
and please guys, I know it's a big topic, but I know there are a lot of experts and smart TI employees around the forum, so come on, I need this help!
What is happening is that with the latest addition of some constant pooling on the serial, the other serial and the ethernet became considerably less stable and constantly locking up one comm channel or other.
Let me explaining how is setup:
I upped both cores stack_size, M3 have 8K available and C28 have 1K. As you'll see some specially large buffers are pre-allocated on S-RAM. Both applications are being compiled with Full Symbolic Debug (because it's still being debuged) and no optimization as I was planning to put those to the maximum closer to the end of development.
There is a separate buffer for in/out uart0/uart1 (4 in total) and all of them with 256bytes each located at S7 using PRAGMA
There is the whole S8 (using pragma) area for the Ethernet response buffer which can reply 2 to 3 ethernet packs.
All comms parsing is done by the same code, no matter from which com it arrived. The comm parsing code is built upon cmdline.c that TI provides.
For sure WRITE_EEPROM and READ_EEPROM commands are effectively the slowest ones because the comms parser have to communicate with the EEPROM over the I2C before replying to it. But what mostly happen is one READ_EEPROM when an external device connects to the Concerto and it might or not send further READ/WRITE but with several minutes of space between them.
UART0 and UART1 input interruption handlers buffers the chars while (UARTCharsAvail(UARTx_BASE)) and once the message termination char is received it adds a char 0 at the end of the buffer and pass as pointers its input and output buffer to the comm parsing routines. If the parser reply is > 0 then it sends back the message stored on the output buffer, or a fixed "BAD COMMAND" if =< 0
UART0 also instantly echoes back each char received, so it can be seen on the terminal.
UARTs reads and echoes uses UARTCharGetNonBlocking and UARTCharPutNonBlocking and UARTs comm parsed reply uses UARTCharPut as on the beginning of the developing I saw some issues on it, maybe I should revert it back? Could I increase UART internal buffer to be able to use NonBlocking? I'm not sure on this.
Ethernet handling is copied from the uip_eth example and honest to God I tried but I can't figure how to move it to a timed interrupt or comm interrupt without breaking it, so it's running inside my main loop, and it's the only thing on the main loop.
The ethernet input comes from the same ucUIPBuffer as in the example uip_eth and the cmdline places answers on the S8 memory and a small routine decides if the whole buffer can go in one package or divide it into 1400bytes long packages, uip_send() them and updates the pointer to the next start-of-package to be processed on uip_acked(). At the end of a reply it sends a uip_close(). For the next poll whatever decide is communicating with it have to open the connection again.
So on this mess of comms all was working fine:
UART0 was debug only and barely used at this advanced stage of development;
UART1 was sending a message every 500ms to a connected LCD to update it's values and only receiving anything if the user touched the touch-screen, which was just Start, Stop and Reset commands, almost never)
Ethernet was the one working harder as it was connecting to the engineering station that was pooling values 3 times a second and the user (me) sending commands every once in a while.
The problem started when (as a purely development and testing tool before the final electronics boards be ready for testing) I started sending every 310ms some extra info (32bytes) over UART0.
Now I have Ethernet randomly stopping, the screen times-out every once in a while, even the UART0 stops receiving the values.
I can't see as it's being some memory corruption thing cause every communication channel have it's own input and output buffers that is passed as parameters.
I'm about to test with compiler optimization, remove the echo back from UART0 and change the UART send to NonBlocking.
But I'm not very confident that any of those will have significant impact on the those comms randomly failing, and I reckon that removing the NonBlocking will give me headache again on the uart.
So, do the experts have some good comments, suggestions, tips-n-tricks, or anything to help me on this one?
I still have in a near future make the board be able to handle communication with more than one device constantly pooling the ethernet and with current problems I don't see it happening.
thanks!!!