Hello @drew.tx and @DaveM ,
Thanks a lot for your suggestion after created new project then it started working and able to set breakpoint and successfully debug my hello example. I am trying to run simple UART example using IVY Carrier board and iMX8MP SOM but able to send and received simple data.
The below simple example i written in c program:
// File: main.c
//
// This program demonstrates basic UART communication on a Toradex i.MX8M Plus module
// running Torizon OS. It opens a specified serial port, configures it using termios,
// sends a message, and attempts to read a response.
//
// To compile and run this application within a Docker container managed by the
// Torizon IDE Extension in VS Code, ensure your project's Dockerfile and
// docker-compose.yml are correctly configured as described below.
#include <stdio.h> // Standard input/output definitions
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions (for read, write, close)
#include <fcntl.h> // File control definitions (for open)
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions (for termios API)
// Define the path to the UART device.
// For Toradex Verdin modules, /dev/verdin-uart1 is a common general-purpose UART.
// You can verify available UARTs on your module by running 'ls -l /dev/verdin-uart*'
// in the module's terminal.
#define UART_DEVICE "/dev/verdin-uart1"
int main() {
int uart_fd; // File descriptor for the UART device
struct termios tty; // Structure to hold the terminal attributes
printf("UART Example Started.\n");
// ------------------- 1. OPEN THE UART DEVICE -------------------
// O_RDWR : Open for reading and writing
// O_NOCTTY : This port is not a controlling terminal for the process
// O_NDELAY : Non-blocking open. If the port is not ready, open() returns an error.
// This flag can be removed if you want a blocking open.
uart_fd = open(UART_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
if (uart_fd < 0) {
perror("Error opening UART device");
return -1;
}
printf("UART device %s opened successfully.\n", UART_DEVICE);
// ------------------- 2. CONFIGURE THE UART -------------------
// Get the current attributes of the terminal
if (tcgetattr(uart_fd, &tty)!= 0) {
perror("Error from tcgetattr");
close(uart_fd);
return -1;
}
// Clear all flags and set to default values (important for clean configuration)
memset(&tty, 0, sizeof(tty));
// Control Modes (c_cflag):
// CREAD : Enable the receiver (essential for receiving data)
// CLOCAL : Ignore modem control lines (e.g., DCD, DTR) - crucial for direct serial comms
tty.c_cflag |= CREAD | CLOCAL;
// Set the baud rate for both input and output. B115200 is 115200 bits per second.
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
// Set the character size to 8 bits.
// Use `CS8` for 8-bit characters. Other options: CS5, CS6, CS7.
tty.c_cflag &= ~CSIZE; // Clear current size bits
tty.c_cflag |= CS8; // Set 8 data bits
// Disable parity (odd/even)
tty.c_cflag &= ~PARENB; // Disable parity generation and checking
tty.c_cflag &= ~PARODD; // Ensure odd parity is also disabled if PARENB was set
// Disable hardware flow control (RTS/CTS)
tty.c_cflag &= ~CRTSCTS;
// Set 1 stop bit. CSTOPB sets two stop bits; clearing it sets one.
tty.c_cflag &= ~CSTOPB;
// Local Modes (c_lflag):
// Raw mode: Disable canonical processing (ICANON), input echoing (ECHO, ECHOE),
// and signal generation (ISIG). This is typically desired for machine-to-machine
// communication to prevent the kernel from interpreting special characters.
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// Input Modes (c_iflag):
// No software flow control (IXON/IXOFF)
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
// Disable any special handling of newline characters or break conditions
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
// Output Modes (c_oflag):
// No output processing (OPOST) - ensures raw data is sent without modification
tty.c_oflag &= ~OPOST;
// Set the timeouts for read() operations:
// VMIN = 0, VTIME = 5: A read() will return after 500ms (5 * 0.1s) if no data
// is available, or as soon as at least one character is received.
tty.c_cc[VMIN] = 0; // Minimum number of characters for non-canonical read
tty.c_cc[VTIME] = 5; // Timeout in 0.1s increments (5 = 0.5 seconds)
// Apply the settings immediately (TCSANOW)
if (tcsetattr(uart_fd, TCSANOW, &tty)!= 0) {
perror("Error from tcsetattr");
close(uart_fd);
return -1;
}
printf("UART configured successfully: 115200, 8N1, No Flow Control.\n");
// ------------------- 3. SEND DATA -------------------
char tx_buffer[] = "Hello from Toradex i.MX8M Plus UART!\n";
int tx_bytes = strlen(tx_buffer);
printf("Sending %d bytes: '%s'\n", tx_bytes, tx_buffer);
if (write(uart_fd, tx_buffer, tx_bytes) < 0) {
perror("Error writing to UART");
}
// tcdrain() waits until all output written to the object referred to by fd has been transmitted.
// This is important to ensure data is physically sent before proceeding, especially before reading.
if (tcdrain(uart_fd)!= 0) {
perror("Error from tcdrain");
}
// Small delay to allow external device to process and respond
usleep(100000); // 100ms delay
// ------------------- 4. RECEIVE DATA -------------------
char rx_buffer[256]; // Corrected: Declared as an array to hold received data
int rx_bytes = 0;
printf("Waiting for response...\n");
rx_bytes = read(uart_fd, rx_buffer, sizeof(rx_buffer) - 1); // Read up to buffer size - 1 for null terminator
if (rx_bytes < 0) {
perror("Error reading from UART");
} else if (rx_bytes == 0) {
printf("No data received within timeout.\n");
} else {
// Null-terminate the received data to treat it as a C string
rx_buffer[rx_bytes] = '\0';
printf("Received %d bytes: '%s'\n", rx_bytes, rx_buffer);
}
// ------------------- 5. CLOSE THE UART DEVICE -------------------
close(uart_fd);
printf("UART device closed.\n");
return 0;
}
And when I run this example I saw not getting any ERROR for opening the UART port and saw below message on debug console:
=thread-group-added,id="i1"
GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Warning: Debuggee TargetArchitecture not detected, assuming x86_64.
=cmd-param-changed,param="pagination",value="off"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at src/main.c:28
Loaded '/lib/ld-linux-aarch64.so.1'. Symbols loaded.
Loaded '/lib/aarch64-linux-gnu/libc.so.6'. Symbols loaded.
UART Example Started.
[Inferior 1 (process 40) exited with code 0377]
The program '/home/torizon/app/UARTTest' has exited with code 377 (0x00000179).
Just to check I added simple log using printf(“UART Example Started.\n”);
could you please help me out to run simple UART example? Is there any configuration that required to access UART port? As i know I already added devices in “docker-compose.yml” as like be
)
I really appreciate your help to run out my simple example? Can you please also share me where to connect USB to TTL converter PIN mapping for IVY Carrier board?
Thanks Again..!!
Vishal