问题
A while back I had posted this question on SO. In that question I was looking for a way to implement a solution which we had thought of. But from the answers I got, I saw that that solution was unimplementable using the default C preprocessor.
So I've decided to post the problem directly and see if a proper solution can be found.
PROBLEM STATEMENT
We have a custom hardware platform on which we've used the Contiki OS to build the firmware. The hardware is based on the MSP430 micro-controller. Being an embedded and restrained environment, we are looking for ways to optimize the code.
One area were we want to optimize is the logs we are printing to the console. The default printf()
function is not working because reasons. So we have our own function to print to the console using the UART.
void ax_log_msg(enum log_msg_id, char* message);
This obviously will only take fixed strings unlike printf()
but it serves our purpose.
Now the fixed strings that we give in the function will obviously take up a considerable amount of memory. We want to reduce the memory usage by doing something before the actual compilation that will replace the strings with a fixed integer/number that is unique to every call. It will also generate a table or file where the integers will be mapped to the string they replaced. This table would be used in the user-end application to show the actual message while the device will only print integers.
So what I'm looking for is a way to implement such a solution. Any answer would help: just ideas or pre-existing solutions; anything helps.
Additional Notes
The
log_msg_id
enum and the message the user wants to print are not related to one another. The enum values will mostly be used to group the strings for the table/document.We are using the TI CCS IDE to build our application.
Unique values for each unique string instead of each call would be better, but not necessary.
The firmware is written in C.
The message that will be printed can be anything the user/programmer wants. The system should pick it out from the code.
Since the firmware code will span across multiple files written by different people, the system should be able to hold values across the files. This is one of the reasons the basic C- preprocessor was not used.
If any information is missing, please do mention it and I will add it.
Thank You
回答1:
Sound like a job for the X-macros:
log_table.x
/*Symbol ID Message */
X(LOG_ID_BOOTING, 1, "Booting" )
X(LOG_ID_OUT_OF_MEM, 2, "Out of memory" )
X(LOG_ID_FOO_BAR, 3, "Foo failed to bar")
log.h
/* Generate list of available ID numbers */
enum LogID {
#define X(a, b, c) a = b,
#include "log_table.x"
#undef X
};
void do_log(enum LogID id);
some_module.c
p = malloc(sizeof(Foo));
if(!p)
do_log(LOG_ID_OUT_OF_MEM);
Note that you could add some more columns to log table, like error level, etc.
In this example I ignored the message column completely. This is major advantage. You could generate string table to debug versions, and leave it out from the final release.
Another nice advantage is that .x file is easy to parse, so you could use Python script for example to generate nice PDF file with all error codes and explanations in it.
来源:https://stackoverflow.com/questions/25440962/embedded-console-log-optimization