Split from: How to import libraries into my project in Atmel Studio 7?

Go To Last Post
34 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Folks,

 

If you don't mind me joining this thread, I would like your help on a similar issue.

I clicked on 'Libraries'->Add Library->Browse Libraries. Atmel sees the library project in the solution. All is good, the library shows up in the main project. By the way, I am NOT trying to include the Arduino libraries.

Unfortunately, I don't know how to call it in "main.c". I tried #include <ADC>, #include <ADC.h> (there is no .h file), #include <ADC.a> (there is a .a file), #include "ADC.h" and other variations. As you have guessed, none worked.

 

The Output gives this if there is no include:
implicit declaration of function 'initADC' [-Wimplicit-function-declaration]

 

And this for each flavor of #include I tried (#include <ADC> in that case):
recipe for target 'main.o' failed    ArduinoRobot
ADC: No such file or directory    ArduinoRobot

 

Did I miss any steps ? What am I doing wrong ?

 

Regards,

 

 

This topic has a solution.
Last Edited: Fri. Dec 15, 2017 - 02:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
there is no .h file

You need[1] a .h file!

 

If you haven't got one, then you haven't got a complete, usable library!

 

You need to go back to the author or source where you obtained this, and request it.

 

So this is not related to the original question.

 

 

EDIT

 

[1] OK, so you could create one yourself; but then you would need a complete specification of all the required declarations, etc - which would be the content of the .h file anyhow.

It makes to no sense to provide a library without a header.

 

 

EDIT 2

 

Was originally tagged onto the end of http://www.avrfreaks.net/forum/how-import-libraries-my-project-atmel-studio-7

 

EDIT 3

 

typo - "it makes no sense..."

Last Edited: Fri. Dec 15, 2017 - 10:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
 I am NOT trying to include the Arduino libraries.

But Porkipic also wrote:
 recipe for target 'main.o' failed    ArduinoRobot
ADC: No such file or directory    ArduinoRobot

 

So NOT including Arduino libraries, but it IS called "ArduinoRobot" ?

 

Some background would be helpful to know how you got to this point.

 

What is this "ADC kibrary" that you're trying to use?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
I clicked on 'Libraries'->Add Library->Browse Libraries.
Let's just be clear what a "library" is and what a library isn't. That Libraries->Add Library->Browse you talk about is ONLY for the use of compiled static binary libraries. That would be when someone has given you something like libADC.a and ADC.h. The libADC.a is the static library that can be added using that "browse" option. If what you really have is ADC.c (or perhaps ADC.cpp) and also ADC.h then that is not a "library". That's just some additional source files to be added to your project. If you have those then Libraries->Add Library is of NO relevance here.

 

So do you really have a libSOMETHING.a file ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good point, but

Porkipic wrote:
 (there is a .a file)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah good point. In which case, as you say a .a file without a .h is like a car without petrol. Pretty useless!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Awneil and Clawson,

 

Thank you for your responses.

 

ArduinoRobot is just the name of the project. It is called that way because I am using an Arduino board, but I am trying to move away from the Arduino IDE. It should not really matter in this problem, I think.

I created the "ADC library" in the same solution as the main program for the robot. It is not a library found somewhere on the web.

The folder structure is the following:

Solution: ArduinoRobot

      |

      |-> Project: ADC

      |-> Project: MainProgram

 

So there is ONLY a libADC.a file in the Output file of the ADC project. Building the complete solution does not generate a libADC.h file (or whatever the naming convention is).

It feels strange to be able to add the ADC library in the MainProgram project even if the library is missing a (mandatory ?) .h file and that building the solution does not generate one or gives a error at least.

Do I need to create the .h file manually ? Is there something to add in the linker ?

 

My understanding of libraries in Atmel Studio is the following:

  • Toolchain libraries are generic ones that could be used for multiple projects (ADC should be this type, but I did not created it that way for some reason). I did not explore this route, but maybe I should.
  • Project libraries are project specific (mostly functions doing a specific job) that come precompiled (and IDE dependent ?).
  • External "libraries" (a collection of uncompiled .h and .c files) are there to use existing "libraries" that are IDE independent.

Am I correct in my assumptions ?

 

Regards,

Last Edited: Fri. Dec 15, 2017 - 02:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
Do I need to create the .h file manually ?
awneil wrote:
You need to go back to the author or source where you obtained this, and request it.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi theush,

 

As I am the author, that means I have to create it manually.

 

Thanks for your response.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
ArduinoRobot is just the name of the project. It is called that way because I am using an Arduino board, but I am trying to move away from the Arduino IDE. It should not really matter in this problem, I think.

OK, I see.

 

I created the "ADC library"

So, in that case, you need to create the header to go with it!

 

Building the complete solution does not generate a libADC.h file

No, of course it doesn't - as above, it is something you need to do.

 

Exactly as if you had just written a .c file - you'd write a corresponding .h file for the symbols it "shares"

 

In fact, what is the point of a library anyhow - why not just include the source in your project?

 

Do I need to create the .h file manually ?

Yes.

 

Is there something to add in the linker ?

Adding the library (the .a) to the Project should take care of that.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wrote:
Exactly as if you had just written a .c file - you'd write a corresponding .h file for the symbols it "shares"

 

http://www.avrfreaks.net/comment...

 

http://www.avrfreaks.net/comment...

 

http://www.avrfreaks.net/comment...

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Awneil, this is way clearer now.

 

In fact, what is the point of a library anyhow - why not just include the source in your project?

Readability of MainProgram, reusability of the library, mostly. One could argue that having .c and .h files instead of a library project achieves the same goal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
 reusability of the library

Cliff will be along shortly to point out that this doesn't really work in this field...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
reusability of the library, mostly.
Not really on AVR. If you switch to another model of AVR (even just a jump in memory size in the same "family") you have to recompile so a precompiled binary is of no use. The other reason folks used to use static libs was that you could compile each function in a separate source file then put all the .o files together in a .a libray. Then when you linked with such a library the linker only pulled out the members that were actually used. But these days you can achieve all that by just compiling all the source with -ffunction-sections and then link with -gc-sections and only the "used" functions remain anyway.

 

I'd just make a "filter group" and put your adc.c and adc.h in there if you want it "separate" in some way from the other "modules".

 

But as for .h, yeah you need one. Your lbadc.a might well have ADC_init() and ADC_read() but how is the calling code going to know how to invoke that without a .h to document the functions? Presumably ADC_init() is simply "void ADC_init(void);" but what about ADC_read? I'm guessing something like "uint16_t ADC_read(uint8_t chan_num);" or something like that? Without a .h how would the calling code know to pass in a uint8_t and expect a uint16_t as a return?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, that may explain why nobody is using the precompiled libraries. I was surprised that even the Atmel tutorials used "copy and paste" .c and .h files.

 

But these days you can achieve all that by just compiling all the source with -ffunction-sections and then link with -gc-sections and only the "used" functions remain anyway.

I will have to look into this in the avr-gcc documentation. No clue what the -ffunction-sections and -gc-sections arguments are.

 

how is the calling code going to know how to invoke that without a .h to document the functions?

The magic of Christmas spirit cheeky. I though that the IDE had some hidden way to do it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
I will have to look into this in the avr-gcc documentation. No clue what the -ffunction-sections and -gc-sections arguments are
AS7 has these enabled by default anyway. -function-sections (and its friend -fdata-sections) puts each function and each data object in a separate named section. At link time the linker keeps track of references to each section. If it is invoked with -gc-sections ("garbage collect sections"), and it is in AS7, then it discards and function or data sections that have no references. So a function that is not called or a data object that is not referenced will be discarded (and listed in the .map file section of discards).
Porkipic wrote:
I though that the IDE had some hidden way to do it.
Have you used Arduino by any chance? It does that kind of thing (and trains programmers into bad habits because of it!).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
One could argue that having .c and .h files instead of a library project achieves the same goal.

Yes, definitively.

 

Porkipic wrote:
Quote:
But these days you can achieve all that by just compiling all the source with -ffunction-sections and then link with -gc-sections and only the "used" functions remain anyway.

 

I will have to look into this in the avr-gcc documentation. No clue what the -ffunction-sections and -gc-sections arguments are.

 

Essentially this:

 

-ffunction-sections tells the compiler to put each function into its own unique section.

 

-gc-sections tells the linker to throw out any unused (un-referenced) sections. ("gc" for "Garbage Collect".)

 

It all boils down to only the functions actually used going into the binary executable.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
 No clue what the -ffunction-sections and -gc-sections arguments are.

the key when googling such things is to either omit the leading "-", or to put the whole thing in quotes.

 

(because google takes "-" prefixed to a search term to mean exclude that term)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you used Arduino by any chance?

I did, sir. And I am sorry ! 

 

After some coding on libraries, I realized that doing ADC with ISR in a library is a nightmare. I now understand why the Arduino libraries are blocking. It seems impossible to do non-blocking libraries containing ISRs.

So ... back to the drawing board, I guess.

 

@ JohanEkdahl: Thanks for the explanations

@ awneil: Thanks for the tip

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, not back to the drawing board - you just don't bother with separately building it as a library.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Coding for uC needs different habits that coding for computers.

I tried to have a 100% self contained piece of code performing ADC with ISR. But it looks like this is not the way to go:

  • Atmel Studio libraries: not useful if the uC changes.
  • .c & .h collections: blocking.
  • Copy & paste pre-made code: not 100% self-contained (program loop should check flags set by ISRs).

 

It was surprising to find very little resources about Atmel libraries and .c & .h collections were all blocking as soon as ISR were involved. I understand why, now.

 

Thanks guys for all your help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
.c & .h collections: blocking.

There is no reason why they have to be blocking.

 

  • Copy & paste pre-made code: not 100% self-contained (program loop should check flags set by ISRs).

I don't see what you mean by "not 100% self-contained" there?

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is no reason why they have to be blocking.

I don't see any way to have the main loop check a flag (isADCComplete for example) because the code for that is in the main program, but the variable isADCComplete is declared in the library. I would like to avoid declaring EXTERN variables.

How can I move the isADCComplete flag to the main program ?

//////////////////////////////////////Main program code
main (){
    int ADCVAlue = readADC(ADC0);
}
//////////////////////////////////////////////Library code
int isADCComplete = 0;              <----------- Declared in library and not available to the main loop for check.

int readADC(channel){
    int result = 0;
    Set registers to configure and start ADC;
    while (!isADCComplete){         <----------- Have to stay within library code to check the flag.
    }                                            If main program could perform this, it would solve the problem
    return result = ADCH and ADCL registers;
}

ISR(ADC_vect){
    isADCComplete = 1;
}

I don't see what you mean by "not 100% self-contained" there?

Basically the main loop has to know the name of the flag to check (isADCComplete). So if I copy/paste that ADC code, I have to make sure that the main loop checks "isADCComplete" and not "ADCFinished", for example.

Maybe pointers can help here. I am not sure if this would be good coding practice and I do not understand pointers well enough to see if that could help in any way.

Last Edited: Fri. Dec 15, 2017 - 08:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Typically you would declare/define getters and setters.

Perhaps something like:

// in .h file
int get_isADCComplete(void);

// in .c file
int get_isADCComplete(void) {
    return isADCComplete;
}

Edit: the function can incorporate any requirements necessary to insure the value returned is valid (e.g. if ATOMIC access is required, or special read sequencing, ...)

Edit2: since isADCComplete is used both inside and outside the ISR, it should be declared as volatile.

David (aka frog_jr)

Last Edited: Fri. Dec 15, 2017 - 08:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
I would like to avoid declaring EXTERN variables. How can I move the isADCComplete flag to the main program ?

You have two reasonable options:

 

1) Do the extern declaration (Not sure why you want to avoid it. With a good design you can keep the number of extern variables at a minimum.)

 

2) Write a function residing in the ADC source file that returns the value of the complete flag. Let the code in main call that function to check the state of that flag.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
I have to make sure that the main loop checks "isADCComplete" and not "ADCFinished", for example.

Well, yes - of course.

 

That's bound to be the case whether you use .c and .h files or a true library.

 

It's the same for any API - you have to know what the API call is in order to "call" it!

 

As the others have said, you could have getters & setters - but you'd still need to know their names!

 

Even with pointers, you'd have to know what to point to.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Let the code in main ...

But OP doesn't want any "code in main", right?

Porkipic wrote:
I don't see what you mean by "not 100% self-contained" there? Basically the main loop has to know the name of the flag to check (isADCComplete). So if I copy/paste that ADC code, I have to make sure that the main loop checks "isADCComplete" and not "ADCFinished", for example.

 

I suppose if political-correctness is of paramount importance, one could translate each flag check (which takes a couple words of code and less than a microsecond) into a test function which takes several microseconds and more code words.  (Your toolchain will be able to inline all of these in a real/comprehensive app?  Some of my "important" app structures might have a dozen or more important status variables, and often a number of values for each.)

 

Anyway, if OP thinks the below is enough "self-contained", then make the tests into library "function calls" with fragments like

if (mylib_adc_has_completed() == MYTRUE)
    {
        ...
    }
...
if (mylib_adc_has_not_completed() == MYTRUE)
    {
        ...
    }

I can't see how it can be more "contained" than that.  After all, once the box is opened...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
But OP doesn't want any "code in main", right?

He wrote:

I don't see any way to have the main loop check a flag (isADCComplete for example) because the code for that is in the main program, but the variable isADCComplete is declared in the library.

Which I read ass he wants to somehow check the flag in main. "Doing something" in main implies code in main, right?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nobody's mentioned call-backs ...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys, you went way beyond my wildest expectations. Thank you for that.

A getter is perfectly fine with meI did not think about it, for some reason.

I have a bit of (rusty) programming background in Java, so having a EXTERN variable hanging in the code is not something I am used. Maybe it is the right thing to do with uC programming in C ! What do I know ? I am just starting with it.

 

Last question to settle everything: what is the best way to do it in terms of code cleanliness, best practices and code speed ?

  • extern variable (extern volatile would be more correct ?)
  • getter function

 

Again, thank you all for your help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Code cleanliness, best practices : opinous. You decide what you think ;-)
.
Code speed: Possibly extern variable but if the tool chain optimizes it by inlining then they might become equal.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
the code for that is in the main program,
Porkipic wrote:
I tried to have a 100% self contained piece of code performing ADC with ISR.
Porkipic wrote:
not 100% self-contained (program loop should check flags set by ISRs).

JohanEkdahl wrote:
"Doing something" in main implies code in main, right?

But see #23 and earlier -- my "no code in main" pharase was a summary.

Porkipic wrote:
the code for that is in the main program,
Porkipic wrote:
I tried to have a 100% self contained piece of code performing ADC with ISR.
Porkipic wrote:
not 100% self-contained (program loop should check flags set by ISRs).

 

But indeed, if you aren't going to do anything in main with status or value results -- then you must do it all in the ISR.  Does that make sense in any but a very isolated case?

 

As you said

JohanEkdahl wrote:
2) Write a function residing in the ADC source file that returns the value of the complete flag. Let the code in main call that function to check the state of that flag.

and I said

theusch wrote:
then make the tests into library "function calls" with fragments like

 

Reading more responses, I see OP finally acknowledged the approach.  Yet, I don't see the "ISR-code" only fixation for something like a peripheral driver.  Using the mentioned ADC as an example, how does the ADC get set up without "code in main" ?  How does one take action with ADC results without "code in main" ?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Code cleanliness, best practices : opinous. You decide what you think ;-)

I was expecting this answer to be honest.

 

Using the mentioned ADC as an example, how does the ADC get set up without "code in main" ?  How does one take action with ADC results without "code in main" ?

I was not clear here, sorry. The ADC will be setup with a initADC() function called from main, but the code for the function is in the library. Same with readADC and other functions that may be necessary.

Anyways setting a getter function will mean that the main code will still have to call the function, so why not go with an extern volatile variable exposed from the library to the main code.

 

Yet, I don't see the "ISR-code" only fixation

Probably due to Java, to be honest. I compared the library to a Java class where variables are never exposed. It would not be the job of the main code to check the status of a variable stored in a separate class.

I wanted to have the ISR driven equivalent of analogRead() available in the Arduino IDE. Now I understand why analogRead is build the way it is.

 

Alright folks, we can wrap up this topic. Unfortunately, you have been of tremendous help, so chances are I will bother you again with another problem in the future. cheeky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Porkipic wrote:
Anyways setting a getter function will mean that the main code will still have to call the function, so why not go with an extern volatile variable exposed from the library to the main code.

Duh.  Isn't that what you were objecting to?

 

I've lost track.  Are you talking of a true library?  And you want to do everything in the ISR?  But you >>will<< have an init function that is called from main() ?  But somehow that is not heretical, but other functions are -- setter; getter; other action?   Again continuing with AVR8, how will your true library handle using the correct vector for all models?

Porkipic wrote:
I wanted to have the ISR driven equivalent of analogRead() available in the Arduino IDE. Now I understand why analogRead is build the way it is.

???  Isn't that apples and oranges?  doesn't analogRead do a polled ADC operation? 

 

I give up.  Luckily,

Porkipic wrote:
we can wrap up this topic

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.