We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
How many bytes will printf() take up in a non debug-monitor environment? Also, is it easy to set up printf() to map to a second UART? I will need control of the UART ISR so that I can handle receives appropriately. How will this confict with printf()?
#pragma maxargs (20) will set the number of bytes used by variable arg. functions such as printf to 20. The default for the small model is 15, for the large 40. See page 34 of the latest C51 v6.02 C51.pdf manual. Mapping printf to any device is simple. First, write your own putchar(). One that can print to either UART based upon some file static var. This will automatically replace the library version. Then, write a device switcher function that controls the file static var. that putchar uses to determine which UART to use. Printf will use what ever function has the name putchar. - Mark
Thanks Mark. But also, how much space will the function take? I've heard people say that printf() may take up to 2K of code space. Meaning that if printf() is used in the embedded application, then 2K of code space will be eaten up. If thats the case then I'll have to come up with my own transmission mechanism.
Oh goodness yes, printf is fat. Just build a small file with only main() and no printf call and note the size of the code in the .m51. Then make a call to printf in this file, build and check the .m51 file again. This will tell you the size of printf for a given model. For protocols I'd skip printf. I always use some variant of:
STX | message class | class subtype | body | checksum
void sendPacket(Major maj, Minor min, char *pBody, U8 bodyLen) { U8 idx; U8 checksum; putchar(STX); checksum = STX; checksum += putEscapedChar(maj); checksum += putEscapedChar(min); checksum += putEscapedChar(bodyLen); checksum += putEscapedChar(~bodyLen); for (idx = 0; idx < bodyLen; ++idx) { checksum += putEscapedChar(*pBody++); } putEscapedChar(checksum); }
would please tell me more about the folloing function: putEscapedChar(checksum)
I'd write my own putchar() like this:
char putchar(char outChar) { TI = 0; SBUF = outChar; while (!TI); return outChar; }
void putFiltByte(U8 outByte) { if (STX == outByte || DLE == outByte) { // Escape this data char. putchar(DLE); // Ensure this data char. is never an STX or DLE. outByte += ' '; } putchar(outByte); }
So I just have to have a putchar() somewhere in my code and this will automatically override the putchar() that printf() uses? And if I decide not to use printf() can I override the interrupts for UART transmit and receive the same way? Also, I need to prove my code works using the uVision2 simulator because we won't have a prototype for some time.
Again, I'm using the uVision2 eval simulator. When I try to see code size it doesn't appear to include the size of printf(). In fact it just tells me the starting location of my functions but not the sizes. Is there a way to list the code and data sizes of objects? Also, even at the end of the .m51 file, the total code size does not seem to include the size of the printf() function. Is this because of the simulator?
I just compiled and linked the HELLO example project. The following excerpt from the MAP file (*.m51) lists the starting location and sizes of the modules inthe program.
LINK MAP OF MODULE: Hello (HELLO) TYPE BASE LENGTH RELOCATION SEGMENT NAME ----------------------------------------------------- * * * * * * * D A T A M E M O R Y * * * * * * * REG 0000H 0008H ABSOLUTE "REG BANK 0" DATA 0008H 0014H UNIT _DATA_GROUP_ 001CH 0004H *** GAP *** BIT 0020H.0 0001H.1 UNIT _BIT_GROUP_ 0021H.1 0000H.7 *** GAP *** IDATA 0022H 0001H UNIT ?STACK * * * * * * * C O D E M E M O R Y * * * * * * * CODE 0000H 0003H ABSOLUTE CODE 0003H 035CH UNIT ?PR?PRINTF?PRINTF CODE 035FH 008EH UNIT ?C?LIB_CODE CODE 03EDH 0027H UNIT ?PR?PUTCHAR?PUTCHAR CODE 0414H 001BH UNIT ?PR?MAIN?HELLO CODE 042FH 000DH UNIT ?CO?HELLO CODE 043CH 000CH UNIT ?C_C51STARTUP
So I just have to have a putchar() somewhere in my code and this will automatically override the putchar() that printf() uses? Yes, of course. Same for getchar(). And if I decide not to use printf() can I override the interrupts for UART transmit and receive the same way? You can use interrupts with or without printf() being used. It's up to how you implement putchar and getchar. Either way, you are not overriding the interrupts. In a uC you are in complete control. Interrupts are not used by the default putchar/getchar supplied by Keil. Also, I need to prove my code works using the uVision2 simulator because we won't have a prototype for some time. I can't help you there. I always use an In-Circuit Emulator on a simple board with a RS-232 driver. - Mark
Again, I'm using the uVision2 eval simulator. When I try to see code size it doesn't appear to include the size of printf(). In fact it just tells me the starting location of my functions but not the sizes. Is there a way to list the code and data sizes of objects? Also, even at the end of the .m51 file, the total code size does not seem to include the size of the printf() function. Is this because of the simulator? Just look in the .m51 file for a simple foo.c file compiled and linked, don't use your big project for this. Build the file without using printf, check the total size. Then add one call to printf, check the size again. The simulator has nothing to do with the linker output file (.m51). - Mark
CODE 0003H 035CH UNIT ?PR?PRINTF?PRINTF