Ignore:
Timestamp:
Jan 13, 2021, 12:36:17 AM (3 years ago)
Author:
alain
Message:

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/printk.c

    r669 r683  
    4141//////////////////////////////////////////////////////////////////////////////////////
    4242// This static function is called by printk(), nolock_printk(), and snprintk(),
    43 // functions to build a string from a printf-like format, and stores it
    44 // in the buffer defined by the <string> and <length> arguments.
    45 // It does NOT add a terminating NUL character in the <string> buffer.
    46 // If success, it returns the number of bytes actually copied in the string buffer.
     43// functions to build a string from a printf-like <format>, and stores it
     44// in the buffer defined by the <string> and <size> arguments.
     45// The <format> itself is supposed to be a NUL terminated string. The <string>
     46// buffer <size> must be large enough to contains also the NUL terminating character.
     47// If success, it returns the number of bytes actually copied in the <string> buffer,
     48// but this length does NOT include the terminating NUL character.
    4749// It returns -2 in case of illegal format, it returns -1 if the formated string
    48 // exceeds the length argument.
     50// exceeds the <size> argument.
    4951//////////////////////////////////////////////////////////////////////////////////////
    5052// @ string    : buffer allocated by caller.
    51 // @ length    : buffer size in bytes
     53// @ size      : buffer size in bytes
    5254// @ format    : printf like format.
    5355// @ args      : va_list of arguments.
     
    5557//////////////////////////////////////////////////////////////////////////////////////
    5658static int32_t format_to_string( char       * string,
    57                                  uint32_t     length,
     59                                 uint32_t     size,
    5860                                 const char * format,
    5961                                 va_list    * args )
    6062{
    6163
    62 #define TO_STRING(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0);
     64#define TO_STRING(x) do { string[ps] = (x); ps++; if(ps==size) return -1; } while(0);
    6365
    6466    uint32_t   ps = 0;        // index in string buffer
     
    7476            goto format_to_string_arguments;
    7577        }
    76         else                  // copy one char to string
     78        else                  // copy one char of format to string
    7779        {
    7880            TO_STRING( *format );
     
    8183    }
    8284
    83     TO_STRING( 0 );
    84     return ps;
     85    TO_STRING( 0 );      // NUL character written in buffer
     86    return (ps - 1);     // but not counted in length
    8587
    8688format_to_string_arguments:
     
    9597        switch (*format)
    9698        {
    97             case ('c'):             // char conversion
    98             {
    99                 int val = va_arg( *args , int );
    100                 buf[0] = (char)val;
     99            case ('c'):             // one printable character
     100            {
     101                buf[0] = (char)va_arg( *args , uint32_t );
    101102                pbuf   = buf;
    102103                len    = 1;
    103104                break;
    104105            }
    105             case ('d'):             // up to 10 digits decimal signed integer
     106            case ('b'):             // one ASCII code value (2 hexadecimal digits)
     107            {
     108                uint8_t val = (uint8_t)va_arg( *args , uint32_t );
     109                buf[1] = HexaTab[val & 0xF];
     110                buf[0] = HexaTab[(val >> 4) & 0xF];
     111                pbuf   = buf;
     112                len    = 2;
     113                break;
     114            }           
     115            case ('d'):            // one int32_t (up to 10 decimal digits after sign)
    106116            {
    107117                int32_t val = va_arg( *args , int32_t );
     
    120130                break;
    121131            }
    122             case ('u'):             // up to 10 digits decimal unsigned integer
     132            case ('u'):           // one uint32_t (up to 10 decimal digits)
    123133            {
    124134                uint32_t val = va_arg( *args , uint32_t );
     
    132142                break;
    133143            }
    134             case ('x'):             // up to 8 digits hexad after "0x"
    135             case ('X'):             // exactly 8 digits hexa after "0x"
     144            case ('x'):           // one uint32_t (up to 8 hexa digits after "0x")
     145
    136146            {
    137147                uint32_t val = va_arg( *args , uint32_t );
     
    141151                {
    142152                    buf[7 - i] = HexaTab[val & 0xF];
    143                     if( (*format == 'x') && ((val >> 4) == 0) )  break;
    144153                    val = val >> 4;
     154                    if(val == 0)  break;
    145155                }
    146156                len =  i + 1;
     
    148158                break;
    149159            }
    150             case ('l'):             // up to 16 digits hexa after "0x"
    151             case ('L'):             // exactly 16 digits hexa after "0x"
     160            case ('X'):         // one uint32_t (exactly 8 hexa digits after "0x")
     161            {
     162                uint32_t val = va_arg( *args , uint32_t );
     163                TO_STRING( '0' );
     164                TO_STRING( 'x' );
     165                for(i = 0 ; i < 8 ; i++)
     166                {
     167                    buf[7 - i] = (val != 0) ? HexaTab[val & 0xF] : '0';
     168                    val = val >> 4;
     169                }
     170                len = 8;
     171                pbuf = &buf[0];
     172                break;
     173            }
     174            case ('l'):          // one uint64_t (up to 16 digits hexa after "0x")
    152175            {
    153176                uint64_t val = (((uint64_t)va_arg( *args, uint32_t)) << 32) |
     
    158181                {
    159182                    buf[15 - i] = HexaTab[val & 0xF];
    160                     if( (*format == 'l') && ((val >> 4) == 0) )  break;
    161183                    val = val >> 4;
     184                    if( val == 0)  break;
    162185                }
    163186                len =  i + 1;
     
    165188                break;
    166189            }
    167             case ('s'):             /* string */
     190            case ('L'):          // one uint64_t (exactly 16 digits hexa after "0x")
     191            {
     192                uint64_t val = (((uint64_t)va_arg( *args, uint32_t)) << 32) |
     193                               ((uint64_t)va_arg( *args, uint32_t));
     194                TO_STRING( '0' );
     195                TO_STRING( 'x' );
     196                for(i = 0 ; i < 16 ; i++)
     197                {
     198                    buf[15 - i] = (val != 0) ? HexaTab[val & 0xF] : '0';
     199                    val = val >> 4;
     200                }
     201                len =  16;
     202                pbuf = &buf[0];
     203                break;
     204            }
     205            case ('s'):             /* one characters string */
    168206            {
    169207                char* str = va_arg( *args , char* );
     
    213251    // build a string from format
    214252    length = format_to_string( buffer,
    215                       CONFIG_PRINTK_BUF_SIZE,
    216                       format,
    217                       &args );
     253                               CONFIG_PRINTK_BUF_SIZE,
     254                               format,
     255                               &args );
    218256    va_end( args );
    219257
     
    258296    // build a string from format
    259297    length = format_to_string( buffer,
    260                       CONFIG_PRINTK_BUF_SIZE,
    261                       format,
    262                       &args );
     298                               CONFIG_PRINTK_BUF_SIZE,
     299                               format,
     300                               &args );
    263301    va_end( args );
    264302
     
    315353        if( length > 0  )  // display panic message on TXT0, including formated string
    316354        {
    317             printk("\n[ASSERT] in %s / core[%x,%d] / thread[%x,%x] / cycle %d\n       %s\n",
     355            printk("\n[ASSERT] in %s / core[%x,%d] / thread[%x,%x] / cycle %d\n   <%s>\n",
    318356            func_name, local_cxy, lid, pid, trdid, cycle, buffer );
    319357        }
     
    332370{
    333371    va_list       args;
    334     int32_t       string_length;
     372    int32_t       length;
    335373
    336374    // build args va_list
     
    338376
    339377    // build a string from format
    340     string_length = format_to_string( buffer , size , format , &args );
     378    length = format_to_string( buffer , size , format , &args );
     379
     380    // release args list
    341381    va_end( args );
    342382
    343     if( (string_length < 0) || (string_length == (int32_t)size) )  // failure
    344     {
    345         return -1;
    346     }
    347     else                                                           // success
    348     {
    349         // add NUL character
    350         buffer[string_length] = 0;
    351 
    352         return string_length;
    353     }
     383    if( length < 0 )   return -1;
     384    else               return length;
     385
    354386}   // end snprintk()
    355387
Note: See TracChangeset for help on using the changeset viewer.