NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Questions about after dividing a program into 'object modules'...

December 13, 2011
by JimFrederickson
JimFrederickson's Avatar

I have 2 questions...

1 - #ifndef This statement is in the Nerdkit 'header files' that are included for incorporating various Nerdkit 'object files' into a program.

I read about their use, and there seems to be the conclusion that this
statement will stop redeclaration from occurring if the 'header file' is
included into multiple 'c files' in a particular program.

Well, I created those initially and everything worked.

I took those out, to see the affects, and everything still worked?

Are these necessary?  (maybe they been deprecated?)
Or does the AVR-GCC Toolset just figure that if something is in a
'header file' then it may be shared amongst multiple 'c files'?

2 - This question is MUCH MORE important to me. When I divided the program into modules one of the benefits I was looking for was reporting on the size of the program code, uninitialized data, and initialized data by module/object file.

I don't get that?

The size information for the 'object files' doesn't show any data.
(Regardless of whether it is defined only in the 'object files' 
corresponding 'c file' or 'header file'?  It only reports the
size of the code.

Now the 'data does get allocated' because the total size of the data
sections in the 'linked program' is the same as it was before I 
broke it apart.

I can see the 'rationale' if the assumption is that the 'data is not
really defined until it is linked into a program', but that is not
really what I want...

Is there a way I get information on how much data is defined for use
in the 'object file'?
December 13, 2011
by BobaMosfet
BobaMosfet's Avatar

Answer 1--

Whether or not '#ifndef' (if not defined) has any bearing is a matter of how things are written for your specific code.

Answer 2--

Header files do not contain code per se. They contain constants and references (interfaces). '.c' files contain source-code.

Data is allocated in two places, depending on how you write your program (and how libraries are written that you link in)-- At compile time- which is what you see in the '.data' count, and a runtime (when the code is being executed-- not found in .data). Data allocated at compile time is usually composed of things like strings or pre-allocated arrays, data tables, and so forth.

Everything that is a human understandable word- like function names, constants and such are symbols. The compiler builds a symbol table and tracks everything that has a label or an address or an offset.

If you want to see exactly what it's doing, look at your .map file (make sure the compiler outputs it- as this will tell you what the linker did.)

Breaking your project into various .c and .h files does not impact code size- that is only for your convenience and organization. When the compiler runs, it loads it all in as if it's one large file, then begins the syntax check, linking, etc.

An object file contains both code and pre-allocated .data. If you have any pre-allocated data in the .data segment the compiler shows that to you in the compiler output. If it shows zero for .data, you didn't have any.

Make sure you understand what becomes .data- otherwise your incorrect expectation will lead to frustration and confusion.

BM

December 13, 2011
by JimFrederickson
JimFrederickson's Avatar

Thanks for the reply.

I don't really have any 'frustrations', and not anything that I would classify as 'confusion' more like 'surprise'...

It still doesn't really answer the questions though.

The type of things that I have in in the '#ifndef' are specifically what I think are likely the 3 most common things to put there. (which at least for me are '#defines', 'data definitions/declarations' and 'function prototypes').

I guess, for now, I will just not use it until I find something that ends up causing an error?

I am well aware of 'what becomes data', I was just expecting that the AVR-GCC Toolset would 'let me know how much data had been defined in a specific module' as that module's 'object file' was created rather than 'only when the object files were linked'. (Much like every Assembler I have used in the past, as well as assorted miscellaneous compilers).

What is this '.map file' that you mentioned? Is this something from 'avr-objdump'?
(I looked at the embedded help and didn't see any '.map file' references, so maybe this is something different?)

December 13, 2011
by JimFrederickson
JimFrederickson's Avatar

I have noticed as well that there are no 'public', 'private', or 'local' attributes for data that is defined so that may also factor into how/why it reports data as it does. (I was thinking that mostly because those attributes are available the AVR-GCC Tool chain doesn't even try to allocate that information to a module. It just 'lumps it all together'.)

But even if there was a way to show a total of the 'size of the data structures referenced' from within a module that would work for the vast majority of the situations I have.

December 18, 2011
by BobaMosfet
BobaMosfet's Avatar

JimFrederickson-

I think the problem is we're coming at this from slightly two different perspectives. I come from C and assembler, having written many compilers, interpreters and assemblers. They way you are using terms seems a little 'off the mark' to me (I feel like you are more OOP oriented). Like 'module' for example.

Modules don't exist in C. Libraries do. (.lib). Which are compiled object files with headers allowing external references to the functions, procedures, and variables located within. Are you wanting to break your code in to Libraries? Which would give you more of the kind of numbers you're looking for?

I'm trying to get us on common ground of vernacular. It would help me to understand where you are coming from so we can build a common understanding of terms. For example, if you want to control variable scope in C, you have to specifically tell the compiler what a variable's scope is. Things like 'private' and 'local' are later developed terms, not from C. Instead you would place the variables differently, use 'static', 'volatile', 'register', and 'extern' referencing.

Let us know, please.

BM

December 23, 2011
by JimFrederickson
JimFrederickson's Avatar

Thanks for reply.

While my use of 'Module' doesn't match the 'specific definition of Modern Object Oriented Languages' anything can be 'broken into modules'. ('sub-assemblies', 'sub-components', 'pieces' if you would prefer. Although 'module' is a better choice because it is the term used to better approximate the equivalent of what I would like to accomplish.)

And yes, c is not 'Object Oriented' but that doesn't mean that an application cannot be broken into 'modules'. (The basic act of 'modularization' can be applied to pretty much any process or object that can be broken into smaller components.)

What I want to accomplish is very much like what a true 'Module is for Object Oriented Programming'.

'static', 'volatile', 'register' are not what I am seeking.

At it's very 'essence' a 'c object file' meets the basic generalized definition of a 'module' even if it doesn't meet the more specific definition of an 'object oriented programming language module'.

So I do want to accomplish the 'modularization' of my program.

So to be more specific...

1 - I want to break my program apart into code pieces that are 'self-contained' and 'fully functional' for what they do.

2 - I want to create specific references to the functions and data that external 'modules' will need. (Even if those references are not directly enforced or recognized by the 'avr-gcc toolset'. My 'coding conventions' will be such to create that 'affect'.)

3 - I would like some sort of mechanism/process to easily create a report showing how much data space is used in the module. ('Object File' if you would prefer.) The 'avr-size' utility would work just great for what I want, IF it only could report the 'data' and 'bss data' used an 'object file that was part of a complete program but not yet complete'. Yes I do understand that if that was it would not necessarily be correct, since there is not, at least does not seem to be, a way for the 'avr-gcc toolset' to know the scope of a data element.

For most of what I am doing the data is so small it is not really that important, but it would be nice.

Keeping in mind as well the 'avr-gcc toolset' is not 'strictly c' it is 'their implementation of c'. (even interpretation of you will.) It already has hooks for doing things that are not part of c.

Additionally it does support other languages than c.

So I am quite sure something can be done to do this easily. (If it cannot be easily done, then it really isn't worth it to me.)

So far, from what I have read, the only thing that seems like it 'could work for what I want' is breaking data into 'section'. I am not sure if that could be easily done though.

4 - I don't want 'Libraries'. The resources on the Microcontrollers are restricted enough that I don't want things just be 'grabbed and interjected'. I only want 'those things' that I 'select to be used'. So 'linking specific object files' will accomplish that.

5 - Lastly... What is the '.map' file you referenced before? How to I get/produce that file?

December 24, 2011
by BobaMosfet
BobaMosfet's Avatar

JimFrederickson-

That's what I thought. I understand the concept of modularization, I was writing code before C or C++ existed. I've written compilers, interpreters, assemblers, chip debuggers and more. I just wanted to make sure I understood your perspective.

Yes, you do want a library. First off, the compiler has a 'smart-linker'. It only links in the functions/code from each library that are used, not the entire object of the library. Compilers that link in the entire binary of a library died off before 1995.

In C, you use a 'Library'. (.lib instead of .obj). This will do what you want. Write your code as as separate project/makefile, with your functions. Write one .h file that contains the external prototype references to the functions and procedures, and global variables you wish to expose. Do not include this .h file in the library. Compile the code into a library.

Then you may write other programs to include that library and the header file (just like any other compiler library you would use). Your linker output will show you the code/data use of each library, separately from the object (.obj) file your program creates.

Map file is created when you run the disassembler, to disassemble your code.

You might want to explore using an IDE, like WinAVR for example, to wrap around the compiler, to give you easier control of the makefile, to help you access these features.

Merry Christmas,

BM

December 27, 2011
by JimFrederickson
JimFrederickson's Avatar

Merry Christmas as well,

For now Libraries are not what I want to use.

For some things, in the future, a library will be used. This question though is more concerned with various benefits for dividing a source into specific/logical modules. (If nothing else just maintaining the appropriate mindset...)

I think that your characterization of libraries is not entirely accurate. (I could very well be wrong, because I only glanced at them enough to be pretty sure they weren't going to accomplish what I was looking for right now.)

You said...

"First off, the compiler has a 'smart-linker'. It only links in the functions/code from each library that are used, not the entire object of the library."

I think that is incorrect...

I 'smart linker' does 'link in each of the entire object modules that are in a given library if they contain references in the calling program'. (And, of course given that the 'smart linker' has been told in the first place to search the library.)

If individual 'functions/code' are not in the completed linked program from a 'specific object file' then that is a function of the 'optimizing features and not libraries per se'.

The 'c libraries' have been broken up into multiple 'object modules per library' so while the 'result is that individual functions/code are linked' that is a result of 'how the library is created' and not that the 'code was put into a library'.

I am pretty happy with the 'makefiles' I am using. They already rebuild the potential cascade of files I need when necessary and produce the of items I find useful.

While I do indeed have, and have had for years, Atmel IDE loaded it's use for me is pretty limited.

I am pretty familiar with the "Programmers Notepad' so that is not much of an issue for me.

I still don't see any information for a 'Map File'?

What I have been doing is incorporating the 'symbol table' into the disassembled object file results from 'avr-objdump'.

Using:

avr-objdump -t -S -D main.o > main.asm

Is that what you were referring to?

December 29, 2011
by Ralphxyz
Ralphxyz's Avatar

Well a starter for a MAP file is here.

 % avr-gcc -g -mmcu=at90s2313 -Wl,-Map,demo.map -o demo.out demo.o

Google AVR .map file gives some interesting results.

As usual there are various views of usability.

Ralph

December 29, 2011
by JimFrederickson
JimFrederickson's Avatar

Thanks Ralph,

I took a couple quick looks as some examples, including the link you supplied.

I am quite curious to see what this output looks like for my projects and determine if this is something that would be useful for me.

It may be a couple weeks though, I am working on a few other things and for now the Symbol Table Dump has been working well for what I need.

December 30, 2011
by Ralphxyz
Ralphxyz's Avatar

It is so interesting, one's perspective.

I have been using the Nerdkit for almost two years now and I have never had the need of using a MAP file or even a "Symbol Table Dump" for that matter :-).

For "me" I think that I have done some pretty heavy lifting, as in some very interesting projects (at least for me).

But for others, such as yourself, you feel you will need a "deeper" involvement i.e. MAP files.

That is just so cool!!

Fascinating how the human mind works and then when you individualize it, it becomes absolutely awesome.

It is so wonderful of Humberto and Mike (whom I haven't much from lately) to provide us such a ready avenue to travel.

We can all progress at our own pace and need but the friendly folks here at the forum are always ready to help.

Ralph

January 05, 2012
by pcbolt
pcbolt's Avatar

Hi Jim -

In response to your 2nd question, have you tried using the program called "avr-size.exe" that is part of the AVR utility package? I tried it on one of my object files and it listed the .text , .bss, .data sizes. Hope it helps.

January 05, 2012
by pcbolt
pcbolt's Avatar

Jim -

Ooops...my bad. I just read your Dec 23rd post (bullet item 3). Sorry about the last post.

Post a Reply

Please log in to post a reply.

Did you know that a motor's no-load current at a given voltage is much less than it's resistance would suggest? Learn more...