This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Context:
I am currently working on a project involving data transmission from UART to SSH using a TM4C1294 microcontroller. The development environment is Code Composer Studio.
Problem Statement:
I'm experiencing issues with the formatting and completeness of data transmitted between UART and SSH. For example when trying to send this data;
Serial 0 is up, line protocol is up Hardware is MCI Serial Internet address is 150.136.190.203, subnet mask is 255.255.255.0 MTU 1500 bytes, BW 1544 Kbit, DLY 20000 usec, rely 255/255, load 1/255 Encapsulation HDLC, loopback not set, keepalive set (10 sec) Last input 0:00:07, output 0:00:00, output hang never Output queue 0/40, 0 drops; input queue 0/75, 0 drops Five minute input rate 0 bits/sec, 0 packets/sec Five minute output rate 0 bits/sec, 0 packets/sec 16263 packets input, 1347238 bytes, 0 no buffer Received 13983 broadcasts, 0 runts, 0 giants 2 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 2 abort 1 carrier transitions 22146 packets output, 2383680 bytes, 0 underruns 0 output errors, 0 collisions, 2 interface resets, 0 restarts
Serial 0 is up,
Serial 0 is up, line protocol is up Hardware is MCI Serial Internet address is 150.136.190.203, subnet mask is 255.255.255.0 MTU 1500 bytes, BW 1544 Kbit, DLY 20000 usec, rely 255/255, load 1/255 Encapsulation HDLC, loopback not set, keepalive set (10 sec) Last input 0:00:07, output 0:00:00, output hang never Output queue 0/40, 0 drops; input queue 0/75, 0 drops Five minute input rate 0 bits/sec, 0 packets/sec Five minute output rate 0 bits/sec, 0 packets/sec 16263 packets input, 1347238 bytes, 0 no buffer Received 13983 broadcasts, 0 runts, 0 giants 2 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 2 abort1 carrier transitions 22146 packets output, 2383680 bytes, 0 underruns 0 output errors, 0 collisions, 2 interface resets, 0 restarts
What I've Tried:
Relevant Code Snippets:
UART Initialization and Read Function:
uint32_t UARTRead(uint32_t ui32Base, uint8_t *buffer, uint32_t length) { uint32_t i; for (i = 0; i < length; ++i) { if (!UARTCharsAvail(ui32Base)) break; buffer[i] = UARTCharGet(ui32Base); } return i; } void UARTWrite(uint32_t ui32Base, const uint8_t *buffer, uint32_t length) { for (uint32_t i = 0; i < length; ++i) { UARTCharPut(ui32Base, buffer[i]); } }
void startSerialSession(ShellServerSession *session) { uint8_t uartBuffer[1024]; uint32_t uartBytesRead; while (1) { uartBytesRead = UARTCharsAvail(UART0_BASE) ? UARTRead(UART0_BASE, uartBuffer, sizeof(uartBuffer)) : 0; if (uartBytesRead > 0) { shellServerWriteStream(session, (char *)uartBuffer, uartBytesRead, NULL, 0); } char shellBuffer[1024]; size_t shellBytesReceived = 0; error_t readError = shellServerReadStream(session, shellBuffer, sizeof(shellBuffer), &shellBytesReceived, 0); if (readError == NO_ERROR && shellBytesReceived > 0) { UARTWrite(UART0_BASE, (uint8_t *)shellBuffer, shellBytesReceived); } osDelayTask(10); // To prevent CPU overload } }
Specific Question:
- How can I ensure that the entire data payload is transmitted without truncation and preserves the intended formatting?
- In the context of UART communications, what are the recommended strategies for explicitly handling special characters such as carriage returns and line feeds? How can I ensure these characters are correctly processed to maintain data formatting between UART and SSH?
- How critical is it to have synchronized hardware settings like baud rate, parity, and stop bits across communicating UART devices? Can slight discrepancies lead to significant communication errors, and how can I best verify and align these settings?
- I'm considering implementing CRC checks or a simpler checksum method to ensure data integrity during UART communication. Does anyone have advice on the most efficient methods to implement these checks in embedded systems, particularly for the TM4C1294 microcontroller?
Additional Details:
Thank you for any suggestions or guidance you can provide!
Hi,
Are you in interrupt mode or polling mode?
If you try a slower baudrate like 9600, does it make a difference? This experiment will help determine if the problem is due to baudrate.
I use the below code in interrupt mode with baudrate at 119200 and use Hercules utility to read a text file that has the same content as yours and I don't see any issue. I will suggest you try the the below code and see if it makes a difference.
#include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "driverlib/debug.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" //***************************************************************************** // //! \addtogroup example_list //! <h1>UART Echo (uart_echo)</h1> //! //! This example application utilizes the UART to echo text. The first UART //! (connected to the USB debug virtual serial port on the evaluation board) //! will be configured in 115,200 baud, 8-n-1 mode. All characters received on //! the UART are transmitted back to the UART. // //***************************************************************************** //**************************************************************************** // // System clock rate in Hz. // //**************************************************************************** uint32_t g_ui32SysClock; //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif //***************************************************************************** // // The UART interrupt handler. // //***************************************************************************** void UARTIntHandler(void) { uint32_t ui32Status; // // Get the interrrupt status. // ui32Status = MAP_UARTIntStatus(UART0_BASE, true); // // Clear the asserted interrupts. // MAP_UARTIntClear(UART0_BASE, ui32Status); // // Loop while there are characters in the receive FIFO. // while(MAP_UARTCharsAvail(UART0_BASE)) { // // Read the next character from the UART and write it back to the UART. // MAP_UARTCharPutNonBlocking(UART0_BASE, MAP_UARTCharGetNonBlocking(UART0_BASE)); } } //***************************************************************************** // // Send a string to the UART. // //***************************************************************************** void UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count) { // // Loop while there are more characters to send. // while(ui32Count--) { // // Write the next character to the UART. // MAP_UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++); } } //***************************************************************************** // // This example demonstrates how to send a string of data to the UART. // //***************************************************************************** int main(void) { // // Run from the PLL at 120 MHz. // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and // later to better reflect the actual VCO speed due to SYSCTL#22. // g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_240), 120000000); // // Enable the GPIO port that is used for the on-board LED. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // // Enable the GPIO pins for the LED (PN0). // MAP_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); // // Enable the peripherals used by this example. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Enable processor interrupts. // MAP_IntMasterEnable(); // // Set GPIO A0 and A1 as UART pins. // MAP_GPIOPinConfigure(GPIO_PA0_U0RX); MAP_GPIOPinConfigure(GPIO_PA1_U0TX); MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Configure the UART for 115,200, 8-N-1 operation. // MAP_UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // // Enable the UART interrupt. // MAP_IntEnable(INT_UART0); MAP_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT); // // Prompt for text to be entered. // UARTSend((uint8_t *)"\033[2JEnter text: ", 16); // // Loop forever echoing data through the UART. // while(1) { } }
Hello, I have an update on my end;
Changes Made:
New Issues: We tested the physical UART4 port on an RS-232 Level Shifter with three devices. One device worked partially, but the other two sent gibberish.
Devices Tested:
Device 1 and 2 Input/Ouput:
Device3 Input/Output:
The SSH to reverse serial functionality is working, but there are discrepancies in the configuration and initialization process that need to be resolved.
UART Initialization and Interrupt Handler:
void PhyUART4Init(uint32_t baudrate) { uint32_t ui32SysClk = 120000000; // System clock frequency // Enable GPIOK and UART4 peripherals SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4); // Wait for the peripherals to be ready while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOK)); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_UART4)); // Configure GPIO pins for UART4 GPIOPinConfigure(GPIO_PK0_U4RX); // PK0 as U4RX GPIOPinConfigure(GPIO_PK1_U4TX); // PK1 as U4TX GPIOPinTypeUART(GPIO_PORTK_BASE, GPIO_PIN_0 | GPIO_PIN_1); // Set UART4 configuration UARTConfigSetExpClk(UART4_BASE, ui32SysClk, baudrate, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); // Enable the UART FIFO UARTFIFOEnable(UART4_BASE); UARTFIFOLevelSet(UART4_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8); // Register and enable UART interrupts UARTIntRegister(UART4_BASE, UART4IntHandler); UARTIntEnable(UART4_BASE, UART_INT_RX); IntEnable(INT_UART4); // Enable the UART for operation UARTEnable(UART4_BASE); // Debug: Log UART configuration completion TRACE_INFO("UART4 configured with baud rate: %u\n", baudrate); } void UART4IntHandler(void) { uint32_t ui32Status; BaseType_t xHigherPriorityTaskWoken = pdFALSE; char data; ui32Status = UARTIntStatus(UART4_BASE, true); UARTIntClear(UART4_BASE, ui32Status); if (ui32Status & UART_INT_RX) { while (UARTCharsAvail(UART4_BASE)) { data = (char)UARTCharGetNonBlocking(UART4_BASE); xQueueSendToBackFromISR(qUART4, &data, &xHigherPriorityTaskWoken); } } if (xHigherPriorityTaskWoken == pdTRUE) { portYIELD(); } }
UART Read and Write Functions:
uint32_t UARTRead(uint32_t ui32Base, uint8_t *buffer, uint32_t length) { uint32_t i; for (i = 0; i < length; ++i) { if (!UARTCharsAvail(ui32Base)) break; buffer[i] = UARTCharGet(ui32Base); } return i; } void UARTWrite(uint32_t ui32Base, const uint8_t *buffer, uint32_t length) { for (uint32_t i = 0; i < length; ++i) { UARTCharPut(ui32Base, buffer[i]); } }
Session Handling:
void startSerialSession(void *pvParameters) { uint8_t uartBuffer[1024]; char data; while (1) { uint32_t uartBytesRead = 0; while (xQueueReceive(qUART4, &data, 0) == pdTRUE) { uartBuffer[uartBytesRead++] = data; if (uartBytesRead >= sizeof(uartBuffer)) { break; } } if (uartBytesRead > 0) { shellServerWriteStream(g_serialSession, (char *)uartBuffer, uartBytesRead, NULL, 0); } vTaskDelay(10); // To prevent CPU overload } }
Specific Questions:
Additional Details:
Thank you for any suggestions or guidance you can provide!
Hi Can,
We found the UART cannot RX/TX 32 bytes using 16 word FIFO R/W mode without monitoring the buffer empty flag in non-blocking high speed serial data transports. Perhaps try reducing (assuming you have implemented ringbuffer.c) to 16 word R/W. Otherwise slow down TX/RX loops using SysCtrlDelay(MyDelayPeriod) zoom in on timing issues even in interrupt level FIFO mode.
Regards,
Hi,
Looks like you are using FreeRTOS. Have you tried my posted code? If you have not tried my bare-metal code, why don't you try it first? If you are getting gibberish data, then I tend to think the problem is related to both sides not having the the same baudrate or configuration. If the cause is due to data buffering then the result would be missing data instead of gibberish data.
I will suggest you send simple data to begin with for easier diagnose/debug. Try sending just a few characters first. You can examine the receive buffer and see if the buffer contains the correct data. This way it is easier to isolate the problem.
Hi Genatco,
I will try your recommendation regarding the FIFO R/W mode. I haven't implemented ringbuffer.c
, but I'll look into adjusting the buffer size and incorporating SysCtrlDelay(MyDelayPeriod)
to address potential timing issues. I'll update you with the results.
Hi Charles,
Yes, I am using FreeRTOS and currently isolating the problems to determine if it’s due to baud rate/configuration mismatches, data buffering or else. I'll check again by sending simple data and check the receive buffer for accuracy, maybe compare them out with an oscilloscope. I'll follow up with the outcomes of these tests shortly. Thanks again for your guidance.
Hi Can,
One more thing to check if SSH performs any data encryption. I don't know how SSH works. You will need to check if there is any encryption/decryption required or plaintext can be used.