is it possible write to console without stdlibs? c/c++

前端 未结 4 1726
夕颜
夕颜 2021-02-19 20:10

I am programming on an arm microprocessor and am trying to debug using print statements via UART. I do not want to add stdlibs just for debugging. Is there a way to

4条回答
  •  生来不讨喜
    2021-02-19 20:18

    Short answer: Yes, it's entirely possible to do both of your solutions.

    The printf function is quite complex if you want to support all of the data types and formats. But it's not that hard to write something that can output a string or an integer in a few different bases (most people only need decimal and hex, but octal probably only adds another 3-4 lines of code once you have decimal and hex).

    Typically, printf is written like this:

     int printf(const char *fmt, ...)
     {
         int ret;
         va_list args; 
    
         va_start(args, fmt)
         ret = do_xprintf(outputfunc, NULL, fmt, args); 
         va_end(args);
         return ret;
    }
    

    And then the do_xprintf() does all the hard work for all variants (printf, sprintf, fprintf, etc)

    int do_xprintf(void (*outputfunc)(void *extra, char c), void *extra, const char *fmt, va_list args)
    {
        char *ptr = fmt;
        while(1)
        {
           char c = *ptr++;
    
           if (c == '%')
           {
                c = *ptr++; // Get next character from format string. 
                switch(c)
                {
                   case 's': 
                      char *str = va_arg(args, const char *);
                      while(*str)
                      {
                          count++;
                          outputfunc(extra, *str);
                          str++;
                      }
                      break; 
                   case 'x': 
                      base = 16;
                      goto output_number;
    
                   case 'd':
                      base = 10;
             output_number:
                      int i = va_arg(args, int);
                      // magical code to output 'i' in 'base'. 
                      break;
    
                   default:
                      count++;
                      outputfunc(extra, c);
                      break;
             }
             else
                 count++;
                 outputfunc(extra, c);
         }
         return count;
     }                
    

    Now, all you need to do is fill in a few bits of the above code and write an outputfunc() that outputs to your serial port.

    Note that this is rough sketch, and I'm sure there are some bugs in the code - and if you want to support floating point or "widths", you will have to work a bit more at it...

    (Note on the extra parameter - for output to a FILE * that would be the filepointer, for sprintf, you can pass a structure for the buffer and position in the buffer, or something like that)

提交回复
热议问题