Build multiple executables with only one symbolic constant change

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

I have a project where I need to get 12 binaries.  The only difference in the source that generates the binaries is a single, symbolic constant--MY_TIMESLOT.

 

I accomplished this by having a solution with 12 projects.  Under Project Properties->Tool Chain-->AVR GNU C Compiler-->SYMBOLS, I added a entry for MY_TIMESLOT:

 

 

I did this for each of the 12 projects.

 

This has been working, but I think there might be a better way.   Or, maybe I need some help on how to debug a selected project in a multiple project solution.

 

I can't seem to figure out how to tell Studio which project I want to debug.  The only way I can seem to get things to work is to unload all projects except the one I want to debug.

 

I could create a custom makefile to do the the builds, but I'd still have to figure out how to tell Studio which binary I want to debug.

 

So, the questions:

 

1)  Is the best way to accomplish what I want, or at least about as good as any other approach. 

2)  If not, what is a good alternative?

3)  If this is a recommended way to use Atmel Studio (a separate project just to #define a constant), how to I specify which project to debug (other than closing 11 projects after opening the solution).

 

Thanks!

 

 

 

 

 

 

This topic has a solution.
Last Edited: Thu. Dec 12, 2019 - 03:45 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


 

davethomaspilot wrote:
how to tell Studio which project I want to debug

Visual Studio and, thus, Atmel Studio calls this the Startup Project

 

The Startup Project is highlighted in Bold in the Solution Explorer

 

You set it in the Solution Properties:

 

 

EDIT

 

I don't have an Atmel Studio example, but here's what it looks like in Visual Studio:

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Dec 12, 2019 - 03:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

davethomaspilot wrote:
but I think there might be a better way. 
Not really - that is the way you'd usually do something like this - obviously the "contents" of the 12 projects will all just be "shared links" rather than 12 different copies of each source but other than that this is the way to do it.

 

As for which one to debug. In visual studio (on which AS7 is based) you pick the one you want and "set as startup project" and then that is the one that is debugged. I sort of assume AS7 is the same in this sense?

 

What you might want to explore is some kind of "build automation". Maybe using Cmake, maybe using MSBuild, maybe using both but I'm not sure how Studio+avr-gcc lends itself to this kind of thing, those technologies are developed for Visual Studio not Atmel Studio (even though, under the hood, it's mainly the same or at least very similar).

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

davethomaspilot wrote:
Is the best way to accomplish what I want,

That depends on what you actually what to accomplish?

 

Do you really want this to be a build-time option ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


BTW as Andy said..

awneil wrote:
The Startup Project is highlighted in Bold in the Solution Explorer
So in AS7 I currently have this:

 

 

"test" is the project set as "start up " and will be debugged. If I then use:

 

 

then it ends up as:

 

 

so now "foobar" is the one that will be debugged (and is hence shown in bold).

 

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

I think your method sounds pretty good. Use same source code (and add as links in your project!) and define different symbols in the compiler options.

 

It is a very neat and flexible solution. I use it for compiling the same code for different target hardware. I even use it for compiling the same code for different "application targets" i.e. slightly different applications for same hardware (or even different hardware...).

/Jakob Selbing

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

Wow, so many fast replies!  Thanks.

 

Feel stupid.  I saw "Startup Project", but I assumed (incorrectly) this would be the active project when I opened the solution.  

 

But, it makes sense--start up as in what project gets started in a debug session.  I'll give that a try.

 

That depends on what you actually what to accomplish?

 

Do you really want this to be a build-time option ... ?

Yes, there are  6 processors to be programmed, all the same code except for a handful of constns.  No need for runtime switch.

 

What you might want to explore is some kind of "build automation". Maybe using Cmake, maybe using MSBuild, maybe using both but I'm not sure how Studio+avr-gcc lends itself to this kind of thing, those technologies are developed for Visual Studio not Atmel Studio (even though, under the hood, it's mainly the same or at least very similar).

All the projects in the solution can be built with a single click, though I've found the dependencies aren't quite what I'd expect. 

 

I posted a thread on that a month or so ago--I don't recall exactly what the problem was, but maybe a project doesn't get rebuilt just because you changed a symbol definition.   I just take care to "Rebuild" each project individually, rather than counting on "rebuild" of the solution.  Probably not the smartest way to do it, but I only have the issues when testing a new, multiple project solution.  I think the dependencies work great when I actually change source code.

 

So, I don't think I really need something else like CMake.   "Startup Project" was the magic bullet.

 

Thanks!

 

    

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

davethomaspilot wrote:

Feel stupid.  I saw "Startup Project", but I assumed (incorrectly) this would be the active project when I opened the solution.  

 

But, it makes sense--start up as in what project gets started in a debug session.  I'll give that a try.

"Startup" has more relevance to Visual Studio where you are generally creating EXE files for use on PCs so the one that runs ("starts up") when you select something like "run without debugging" is the bold one.
davethomaspilot wrote:
but maybe a project doesn't get rebuilt just because you changed a symbol definition.
Depends if it is in .h or specified on command line with -D. The fact is the .d files in avr-gcc are all about tagging which .c are dependent on which .h so that if a .h is edited then all the .c that are indirectly dependent on it are flagged as needing rebuild. But I'm not sure this works for -D's on the command line.

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

davethomaspilot wrote:
  No need for runtime switch.

My question was really whether some sort of runtime configuration/commissioning might be better than having a dozen builds which differ only in their configuration ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
My question was really whether some sort of runtime configuration/commissioning might be better than having a dozen builds which differ only in their configuration ... ?
Agree - one code image (to reduce maintenance /testing requirement) but configurable with options in EEPROM or similar can often be a good idea. (though I guess you still need to test all configured variants).

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

You "Make Solution".   All 12 projects get updated.

"Startup Project" gets debugged.

 

I would assume you have one single set of source files.   Each project accesses as "linked files"

 

Edit one file and all 12 projects get re-built.   But only as necessary.

In the modern world the build time is trivial.

In the old days you would use a single Makefile but specify the dependencies carefully.   e.g. to maintain the minimal number of unique object files.

 

David.

Last Edited: Thu. Dec 12, 2019 - 05:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My question was really whether s

ome sort of runtime configuration/commissioning might be better than having a dozen builds which differ only in their configuration ... ?

 

Not following you.  There would need to be something at runtime to test. 

 

I could use a dip switch, jumpers, or solder jumpers on the identical pcbs, but it seems  much easier to  build to custom the binaries by using compile time flags rather than having to build and inventory unique pcbs for each timelsot.

 

Of course everything has to be built.  There are dozens of processors to program.

 

 

with options in EEPROM or similar can often be a good idea

 

Why would putting in EEPROM be a good idea for this case?  

 

 

I would assume you have one single set of source files.   Each project accesses as "linked files"

 

Yes, of course there is only one file shared between all the projects.

 

Everything works fine (and has for several years), except changing a symbolic constant in the project properties does not force a rebuild in that project.  As I mentioned, that only "bites" me when I set up a derivative solution.  Now that I'm aware of it, it's no big deal to do rebuild of individual projects instead of counting on rebuild of the solution to force recompilation.

 

I just needed to understand how "Start Up Project" works.  

 

Thanks again! 

 

 

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

davethomaspilot wrote:
There would need to be something at runtime to test. 

Yes, there would.

 

Or some sort of command/control interface ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

davethomaspilot wrote:

There would need to be something at runtime to test. 

 

Yes, there would.

 

Or some sort of command/control interface ...

 

Even with such an interface, each pcb would need a unique address, wouldn't it? 

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

Not necessarily; eg, if it's just a UART, you know which one you're talking to

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still don't get it.

 

Say you have 10 processors on an SPI bus or I2C bus.   No resistor jumper or similar to make the hardware different.

 

Fruther assume each processor has the exact same microcode (exactly my case, but the code actually differs only in a constant which defines that pcb's address).

 

Anything sent by an master will be received by ALL slaves, since there is nothing to that can be sent that will be recognized by one and only one of the identical pcbs.  

 

Am I missing something?  If there's a way to use I2C or SPI to get an unique address to each processor with all running the exact same code and nothing initialized differently in EEPROM, that would be interesting.

 

 

 

 

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

Which device?  E.g. ATmega328PB include a unique serial number in the signature row, can serve as an address, or as the source for a hash which generates an address.

 

For devices lacking serial numbers, slaves generate a random address on first run, store it in EEPROM, use it thereafter.  Random numbers can be generated by simple code which leverages jitter between system clock and the WDT.

 

Master can perform a device discovery procedure to identify addresses of connected slaves.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Which device?

Attiny24 on previous implementations,  Attin1614 on spin off implementation.

 

Random addresses won't work.  Each address would have to be associated with the processor's physical location.  Or, there would have to be a way to know the physical location of address.

 

For example, the pcbs are all aligned vertically.  The top most processor must strobe its inputs during timeslot 0, the second to the top must do that during timeslot0 and timeslot1,   the third during timeslots 2, 3, and 4, etc.  

 

So, even with a unique address for each pcb, I'd still need a way to determine which address was in each physical location.

 

Sorry I didn't mention that originally.

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

davethomaspilot wrote:

Am I missing something?  If there's a way to use I2C or SPI to get an unique address to each processor with all running the exact same code and nothing initialized differently in EEPROM, that would be interesting.

 

Yes. Dynamic IDs.... https://www.ibrtses.com/embedded...

 

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

I read that. 

 

So, each "slave" could get a unique address.  But, there would be no way to tell the physical location of each processor, or for individual processors to know their physical location.

 

 

 

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

davethomaspilot wrote:

So, each "slave" could get a unique address.  But, there would be no way to tell the physical location of each processor, or for individual processors to know their physical location.

That could (should?) be designed into the rack i.e. the address is communicated to the slave by virtue of its position in the rack.  With 12 slaves, a 4-bit address is sufficient.  If you can't provide 4 I/O lines to do it, a single line with an analog voltage would be another way.

 

Maybe you could explain more about the system as a whole?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

joeymorin wrote:

davethomaspilot wrote:

 

So, each "slave" could get a unique address.  But, there would be no way to tell the physical location of each processor, or for individual processors to know their physical location.

That could (should?) be designed into the rack i.e. the address is communicated to the slave by virtue of its position in the rack.  With 12 slaves, a 4-bit address is sufficient.  If you can't provide 4 I/O lines to do it, a single line with an analog voltage would be another way.

 

Maybe you could explain more about the system as a whole?

 

There is no "rack".   PCBs are fastened to a 3/4" wide aluminum strip spaced 3" apart and connected via ribbon cable.

 

Among other things, each pcb is monitoring a set of IR receivers.  There are certain timeslots when the monitored receivers are checked.  Each pcb has two or three timeslots when its IR receivers should be checked.

 

As I mentioned earlier, I could use solder jumpers to make each card unique.  But, it's much more hassle to configure solder jumpers (or something like a dip switch) rather than program the right binary into each processor after it's mounted on the strip.

 

"a single line with an analog voltage would be another way."   There would need to be a way to make the analog voltage unique to every card.   Tjat would require a hardware difference to uniquely identify each pcb

 

Seems you need to pick whether each pcb hardware will be identical, or whether the programming will be identical.  For my application, having the hardware identical is better.   

 

 

 

 

 

 

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

Surely you configure the "system" at installation.   e.g. blink an LED or play a tune for each unique board address.

The installer moves them into a convenient logical order via a GUI.   Just like you move items in any software.  e.g. to make all the LEDs light top to bottom.

 

Think about it.   Many systems are built from identical blocks.   The Field engineer does not have to order a unique serial number.   She simply runs the test software.   And reports the new ID that she has installed into the specific physical location.

 

David.

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

davethomaspilot wrote:

There is no "rack".   PCBs are fastened to a 3/4" wide aluminum strip spaced 3" apart and connected via ribbon cable.

 

Ah, now it gets easier. You run an extra line in your ribbon which loops through each slave, which is under software control of each slave. You can now instruct each downstream unit to ignore any comms until the upstream unit is configured.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

Yes, that would work.

 

 

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

david.prentice wrote:

Surely you configure the "system" at installation.   e.g. blink an LED or play a tune for each unique board address.

The installer moves them into a convenient logical order via a GUI.   Just like you move items in any software.  e.g. to make all the LEDs light top to bottom.

 

Think about it.   Many systems are built from identical blocks.   The Field engineer does not have to order a unique serial number.   She simply runs the test software.   And reports the new ID that she has installed into the specific physical location.

 

David.

 

I don't see any advantage versus what I have been doing.  No unique serial numbers are required, all pcbs are identicaql.

 

Each processor must be programmed.  The "system configuration" is simply picking the right binary for each timeslot.

 

I could write a GUI to pick the right binary by clicking on a picture (or something similar), but it's really not a problem as is.  

 

Doing something automatic like Brian Fairchild suggested would simplify things a bit, only in that I would use the same file regardless of timeslot.   I might play with that, but its a relative low priority at this point. 

 

But, Brian's suggestion would require two ribbon cable connectors on each card instead of a pass through cable on a single ribbon connector.   I think that's what you mean by "loops through". 

 

It can't be a "bus" where all processors are looking at the same ribbon cable wires.  But, I may end up using two connectors on the derivative project anyway (for other reasons)--if so I'll make one of the signals in and out of the processor so I can play with the idea if I have time.

 

Thanks