Condition code generation in library..

Hi friends,

I have some C Source file such as Serial.c, Modbus.c, Ring_Buffer.c My aim is to create a .lib file in Keil uv4 for Cortex m3.

Some function contains the #ifdef type conditional code's. How to deal with this?

Please suggest any work around..

Thanks, Kishore.

Reply to
kishor
Loading thread data ...

What's to "work around"? You can either #define the symbols referenced -- or not. An examination of the code (and commentary) should provide hints as to what you would *like* those symbols to be...

Beyond that, there is no impact on library generation, etc.

Reply to
D Yuniskis

I guess he means something like different defines for different IO registers, depending on which CPU he is using and other things like this.

One idea would be to refactor it, so that all #ifdefs are in the header files, only, and don't affect the compilation of the library. Maybe something like this:

In the C file:

static void commonUartInit() { ... }

void initUart_at9g20() { commonUartInit(); ... }

void initUart_stm32() { commonUartInit(); ... }

In the header file:

#if defined(AT9G20) #define initUart initUart_at9g20 #elif defined(STM32) #define initUart initUart_stm32 #else #error "unsupported CPU" #endif

Then the linker takes care that the used functions only are linked to the program, to keep it compact. If you have more resources, and e.g. C++ and templates, you could do it more general, without all the macro kludge.

--
Frank Buss, http://www.frank-buss.de
piano and more: http://www.youtube.com/user/frankbuss
Reply to
Frank Buss

Thanks for quick reply,

I got the point. Instead of using #ifdef in function I should create two different functions. So the linker will select the functions depending on #define in header file.

Thanks, Kishore.

Reply to
kishor

Yes. But for small microcontroller projects, compile time doesn't matter and if you have the source of the library, maybe just add the source code to your projects, then you don't need to change anything. The source code of your libraries can still be located in different directories.

But using libraries helps to separate the project in modules and makes it more difficult to apply quick project specific hacks inside the library :-)

Another idea is to do copy-and-paste reuse. The advantage is that older projects still works, even if you change some common used parts of the code. This is what works best for me. Maybe doesn't work so good, if there is more than a few programmers working on multiple projects.

--
Frank Buss, http://www.frank-buss.de
piano and more: http://www.youtube.com/user/frankbuss
Reply to
Frank Buss

Perhaps. The question seemed unclear, to me. ("Why is there air?")

... and then remembering that "initUart" is where you (presumably) want to be.

But, you're still dealing with preprocessor directives (#if defined() being #ifdef in an alternate form)

I think this approach would (if consistently applied) result in more "littered" code (than burying the conditionals within routines).

E.g., any function that talks to the UART at the hardware level needs to be treated like this (if you are being consistent) -- instead of folding all those issues into one routine "conditionally".

The *advantage* this (your) approach has is that you can write initWHATEVER() without concern for WHATEVERELSE. OTOH, chances are that WHATEVER and WHATEVERELSE will have similar requirements/structure.

[this *wouldn't* be the case if, for example, you were writing "initUserInterfaceDevice()" and mapped that to "initUART" vs. "initCRT"! In that case, there would be very little "similar structure" to exploit and forcing all that code into a single routine would leave you with a mess]

This means you have to make sure the function is part of a *library* and not a "module" (lest the rest of the module get dragged in as well)

Reply to
D Yuniskis

Hi D Yuniskis,

My approach to conditional code is to enable optional extra features.

In case of UART features are RS485, Hardware flow control for RS232, etc

for RS485 mode before transmitting, I need to enable the RS485 transmit pin. In flow control before transmitting the data I check the CTS status.

These features are deeply embedded in Serial.c.

And the work around for this situation is,

Writing separate functions for each features implemented with same function name. Linker will select the correct function depending on #define in header file.

Kishore.

Reply to
kishor

Doesn't matter. You should look at how code that tries to run on various platforms is written (hint: lots of #ifdef's). The risk you run in selecting from a set of individual routines is that any change that you later discover must be applied to

*all* of them runs the risk of:

- being incorrectly applied to *one* of them

- being hard to shoehorn in because you opted for a different code structure in some of them

For example:

void TxIntService() { /* get here when transmitter needs service */ ...

/* Tx is ready for another character */ do { /* check Tx output FIFO for data available */ if (OK != FifoStatus(TxFIFO)) { /* shut down Tx interrupt; system will reenable * when it decides there is something else to XMIT */ TxIRQ = NULL; /* yada yada yada */

break; /* yes, we have no bananas */ }

/* get character from Tx output FIFO/mbuf */ c = FifoRead(TxFIFO);

#ifdef RS232 /* examine CTS input to determine if we *can* send */ if (!CTS) break; #endif #ifdef RS485 /* turn on EIA485 buffer */ BufferControl(ON); #endif

SendCharacter(c); } while (0); /* once around the block, Sigfried */

/* cleanup */

}

This (bogus) code fragment is intended to show that you *probably* have a lot in common between the different serial port configurations and how they perform specific actions (e.g., checkiing if there is data available, getting the next character to transmit; shutting down the transmit IRQ when the last character has been sent; taking / releasing mutexes, etc). If you break the routine into N different versions, you run the risk of forgetting one of these activities -- or, implementing it "differently/incorrectly" -- in one or more of them.

Taken to its logical extreme, would you write N different

*programs* for your N different product configurations, put them all into one big file and then #ifdef around each "configuration specific section"?

Reply to
D Yuniskis

I agree you.

But I am expecting some solution from you..

Or instead of making .lib file should I keep using C file ???

Thanks, Kishore

Reply to
kishor

Whether you use a C module or compile the routines into a library is entirely up to you.

If you do it the way I suggested, you will have *one* function for each UART action (transmit, receive, initialize, etc.). You can chose to put these into a library if you want. But, I suspect you will always be using *all* of them (i.e., will you ever build a system that only transmits and never receives? If so, then you would want to be able to include the transmit function and NOT the receive function. If they are in a library, then the linker will only drag the transmit function into your final executable if the receive is never referenced.)

If all of the functions will be used, then they can all reside in a single C module (source file).

OTOH, the other way you described requires you to compile EVERY different version of EVERY UART routine. E.g., RS232_Receive, RS485_Receive, RS232_Transmit, RS485_Transmit, RS232_Initialize, RS485_Initialize, etc. You woul dput ALL of these into a library (or libraries). Then, conditionally bind one of them to UART_Receive, another to UART_Transmit, etc. In that way, only one of the will be extracted from the library instead of "all flavors".

Figure out how to best *write* the code (so it is understandable, etc.). Then, figure out how to *link* it. Don't let linkage issues govern how you *write* the code.

[standard disclaimers apply, YMMV, do not bend/fold/mutilate]
Reply to
D Yuniskis

You mean create multiple object files UART.obj, UART_RS485.obj, UART_RS232.obj, etc from single UART.c file and merge all of them into single lib file??

Please explain the procedure in detail. I don't know how to do it??

Kishore.

Reply to
kishor

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.