Studio 6: Sharing code betwixt projects

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

So, how do you do this?

I created a "solution."

Inside this solution, I created 3 projects.

My thought was to put common code in the solution folder, and code specific to each project in the project folders.

So I added the .h and .c for a common bit of code using "Add existing item and selected the files from the solution folder.

But when I make, it stumbles over

#include "spi.h"

Apparently, make.exe doesn't know to look in the application folder (parent) for this .h file. It didn't take a lot of intuition on my part to realize, "I must be doing it wrong."

I didn't really figure on making "Static Libraries."

I watched an Atmel video where the guy showed to add these "library" files to the project in the "Drivers" folder, but I don't seem to have a "Drivers" folder in studio 6.

I've spent a lot of time figuring out how things CAN be done. Now I'm trying to figure out how things SHOULD be done.

I have :
Atmel Studio 6 (Version: 6.1.2674 - Service Pack 1)
© 2013 Atmel Corp.
All rights reserved.

OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
Platform: Win32NT

Installed Packages: Shell VSIX manifest - 6.1
Shell VSIX manifest
Version: 6.1
Package GUID: 5aa6ea3e-da7b-48c1-9b2a-cab2329d32ac
Company: Atmel Corporation

Installed Packages: Atmel ARM GNU Toolchain - 4.7.3.1029
ARM Toolchain
Version: ARM_Toolchain_Version:4.7.3.158 GCC_VERSION:4.7.3
Package GUID: D83C9208-1D2D-4665-9760-EB9EE264CF8F
Company: Atmel
HelpUrl:
Release Description: ARM Toolchain

CMSIS
Version: 3.20
Package GUID: D83C9208-1D2D-4665-9760-EB9EE264CF8F
Company: Atmel
HelpUrl:
Release Description: ARM Support File Version

Installed Packages: AVR macro Assembler - 2.1.39.1005
AVR Assembler
Version: 2.1.39.232
Package GUID: 03CB4AE1-80EA-40C7-B561-98CC87EA539C
Company: Atmel
HelpUrl:
Release Description: AVR Assembler For 8-Bit Devices

Installed Packages: Atmel AVR (32 bit) GNU Toolchain - 3.4.2.1002
AVR Toolchain 32
Version: AVR32_Toolchain_Version:3.4.2.435 GCC_VERSION:4.4.7
Package GUID: DB6D383F-C5D9-4E7E-BBF9-F37C6EEB59FD
Company: Atmel
HelpUrl:
Release Description: AVR Toolchain For 32-Bit Devices

Installed Packages: Atmel AVR (8 bit) GNU Toolchain - 3.4.2.1002
AVR Toolchain 8 Bit
Version: AVR8_Toolchain_Version:3.4.2.992 GCC_VERSION:4.7.2
Package GUID: 2C7AA7CF-94C6-463C-81DA-4AA03B613C3B
Company: Atmel
HelpUrl:
Release Description: AVR Toolchain For 8-Bit Devices

Installed Packages: Atmel Gallery - 1.3.1
Atmel Gallery
Version: 1.3.1
Package GUID: AtmelStudioExtensionManager
Company: Atmel

Installed Packages: Atmel Kits - 1.3.172
Atmel Kits
Version: 1.3.172
Package GUID: bea809ab-462e-4535-99f1-3f9ced2f09ff
Company: Atmel

Installed Packages: Atmel Software Framework - 3.9.1.780
ASF
Version: 3.9.1
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.9.1
Release Description: ASF - 3.9.1 Release

ASF
Version: 3.8.1
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.8.1
Release Description: ASF - 3.8.1 Release

ASF
Version: 3.7.3
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.7.3
Release Description: ASF - 3.7.3 Release

ASF
Version: 3.6.0
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.6.0
Release Description: ASF - 3.6.0 Release

ASF
Version: 3.5.1
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.5.1
Release Description: ASF - 3.5.1 Release

ASF
Version: 3.5.0
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.5.0
Release Description: ASF - 3.5.0 Release

ASF
Version: 3.4.1
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.4.1
Release Description: ASF - 3.4.1 Release

ASF
Version: 3.3.0
Package GUID: 8BA748A3-6DE3-4707-BBE4-FBB45AC9A491
Company: Atmel
HelpUrl: http://asf.atmel.com/3.3.0
Release Description: ASF - 3.3.0 Release

Installed Packages: AtmelToolchainProvider - 6.1.0.447
AtmelToolchainProvider
Version: 6.1.0.447
Package GUID: AtmelToolchainProvider.Atmel.83804b14-6626-4e13-bfdc-3a0135fa98f1
Company: Atmel

Installed Packages: Visual Assist X for Atmel Studio - 10.7.1930.2
Visual Assist X for Atmel Studio
Version: 10.7.1930.2
Package GUID: 7997A33C-B154-4b75-B2AC658CD58C9510
Company: Whole Tomato Software

Installed Packages: Designing a Wireless Sensor in ASF - 1.0.0
Designing a Wireless Sensor in ASF
Version: 1.0.0
Package GUID: c1a1ff81-6927-4562-84e6-da94a09c6519
Company: Atmel Training

 

277,232,917 -1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store

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

Quote:
Studio 6: Sharing code betwixt projects
What's betwixt? :roll:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Quote:

What's betwixt?

Between.

Torby,

What you attempted would have worked if you had simply set an include path of .. (i.e. "-I..") for the projects that wanted to "see" spi.h and others.

But there's no hard and fast rules for how to lay stuff out either in the way it's viewed in Solutions/Projects or in the way it's held on disk in directories and sub-directories.

Just pick a layout that suits you then create the projects that will use the code to adapt to your chosen layout.

I'm not saying it's a particularly good model but if you look at the way an ASF project holds the various library .c and .h files it is one model you could choose to adopt. However ASF is far from optimal. It effectively "checks out" a copy of the required files into the local project structure. It can do that as you won't (shouldn't anyway!) be editing the library files so the copy is effectively read-only and it doesn't matter if it's duplicated several times on your disk.

For what you are doing you really want to keep your spi.c/spi.h, uart.c/uart.h, lcd.c/lcd.h and so on in one central, editable master copy.

Now one way to achieve that would be to use source code control (SVN/Git/etc) then you could work on any checked out copy then push the edits back to the repository and other projects could then pull a fresh copy of the files after updates.

But another way is to use AS6's facility to [Add link] rather than jut [Add] when adding those .c and .h to a new project. In this case it doesn't copy the files but they can remain in a single, master copy somewhere. This is probably the best way to use AS6.

But, like I say, there's no hard and fast rules - pick a paradigm that suits you.

To illustrate what I'm talking about I'll go and grab a copy of some library code (perhaps Fleury's UART code?) then make two projects that use it. Even then questions remain as to whether I use two lots of solution/project or a single solution/project/project. Again a personal choice.

Back soon...

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

OK so I checked I had a copy of the Fleury code:

E:\>dir fle*
 Volume in drive E is VBOX_windows
 Volume Serial Number is 0000-0801

 Directory of E:\

12/08/2013  15:42              fleuryi2c
08/02/2012  11:33              fleurylcd
22/11/2012  11:05              fleuryuart
04/10/2012  18:08              fleurybl
               0 File(s)         16,384 bytes
               4 Dir(s)  340,165,402,624 bytes free

Within the fleuryuart directory there is:

E:\fleuryuart>dir
 Volume in drive E is VBOX_windows
 Volume Serial Number is 0000-0801

 Directory of E:\fleuryuart

22/11/2012  11:03            15,228 broken.c
10/07/2005  14:47             1,281 doxygen.png
15/09/2012  18:01            14,409 makefile
19/11/2012  21:52             7,472 uart.h
10/11/2012  14:59            21,551 uart.c
10/07/2005  14:47             1,816 doxygen.css
10/07/2005  14:47            24,856 group__pfleury__uart.html
15/09/2012  17:33             3,893 test_uart.c
               8 File(s)         90,506 bytes

In that I'm only really interested in 3 files: uart.h, uart.c and test_uart.c. What I'll do is create a single solution in AS6 with two separate projects and each will make use of the uart.c and uart.h files there. To make my life simple I'm just going to lift the contents of test_uart.c for my two main()'s.

So in AS6 I create a new Solution/Project. I use File-New Project..., leave the selection at default (GCC executable). Now Name and Solution Name behave very oddly in this dialog (extremely counter-inutitive) in that if you type anything into "Name" then what you type gets duplicated into "Solution Name". But if you type into "Solution Name" it's not duplicated into "Name". I want to call the Solution "FleuryExamples" and I want to call the project "Example1". So I initially type "Example1" against Name and it also appears against Solution Name. However as soon as you type in the Solution Name field the link between the two entries is broken. So now I type "FleuryExamples" against Solution Name replacing "Example1".

In my case the Location is set to C:\Documents and Settings\asl\My Documents\Atmel Studio\. I then press [OK]. In the following dialog I pick Atmega16 (I generally always do). Then [OK].

So now AS6 has created me a solution called FleuryExamples, a project called Example1 and an empty main() in a file called Example1.c.

While there's probably some clever way to do this I just want Fleury's test_uart.c in the body of this Example1.c so I just edit the Fleury file using an external editor (Notepad++ in fact). I just Ctrl-A/Ctrl-C to take a copy of the entire thing. I then switch back to the Example1.c that is in the AS6 editor and replace what's in it with a paste of the clipboard contents. To differentiate this example and the next one I'm going to create I edit the "String stored in SRAM" to be "This is Example1".

So now, if I try to build this without changing anything else here's what happens:

C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Example1.c(17,18): uart.h: No such file or directory

Not a surprise really. I haven't done anything to tell it where to look for uart.h. So now I edit the project properties for the Example1 project. Under Toolchain-AVR/GNU C Compiler-Directories I hit the icon with the green plus sign then use the [...] to browse to E:\fleuryuart which is the place where I have the master copy of those Fleury library files. (in fact my AS6 uses \\VBOXSVR\windows\fleuryuart rather than E:\fleuryuart as that directory is really on a network share and AS6 uses UNC paths). I then [OK] that path selection.

Now when I build the code this happens:

		Invoking: AVR/GNU Linker : 3.4.2
		"C:\Program Files\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-gcc.exe" -o Example1.elf  Example1.o   -Wl,-Map="Example1.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mmcu=atmega16 
		Example1.o: In function `main':
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(43,1): undefined reference to `uart_init'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(57,1): undefined reference to `uart_puts'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(62,1): undefined reference to `uart_puts_p'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(70,1): undefined reference to `uart_puts'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(76,1): undefined reference to `uart_putc'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(87,1): undefined reference to `uart_getc'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(103,1): undefined reference to `uart_puts_p'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(112,1): undefined reference to `uart_puts_p'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(120,1): undefined reference to `uart_puts_p'
C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1\Debug/.././Example1.c(125,1): undefined reference to `uart_putc'
collect2.exe(0,0): ld returned 1 exit status

Well, yes, again this is to be expected. I have sorted out the finding of uart.h but uart.c is not being built so when Example1.c calls those functions the linker is not going to find implementations. So now to fix that...

This is where the clever AS6 feature comes into play. I could simply lift a copy of uart.c and put it in the Example1 project directory then add that as an item to be built but that would have caused me to branch the uart.c file. If a fault were ever found that required uart.c to be edited then I'd have to hunt all over my HDD for copies and put the fix into them all. AS6 allows you to add a file as a "link" rather than a physical copy. So you can, instead, leave that single copy in E:\fleuryuart (\\VBOXSVR\windows\fleuryuart).

So right click the Example1 project name in the Solution Explorer and use Add-Existing Item..., use the file selector to browse to E:\fleuryuart or wherever you have the "library" file to be used. Highlight uart.c but do NOT click [Add]. If you do then AS6 will make a copy of uart.c to the current project directory. To illustrate this I just did what I said you must not do and ended up with this:

 Directory of C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1

27/09/2013  10:40              .
27/09/2013  10:40              ..
27/09/2013  10:33              Debug
27/09/2013  10:28             3,888 Example1.c
27/09/2013  10:33             4,918 Example1.cproj
10/11/2012  14:59            21,551 uart.c

As you can see it has copied uart.c to the project directory (though uart.h will still use the "master copy"). What I should do in that Existing Item... dialog is notice that the [Add] button has a drop arrow to the right hand side. If you click that a sub-menu appears. There are two options "Add" and "Add As Link. It is the latter that we need to use. Having selected "Add As Link" I see uart.c in the list of files for Example1 but you may notice that the "C" icon to the left of the filename has a small arrow overlaid? That is showing that the file is not in the project directory as you can see here:

 Directory of C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples\Example1

27/09/2013  10:43              .
27/09/2013  10:43              ..
27/09/2013  10:33              Debug
27/09/2013  10:28             3,888 Example1.c
27/09/2013  10:33             4,918 Example1.cproj
               2 File(s)          8,806 bytes

but it is a link to another location. If I now build the code I get:

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

			Projects Build Summary
			----------------------
  Time        | Status    | Project [Config|platform]
 -------------|-----------|-----------------------------------------------------------------------------
  00:00:09.08 | Succeeded | Example1\Example1.cproj [Debug|AVR]

Yeah! It worked.

So this has succeeded in creating a project that uses "library" uart.h/uart.c files but that remain in their original location on disk as a single master copy without needing to have copied them into the project directory where they are used. The .h is found as a result of -I and the .c is found as the result of being a link. The actual build of the .c file used the master copy as you can see here:

		Building file: E:/fleuryuart/uart.c
		Invoking: AVR/GNU C Compiler : 3.4.2
		"C:\Program Files\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-gcc.exe"  -funsigned-char -funsigned-bitfields -DDEBUG  -I"\\VBOXSVR\windows\fleuryuart"  -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega16 -c -std=gnu99 -MD -MP -MF "uart.d" -MT"uart.d" -MT"uart.o"   -o "uart.o" "E:/fleuryuart/uart.c"
		Finished building: E:/fleuryuart/uart.c

You can see that when it was built the object file was created locally:

C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples>tree /f
Folder PATH listing
Volume serial number is 00730065 E0DD:96FE
C:.
¦   FleuryExamples.atsln
¦
+---Example1
    ¦   Example1.c
    ¦   Example1.cproj
    ¦
    +---Debug
            Example1.d
            Example1.eep
            Example1.elf
            Example1.hex
            Example1.lss
            Example1.map
            Example1.o
            Example1.srec
            makedep.mk
            Makefile
            uart.d
            uart.o

The uart.o and uart.d files have been created "locally" (as will uart.s and uart.i if you use -save-temps).

So now to add a second project that also uses those two uart files...

In the Solution Explorer right click the solution name ("FleuryExamples") and use Add-New Project..., this time set the Name to be "Example2" with all other selections left at default. Select mega16 (or whatever) again. Replace the contents of Example2.c with a copy of the Fleury test_uart.c code. We now need to do the two things as before to connect with uart.h and uart.c so edit the Project toolchain properties and set a "Directories" entry to E:\fleuryuart. Then right click Example2 in the Solution Explorer and Add-Existing Item..., add e:\fleuryuart\uart.c using "Add as Link".

Now "Build Example2". Success again. So we have a solution with two projects that are each using external UART files. The tree now looks like:

C:\Documents and Settings\asl\My Documents\Atmel Studio\FleuryExamples>tree /f
Folder PATH listing
Volume serial number is 00730065 E0DD:96FE
C:.
¦   FleuryExamples.atsln
¦
+---Example1
¦   ¦   Example1.c
¦   ¦   Example1.cproj
¦   ¦
¦   +---Debug
¦           Example1.d
¦           Example1.eep
¦           Example1.elf
¦           Example1.hex
¦           Example1.lss
¦           Example1.map
¦           Example1.o
¦           Example1.srec
¦           makedep.mk
¦           Makefile
¦           uart.d
¦           uart.o
¦
+---Example2
    ¦   Example2.c
    ¦   Example2.cproj
    ¦
    +---Debug
            Example2.d
            Example2.eep
            Example2.elf
            Example2.hex
            Example2.lss
            Example2.map
            Example2.o
            Example2.srec
            makedep.mk
            Makefile
            uart.d
            uart.o

And that's it I guess. So there's only two "tricks" to know about:

1) Make sure the "Directories" entry for a project has the names of any directories where "library" .h files are stored.

2) Add any library .c files using "Add As Link" to the list of project files. Verify that their icons have a little arrow showing they aren't actually in the project directroy.

3) err...

4) ... that's it.

I attach the solution files in a .zip but note that this won't build for you because it makes reference to e:\fleuryuart files and the \\VBOXSVR\windows\fleuryuart directory that you don't have (which may be an argument against this way of working as you cannot easily distribute "complete solutions").

Attachment(s): 

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

Thanks!

To make it clear for other idiots like me:

1. Add you "library folders" as directories under ToolChain:

I unchecked the "relative path" checkbox because I don't know any better. I think, in the long run, that it would be better to have the relative path in case I someday move the whole thing to a different folder.

When you add these files to your project, right click the project name, choose Add item - existing item. Then select all the items you want to add, but don't click the add button. Instead, look for the arrow and click that. Then select "Add as link."

This will leave the files in the library folder, rather than copying them to your project's source, and just use them from there.

 

277,232,917 -1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store

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

Hmm. Doesn't work quite as I was hoping...

I made myself a "Library" folder and added it and linked the bla bla bla like above.

My idea was that each app folder would include "Config.h" that described the board with defines, and the "Library" files would #include "Config.h" which it would get from the app's folder... but...

When "Nordic.C" in the library folder

#include "Config.h"

, it's looking for it in the library folder, not in the application's folder. Of course, Config.c was to be the interface between the library code and the application, which might have the pins on different ports and suchlike.

Suggestions?

 

277,232,917 -1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store

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

Quote:

Suggestions?

OK I just got this to work with my Fleury UART examples project. What I did was edit the "library" file called uart.c to #include "config.h". As you say, when I built the Examples1 project I then got an error about uart.c not being able to find config.h. So then I highlighted the link to uart.c in the Solution Explorer so that it's details were shown in the File Properties pane beneath. Under "Custom Compilation Setting" (that is a command to the compiler only used when this particular file is compiled) I entered -I"path/to/project/copy/of/config.h"

A picture, as they say is worth 1,000 words so here's 1,000 words on the subject:

Attachment(s): 

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

Well, I got it to make. Seems ANY .c that looks for ANY .h in the app's folder needs this.

If I had built and application like this, the users would be storming the gate

 

277,232,917 -1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store