lpcware

va_list FreeRTOS thread-safe with critical region?

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by FlySnake on Tue Oct 16 03:15:52 MST 2012
Hi, everyone!
Please, look at this piece of code:
uint_fast8_t syslog_write(SysLogRecordType type, const signed char * const threadname, const char *fmt, ...)
{
    /* whatever */
    char string[SYSLOG_MAXLINE] = {0};

    taskENTER_CRITICAL();

    va_list args;
    va_start(args, fmt);
    length = format_string(string, sizeof string, type, threadname, fmt, args);
    va_end(args);

    taskEXIT_CRITICAL();

    /* whatever (add to queue) */
}

Where format_string():
static size_t format_string(char *buffer, size_t size, SysLogRecordType type, const char * const threadname, const char *fmt, va_list args)
{
       /* whatever */

       vsnprintf(buffer, size, fmt, args);

       /* whatever */
}

If syslog_write() called from 1 task - no problems
If syslog_write() called from 2 or more preemptive tasks, than it cause BusFault  CFSR = 0x8200 (PRECISERR | BFARVALID) and BFAR = 0x201A8C0 which is outside of memory map.
If I replace vprintf with, for instance, sprintf("hello") than it works perfect. Only printf with va_list as arguments cause an error.
When I run this code under debugger I see last instruction before fault is in main() which has already exec. Probably something wrong with pointers inside vprintf. 
Disassembly:
0000ee08 <vsnprintf>:
    ee08:    b5f0          push    {r4, r5, r6, r7, lr}
    ee0a:    b08f          sub    sp, #60; 0x3c
    ee0c:    4606          mov    r6, r0
    ee0e:    460c          mov    r4, r1
    ee10:    4615          mov    r5, r2
    ee12:    2100          movs    r1, #0
    ee14:    2228          movs    r2, #40; 0x28
    ee16:    a804          add    r0, sp, #16
    ee18:    461f          mov    r7, r3
    ee1a:    f001 f94d     bl    100b8 <memset>
    ee1e:    230a          movs    r3, #10
    ee20:    9307          str    r3, [sp, #28]
    ee22:    f06f 4300     mvn.w    r3, #2147483648; 0x80000000
    ee26:    9306          str    r3, [sp, #24]
    ee28:    4b0d          ldr    r3, [pc, #52]; (ee60 <vsnprintf+0x58>)
    ee2a:    9604          str    r6, [sp, #16]
    ee2c:    2600          movs    r6, #0
    ee2e:    1e62          subs    r2, r4, #1
    ee30:    9302          str    r3, [sp, #8]
    ee32:    a804          add    r0, sp, #16
    ee34:    4633          mov    r3, r6
    ee36:    9500          str    r5, [sp, #0]
    ee38:    9701          str    r7, [sp, #4]
    ee3a:    f000 f9e9     bl    f210 <__vfprintf>
    ee3e:    9b06          ldr    r3, [sp, #24]
    ee40:    4604          mov    r4, r0
    ee42:    3b01          subs    r3, #1
    ee44:    42b3          cmp    r3, r6
    ee46:    9306          str    r3, [sp, #24]
    ee48:    db02          blt.n    ee50 <vsnprintf+0x48>
    ee4a:    9b04          ldr    r3, [sp, #16]
    ee4c:    701e          strb    r6, [r3, #0]
    ee4e:    e003          b.n    ee58 <vsnprintf+0x50>
    ee50:    4630          mov    r0, r6
    ee52:    a904          add    r1, sp, #16
    ee54:    f001 f954     bl    10100 <__flsbuf>
    ee58:    4620          mov    r0, r4
    ee5a:    b00f          add    sp, #60; 0x3c
    ee5c:    bdf0          pop    {r4, r5, r6, r7, pc}
    ee5e:    bf00          nop
    ee60:    0000e4f1     .word    0x0000e4f1


LPC1768 RedLib nohost
Version: LPCXpresso v4.2.3 [Build 255] [30/05/2012] GNU/Linux

Outcomes