cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-F411RE and dev/ttyS3 communication

Max75
Associate II

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;
    
}

 

11 REPLIES 11

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
Associate II

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
Principal III

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

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...

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

Thank you, KnarfB, for your answer. I'll think about it. First I'll read this "bible"...


@Max75 wrote:

Terminal like Putty displays only text, 


Yes, that's true.

But the key is to start simple, and start with the minimum number of unknowns.

Using a standard terminal (PuTTY, or whatever) removes all the unknowns on the "host" side - you have a known-good, solid utility.

This allows you to concentrate on getting the embedded side right.

 


@Max75 wrote:

but I need to display graphics.


Once you have sending & receiving characters working, then sending & receiving binary data is no different.

 


@Max75 wrote:

Nucleo board received garbage


"Garbage characters" is usually a baud rate problem:

https://learn.sparkfun.com/tutorials/serial-communication/all#:~:text=If%20all%20the%20receiving%20device%20sees%20on%20its%20receive%20line%20is%20garbage%2C%20check%20to%20make%20sure%20the%20baud%20rates%20match%20up

possibly the frame size.

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.

Thank you, Andrew, for your answer. PuTTY is working very well for me, but I need to put incoming data to array... OK, I understand... 


@Max75 wrote:

but  (sic?) I need to put incoming data to array... .. 


Not sure how that's a "but" ?

What the receiving end (eg, your Nucleo) does with the data is immaterial to the sending end (eg, PuTTY).

If you want to test that your Nucleo can receive a fast "burst" of data (quicker than you can type), then you can just paste a block of text into PuTTY (or whatever) - which will then send it at "full speed" ...

 

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.