AVR Studio 5.1 - doing it the hard way

Is anyone feeling charitable enough to explain how I might use the Arduino libraries in AVR Studio 5.1? I know there are tutorials on this, and by following them, I've gotten close to having it work. Specifically, I'm getting undefined reference errors, because, of course, the libcore.a library is not being linked.

Now, this is where I'm looking for guidance. I don't really want to use a pre-compiled library. I tinker with the whole gamut of devices: ATmega8s running at 8MHz and 16MHz, 328s and 328Ps running at 16MHz, 1284Ps at 16MHz... So, rather than keep up with maybe half a dozen commonly used variants, I'd like to just start a project, pick my target platform, add the F_CPU symbol, and have the core libs built from scratch, optimized for my target, like they do under the Arduino IDE. The compile time doesn't bother me, I can wait an extra five seconds.

I'm self-taught, and my only prior experience with C is writing code in Kate, and compiling by hand in xterm, so I don't have a clue how to properly resolve dependencies in VS.

Have you checked your Makefile to make sure the core libraries are being linked in the right place? AVR Studio 5 has a bug which places the "-Wl,-lcore" reference too early in the linker command, before it's actually needed. The linker decides those files are irrelevant, doesn't link them, then when it reaches a later library that depends on them, can't find what it needs. If you are linking with that method, you need to edit the Makefile by hand and move those flags to the very end of the command. I'm fairly certain this wasn't fixed in 5.1.

Not sure if you've seen it but we have more background on that issue in our tutorial here: http://www.engblaze.com/tutorial-using-avr-studio-5-with-arduino-projects/#setup

Unfortunately, we use the pre-compiled strategy in that article because people tend to run into enough configuration issues already, without trying to get the core to compile.

If you really want to be device agnostic, have you tried adapting techniques #2 and 3 in the core library section for setting up Eclipse? Arduino Playground - Eclipse

The interface steps will be different but Eclipse and AVR Studio use the same toolchain under the hood.

Yep, that's one of the guides that got me to where I am now. But, it glosses over how all the Arduino .cpp files are involved in compiling the static libs. FWIW, that's probably something I'm just expected to know, but again, IDE noob here.

I'm still pounding away at this, trying to make sense of how VS works. I'm not sure if this is the right approach, but given the wording on step 3 (and taking a stab in the dark at how to translate instructions for one IDE that I've never used at all to another IDE I've never used before now), I've copied all the .cpp files from the cores folder (from the Arduino IDE) to a subdir in my project folder.

So, now I have C:\Users\Me\Documents\AVRStudio 5.1\Arduino-ATmega328P_16MHz\Arduino Core*.cpp

I've added this folder to my project (a static library), went through the C, C++, and Linker settings and added the include paths, optimization, debug, char, enum, F_CPU, etc. etc. I removed the default .cpp file it starts out with, using main.cpp from the distro instead.

Now, assuming I haven't stepped in anything up to this point, I try to build the project..... and it fails.

"'fabs'|'ceil' was not defined in this scope" (from the AVR lib's util/delay.h). I understand this is simply a dependency that hasn't been met, so I checked the output log to see which file it was trying to compile. Turns out, it's the first one: CDC.cpp. I can only assume it is compiling them in alphabetical order, and the majority of the dependencies don't get met until main.cpp includes Arduino.h.

Just for grins, I added back the project-titled .cpp file I got for free and added "#include <Arduino.h>" to the top, removing everything else that was added by default. I thought maybe because the core files were in a subdir, this file might get built first. Nope.

So, am I even taking the right approach here, or have I made a colossal blunder already? If so far so good, how do I insist on a particular module being compiled first? I know I could make a file called "_____MEFIRST.cpp", include Arduino.h, and I'd probably be set -- but that strikes me as a hack, and I would probably be better served by learning how to do this correctly.

I just encountered this too. When using AVRStudio you get a new version of the AVR library & it looks like their implementation of delay.h has changed since the Arduino folk got their AVR library. The new version of delay.h requires <math.h>, which implements the floating point functions you refer to. This library should have been included in delay.h in my view, since delay.h can't compile without it.

Anyway, you'll get it compile if you add #include <math.h> to
AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\avr\include\util\delay.h

I put this #include just after #include <util/delay_basic.h>

Unfortunately, after solving this problem, and figuring out how to make AVRDude send the file to the Arduino, I still don't get the blink program to upload and run correctly. Be keen to hear if you make more progress.

Incidentally, I use this command line with AVRDude:
Command:
C:\Programming\Languages\Arduino\IDE\arduino-1.0\hardware\tools\avr\bin\avrdude.exe

Arguments:
-C C:\Programming\Languages\Arduino\IDE\arduino-1.0\hardware\tools\avr\etc\avrdude.conf -v -v -p m2560 -c wiring -P COM7 -b 115200 -D -U flash:w:"$(ProjectDir)Debug$(ItemFileName).hex":i

I was able to load a program created with the Arduino IDE into the device & have it run, so I think the problem lies in the build step.

Ah, that makes sense! I'll have to try this later today. Thanks for the update!

This might help...

The 2560 and avr dude have a reset problem. You need to force the dtr high and open then close the port immediately prior to calling avr dude for an upload. This forces the 2560 to reset and wait for new code.

Things get more complicated when you start to add libraries to sketch projects (unless you are happy with your own static non-arduino compatible #includes). If you find you are still unhappy with the Arduino & AVR Studio solution then you can always use Visual Studio and the free Visual Micro plugin.

The free plugin is a one click total Arduino solution inside Visual Studio Professional http://www.visualmicro.com.

Some features to note are ability to edit or inspect library sources, 5x faster compile than Arduino, easily add libraries (user and core), works with Arduino 0018 and 1.0, simple toolbar board switch, multiple sketch projects in a single solution, auto pause for upload serial viewer + zillions of Visual Studio extensions on Microsoft Visual Studio Gallery.

Doesn't work with Visual Studio Express (yet). You might be able to get a free copy of Visual Studio professional by reading this Visual Studio for free for Arduino Development

Huh, interesting plugin there. If I find myself using the Arduino libs in larger projects, I'll look into getting VS Pro. I'll keep an eye on it for Express support in the meantime. Thanks for pointing that out.

My goal is to migrate to pure AVR C (at least, when it makes sense), and learn AVR assembly (just for fun, and again, to use when it makes sense). A few of my projects are more burdened by the Arduino core than improved by it, so I'm just trying to broaden my toolbox. The Arduino libs are handy when they're well suited, but why use a crutch when I could do better without?

As I said earlier though, my primary motivation for the move to AVR Studio is to get away from the terrible Arduino IDE. :slight_smile: It's OK for quick jobs, but with a project of any appreciable size whatsoever, it feels like I'm always fighting with it. I just want to have one foot in each platform until my performance projects can migrate off, and convenience for the others. I do alright using a code editor and pasting into the IDE for quick uploads, but when there are headers and multiple C files, it's not worth the trouble.

Yep I understand your reasons for needing more depth.

I didn't make the best point about libraries in Visual Studio. The same option "Project>Show All Arduino Files" also pulls the core sources directly into the project. This might be very helpful because we get to explore the arduino core using the standard Visual Studio code explorer tools, but the addin goes one step further...

The Visual Studio project config and intellisense are seperate to the compile. This means that you can manually include the avr sources (or any reference codes) into your project without affecting/breaking the compilation. This allows you to explore or drill into raw avr files while programing your sketch.

Again, for you, I am not saying Visual Studio is better than AVR Studio so I wish you the best for whatever solution you find.

Hey, it works!

Including math.h from the AVR util/delay.h does solve the problem. I've successfully taken the Arduino core files, compiled them into a static library, then written Blink, compiled it, and linked it against the library created earlier. Very nice.

I'll include complete steps here (from having just installed AVR Studio 5.1) for anyone else inclined to check it out:

Preparing the environment

  • After installing AVRS, there will be a new directory under My Documents (or your equivalent, depending on Windows version) called "AVRStudio 5.1". Organize this however you wish, but I recommend making "Includes", "Libraries" and "Projects" directories at least.

  • Open AVRS and start a new C++ Static Library project. Devise your own naming convention, for example, "Arduino-ATmega328P_16MHz". Use this as the name, and change the location to the Libraries directory. Click OK.

  • For Device Type, chose megaAVR, 8-bit, then pick the ATmega328P. Click OK.

  • In the Solution Explorer pane, right-click the project (the line with your project's name and the orange file icon), pick Add, New Folder. Call it "Core".

  • Open two Windows Explorer windows (file browsers). Navigate one to your Arduino IDE's installation directory. In my case, it's C:\Program Files\Arduino. Then, go down to "hardware", "arduino", "cores", "arduino". Copy all the .c and .cpp files here. (Hint: Arrange by type, then shift-select all of the .c/cpp files.) Navigate the second window to My Documents, then "AVRStudio 5.1", your Libraries directory, your project, your project again. You should see the auto-created .cpp file here, and your "Core" directory. Enter "Core" and paste the files there.

  • In the Arduino window, select all the .h files and copy them to your Includes directory (under MyDocs\AVRStudio 5.1). If you want, create an arduino sub-directory and put them there instead. Remember this if you do, you'll need to specify it later.

  • Finally, go back up to "hardware\arduino". Open "variants", then "standard". Copy the pins_arduino.h file here and paste it with the rest of the files in the other window.

  • Back in AVRS, go to the Project menu, go to Properties, then make these changes, all under the Toolchain tab:

  • AVR/GNU C Compiler:

  • Symbols: Add "F_CPU=16000000L"- Directories: Add your Includes (or Includes\arduino) directory.- Optimization: Add "Prepare functions for garbage collection"

  • AVR/GNU C++ Compiler:

  • Same as above

  • AVR/GNU C++ Linker:

  • Optimize: Garbage collect unused sections

  • AVR/GNU Assembler:

  • Symbols: Add "F_CPU=16000000L"

  • Save, then close the Properties page.

  • In your code window, clear the default code. You can add "#include <Arduino.h>" here, just for grins.

  • In the Solution Explorer pane, right-click the Core folder, pick Add, Existing Item, and select all the .c/.cpp files that you just copied over. Click Add.

  • Open a decent text editor (not Notepad -- it doesn't support Unix-style line endings, but Wordpad does) from the Start menu by right-clicking it and choosing "Run as Administrator". Navigate to (adjust per your installation) "C:\Program Files\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\avr\include\util". Open "delay.h". Scroll down to the line "#include <inttypes.h>", and after that, add "#include <math.h>". Save and exit.

  • Back in AVRS, click Build, Build Solution.

  • If you did everything right, you should get an Output window with your compile progress, and it should say "Build succeeded" at the end.

  • Go to your project directory, then down to the "Debug" folder. There's a "lib.a" file waiting for you. Copy that into your Libraries directory.

Repeat the steps above (pertaining to your project -- the delay.h modification only has to be done once) for each combination of CPU type / clock speed you want to have at your disposal. You only need to create these libraries once -- at least until the Arduino libs change. :wink: AFAIK, you can ignore cosmetic differences (328 vs 328P), but I haven't tested this.

Now, close the static library project, and let's build a project that can be uploaded to a chip.

Building an Arduino project

  • Create a new C Executable project, call it anything you like (e.g., "Blink"), and consider storing it somewhere under the Projects directory. I created a subdirectory called Arduino to keep all the Arduino-based projects together. Click OK.

  • Once again, pick the megaAVR, 8-bit device type, and choose ATmega328P. Click OK.

  • Go to the Project menu and pick Properties again. Make these changes:

  • AVR/GNU C Compiler:

  • Symbols: Add "F_CPU=16000000L"- Directories: Add your Includes (or Includes\arduino) directory from before.- Optimization: Add "Prepare functions for garbage collection"

  • AVR/GNU C Linker:

  • Libraries: Add "Arduino-ATmega328P_16MHz" (or whatever you named the static library project from before

  • Libraries: Add your Libraries directory to the search path.

  • Optimization: Garbage collect unused sections.

  • AVR/GNU Assembler:

  • Symbols: Add "F_CPU=16000000L"

  • Save, then close the Properties page.

  • In the code window for the .c file created with the project, clear out the existing code and add:

#include <Arduino.h>

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}
  • Click Build, Build Solution. Check the Output window for "Build succeeded"
  • You now have a shiny new .hex file in the Debug directory of your project, ready to be uploaded.

You may want to Export this project as a template in your Templates directory to avoid all the setup steps later.

As far as I can see, there's no need for the Makefile trickery anymore, but I may just not have run into that problem yet. If there's anything amiss in the steps above, please let me know and I'll edit accordingly. Thanks to everyone that helped out along the way, and I hope this gets someone else going too.

Thanks

This was really really useful.
At the moment I have the AVR Studio 5.0, so I didnt have to add the math.h.
Other than that what you wrote worked, and one cannot ask for more than that.

One exception, and I probably am missing a step. I had to follow the hints from

http://arduino.cc/playground/Code/Eclipse#AVR_GCC_toolchain

I can see I copied the main.cpp from the Core directory into my static library.
But without explicitly adding in the "main" routine, no final build.

#include <Arduino.h>

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}



int main(void) {

  /* Must call init for arduino to work properly */
  init();

  /****************************/
  /* Add your setup code here */
  /****************************/
  setup();
  
  for (;;) {

    /****************************/
    /*** write main loop here ***/
    /****************************/
	loop();
  } // end for

} // end main

Now to try this with some code I have written in Arduino IDE.
Hopefully I can spot my logic errors :-).
Might need to go off and get the necessary hardware to connect the Arduino into the debugger.

Thanks again.

Regards

Steve H

I'm currently trying to get the arduino libraries to work with Atmel Studio 6.
The thing is - it works with the Arduino Uno already, but I'm trying to get it to work with an evaluation board so I can use different types of microcontrollers with the Arduino libraries. So far so good.

The problem is: I'm trying to put some code in a mega8, plain and simple. But when it try to talk to it in Arduino, it doesn't budge (LEDs on the board don't light up). I tried talking to it in C++ (copying an example), and lo and behold, the LEDs are turned on as they should be. Next thing I tried was debugging the Arduino code, and this is where it got interresting.

When debugging, it opens a file calles main.cpp, which is not the project file, and it contains this:

#include <Arduino.h>

int main(void)
{
	init();

#if defined(USBCON)
	USB.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

I should note that when I debug the C++-version, it does not open another file, but stays in the one with the C++-code.

By the way, this is what I had for Arduino-code:

void setup() {
	pinMode(6, OUTPUT);
	digitalWrite(6, LOW);
}

void loop() {
	Serial.print("Hello World!");
}

Any ideas or pointers that might explain what I am missing and how to fix it?

Thanks in advance!

Thanks for sharing.

Are the steps from reply #8 identical for AVR Studio 5 and AVR Studio 6?

i downloaded 6.0, too much going on with that program...you need a degree to use it...i tried and failed, must be my old age