um hier mal wieder etwas Leben inne Bude zu bringen, veröffentliche ich hier mal ein sehr kleines printf.
Problem ist, dass man auf Mikrocontrollern zum schöneren debuggen nur die serielle schnittstelle nutzen kann.
Nun hab ich keinen Bock, die zeichen alle einzelnd rüberzschaufeln ...
Worum gehts ?
Ich hab ne Shell für Mirkrocontroller geschrieben. Diese Shell bietet Funktionalitäten wie eine DOS/Linux-Shell, und ermöglicht Funktionsprogrammierung zum debuggen a'la int test_func(int argc, char *argv).
Da sind viele printf's drin.
Dummerweise braucht ein normales printf aus einer uC-Lib so 5k oder mehr an code.
Nimmt man einen AVR, ist das meist bei den kleineren shcon sehr viel.
Daher hab ich mir Gedanken gemacht, und überlegt, was man eigendlich alles so printf'en muss:
text, %i, %c, %s sowie \n und \t sollten für die meisten Sachen ausreichen.
Variadic Functions ? va_xxx machts

Der Code ist stellenweise ziemlich gemein programmiert, aaaber:
Mit Keil uVision compiliert auf ARM Cortex M3 (Luminary Micro, Stellaris:
-O0: 240Byte ROM und 4Byte SRAM
-O3: 180Byte ROM und 4Byte SRAM
Wenn das man nicht geil ist

Parameter und Formatstring (mit o.g. Format-zeichen) wie printf...
Nehmts mir nciht übel, dass ich einen Pointer als Variable vergewaltige

Das fputc stammt noch vom retargeting für das printf. Da die aber auch sehr klein ist (5 zeilen) behalte ich die

Wenn noch jemand was entdeckt, wie mans noch kleiner kriegt, her damit

Code: Select all
// Th printf
/*
Author: Thorsten de Buhr
mail: thorsten@lasertechnix.de
Use:
Use is free, could run or not ;-)
U may change every printf in cour code to thprintf, the rest is the same.
U may use:
%i, %s, %c
\n, \t
More is not implemented now.
Have fun with this very small print-function, it uses ~240 bytes of code
(printf uses >5k!)
*/
#include <stdarg.h>
#include "../src/main.h"
#include "../src/thprintf.h"
int thprintf(char *string, ...)
{
va_list tag;
int i=0;
int *pointer=0;
signed int int_tmp=0;
va_start(tag, string);
do
{
if(*string == '%')
{
switch(*(++string))
{
case 'i':
{
int_tmp = va_arg(tag, int);
if(int_tmp <0)
{
fputc('-', 0);
int_tmp*=-1;
}
pointer = (int*)int_tmp;
for(i=MAX_NUM_DEC; i; i/=10)
{
if((int)pointer/i)
{
fputc((int_tmp/i)+48, 0);
int_tmp%=i;
}
}
} break;
case 'c':
{
fputc((char)va_arg(tag, int), 0);
} break;
case 's':
{
pointer = (int*)va_arg(tag, char*);
do
{
fputc(*pointer, 0);
} while(*pointer++);
} break;
}
} // end if '%'
else if(*string == '\\')
{
switch(*(++string))
{
case 'n': fputc('\n', 0);
break;
case 't': fputc('\t', 0);
break;
}
} // end if '\'
else fputc(*string, 0);
} while(*(++string));
va_end(tag);
return(0);
}