Giter Site home page Giter Site logo

Comments (8)

hexagon5un avatar hexagon5un commented on July 24, 2024

Hey, thanks!

Yeah, the code is in C. It won't work if you try to compile it in Turbo Pascal either. :)

But that's strange about the Arduino IDE. My experience is that if you name the file something.c, it gets compiled with gcc, and if you name the file something.cpp, it gets compiled with g++. (And if you name it something.ino, it gets converted into something.cpp, and it gets hit with g++ again.)

And I haven't used Studio in a dog's age, but I absolutely remember writing in straight C there too.

In Arduino, were you using the default whatever.ino "sketch" file or did you open up your own something.c to start with? In Studio, were you mixing/matching C/C++ outside of my code? Did you use a different extension from .c? How did the compiler chain get confused?

from avr-programming.

PhillyNJ avatar PhillyNJ commented on July 24, 2024

Hi - Thanks for the response. I was using a default sketch, with a reference to a header file .h. when in the Arduino IDE. In Atmel Studio, it was a C/C++ project. Here is my build error from Atmel Studio:

------ Build started: Project: TestOne, Configuration: Release AVR ------
Build started.
Project "TestOne.cppproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Compiler.targets" from project "C:\Users\Philip\Documents\Atmel Studio\6.2\AvrI2CTesting\TestOne\TestOne.cppproj" (target "Build" depends on it):
    Task "RunCompilerTask"
        Shell Utils Path C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils
        C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils\make.exe all 
        Building target: TestOne.elf
        Invoking: AVR8/GNU Linker : 4.8.1
        "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-g++.exe" -o TestOne.elf  src/i2c.o src/USART.o TestOne.o   -Wl,-Map="TestOne.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,-L"../src"  -Wl,--gc-sections -mmcu=atmega168p  
        TestOne.o: In function `main':
C:\Users\Philip\Documents\Atmel Studio\6.2\AvrI2CTesting\TestOne\Debug\TestOne.cpp(1,1): error: undefined reference to `initUSART()'
C:\Users\Philip\Documents\Atmel Studio\6.2\AvrI2CTesting\TestOne\Debug\TestOne.cpp(1,1): error: undefined reference to `printString(char const*)'
C:\Users\Philip\Documents\Atmel Studio\6.2\AvrI2CTesting\TestOne\Debug\TestOne.cpp(1,1): error: undefined reference to `printString(char const*)'
collect2.exe(0,0): error: ld returned 1 exit status
        make: *** [TestOne.elf] Error 1
        The command exited with code 2.
    Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "TestOne.cppproj" -- FAILED.
Done building project "TestOne.cppproj" -- FAILED.

Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

Like I said, when I wrapped your code into a cpp class. It compiles and loads fine.

from avr-programming.

hexagon5un avatar hexagon5un commented on July 24, 2024

It looks like the code is called "TestOne.cpp", and the project, "TestOne.cppproj".

Is there a place in Studio where you tell it you're working in C/C++? Like a check box early on or something? Did you pick these extensions? They're the classic C++ ones.

Studio really seems convinced that you're working in C++ rather than C, and that's what's forcing you to write in C++ rather than C. I know Studio supports C, though -- it's using the same compiler toolchain that we all use (Studio, Arduino, and the book / me). You just gotta figure out how to convice it.

Have you tried just opening up my files? Or are you cutting/pasting into a pre-existing (C++) project?

I know a ton of people have been using Studio and made it work, but I never thought to ask how.

from avr-programming.

PhillyNJ avatar PhillyNJ commented on July 24, 2024

Atmel Studio has several options from when creating a project. When you choose the project type, it knows how to compile the code. A description can be found here.

On that page there is a table describing the project types. From my understanding it is either c project or cpp. Since many of the AVR Arduino libraries are written in c++, I have to choose the c++ project. For example, I want to use your USART code with an OLED library written by Adafruit. The Adafruit library is written in c++. This could be a moot point as perhaps to use the USART code I must use a c compiler. This is understood, but I am only pointing out that a great deal of AVR community is coming over from the Arduino IDE and a great deal of libraries are written in c++.

The Arduino IDE on the other hand uses a c++ compiler and some of your code will not compile. Perhaps there is a setting in the Arduino IDE to tell it to compile both.

As you stated, a ton of people have been using Studio and made it work. So did I :) - I am telling you how I did it. Maybe there is a way to compile your c code in the Arduino IDE, but I haven't figured out how unless I wrap your code in a c++ class.

With all this said, again the book is a great read and provides excellent information, I wish you wrote one on Assembly :)

from avr-programming.

hexagon5un avatar hexagon5un commented on July 24, 2024

I wish I was good enough at AVR assembly to write one! :)

I (finally!) understand your problem: it's not with Studio or Arduino, but with mixing C and C++. I don't do that often, but if you're comfortable with C++ (as it looks like you are) you can just include my C code by making sure that you wrap the header includes with the extern "C" {} construct as you suggested to begin with. The GCC compiler/linker will take care of the rest for you.

Or you could do the opposite and wrap up the C++ declarations in extern "C" {} and call them from C code.

https://isocpp.org/wiki/faq/mixing-c-and-cpp is the best link I've found for explaining how to do it. Or have a look at arduino/avr/libraries/Wire/Wire.cpp which calls arduino/avr/libraries/Wire/utility/twi.c, for instance, in the Arduino codebase.

But yeah. If your goal is to pull some of the Arduino C++ code into your C project, you can either give up and write C++ (probably easier) or just add the extern "C" to each function declaration (or to the entire header file if you're lucky).

Note that it sounds like I've finally caught up with you, PhillyNJ, and so I'm just writing this stuff down for anyone else who stumbles on this thread and wants to know how to deal with the C/C++ dilemma.

from avr-programming.

hessa59 avatar hessa59 commented on July 24, 2024

I had the same problem trying to compile the code in Atmel studio 7. But I switched to a C project and copied the pin defines to C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\pinDefines.h

I also had to add # define F_CPU 16000000UL to usart.c

from avr-programming.

hessa59 avatar hessa59 commented on July 24, 2024

I got the Usart echo program to work in Atmel Studio 7 in C++ mode by typing extern "C" in front of all the function definitions in usart,h as in:

extern "C" void transmitByte(uint8_t data);

from avr-programming.

hexagon5un avatar hexagon5un commented on July 24, 2024

Thanks @hessa59 for chiming in. I'm really weak with Studio -- I haven't used it since like 2006. Oh my, I'm old.

The issue with the defines is due to Studio putting global defines somewhere other than the makefile. According to this website, Studio calls them "symbols" and they're found buried pretty deep in some menus: Project - Properties - Toolchain - All Configurations - Symbols.

Anyway, long story short, you add F_CPU and BAUD there and you're good. The other option is for me to hardcode a CPU speed into USART.c, but then it would stand a chance of simply being wrong with no warning.

The issue looks to be starting off with a C++ project in Studio sets up a different compiler toolchain, which then causes problems with some of the subtler differences in the way C and C++ interoperate.

The path of least resistance, as @PhillyNJ found out, seems to be starting off in C++ for the Arduino libs, and then including whatever straight-C code wrapped in the "extern C" brackets.

from avr-programming.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.