Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


Redirecting printf with a custom, non-global, callback

After a bit of investigating, I found a workable solution.

The full post is here, including an image of the final product: https://zfembedded.wordpress.com/2020/02/27/redirecting-printf-on-stm32-using-fopencookie/Question

Starting with the basic program that prints a “B” to the screen, I did the following:

1. The fopencookie function is in stdio.h so this needs to be included.
2. In order to activate it, _GNU_SOURCE must be defined before this include.
3. We create a stream for our display, my_stream0. We can also create one for stdout.
4. The fopencookie function needs cookie_io_functions so we define them. These don’t appear to participate in the action but without them things don’t work for me. Hints on why this is so are helpful.
5. We write out the function for a component of the cookie_io_functions, in this case for .write. For me, this function need not do anything.
6. We write the stream write function.
7. We pass the stream write function and the board definition to the streams defined.
8. We modify the buffering of the streams.
9. We test out both fprintfs and the printf of the created streams.

/* 2 */
#define _GNU_SOURCE
        
/* 1 */
#include <stdio.h>

/* 5 */
static ssize_t dummy_cookie_write(void *c, const char *buf, size_t size)
{
    return size;
}
    
/* 6 */
int displayA_stream_write(struct _reent *q1, void *q2, const char *q3, int q4)
{
    (void)q1;
    BOARD_TypeDef_t* q5 = (BOARD_TypeDef_t*)q2;
    
    int DataIdx;
    
    for (DataIdx = 0; DataIdx < q4; DataIdx++)
    {
    	display_write(&q5->display[displayA], *q3++);
    }
    
    return q4;
}
    
void main(void)
{
    /* Declare BOARD typedef. */
    BOARD_TypeDef_t board;
    
    /* Initialize BOARD typedef. */
    board_init(&board);
    
    /* Initialize display */
    display_init(&board.display[displayA]);
    
    /* Writes a "B" to the display */
    display_write(&board.display[displayA], 0x42);
    
    /* 4 */
    cookie_io_functions_t dummy_cookie_funcs = {
            .read  = 0,
            .write = dummy_cookie_write, /* Setting this to 0 breaks the solution. */
            .seek  = 0,
            .close = 0
            };
    
    /* 3 */
    FILE *my_stream0 = fopencookie(NULL,"w", dummy_cookie_funcs); /* Replacing dummy_cookie_funcs with NULL breaks the solution. */
    stdout = fopencookie(NULL,"w", dummy_cookie_funcs);
    
    /* 8 */
    setbuf(my_stream0, NULL);
    setbuf(stdout, NULL);
    
    /* 7 */
    my_stream0->_write = displayA_stream_write;
    my_stream0->_cookie = (void *)&board;
    stdout->_write = displayA_stream_write;
    stdout->_cookie = (void *)&board;
    
    /* 9 */
    fprintf(my_stream0, "\nNowhere");
    fprintf(stdout, "\nSomewhere");
    printf("\nHere");
    
}


The key find that made this all possible was finding out that #7 write was more important than #4 write.

Regards,
J