Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: David Brown Newsgroups: comp.arch.embedded Subject: Re: Log for debug purposes Date: Fri, 24 May 2024 11:07:35 +0200 Organization: A noiseless patient Spider Lines: 129 Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Fri, 24 May 2024 11:07:35 +0200 (CEST) Injection-Info: dont-email.me; posting-host="aa31083d92649562fe347cd52a2a5ec5"; logging-data="2384554"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+aiI1hriNxWKw/N0XXL6nLW0dD+Z1hVOc=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Cancel-Lock: sha1:cMgKUdG+tGiXvGIxmxAisbKGWME= Content-Language: en-GB In-Reply-To: Bytes: 6127 On 24/05/2024 08:57, pozz wrote: > Il 23/05/2024 13:46, David Brown ha scritto: >> On 22/05/2024 22:36, pozz wrote: >>> I don't repeat here what is written there[1]. I found trice library >>> and I find it interesting to emit log messages for debug purposes, >>> avoiding printf execution on the target. >>> >>> What I don't like is patching my code before compiling. This step >>> delays the build process and could mess up the repository, even if is >>> simple to un-patch the code before committing. >>> >>> Do you apply other strategies? >>> >>> I'm thinking to introduce this type of log in one of my application >>> where the firmware runs on an embedded platform indirectly connected >>> to Internet. I mean the main MCU is connected to another >>> Internet-connected device by a RS485 bus. >>> >>> It could be very useful to receive logs from the main MCU through >>> Internet. >>> >>> >>> [1] https://github.com/rokath/trice >> >> >> I would not use a system that changed my source code - it's just out >> of the question for me.  I'm fine with /generation/ of source code >> files as part of a build process, but not /changing/ code I have >> written.  So if I were making a system like this, I would definitely >> not have it change the source code. >> >> Suppose you want to trace calls to the "new_position" function in your >> source code file "positioning.c".  With trice, you'd have something like: >> >> void new_position(uint32_t x, uint32_y, int16_t a) >> { >>      trice("Moved to new position %lud, %lud, %d", x, y, a); >>      ... >> } >> >> After the patching, you get a parameter "iD(1234)" added to that macro. >> >> My way to handle this would be that you write : >> >>      trice(new_position, "Moved to new position %lud, %lud, %d", x, >>                  y, a); >> >> >> Here, I'd be using a definition of the macro "trice" to convert this to: >> >>      trice_new_position(x, y, a) >> >> The pre-processing step, the equivalent of "trice insert", would run >> through the file "positioning.c" and generate files >> "positioning.trace.json" and "positioning.trace.h".  The id would be >> generated from a 32-bit hash (say 1234) of "positioning.c" and >> "new_position", and the json file would include an entry with the >> hash, the filename, function name and line number, the format string, >> and the names of the parameters.  The header file would contain a line: >> >> #define trice_new_position(x, y, a) do_trice_3(1234, x, y, a) >> >> And do_trice_3() would be an inline function that sends out the trace >> on the uart (or whatever). >> >> >> The file "positioning.c" would have a line #include >> "positioning.trice.h".  The generated files (including that header) >> would be in the build directory, not the source directory, and >> generated automatically by the makefile whenever the C code changed. >> >> >> This would give you everything you get from the "trice" library, but >> without any patching or unpatching, and with the trace generation >> updated automatically as part of the "make" process. >> >> I think it could be done a bit smarter, using _Generic macros to >> handle detection of the types of the parameters so that sizes get >> handled automatically. > > The drawback of your approach is that the developer must invent every > time a different trace name. Suppose you want to emit several trace > messages inside a function: Yes. Whether it is a drawback or an advantage (it can make it a lot easier to cross-reference between the logs and the source code) is subjective. > > void new_position(uint32_t x, uint32_y, int16_t a) > { >     trice(new_position_enter, "Entering new position(%lud, %lud, %d)", > x, y, a); >     if (a == 0) { >       trice(new_position_a0, "Hey, you pass a wrong parameter for a"); >     } >     if ((cr_x != x) || (cr_y != y) || (cr_a != a)) { >       trice(new_position_changed, "The new position really changed > (cr=%lud,%lud,%d)", cr_x, cr_y, cr_a); >       cr_x = x; >       cr_y = y; >       cr_a = a; >     } >     ... > } > > Here the postfixs "new_position_enter", "new_position_a0", > "new_position_changed" are needed to create a different ID by > calculating the 32-bits hash of the string "position.c ". > > What about using the line number instead of a custom postfix that the > developer must invent at every trace macro? > It would be possible, perhaps, to use __FILE__ and __LINE__ within the new trice macro to generate names automatically. > Surely the line number is not constant during developing, but I don't > think it's important. Agreed. > The tracer tool running on the host could reload > the json file (with IDs) when it changes. > In this case, every build is linked to a trace json file, like a symbol > file. >