| Author |
Message |
|
|
Posted: May 22, 2012 - 06:39 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
| I imported a studio 4 project into studio 6 beta and everything was working great. I updated to studio 6.0.1843 and now I get compile/link errors that the function is not defined. |
|
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 06:44 PM |
|


Joined: Apr 29, 2011
Posts: 199
Location: Portland, OR, US
|
|
| I am using inline functions with AS6.0.1843 without problems. How are you declaring/including them? |
_________________ Gamu The Killer Narwhal
Portland, OR, US
_________________
Atmel Studio 6.1beta on Windows 8
XMEGA-A1/XMEGA-A3BU
AVR Dragon (Ver. 2)
JTAGICE mkII
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 06:50 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
|
Quote:
now I get compile/link errors that the function is not defined
Show code, both function definitions and calls.
Show verbatim error messages. |
|
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 07:15 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
H file
#define INLINE static inline __attribute__ ((always_inline))
inline char BooleanToChar( _Bool value );
C file
inline char BooleanToChar( _Bool value )
{
return ( ( value==1 ) ? '1': '0' );
} |
|
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 07:50 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
[quote="Larrydew"]H file
#define INLINE static inline __attribute__ ((always_inline))
inline char BooleanToChar( _Bool value );
C file
inline char BooleanToChar( _Bool value )
{
return ( ( value==1 ) ? Warning 58 inline function 'BooleanToChar' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\util.h 18 13 ApmMaster
Error 842 undefined reference to `BooleanToChar' D:\ArcLight\APM Second Generation\Firmware\ApmMaster\default/../../ApmLib/CommAdapter.c 242 1 ApmMaster |
|
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 08:31 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
Larrydew!
Take a look at your posts, and see how they came out. For me they are hardly readable. You can hit the Edit button and fix them so that they become inviting for pewople to read, upping your chances of getting good help. One thing to learn is how to apply CODE tags so that your code is shown here just as nicely formatted as it hopefully is in your editor.
Anyway:
1) Nowhere can I see a call to BooleanToChar.
2) Is the definition (implementation) of the function in the same file as the call?
3) Is the header file with the declaration (prototype) #included into the file with the definition (implementation)?
4) Is the header file with the declaration (prototype) #included into the file where the function is called?
5) Is the C file with the implementation actually added to the project? |
|
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 08:44 PM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
You define a macro with the upper case name "INLINE" but then never use it. The following functions are simply:
Code:
inline char BooleanToChar( _Bool value )
{
return ( ( value==1 ) ? '1': '0' );
}
using the standard C keyword. Did you mean to use:
Code:
INLINE char BooleanToChar( _Bool value )
{
return ( ( value==1 ) ? '1': '0' );
}
perhaps? |
_________________
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 08:52 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
Please explain what you mean by CODE tags? I cut and pasted the code from my 'C' and 'H' files from the editor and the warnings and error messages verbatim.
To answer you question list:
1) I did not include the code that called BooleanToChar but I assure it is made several times.
2) It is implemented in a util.c file and prototyped in a util.h file that is included in every file that calls it.
3) yes
4) yes
5) yes
This project compiled and loaded in the target device from AVR4 and AVR6beta. It was when I updated that things went south.
Thanks for your help. |
|
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 09:04 PM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
This is normal text
where indentation
is lost
Code:
And This is it in code tags
where indentation
is not lost
|
_________________
|
| |
|
|
|
|
|
Posted: May 22, 2012 - 09:11 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
Re the code tag, a picture says more than a thousand words (sometimes):
Quote:
I did not include the code that called BooleanToChar but I assure it is made several times.
I did not ask to see the call to make sure it was made. I asked for it to see how it was made. Tell me if you want to question / argue against supplying the info that we ask for or if you want help to solve the problem. If the former, I can promise you I will be out of here faster than you can blink an eye.
Quote:
This project compiled and loaded in the target device from AVR4 and AVR6beta. It was when I updated that things went south.
That might very well be so, but we have to start from somewhere if we want to wrestle this problem down. This also means that some basic check-questions have to be asked and answered. Some of these will in hindsight turn out to be unrelated to the actual problem, once revealed. But the questions per se are not unnecessary - they are a part of the problem solving process.
One possibility to get to the problem faster is if it is possible for you to ZIP up the whole project folder and post it as an attachment here. Then we can simply d/l it, to a test build and analyze and tinker with it.
Your call.. |
|
|
| |
|
|
|
|
|
Posted: May 23, 2012 - 12:55 AM |
|

Joined: May 22, 2012
Posts: 17
|
|
| I do not mean to be rude or uncooperative. I have no problems zipping up the entire project directory structure. How do I attached the file? |
|
|
| |
|
|
|
|
|
Posted: May 23, 2012 - 05:49 AM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
Look at the picture.
EDIT: I'll fix the arrows later guys. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 23, 2012 - 06:22 AM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
| The key to getting to the attachment functionality is to use the new reply button to start composing a post, rather than just using the Quick Reply area. |
|
|
| |
|
|
|
|
|
Posted: May 23, 2012 - 11:09 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
| This posting contains the files needed to duplicate my problem of AVR6 not compiling "inline" function into code. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 08:30 AM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
Just had a quick look at it - not much time riht now..
You likely have a problem with the wrong header files being included. If I place an obvious error in the very first line of e.g. registers.h and then compile Config.c this error is not detected. So it is not your registers.h that is included, but probably rather some system standard file. The name is very generic...
One thing that you might consider is to rename your header files so that they are prefixed with the project name, e.g. ApmRegister.h, ApmConfig.h etc.
Sorry no time for more on this ATM... |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 08:50 AM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
OK, another quick look.
It is you mixing up your own include files. You have a file registers.h in both ApmMaster and ApmLib. The former is the one that is included, the latter is probably the one you wanted to be included.
This is not the only include file that exists in two places with the same name.
The project is a mess. Sorry for the bluntness, but it really is. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 03:24 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
OK. Do this:
Back up your project to a safe location before continuing. You take all risk for this on your own!!!
1. Clean Solution
2. Remove All the files in the Solution Explorer that are below "Output Files" except main.c. "Remove" not "Delete".
3. Rebuild Solution.
At this time you will have 27 errors due to these three lines in leds.h:
Code:
ASSIGN_PIN(STATUS, D, 5); /* LED */
ASSIGN_PIN(COMM_TX,D, 6); /* LED */
ASSIGN_PIN(PWR_OK, D, 7); /* LED */
Which lead to this in gpio.h:
Code:
#define ASSIGN_PIN(name, port, bit) \
INLINE void GPIO_##name##_set() {PORT##port |= (1 << bit);} \
INLINE void GPIO_##name##_clr() {PORT##port &= ~(1 << bit);} \
INLINE byte GPIO_##name##_read() {return (PIN##port & (1 << bit)) != 0;} \
INLINE byte GPIO_##name##_state() {return (DDR##port & (1 << bit)) != 0;} \
INLINE void GPIO_##name##_make_out() {DDR##port |= (1 << bit);} \
INLINE void GPIO_##name##_make_out_set(){PORT##port |= (1 << bit); DDR##port |= (1 << bit);} \
INLINE void GPIO_##name##_make_in() {DDR##port &= ~(1 << bit); PORT##port |= (1 << bit);} \
INLINE void GPIO_##name##_make_pullup() {PORT##port |= (1 << bit);}\
INLINE void GPIO_##name##_toggle() {PORT##port ^= (1 << bit);}
4. Comment the 3 lines out temporarily and Rebuild Solution.
At this time you will have 2 errors in main. You will also have 32 warnings.
5. Go back and uncomment the lines in leds.h and fix the errors there and in main. Read and heed the warnings.
This project needs some serious rethinking IMO.
HTH Good Luck
EDIT: Added clarification details.
Code:
===================================================================================================
|
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
Last edited by larryvc on May 24, 2012 - 04:12 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 04:01 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
If you look at the name of the registers.h file in the ApmMaster directory you will see that is really _registers.h and the name of the file in the ApmLib directory is registers.h. They are not the same name. I have renamed the registers file name to ApmRegister.x and corrected the #include directives as well. Compiling still produces the same set of errors and warnings:
Error 107 undefined reference to `BooleanToChar' D:\ArcLight\APM Second Generation\Firmware\ApmMaster\default/../../ApmLib/CommAdapter.c 242 1 ApmMaster
Warning 3 inline function 'BooleanToChar' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\util.h 18 13 ApmMaster
This inline function is not in the registers.h file. All of the inline declarations and implimentations are being ignored and there are no other errors or warnings.
Please take another look and consider something within the compiler options as a possible cause? |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 04:13 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
Did you try what I suggested? It is not the compiler, it is the way the project has been created in AS6.
Or perhaps what you have given us does not build the same as it does on your system. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 04:19 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
|
Quote:
If you look at the name of the registers.h file in the ApmMaster directory you will see that is really _registers.h and the name of the file in the ApmLib directory is registers.h.
No, you take a good look at what you have. You will find that in the ApmMaster directoy there is a file registers.h. Now take a look in the ApmLib directory and find an identically named file. Those files are not identical regarding content though. (This is part of the mess I still argue is in this project.) Yes, I did see the _registers.h file, and yes I concluded that it has nothing to do with the problem.
Quote:
All of the inline declarations and implimentations are being ignored and there are no other errors or warnings.
I did a clean of the whole project and a build and I get several errors for things like NODE_1_REGISTER being undefined. So I do not think that "no other errors or warnings" holds. Those defs are in one of the header files registers.h, but not in the other. You will also note if you look at your error messages for the inline functions that the messages point to the file registers.h .
My hypothesis is still that part of the problem is that "the inline declarations" that you are looking at is not the ones pulled in by the compiler.
If you switch to the Output tab afer your failed build you will see the complete name of tHe header file, and in my case it is
..../ApmMaster/registers.h
that is included. You claim that that file does not even exist. It is also illuminating that that file (in the ApmMaster directory) does lack the define of e.g. NODE_1_REGISTER while the other registers.h (in the ApmLib directoy) has that define.
Now... I spent serious time analyzing your problem to this point, and I still think that a cause for a lot of your build errors are due to wrong header files being included. Please honour the time I spent for you by actually checking if what I say holds on your hard disk too.
I do not think there is a simple project setting that will make your problems go away. You need to realize that this mess needs cleaning up. Even if you find a setting that makes your current problems go away you will be hit again by the mess at some point. My advice it to clean it up now. |
Last edited by JohanEkdahl on May 24, 2012 - 04:31 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 04:19 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
| Oh. Did you try to build the code that you sent us? Did you put it in a separate folder and try to build it from there? That will show you what we are seeing. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 04:26 PM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
I donwloaded the archive. My ZIP viewer sees THREE files that have a name equal to or close to registers.h
there are:
Code:
Firmware/AppMaster/_registers.h 112,459 bytes
Firmware/AppMaster/registers.h 133,605 bytes
Firmware/ApmLib/registers.h 201,801 bytes
How extraordinarily confusing ! |
_________________
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 04:41 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
Just another note, Larrydew. You might think that having the correct header file (i.e. .../ApmLib/registers.h) in the Solution Explorer tree to the right will direct the compiler so that it is that file that is included. It does not. In fact, for building purposes there is no reason at all to add header files to the Solution Explorer. The include is governed completely by
i) the #include directives in the source, and
ii) the implied (or should that be "implicit"?) include search paths that the toolchain has, and
iii) the explicit include paths that are given in the project setup.
The include mechanism also varies in behaviour depending on if you use "" or <> in the #include directives. Ground rule of thumb is: Use <> for system includes and "" for includes of project-local header files. Note "rule of thumb" - the key to all this is to atually know and understand how it works. Any good GCC docuentation/tutorial/whatever will sort this out for you. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 05:03 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
And now for the "declared but never defined" errors...
I stay with the config.c file as the working example:
The first such error when I compile config.c is re the SetBreakerSaveConfigBit function. There is a prototype declared in the file .../ApmLib/registers.h, but there is no implementation of it in config.c . So the error message is correct. I do not know how you avoided that error when using AVR Stusio 4 (two possible hypothesis: One that that version of the toolchain nactually did not generate the error. The other is that you used the "whole program" switch to actually compile all source files as one compilation unit).
Anyhow you have this error now, it is a correctly issued error message and you have some cleaning up to do.
Background:
There is a principal difference in how a C tool chain handles non-inlined and inlined functions.
For non-inlined functions the compiler generates code for the function and leaves it to the linker to resolve calls to it. The compiler does not care if it sees a prototypethat has no implementation. In fact, this is a normal situation - prototypes needs to be seen before calls and it is quite common that the implementation is in a source file different from the source file with the call.
For inlined functions the compiler produces inlined assembler code and leaves nothing to the linker to resolve. This also means that you can not have an implementation (definition) of an inlined function in one C source file and call it from another C source file. The compiler will not have generated a standalone assembler version of the function, it's name and relocatable address is not in any symbol/map table etc. Thus, if a inline funtion prototype is seen but the implementation isn't seen this is not a normal situation. In fact the implementation must be seen in the same "compilation unit" (i.e. the single C source file with all #includes done).
What you are seeing now is a version of the compiler that is saying "Hey I saw a prototype of this inlined function but never sw any implementation" so there might be something fishy here. No, the compiler is not smart enough to see that you never actually call SetBreakerSaveConfigBit() in config.c, and that the situation thus is benign.
Advice:
1) Consider reworking the code so that you have header file contents separated in a way that you do not do un-necessary includes of e.g. inline function declarations. If config.c does not contain a call to an inlined function SetBreakerSaveConfigBit() it should not see any protoype of it.
2) If this is totally un-acceptable then you could consider rolling back to the tool chain you used in AR Stuio 4.18. You can still use Atmel Studio 6, and just point to other tool chain instances (IIRC you just need to point to the desired instance of avr-gc.exe and make.exe).
3) In any case you should clean up your project filewise. You definitively have a problem with duplicated filenames for header files. It hit me while investigating. It might not, by some phase-of-the-moon-like situation have hit you. Yet... It almost certainly will, at some point in time. This might be the day before your next release. Fix it now.
4) While there might be a way to just shut off the error message (e.g. is this a tool chain that is modern enough to support all that fancy pragma stuff) burt I strongly advice against that. It would be to just hide the actual problem under the carpet, and when you do such a manouvre you always risk missing out on a genuine and important issue of that error message. Fix the core problem. Don't just paint over the rust - remove it. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 06:21 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
|
larryvc wrote:
OK. Do this:
Back up your project to a safe location before continuing. You take all risk for this on your own!!!
1. Clean Solution
2. Remove All the files in the Solution Explorer that are below "Output Files" except main.c. "Remove" not "Delete".
3. Rebuild Solution.
At this time you will have 27 errors due to these three lines in leds.h:
Code:
ASSIGN_PIN(STATUS, D, 5); /* LED */
ASSIGN_PIN(COMM_TX,D, 6); /* LED */
ASSIGN_PIN(PWR_OK, D, 7); /* LED */
Which lead to this in gpio.h:
Code:
#define ASSIGN_PIN(name, port, bit) \
INLINE void GPIO_##name##_set() {PORT##port |= (1 << bit);} \
INLINE void GPIO_##name##_clr() {PORT##port &= ~(1 << bit);} \
INLINE byte GPIO_##name##_read() {return (PIN##port & (1 << bit)) != 0;} \
INLINE byte GPIO_##name##_state() {return (DDR##port & (1 << bit)) != 0;} \
INLINE void GPIO_##name##_make_out() {DDR##port |= (1 << bit);} \
INLINE void GPIO_##name##_make_out_set(){PORT##port |= (1 << bit); DDR##port |= (1 << bit);} \
INLINE void GPIO_##name##_make_in() {DDR##port &= ~(1 << bit); PORT##port |= (1 << bit);} \
INLINE void GPIO_##name##_make_pullup() {PORT##port |= (1 << bit);}\
INLINE void GPIO_##name##_toggle() {PORT##port ^= (1 << bit);}
4. Comment the 3 lines out temporarily and Rebuild Solution.
At this time you will have 2 errors in main. You will also have 32 warnings.
5. Go back and uncomment the lines in leds.h and fix the errors there and in main. Read and heed the warnings.
This project needs some serious rethinking IMO.
HTH Good Luck
EDIT: Added clarification details.
Code:
===================================================================================================
Thanks for your comments. I followed your instructions and I get 2 errors that make sense since the master.c file is not included in the project.
Error 33 undefined reference to `InitMaster' D:\ArcLight\APM Second Generation\Firmware\ApmMaster\default/.././Main.c 32 1 ApmMaster
and
Error 34 undefined reference to `MasterMain' D:\ArcLight\APM Second Generation\Firmware\ApmMaster\default/.././Main.c 33 1 ApmMaster
I get 32 warnings with the verbage:
Warning 1 inline function 'ClearUsbXmtBuffer' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\usb.h 25 13 ApmMaster
Warning 2 inline function 'SetBreakerSaveConfigBit' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\ApmRegisters.h 3238 13 ApmMaster
Warning 3 inline function 'ClearBreakerSaveConfigBit' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\ApmRegisters.h 3237 13 ApmMaster
Warning 4 inline function 'WriteBreakerStateBit' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\ApmRegisters.h 3236 13 ApmMaster
Warning 5 inline function 'WriteBreakerFailedClosedBit' declared but never defined [enabled by default] D:\ArcLight\APM Second Generation\Firmware\ApmLib\ApmRegisters.h 3235 13 ApmMaster
There is no error/warnings referenced to the leds.h file or the gpio.h file as you indicate. My project is just the main.c file and the h files included in the main.c file. It appears there is something wrong with my IDE environment not my files?
I truly do appreciate your help, but this is becoming very frustrating to me, you say my project is a mess however I believe it to be very structured. I need to share a number of file between 5 different projects and have grouped the files accordingly. Therefore I am using links to include files into the project instead of copies of each file into each project and only the unique files are located in the project respective directory. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 06:58 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
|
JohanEkdahl wrote:
Quote:
If you look at the name of the registers.h file in the ApmMaster directory you will see that is really _registers.h and the name of the file in the ApmLib directory is registers.h.
No, you take a good look at what you have. You will find that in the ApmMaster directoy there is a file registers.h. Now take a look in the ApmLib directory and find an identically named file. Those files are not identical regarding content though. (This is part of the mess I still argue is in this project.) Yes, I did see the _registers.h file, and yes I concluded that it has nothing to do with the problem.
Quote:
All of the inline declarations and implimentations are being ignored and there are no other errors or warnings.
I did a clean of the whole project and a build and I get several errors for things like NODE_1_REGISTER being undefined. So I do not think that "no other errors or warnings" holds. Those defs are in one of the header files registers.h, but not in the other. You will also note if you look at your error messages for the inline functions that the messages point to the file registers.h .
My hypothesis is still that part of the problem is that "the inline declarations" that you are looking at is not the ones pulled in by the compiler.
If you switch to the Output tab afer your failed build you will see the complete name of tHe header file, and in my case it is
..../ApmMaster/registers.h
that is included. You claim that that file does not even exist. It is also illuminating that that file (in the ApmMaster directory) does lack the define of e.g. NODE_1_REGISTER while the other registers.h (in the ApmLib directoy) has that define.
Now... I spent serious time analyzing your problem to this point, and I still think that a cause for a lot of your build errors are due to wrong header files being included. Please honour the time I spent for you by actually checking if what I say holds on your hard disk too.
I do not think there is a simple project setting that will make your problems go away. You need to realize that this mess needs cleaning up. Even if you find a setting that makes your current problems go away you will be hit again by the mess at some point. My advice it to clean it up now.
I have deleted all register.h files from my directories and renamed the remaining register files to ApmRegister.x. The file that did not have the NODE_1_REGISTER was clearly named _register.h. If the leading underbar is being ignored by the compiler shame on it. No where is _register.h included in the project except for being a file in the ApmMaster directory. Following the advice of another I removed all C files except main and its include H files and the problem still exits.
I have done everything you have asked and you are focused on something that does not exist. THERE IS NO REGISTERS.H file in the ApmMaster directory there never was so delete the file from you directory and get on with trying to determine the underlying problem. The complier says the inline functions are being declared but not defined and the linker says they are undefined but the .O exist for each file that they are define in. Could it be that my #define of inline....... is not being recognized by the compiler when the implementation of the function is being made? but the prototype is accepted? |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 07:44 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
|
larryvc wrote:
Did you try what I suggested? It is not the compiler, it is the way the project has been created in AS6.
Or perhaps what you have given us does not build the same as it does on your system.
Yes, I have done everything you have suggested. Please see my last posting. My environment does seem to be different than yours. I installed AS6 on Monday of this week and headed out for a trade show. I copied the files (directory structure) from my desktop which was working just fine (was AS6 beta) and nothing will compile correctly now on the laptop. Is there something wrong with my #define inline...... statement? |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 08:07 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
|
clawson wrote:
You define a macro with the upper case name "INLINE" but then never use it. The following functions are simply:
Code:
inline char BooleanToChar( _Bool value )
{
return ( ( value==1 ) ? '1': '0' );
}
using the standard C keyword. Did you mean to use:
Code:
INLINE char BooleanToChar( _Bool value )
{
return ( ( value==1 ) ? '1': '0' );
}
perhaps?
Did you even read this? Those warnings went away when I changed things. Quit blaming the compiler. Face the fact that it is your code that is incorrect. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 08:51 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
OK. After fixing all the above I am down to the 2 errors in main and 16 warnings about functions being declared but not defined.
Here is your definition of INLINE:
Code:
#define INLINE static inline __attribute__ ((always_inline))
So the key here is what Cliff said above. Change your functions that begin with "inline" to "INLINE". Do this in both the function declarations and the function definitions .
I think you are almost there. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 10:37 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
The problem you are having with these in leds.h
Code:
ASSIGN_PIN(STATUS, D, 5); /* LED */
ASSIGN_PIN(COMM_TX,D, 6); /* LED */
ASSIGN_PIN(PWR_OK, D, 7); /* LED */
is that you have already assigned them in gpio.h as
Code:
ASSIGN_PIN(STATUS, D, 7); /* LED */
ASSIGN_PIN(COMM_TX, D, 6); /* LED */
ASSIGN_PIN(PWR_OK, D, 5); /* LED */
|
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 10:40 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
|
Quote:
THERE IS NO REGISTERS.H file in the ApmMaster directory there never was so delete the file from you directory and get on with trying to determine the underlying problem.
I have not put it there. If you read one of Cliffs comments above he also sees a registers.h in the ApmMaster directory. If you have something else on your hard disk than what you zipped up and attached here then this whole exercise has really been a waste of everybody's time. How about you downloading the ZIP file you uploaded, and unzip it in a temporary directory and see if it is there.
For the time being I will not waste more of my time on this ghost-hunt. I'm out. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 11:18 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
|
JohanEkdahl wrote:
Advice:
1) Consider reworking the code so that you have header file contents separated in a way that you do not do un-necessary includes of e.g. inline function declarations. If config.c does not contain a call to an inlined function SetBreakerSaveConfigBit() it should not see any protoype of it.
2) If this is totally un-acceptable then you could consider rolling back to the tool chain you used in AR Stuio 4.18. You can still use Atmel Studio 6, and just point to other tool chain instances (IIRC you just need to point to the desired instance of avr-gc.exe and make.exe).
3) In any case you should clean up your project filewise. You definitively have a problem with duplicated filenames for header files. It hit me while investigating. It might not, by some phase-of-the-moon-like situation have hit you. Yet... It almost certainly will, at some point in time. This might be the day before your next release. Fix it now.
4) While there might be a way to just shut off the error message (e.g. is this a tool chain that is modern enough to support all that fancy pragma stuff) burt I strongly advice against that. It would be to just hide the actual problem under the carpet, and when you do such a manouvre you always risk missing out on a genuine and important issue of that error message. Fix the core problem. Don't just paint over the rust - remove it.
Heed this advice. The problem with having files, .h or .c, with the same names is that you do not know which one you are working with. What if you edit a file in one folder and the solution is looking at a file in another folder? |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
Last edited by larryvc on May 25, 2012 - 07:02 AM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: May 24, 2012 - 11:21 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
|
larryvc wrote:
Oh. Did you try to build the code that you sent us? Did you put it in a separate folder and try to build it from there? That will show you what we are seeing.
What Johan is talking about is what I asked you before. Maybe what you gave us is bogus.
I'm going to sit on the sidelines and wait this one out. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 04:15 AM |
|

Joined: May 22, 2012
Posts: 17
|
|
I have cleaned all files and removed all un-needed H file includes. I compiled each C file without errors, only the warnings that the inline function was defined but not implemented. I then built the solution and got 29 errors: inline functions were "undefined reference" and 300 warnings that the inline function was defined but not implemented and 4 warnings:
Warning 186 variable 'dummy' set but not used [-Wunused-but-set-variable] which makes sense.
I do not understand how the .O files compiled but the inline functions aren't linked in. I have attached the current directory structure that I built with. Please review and comment. |
|
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 06:07 AM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
No time to d/l your new ZIP now. Maybe tonight (I'm at GMT + 2
Quote:
I do not understand how the .O files compiled but the inline functions aren't linked in.
Reread what I wrote above. Inline functions are not handled by the linker ever. They are handled completely by the compiler.
Is this just an unfortunate formulation, or are you actually expecting that you can call an inline function implemented in one .c file from another .c file? If the latter this is simply not possible. |
|
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 03:53 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
| In what C universe is an inline function only visible within the C file it is created? This code compiled and ran under AS4 and AS6beta correctly. Something changed in the implementation of AS601843. I am using inline code within utility files to eliminate the call overhead to functions that are called so the the code is easy to read and yet very fast. If you are telling me that C no longer supports this concept I am very disappointed. Sorry to have bothered you with this issue but the inline functions should be linked in statically by the linker not the compiler. |
|
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 03:58 PM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
In what C universe is an inline function only visible within the C file it is created?
Every universe - even on the planes in parallel dimensions.
inline means "take the source that follows and plonk it (without a CALL/RET overhead) at the point of invocation". Clearly as it's just a few instructions put in the middle of the body of another function it is not callable as an individual entity.
Perhaps time to get yourself a book about programming in C?
Quote:
but the inline functions should be linked in statically by the linker not the compiler.
BTW that is jibberish - you clearly have not understood the concept of "inline" as there's no "linking" involved. (just think about the word itself for a few seconds!). "inline" really means "behave as if I typed those few lines above here at the point where I invoke the function". No "linking" ivolved in that - this happens at compiler time, not link time. The linker (even the assembler) are not aware that such a multi-line text substitution have occurred.
EDIT: OK here's a quick example, first a small function that is deliberately not inlined (I had to force this because GCC is aggressive about inlining when it can):
Code:
__attribute__((noinline)) void setB(unsigned char n) {
PORTB = n;
}
int main(void) {
setB(23);
}
this generates:
Code:
00000092 <setB>:
#include <avr/io.h>
__attribute__((noinline)) void setB(unsigned char n) {
PORTB = n;
92: 88 bb out 0x18, r24 ; 24
}
94: 08 95 ret
00000096 <main>:
int main(void) {
setB(23);
96: 87 e1 ldi r24, 0x17 ; 23
98: 0e 94 49 00 call 0x92 ; 0x92 <setB>
9c: 80 e0 ldi r24, 0x00 ; 0
9e: 90 e0 ldi r25, 0x00 ; 0
a0: 08 95 ret
Now a version which forces inlining:
Code:
__attribute__((always_inline)) inline void setB(unsigned char n) {
PORTB = n;
}
int main(void) {
setB(23);
}
which generates:
Code:
00000092 <main>:
#include <avr/io.h>
__attribute__((always_inline)) inline void setB(unsigned char n) {
PORTB = n;
92: 87 e1 ldi r24, 0x17 ; 23
94: 88 bb out 0x18, r24 ; 24
}
int main(void) {
setB(23);
96: 80 e0 ldi r24, 0x00 ; 0
98: 90 e0 ldi r25, 0x00 ; 0
9a: 08 95 ret
The generated code simply does not contain a callable copy of setB() and the code of the function is just "plonked" into the body of main(). What's more if I use it a few times:
Code:
int main(void) {
setB(23);
setB(51);
setB(89);
setB(107);
}
the generated code is:
Code:
00000092 <main>:
#include <avr/io.h>
__attribute__((always_inline)) inline void setB(unsigned char n) {
PORTB = n;
92: 87 e1 ldi r24, 0x17 ; 23
94: 88 bb out 0x18, r24 ; 24
96: 83 e3 ldi r24, 0x33 ; 51
98: 88 bb out 0x18, r24 ; 24
9a: 89 e5 ldi r24, 0x59 ; 89
9c: 88 bb out 0x18, r24 ; 24
9e: 8b e6 ldi r24, 0x6B ; 107
a0: 88 bb out 0x18, r24 ; 24
int main(void) {
setB(23);
setB(51);
setB(89);
setB(107);
a2: 80 e0 ldi r24, 0x00 ; 0
a4: 90 e0 ldi r25, 0x00 ; 0
a6: 08 95 ret
No sign of any callable copies there, as expected the four invocations have each just added two opcodes to main().
In essence my setB() function is very similar to the situation where I might have used a macro:
Code:
#define SETB(n) PORTB = n
int main(void) {
SETB(23);
SETB(51);
SETB(89);
SETB(107);
}
which generates (the identical):
Code:
00000092 <main>:
}
#define SETB(n) PORTB = n
int main(void) {
SETB(23);
92: 87 e1 ldi r24, 0x17 ; 23
94: 88 bb out 0x18, r24 ; 24
SETB(51);
96: 83 e3 ldi r24, 0x33 ; 51
98: 88 bb out 0x18, r24 ; 24
SETB(89);
9a: 89 e5 ldi r24, 0x59 ; 89
9c: 88 bb out 0x18, r24 ; 24
SETB(107);
9e: 8b e6 ldi r24, 0x6B ; 107
a0: 88 bb out 0x18, r24 ; 24
}
a2: 80 e0 ldi r24, 0x00 ; 0
a4: 90 e0 ldi r25, 0x00 ; 0
a6: 08 95 ret
The difference being that types are checked for the C function but not a macro. It's for this reason that many people prefer to put (inline) functions in a .h file where a macro might previously have been considered (especially true for C++ where type checking is stronger). |
_________________
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 04:58 PM |
|


Joined: Mar 27, 2002
Posts: 18555
Location: Lund, Sweden
|
|
|
Quote:
In what C universe is an inline function only visible within the C file it is created?
I can not vouch for Cliffs claim of every universe, but for sure it holds in this universe.
The whole idea with inlined functions is "Do not create a separate callavle entity of code for this. Instead insert the machine code needed in any place where the source code contains a call to the function".
It follows from this that the thing is done entirely by the compiler. Linker is never involved, linker never even sees that there was inlining going on.
Quote:
the inline functions should be linked in statically by the linker not the compiler
You have a clear misconception when it comes to inlined functions in C.
I have no definitive idea about how this actually compiled in AS4. I can speculate, but what good will this do? Who was it that said "get on with trying to determine the underlying problem".
Oh ok, here is one possible scenario: Inlining did actually not take place. You thought that it was but the functions where actually compiled as ordinary, linkable, functions. This would be so e.g. if there was a macro "INLINE" (or "inline") that expanded to nothing. No, I'm not saying this was it. I am demonstrating an example that shows it is not impossible that inlining did not take place. It is the person questioning everything we say here. If you know that you are right and we are wrong, why ask anything here?
Since I am in your eyes wrong in what I say, despite that I have tried to be detailed in technical explanations, I can see nothing less fulfilling for anyone of us than me staying here. Still, I wish you the best of luck with this.
Now I am definitively out. |
|
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 05:21 PM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
Oh ok, here is one possible scenario: Inlining did actually not take place.
I wondered about this but try as I might both in AS4+old avr-gcc and AS6+new avr-gcc I cannot get anything using the "inline" keyword to also generate a callable, stand alone copy too. The converse is (and pretty much always has been) true. If you don't use "inline" at all then GCC is pretty aggressive about inlining anyway. So using AS4 or AS6 if I write:
Code:
void setB(char n) {
PORTB = n;
}
int main(void) {
setB(37);
}
then I get (AS4):
Code:
0000006c <setB>:
#include <avr/io.h>
void setB(char n) {
PORTB = n;
6c: 88 bb out 0x18, r24 ; 24
}
6e: 08 95 ret
00000070 <main>:
#include <avr/io.h>
void setB(char n) {
PORTB = n;
70: 85 e2 ldi r24, 0x25 ; 37
72: 88 bb out 0x18, r24 ; 24
}
int main(void) {
setB(37);
}
74: 80 e0 ldi r24, 0x00 ; 0
76: 90 e0 ldi r25, 0x00 ; 0
78: 08 95 ret
and AS6:
Code:
00000092 <setB>:
#include <avr/io.h>
void setB(char n) {
PORTB = n;
92: 88 bb out 0x18, r24 ; 24
}
94: 08 95 ret
00000096 <main>:
int main(void) {
setB(37);
96: 85 e2 ldi r24, 0x25 ; 37
98: 0e 94 49 00 call 0x92 ; 0x92 <setB>
}
9c: 80 e0 ldi r24, 0x00 ; 0
9e: 90 e0 ldi r25, 0x00 ; 0
a0: 08 95 ret
Interestingly AS4 was more aggressive about inlining it than AS6 is! In both cases, as expected, a callable copy that could be linked to and reached from a different .c was generated.
There's clearly a change in behaviour here but it's just that something I never actually asked for now isn't happening in the later avr-gcc contained in AS6. |
_________________
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 06:01 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
Larrydew,
It is frustrating to see that 90+ man years* of experience is being questioned here.
I have a possible fix for you that some may find questionable but it does work. If you move the inline function definitions into the header files that have the corresponding function declaration then other modules will see them. See this:
http://embeddedgurus.com/barr-code/2011 ... der-files/
You will also have to define SwapStringBytes as inline and also move it into the header file for this to work.
After doing this with your latest posted project I was able to get down to 5 errors and 4 warnings.
Code:
Warning 1 variable 'dummy' set but not used [-Wunused-but-set-variable]
Warning 2 variable 'dummy' set but not used [-Wunused-but-set-variable]
Warning 3 variable 'dummy' set but not used [-Wunused-but-set-variable]
Warning 4 variable 'dummy' set but not used [-Wunused-but-set-variable]
Error 5 undefined reference to `OpenCloseTimer'
Error 6 undefined reference to `BreakerOperating'
Error 7 undefined reference to `OpenCloseTimer'
Error 8 undefined reference to `BreakerOperating'
Error 9 undefined reference to `InitCommAdapter'
What file contains the code for the undefined references?
Truthfully, I have spent a lot of time looking at this project, probably more than I should have, and I think you should seriously consider doing a very thorough clean up of the code and structure.
One more question, why do you need to define all of those functions as inline? The compiler, as Cliff mentioned, is very good at optimizing the code anyway.
I know I am going to be chastised for suggesting this method so I will go off and flog myself repeatedly all day today.
* 45 of those are Johan's.  |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
Last edited by larryvc on May 25, 2012 - 08:12 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: May 25, 2012 - 08:08 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
Ok.
You had this function misspelled: InitCommAdpter s/b InitCommAdapter.
Hmm, how did all of this work before?
I put in temporary fixes for the missing externs and now it builds correctly with only the 4 warnings about "dummy". |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 26, 2012 - 12:35 AM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
I did a test betweeen the modified project with inline and one with no inlines. This test was done with optimization set to -O1.
inlines:
Code:
Done executing task "RunCompilerTask".
Task "RunOutputFileVerifyTask"
Program Memory Usage : 51602 bytes 39.4 % Full
Data Memory Usage : 21954 bytes 33.8 % Full
EEPROM Memory Usage : 1919 bytes 46.9 % Full
no inlines:
Code:
Done executing task "RunCompilerTask".
Task "RunOutputFileVerifyTask"
Program Memory Usage : 51672 bytes 39.4 % Full
Data Memory Usage : 21954 bytes 33.8 % Full
EEPROM Memory Usage : 1919 bytes 46.9 % Full
Wow! 70 bytes.
Optimization set to -Os gave 48600 bytes vs 48656 bytes.
If you want the cleaned up no inline version just ask.
Code:
==================================================================================
|
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: May 31, 2012 - 10:36 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
| I resolved my problems by eliminating all of the inline functions calls across modules. However when I turn off optomization (none -O0) the compiler chokes on an inline function that is declared/implimented in the same module.
Code:
/**********************************************************************************
**
** Function inline void EEPROM_Wait( void )
**
** Return: void
**
** Purpose: Wait for the Write Cycle to complete
** First wait for the write cycle to begin
** then wait for it to complete.
**
**********************************************************************************/
inline void EEPROM_Wait( void )
{
while ( EECR & (1<<EEPE)); // wait here until done
}
/**********************************************************************************
**
** Function void EEPROM_Write( uint16_t addr, byte data )
**
** Return: void
**
** Purpose: Helper function to actually write the uint16_t data into the EEPROM
**
**********************************************************************************/
void EEPROM_Write( uint16_t addr, byte data )
{
EEPROM_Wait();
EEAR = addr;
EEDR = data;
CS_ENTER;
EECR |= (1<<EEMPE); // write logical 1 to EEMPE
EECR |= (1<<EEPE); // start the eeprom write
CS_LEAVE;
}
The error is
Code:
undefined reference to " EEPROM_Write"
Any new Ideas? |
|
|
| |
|
|
|
|
|
Posted: May 31, 2012 - 11:59 PM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
I don't know why you are receiving that error. Does seem odd though. If you would like me to take another look at the code attach it.
Did you see my last post? Get rid of all the inlines in your program and you won't have any errors. The compiler is inlining for you in almost all of the cases that have optimization enabled. Give it a try and you will be able to move forward with your work.  |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: Jun 01, 2012 - 05:31 AM |
|


Joined: Mar 01, 2001
Posts: 4953
Location: Rocky Mountains
|
|
| And IIRC, avr-libc already has EEPROM functions. So why is the wheel being reinvented?... |
_________________ Eric Weddington
Marketing Manager
Open Source & Community
Atmel
|
| |
|
|
|
|
|
Posted: Jun 01, 2012 - 06:49 AM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
|
Larrydew wrote:
The error is
Code:
undefined reference to " EEPROM_Write"
Are you sure that is the error message you received? EEPROM_Write is not defined as inline. |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: Jun 01, 2012 - 09:35 AM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
"undefined reference" is a link error meaning "I took all the .o files that were presented, at least one calls a function called EEPROM_Write() but amongst all the .o files I cannot find one that actually provides this function". This is usually because the .c file that provides EEPROM_Write() is not listed in the list of files to compile.
Like Eric I wonder why you are writing EEPROM functions when the (tried and tested) functions in AVR-LIbC are available:
http://www.nongnu.org/avr-libc/user-man ... eprom.html |
_________________
|
| |
|
|
|
|
|
Posted: Jun 01, 2012 - 02:46 PM |
|

Joined: May 22, 2012
Posts: 17
|
|
I apologize for a miss type in the error message, it should be EEPROM_Wait not EEPROM_Write, however you all seem to be missing the point. Yes, I read your earlier post and I did remove the inline directive from all files (making them standard functions) where the functions were called from outside modules, This cleared the errors as long as -O0 was not used. I know that the eeprom functions exists and I have a reason to write some of my own. That said I assure you that my eeprom.c file is in the compile list. I know this because I stated that when the project optimization is set above -O0 every thing compiles and links and runs, however when only the optimization is set to -O0 do I get the errors. The code snippet I included with my last post was copied directly from the file. The declaration and implementation of EEPROM_Wait() is before the call to the function and therefore the compiler/should either directly include the code inline or create a non-inline function in the object file and link it in as such. The research I have done indicates that the compiler should try to optimize the "inline" code regardless of the optimization level (since the directive inline means optimize this code block) or simple ignore the inline directive quietly without in-lining. This version of the compiler does not seem to be following the GNU C compiler specification. All of this code compiled and ran under the AVR4 IDE and generated inline code regardless of the -Ox setting.
Again I apologize for the typo with the error message and the confusion it caused. |
|
|
| |
|
|
|
|
|
Posted: Jun 01, 2012 - 02:55 PM |
|


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
This version of the compiler does not seem to be following the GNU C compiler specification.
In what sense. By the way if you want optimization but don't want the compiler to inline small functions then us -fno-inline-small-functions to persuaded it not to.
As I still haven't got the first idea what you are really complaining about here I wonder if you could put together a set of (minimal!) project files that exhibit the issue you are seeing? |
_________________
|
| |
|
|
|
|
|