Pages: [1]   Go Down
Author Topic: Programming via AS6.0  (Read 1185 times)
0 Members and 1 Guest are viewing this topic.
Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm slowly moving to writing code in Atmel Studio 6.0.  When uploading via an STK500, it blows away the Ardiuno bootloader, which I expect to happen.  However, I'm faced with one small project with one of my projects.  First, the gist of the installation:

I have several 328p in a custom design driving LED strings.  All the nodes are linked together for both serial communication as well as I2C.  Here's the fun part: when I want to update the code on all the nodes, I upload it to the first one in the group.  Once uploaded, I press (and hold) a button which sends a reset signal to the next node in line.  When that next node resets the first one starts dumping its memory contents via serial to the one that just reset.  A few seconds later and the second node now has the same (new) code that the first one has on it.  I can keep doing this with all the nodes simply by going down the line, one by one.  If you want more info on how this is done, it comes from George Caley's replicating code: https://github.com/spake/Arduino-Copier (look at the BlinkVirus example, specifically the Copies.pde code.)

Here's the thing, in order for that to work, I need the same ability that the Arduino bootloader is providing when it resets; it listens for serial data.  Without that, the replication fails.  And since uploading data from AS6 blows away the bootloader, I'm stuck ... unless I can figure out how to have that 'listening for serial data' part.  And that's where I'm stuck and wondering if anyone has any idea of how I can accomplish this with AS6, OR a different way to do the replication where I don't need the Arduino bootloader.
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 132
Posts: 6744
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So except for the very first arduino, you're expecting to use the bootloader to program the boards, rather than ISP programming (you said they only have a serial connection.)  The bootloader does more than just "listen for serial data"; it's the bootloader that is responsible for reading that serial data and programming the sketch into the chip; otherwise you'd need SPI connections between the master and target...

If you want the board to self-replicate over serial, you'll have to (manually) install the bootloader on them first, using an ISP programmer.
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Semi correct, they have serial and I2C connection.  The ISP port is being used to drive LED strings though there's nothing that says that I can't modify the circuit to use those pins during boot up, prior to the sketch starting up.

However, the sketch being used uses the serial port to replicate itself onto the next board in line.  So that's why I need to be able to have that serial communication.

I, personally, don't know how to do this, as in being able to have one node send it's currently running code on to another node.  And George's method is perfect for what I want to do and in testing it works beautifully.

So the next question you may have is, why not leave all the nodes with a bootloader on them and only have the master without (being burned via the STK500.)  While that is certainly a possibility, considering that the replicating code itself is already taking up space, there's a good chance that I will run out of space with my own code, so being able to reclaim the bootloader space would be desirable at some point.  Or, I may have to jump up to a larger AVR.

I'm starting to get the feeling that I may have reached a roadblock with this particular issue ...  smiley
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 132
Posts: 6744
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To burn new code over either serial or I2C, you would have to have a bootloader on the target chip.
SPI is the only interface that doesn't require a bootloader.  (but if you have SPI and reset wired up, you would not need any kind of "wait" functionality on the target; via SPI the master has full control over the operation of the target.)
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Right, that I know.  But what I don't know how to do is send the running code (in flash memory) on the first node to the next node (using whatever method) when there's no bootloader present on the target node.  I'm having a hard time trying to understand the method that George uses, all the byte codes ...
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12849
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Sounds very similar to René Bohne's work (without the reset button thing)...
http://forum.arduino.cc/index.php?topic=8869.0
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12849
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When uploading via an STK500, it blows away the Ardiuno bootloader, which I expect to happen.

I don't expect that to happen.  In theory, a bootloader will always be capable of programming faster than an external programmer.  Have you tried increasing the baud rate (that's the limiting factor)?  From my tests, the saturation point is at 500K (I now use 1M exclusively).
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When uploading via an STK500, it blows away the Ardiuno bootloader, which I expect to happen.

I don't expect that to happen.  In theory, a bootloader will always be capable of programming faster than an external programmer.  Have you tried increasing the baud rate (that's the limiting factor)?  From my tests, the saturation point is at 500K (I now use 1M exclusively).

Are you suggesting that the bootloader stays intact when uploading via ISP?  That's not my experience ...
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sounds very similar to René Bohne's work (without the reset button thing)...
http://forum.arduino.cc/index.php?topic=8869.0

Yep, except:
a) that's for a TINY which is too small for my project
b) that too requires a (custom) bootloader
c) when uploading via AS6 using an STK500, it gets rid of the bootloader

So I have to figure out a way to do this on AVRs that don't have a bootloader on them, which means I'm left with the SPI option only I think.  Redesigning the nodes to have those pins interconnected isn't that big a deal and I'm willing to do that if that's what it will take.

However, I don't know how to do that: copy the current running node's flash memory and fire it down the ISP connection to the next one.  And there is no real reason to have a button reset other than that's how the self-replicate code does it.  I suppose I can have each node check its neighbors periodically for a version number and if it's different they can automatically initiate communications to start a flash dump.

And perhaps this is something I should take over to AVRFreaks as it doesn't necessarily pertain to Arduino (either as the IDE nor bootloader) anymore ...
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 145
Posts: 5457
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Right, that I know.  But what I don't know how to do is send the running code (in flash memory) on the first node to the next node (using whatever method) when there's no bootloader present on the target node.  I'm having a hard time trying to understand the method that George uses, all the byte codes ...

If you hold the reset line low you can write directly to an AVR chip's memory using the SPI interface. All the details are in the datasheet.

To program chips in a chain, each chip needs to control the RESET line of the next chip in the sequence and have the SPI bus connected.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you hold the reset line low you can write directly to an AVR chip's memory using the SPI interface. All the details are in the datasheet.
That, is good to know.  Next I have to figure out how to read the current (running) chip's flash memory and dump it to the next.  I think all I have to dump is the hex that's in memory and shove it out to the other chip.

To program chips in a chain, each chip needs to control the RESET line of the next chip in the sequence and have the SPI bus connected.
Yeah, that's how the self-replicate code does it right now, except it's done over serial.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12849
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you suggesting that the bootloader stays intact when uploading via ISP?  That's not my experience ...

I apologize.  I completely misunderstood what you meant by "it blows away the Ardiuno bootloader".
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12849
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

a) that's for a TINY which is too small for my project

Yes.  But the technique works for any AVR processor (that has serial programming enabled).

Quote
b) that too requires a (custom) bootloader
c) when uploading via AS6 using an STK500, it gets rid of the bootloader

In your case, you would be stealing the relevant code and integrating it into your program.

The LumiNet code works by serial programming the neighbors.  I believe it's essentially where you are headed.  (With one exception: I believe the LumiNet code uses a bit-banged SPI rather than the hardware; something you may want to consider doing.)

Quote
So I have to figure out a way to do this on AVRs that don't have a bootloader on them, which means I'm left with the SPI option only I think.  Redesigning the nodes to have those pins interconnected isn't that big a deal and I'm willing to do that if that's what it will take.

You do not need to necessarily interconnect the SPI pins.  The "master" can use any four pins (via bit-banging).  You will have to connect to the SPI  pins on the "target".

Quote
However, I don't know how to do that: copy the current running node's flash memory and fire it down the ISP connection to the next one.

That's something that can probably be stolen from LumiNet.  It the simplest form, you will be reading a chunk from Flash then using the serial programming interface to write that chunk to the target.

Quote
I suppose I can have each node check its neighbors periodically for a version number and if it's different they can automatically initiate communications to start a flash dump.

Were I in your shoes I would start with a daisy-chain architecture.  Each node would be a master to exactly one target.  When the ultimate master is updated, it updates its target and on down the line.

The sequence might go something like this...

• You upload a new version to the ultimate master
• During startup, the ultimate master detects that it has restarted because of RESET
• It clones its memory image to its target
• The first target does exactly the same thing

Quote
And perhaps this is something I should take over to AVRFreaks as it doesn't necessarily pertain to Arduino (either as the IDE nor bootloader) anymore ...

Are you going to share?  Is it an art project?
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In your case, you would be stealing the relevant code and integrating it into your program.
I prefer the word "borrow". smiley  I know, I'm not giving it back, but it's also not a top secret thing, so anyone can have it afterwards.

Were I in your shoes I would start with a daisy-chain architecture.  Each node would be a master to exactly one target.  When the ultimate master is updated, it updates its target and on down the line.

That's pretty much how it is now:

All the nodes are daisy chained together.  Currently, the only pins interconnected, are VCC/GND/TX/RX/I2C, and pin 7 connected to the reset pin of the next node.  I can add others since I am redesigning the nodes anyway.

The sequence might go something like this...

• You upload a new version to the ultimate master
• During startup, the ultimate master detects that it has restarted because of RESET
• It clones its memory image to its target
• The first target does exactly the same thing

Yeah, right now I upload to the first node and hit a button which then causes the self replication code to run which causes the next node to reset and start receiving data over serial.  When it's done, it goes back to what it was doing while the next node boots back up.  I move to the next node and press its button which triggers reset on the third node and the process repeats ...  It's a manual process, so with a lot of nodes and a long chain, it takes a while.

I was thinking of having all the nodes do a periodic check via I2C to the previous node, checking for a version number.  If it's different, they can then instruct that (previous) node to start the process.

Are you going to share?  Is it an art project?
It's my own personal project.  I have a bunch of LED strips that I put in my windows and it would be nice to not have to tear everything apart each time I need to update the code.  If I can just get to the first node and update it and let it propagate down the line, that would be ideal.
Logged

Anchorage, AK
Offline Offline
Edison Member
*
Karma: 42
Posts: 1176
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just FYI, about the bootloader...  Some AVRs have a special area of memory reserved for the bootloader.  It is (and can only be) written via SPI, since that's the bare-metal way of programming an empty (or recycled) AVR.  The bootloader is just fancy code that loads first, and optionally writes its own flash memory based on data it receives from an arbitrary source.  Most use serial and something like STK500 for the communication protocol, but others read flash images from SD cards, network interfaces, or whatever.  There's limited space available to the bootloader code, so it has to be relatively compact.

Since you already have I2C between all the chips, if it were me, I would do this:

Assign each chip a unique ID via a couple spare digital I/O pins.  That determines which is the Master.  Everyone else is a Slave (with unique addresses.)  The bootloader can read a byte from EEPROM or flash that holds a version number.  The Master then probes each sequential address until there's no response, asking for version numbers.  When the Slave responds with the same version number, the Master sends an OK code and the Slave continues booting.  When the Slave responds with a different (not just lower, in case you need to downgrade, or you overflow version numbers), then they enter program mode and the Master sends its flash contents.  Once verified, the Master sends OK and the Slave boots.  When the next incremental address returns no response, the Master knows all Slaves are programmed and continues booting itself.

This assures all devices use 100% the exact same code, even down to the bootloader itself, meaning you don't have to maintain a separate flash image for the Master.
Logged

Pages: [1]   Go Up
Jump to: