Changeset 683 for trunk/kernel/kern/printk.c
- Timestamp:
- Jan 13, 2021, 12:36:17 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/printk.c
r669 r683 41 41 ////////////////////////////////////////////////////////////////////////////////////// 42 42 // 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. 47 49 // It returns -2 in case of illegal format, it returns -1 if the formated string 48 // exceeds the lengthargument.50 // exceeds the <size> argument. 49 51 ////////////////////////////////////////////////////////////////////////////////////// 50 52 // @ string : buffer allocated by caller. 51 // @ length: buffer size in bytes53 // @ size : buffer size in bytes 52 54 // @ format : printf like format. 53 55 // @ args : va_list of arguments. … … 55 57 ////////////////////////////////////////////////////////////////////////////////////// 56 58 static int32_t format_to_string( char * string, 57 uint32_t length,59 uint32_t size, 58 60 const char * format, 59 61 va_list * args ) 60 62 { 61 63 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); 63 65 64 66 uint32_t ps = 0; // index in string buffer … … 74 76 goto format_to_string_arguments; 75 77 } 76 else // copy one char to string78 else // copy one char of format to string 77 79 { 78 80 TO_STRING( *format ); … … 81 83 } 82 84 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 85 87 86 88 format_to_string_arguments: … … 95 97 switch (*format) 96 98 { 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 ); 101 102 pbuf = buf; 102 103 len = 1; 103 104 break; 104 105 } 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) 106 116 { 107 117 int32_t val = va_arg( *args , int32_t ); … … 120 130 break; 121 131 } 122 case ('u'): // up to 10 digits decimal unsigned integer132 case ('u'): // one uint32_t (up to 10 decimal digits) 123 133 { 124 134 uint32_t val = va_arg( *args , uint32_t ); … … 132 142 break; 133 143 } 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 136 146 { 137 147 uint32_t val = va_arg( *args , uint32_t ); … … 141 151 { 142 152 buf[7 - i] = HexaTab[val & 0xF]; 143 if( (*format == 'x') && ((val >> 4) == 0) ) break;144 153 val = val >> 4; 154 if(val == 0) break; 145 155 } 146 156 len = i + 1; … … 148 158 break; 149 159 } 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") 152 175 { 153 176 uint64_t val = (((uint64_t)va_arg( *args, uint32_t)) << 32) | … … 158 181 { 159 182 buf[15 - i] = HexaTab[val & 0xF]; 160 if( (*format == 'l') && ((val >> 4) == 0) ) break;161 183 val = val >> 4; 184 if( val == 0) break; 162 185 } 163 186 len = i + 1; … … 165 188 break; 166 189 } 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 */ 168 206 { 169 207 char* str = va_arg( *args , char* ); … … 213 251 // build a string from format 214 252 length = format_to_string( buffer, 215 CONFIG_PRINTK_BUF_SIZE,216 format,217 &args );253 CONFIG_PRINTK_BUF_SIZE, 254 format, 255 &args ); 218 256 va_end( args ); 219 257 … … 258 296 // build a string from format 259 297 length = format_to_string( buffer, 260 CONFIG_PRINTK_BUF_SIZE,261 format,262 &args );298 CONFIG_PRINTK_BUF_SIZE, 299 format, 300 &args ); 263 301 va_end( args ); 264 302 … … 315 353 if( length > 0 ) // display panic message on TXT0, including formated string 316 354 { 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", 318 356 func_name, local_cxy, lid, pid, trdid, cycle, buffer ); 319 357 } … … 332 370 { 333 371 va_list args; 334 int32_t string_length;372 int32_t length; 335 373 336 374 // build args va_list … … 338 376 339 377 // 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 341 381 va_end( args ); 342 382 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 354 386 } // end snprintk() 355 387
Note: See TracChangeset
for help on using the changeset viewer.