Skip to main content
Max75
Associate II
April 17, 2025
Question

Nucleo-F411RE and dev/ttyS3 communication

  • April 17, 2025
  • 4 replies
  • 1030 views

Hello !

My Nucleo-F411RE board is visible in Cygwin as dev/ttyS3. I try to send message "Hello !" to Nucleo and receive answer from it, but inside the code I found in the internet, the functions tcgetattr() and tggetattr() return the error Invalid argument. How to fix this ?

 

I give the code below... 

#include <errno.h>
#include <fcntl.h> 
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>

int set_interface_attribs (int fd, int speed, int parity)
{
 struct termios tty;
 if (tcgetattr (fd, &tty) != 0)
 {
 perror("error from tcgetattr\r\n");
 return -1;
 }

 cfsetospeed (&tty, speed);
 cfsetispeed (&tty, speed);

 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
 // disable IGNBRK for mismatched speed tests; otherwise receive break
 // as \000 chars
 tty.c_iflag &= ~IGNBRK; // disable break processing
 tty.c_lflag = 0; // no signaling chars, no echo,
 // no canonical processing
 tty.c_oflag = 0; // no remapping, no delays
 tty.c_cc[VMIN] = 0; // read doesn't block
 tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

 tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

 tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
 // enable reading
 tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
 tty.c_cflag |= parity;
 tty.c_cflag &= ~CSTOPB;
 tty.c_cflag &= ~CRTSCTS;

 if (tcsetattr (fd, TCSANOW, &tty) != 0)
 {
 perror("error from tcsetattr\r\n");
 return -1;
 }
 return 0;
}

void set_blocking (int fd, int should_block)
{
 struct termios tty;
 memset (&tty, 0, sizeof tty);
 if (tcgetattr (fd, &tty) != 0)
 {
 perror("error from tggetattr\r\n");
 return;
 }

 tty.c_cc[VMIN] = should_block ? 1 : 0;
 tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

 if (tcsetattr (fd, TCSANOW, &tty) != 0)
 perror("error setting term attributes\r\n");
}

int main(void)
{
char *portname = "dev/ttyS3";
 
 int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
 if (fd < 0)
 {
 perror("error opening port\r\n");
 return 0;
 }

 set_interface_attribs (fd, B9600, 0); // set speed to 9,600 bps, 8n1 (no parity)
 set_blocking (fd, 0); // set no blocking

 write (fd, "hello!\n", 7); // send 7 character greeting

 usleep ((7 + 25) * 100); // sleep enough to transmit the 7 plus
 // receive 25: approx 100 uS per char transmit
 char buf [100];
 read (fd, buf, sizeof buf); // read up to 100 characters if ready to read
 printf("%s\r\n", buf);
 
 return 0;
 
}

 

4 replies

Andrew Neil
Super User
April 17, 2025

That's linux code to run on your Host system - right?

That's beyond the scope of this forum! Try a linux programming forum.

Test it against a terminal...

 


@Max75 wrote:

the functions tcgetattr() and tggetattr() return the error Invalid argument. How to fix this ?


Supply arguments which are valid!

https://linux.die.net/man/3/tcgetattr

 

PS:

There is no such function as tggetattr() - it appears to be just a typo in this message:

void set_blocking (int fd, int should_block)
{
 struct termios tty;
 memset (&tty, 0, sizeof tty);
 if (tcgetattr (fd, &tty) != 0)
 {
 perror("error from tggetattr\r\n"); // <<< here!
 return;
 }

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Max75
Max75Author
Associate II
April 18, 2025

Hello, Andrew !

Are you angry ? :)

About of topic theme. I comment these function callings  and it works. My Cygwin received message well, but Nucleo board received garbage. Working at this...

KnarfB
Super User
April 19, 2025

When testing the Nucleo, start with a known good terminal prog on the host side: minicom, screen, putty, terterm,... and work (and show) on the nucleo code. And: why cygwin? 

but inside the code I found in the internet

ask the author

hth

KnarfB

Max75
Max75Author
Associate II
April 19, 2025

Hello, KnarfB !

 

In my project I want to read video from Arducam camera and display it on my laptop screen. To do this I need to send data arrays ( frames, lines... ) to the code on the laptop. In the future I want do this via Wi- Fi. Terminal like Putty displays only text, as far as I know, but I need to display graphics. I don't know how to do it differently yet...

KnarfB
Super User
April 19, 2025

Well, sending a block of uint8_t chars/bytes/pixels is a single call to HAL_Transmit_UART on the STM side. You could do that with dummy data in the main while loop and check on the other side what you are receiving. This will simply work when the serial port parameters match.

For the other side (laptop), I would use termios and friends only on a native Linux. And, when doing so, read the "bible": Serial Programming HOWTO

Note that cygwin emulation may not be perfect/transparent and may give you unneccessary hassle.

But, nowadays better use Python pyserial which is portable across OSes.

hth

KnarfB

Max75
Max75Author
Associate II
April 20, 2025

Hmm... I think I was wrong. In order to receive data stream on the laptop, I need to send back some kind of confirmation that previous portion of data was successful. But garbage comes from the laptop to the Nucleo board. I'm still racking my brains over this...