Strings to mailboxes

Discussions and support about ChibiOS/RT, the free embedded RTOS.
JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Strings to mailboxes

Postby JSStabl » Tue May 12, 2020 1:45 pm

I want to send string messages over the mailbox q to serve a thread that then writes out the data over the serial bus. From the ChibiOS book I took an example for a console and created the following threads:

Code: Select all

char start_string[] = "start";
char stop_string[] = "stop";

static mailbox_t serial_mb;
static msg_t serial_mb_buffer[10];



uint8_t buffer[8];

THD_WORKING_AREA(serial_output_thread_wa, 128);
THD_FUNCTION(serial_output_thread, arg) {
    (void)arg;
    chRegSetThreadName("Uart Comm Thread");
    chMBObjectInit(&serial_mb, serial_mb_buffer, 10);
    msg_t msg = 0;
    BaseSequentialStream *stream = (BaseSequentialStream *)&SD3;
    while (true) {
        chMBFetchTimeout(&serial_mb, &msg, TIME_INFINITE);
        const char *s_msg = (const char *)msg;
        chprintf(stream, "%s", s_msg);
    }

}

THD_WORKING_AREA(serial_input_thread_wa, 128);
THD_FUNCTION(serial_input_thread, p) {
    (void) p;
    chRegSetThreadName("Serial Input Thread");

    while (true) {
        //clear buffer
        memset(buffer, 0, sizeof(buffer));
        sdReadTimeout(&SD3, buffer, 5, TIME_MS2I(50));

        if (strcmp((char *) buffer, start_string) == 0) {
            chMBPostTimeout(&serial_mb, (msg_t)"Very long string", TIME_INFINITE);

        } else if (strcmp((char *) buffer, stop_string) == 0) {
            sdWrite(&SD3, buffer, 5);
        }

    }
}


When typing start I get "very long string" from the serial, so that seems to work. My question now is why and how does that work? The msg_t is an int32 if I recall correctly, that can fit 4 char variables. So why can I enocde a string longer than that? How would I need to cast the buffer variable in order to send it over the q?

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Strings to mailboxes

Postby Giovanni » Tue May 12, 2020 1:56 pm

Hi,

It is very simple, you are not sending a string, you are sending a -pointer- to the string, the string is in its buffer and the buffer must non change until the message is received.

Giovanni

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Strings to mailboxes

Postby JSStabl » Tue May 12, 2020 2:02 pm

Ah yes, thats actually perfectly reasonable. Thanks as always!

So I need an extra message buffer that only gets cleared when the message is received. When sending the strings as "directly" encoded the compiler probably treats that as a const string and that doesn't change. So If I want to send a dynamic string from a buffer I need to make sure that buffer is constant before it gets read.

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Strings to mailboxes

Postby Giovanni » Tue May 12, 2020 2:13 pm

You should look at the "object FIFOs" mechanism in OSLIB, that provides also buffers handling.

Giovanni

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Strings to mailboxes

Postby JSStabl » Tue May 12, 2020 2:47 pm

At the risk of going slightly off-topic: I'm trying to implement printf in chibiOS since I have some external libraries that use printf for error messages. I included the syscalls.c and added the STDOUT_SD and it seems to work when being called from the main startup code. However as soon as I run printf from the thread context it stops working. Any ideas why?

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Strings to mailboxes

Postby Giovanni » Tue May 12, 2020 4:09 pm

ChibiOS has its own chprintf().

Probably the library is trying to do memory allocation internally, this may fail depending on your setup/version/compiler/etc. I haven't tried that extensively, compilers and libraries change very often.

You should also check if you thread has sufficient stack space, it could be as simple as that.

Giovanni

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: Strings to mailboxes

Postby steved » Tue May 12, 2020 4:35 pm

Dependent on how you're outputting to the UART, you might not need a mailbox; the UART driver implements a circular buffer, whose size you can configure; it's then just emptied in the background. However you'll then probably need a mutex to manage access to the output buffer - it gets fun working out which thread wrote what otherwise!
I've implemented my own printf() equivalent which blocks on the mutex and uses chprintf(); I've also allowed direct access to the mutex and other routines, so that the output of several independent print statements can be guaranteed to be together.

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Strings to mailboxes

Postby JSStabl » Wed May 13, 2020 12:19 pm

The Library was written by myself :) I just want to keep the generic printf instead of the chprintf in there so I can run it on a local machine or a test environment without the chibi code. That keeps the functionality of that part of the code agnostic of the system its being run on.

I was hoping to be able to implement the _write_r function and there just add strings to the serial Q, but it seems printf does some more magic than just calling _write_r. When using the STM32 HAL library implementaing _write for printf works fine.

@Steved could you share your implementation?

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: Strings to mailboxes

Postby steved » Wed May 13, 2020 1:31 pm

It's nothing particularly special (although I've edited out some complications peculiar to my requirements).
I've used a different name for the function, but it should be possible to override the library printf().
Attachments
debugprintf.7z
(1.27 KiB) Downloaded 178 times

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Strings to mailboxes

Postby JSStabl » Wed May 13, 2020 2:06 pm

Thanks steve! Looks really interesting, I would keep the Mailbox logic, since I don't want to interrupt any fast threads with a blocking write. I'm thinking about using sprintf and then pushing that to the mailbox q. Only thing I need to figure out what to do when the thread isn't running yet (i.e. startup code).

Heres my macro that overrides printf:

Code: Select all

#define printf(MESSAGE,args...) { \
  const char *A[] = {MESSAGE}; \
  BaseSequentialStream *stream = (BaseSequentialStream *)&SD3; \
  if(sizeof(A) > 0) {\
    chprintf(stream,*A,##args); \
  } else {\
    chprintf(stream,"\n"); \
  }\
}


Can I initialize the q at the start of my main? When I put the chMBObjectInit in my main instead of the beginning of the thread it stops working.


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: Baidu [Spider] and 5 guests