Redircting STDOUT

leemoore1966
Posts: 11
Joined: Sat Feb 15, 2020 11:51 am

Redircting STDOUT

Postby leemoore1966 » Sat Feb 15, 2020 1:44 pm

Hi All
I need to re-purpose UART0 for my project from its default usage as the monitor
This seems pretty easy from the menuconfig.

However, I still need to have debug messages from the STDOUT file descriptor
I have setup WiFi and I have a method of easily sending UDP messages to a remote listening netcat program

To complete this I need to effectively grab every write() syscall intended for the stdout file descriptor, and simply send this out on my UDP socket to my netcat terminal

Can anyone suggest an easy way to do this ?

Thx
Lee

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: Redircting STDOUT

Postby PeterR » Sun Feb 16, 2020 10:47 am

Try:

Code: Select all

    
static int udp_log_vprintf(const char *fmt, va_list arguments) 
{
// Put your redirect code here.
// vsnprintf() to a buffer and send that buffer to your device
}

// Main   
{    
   esp_log_set_vprintf(udp_log_vprintf);
}
& I also believe that IDF CAN should be fixed.

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: Redircting STDOUT

Postby ESP_igrr » Sun Feb 16, 2020 10:27 pm

To redirect stdout, you can simply reassign stdout to a new FILE* stream. An example of this can be found in https://esp32.com/viewtopic.php?f=13&t= ... 141#p55141. (The specific example redirects to app_trace, in your case it will be something different).

If only writing is required, you can use 'fwopen' to create such a stream, and all writes will be redirected to your provided function. Be sure to call this before other tasks are created, as new tasks inherit stdin/stdout/stderr streams.

Take note that you need to prevent your write handler from re-entering. For example, if you call something from your write handler, and that function tries to log (e.g. an error), this will result in your write handler re-entering. You need to detect that and return in such a case.

leemoore1966
Posts: 11
Joined: Sat Feb 15, 2020 11:51 am

Re: Redircting STDOUT

Postby leemoore1966 » Mon Feb 17, 2020 8:00 pm

ESP_igrr wrote:
Sun Feb 16, 2020 10:27 pm
To redirect stdout, you can simply reassign stdout to a new FILE* stream. An example of this can be found in https://esp32.com/viewtopic.php?f=13&t= ... 141#p55141. (The specific example redirects to app_trace, in your case it will be something different).

If only writing is required, you can use 'fwopen' to create such a stream, and all writes will be redirected to your provided function. Be sure to call this before other tasks are created, as new tasks inherit stdin/stdout/stderr streams.

Take note that you need to prevent your write handler from re-entering. For example, if you call something from your write handler, and that function tries to log (e.g. an error), this will result in your write handler re-entering. You need to detect that and return in such a case.
Thanks for the pointer
I tried this but seem to have run into an issue which I am unable to resolve.
Even with the simplest callback function I get a panic()
First test is simply to print the stdout, onto stderr

Code: Select all

static int app_printf(void *cookie, const char *data, int size) {
    fprintf(stderr, "app_printf: %.*s", size, data);
    return size;
}
in my initialization code

Code: Select all

        stdout_buf = (char *)malloc(128);
        fclose(stdout);
        stdout = fwopen(NULL, &app_printf);
        setvbuf(stdout, stdout_buf, _IOLBF, 128);
        fprintf(stderr, "fwopen ret=%p\n", stdout);
but I get the following
***ERROR*** A stack overflow in task sys_evt has been detected.
abort() was called at PC 0x4009086c on core 0
0x4009086c: vApplicationStackOverflowHook at /home/moore/esp/esp-idf/components/esp32/panic.c:125

ELF file SHA256: 84fc86d812c9e768f1075fd7734acef62ed828743fb98f00d100fb1289c4b02c

Backtrace: 0x4009051d:0x3ffdf6a0 0x40090855:0x3ffdf6c0 0x4009086c:0x3ffdf6e0 0x4009433d:0x3ffdf700 0x40092e10:0x3ffdf720 0x40092dc6:0x00000000 |<-CORRUPTED
0x4009051d: invoke_abort at /home/moore/esp/esp-idf/components/esp32/panic.c:157
0x40090855: abort at /home/moore/esp/esp-idf/components/esp32/panic.c:174
0x4009086c: vApplicationStackOverflowHook at /home/moore/esp/esp-idf/components/esp32/panic.c:125
0x4009433d: vTaskSwitchContext at /home/moore/esp/esp-idf/components/freertos/tasks.c:2770
0x40092e10: _frxt_dispatch at /home/moore/esp/esp-idf/components/freertos/xtensa/portasm.S:431
0x40092dc6: _frxt_int_exit at /home/moore/esp/esp-idf/components/freertos/xtensa/portasm.S:231
Am I supposed to wrap this function with any entry exit calls ?

Thx
Lee

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: Redircting STDOUT

Postby ESP_igrr » Tue Feb 18, 2020 5:43 am

Your code looks about right, but keep in mind that stacks
sizes of most system tasks have been tuned to be just barely larger than needed. Since `fprintf` may consume as much as 1.2kB of stack, you may be simply running out of stack space, as the message indicates.
You can try pushing the heavy lifting related to your log implementation into a separate task, and send log messages to that task e.g. using a ringbuffer. You can also try to increase the stack sizes — most of them are configurable in menuconfig.

Who is online

Users browsing this forum: No registered users and 342 guests