SD bootloader for AVR

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

I'm looking for a bootloader which reads the hex- or bin-file from the root directory of a FAT32 formatted SD card. The size of the compiled code should be less than 2kB, preferrably less than 1kB.

Does anyone know of such bootloader?

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

Quote:

Does anyone know of such bootloader?

Didja search these forums? There have been threads on that over the years. Recently (IIRC) "clawson" discussed/posted one.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

The problem with these suggestion is the size; they require 4kB. A member of AVR Freaks (Jesper) claims to have built one in only 800 Bytes.

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

If Jesper claims he did it, he did it.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

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

Quote:

The problem with these suggestion is the size; they require 4kB. A member of AVR Freaks (Jesper) claims to have built one in only 800 Bytes.


What did you say earlier?

Quote:

The size of the compiled code should be less than 2kB, preferrably less than 1kB.

What does Cliff's project say? (I assume you clicked through to it...)

Quote:
OK the idea isn't new. But hopefully this implementation is. I wanted to write a bootloader that would fit in 2KBytes of a mega16 and would therefore be suitable for a lot of small AVRs. There are other SD/MMC reading bootloaders but because they tend to use the whole of Fat-Fs or Petit-Fs they struggle to be so small. So I simply took the mmc.c from Petit-Fs (and the asmfuncs.S) which builds to be about 800 bytes to give card init and sector read functions (and the SPI and flash handling code) and then see how little additional code it would take to find a file on an SD card and use that to program the application flash.

Did he achieve this goal? You'll have to look at the project to find out, I guess.

There are bootloaders and there are bootloaders. Some are "full function"; some are limited. Cliff's sounds like he tried to find a middle ground by "hard coding" some SD aspects such as file name to keep the SD interface code size down, and probably limit bootloader functions as well.

You probably can pare down further by e.g. skipping the FAT lookup of the file name and hard-code a sector address? But that makes the setup unique, like having a single file on a clean SD card.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:

Cliff's sounds like he tried to find a middle ground by "hard coding" some SD aspects such as file name to keep the SD interface code size down, and probably limit bootloader functions as well.

My project page:

http://spaces.atmel.com/gf/proje...

Describes the limitations/compromises I made:

Quote:
Note that because this bootloader has been built to fit into a very small bootloader space there are some necessary restrictions on its operation. For one thing it can find the root directroy but when looking for the AVRAP file it only considers the first 512 byte sector so the file has to be one of the first 16 entries in the root directory. What's more as soon as the text AVRAP is found it stops looking. So if you copy AVRAP003.BIN and then AVRAP007.BIN to a card it will only "see" AVRAP003 as that comes first and stops the search. In use this means it's best to (a) use a card with virtually nothing else on it and (b) for each update delete the existing AVRAPPnnn.BIN file then copy the new AVRAPn+1.BIN to it (so it reuses the previously used position in the root directory).

Also note that I have a number of build options - lines 61 to 86 in the main source file:

http://spaces.atmel.com/gf/proje...

If you switch all those off by commenting the #defines you can get the code into 1K. It may not meets Jesper's 800 bytes but it gets fairly close to:

Quote:

The problem with these suggestion is the size; they require 4kB. A member of AVR Freaks (Jesper) claims to have built one in only 800 Bytes.

In operation the bootloader works as follows. At power on it reads an existing location in EEPROM (the last 2 bytes) - line 261. It then attempts to mount the SD card - line 265. Assuming that succeeds it reads the housekeeping sectors of the FAT system to determine where the root directory/data area - lines 267..299. It then reads the first sector of the root dir (line 302) and scans for any filename that begins AVRAP (lines 304..319). It then interprets the following 3 characters in the name as digits of a BCD number (allowing for "000" to "999") - line 320.

If the stored EEPROM version number read early is either 0xFFFF (no version yet setor failed during previous update) or if the EEPROM number is less than the number read from the filename it instigates an update (line 321).

It starts by setting the EEPROM version back to 0xFFFF so that if the update is interrupted, at next power on it will restart the process. The value 0xFFFF also prevents any possible attempt of the app code being launched (assuming SD is not found at next power on). (lines 322.326)

Without cluster (ie FAT chain) support enabled the code then just uses the "1st cluster" field of the AVRAPnnn entry to find the data to be programmed into app space. In such a case the entire app has to fit into a cluster (usually 32KB on 1..8GB cards). If cluster support is built in then it can follow cluster chains when it reaches the 32KB (or whatever) boundary.

For each sector read from the cluster it divides it into chunks of SPM_PAGESIZE and programs each in turn. (lines 352..356)

Another compromise of the design is that it always programs flash from 0x0000 onwards. There's no way to specify a non-0 start address. (line 352 - add an offset there to program elsewhere)

Once the entire app space has been programmed (or the single cluster is exhausted if support for cluster following is not enabled) the update ends and the new version number (the nnn from "AVRAPnnn") is written into the end of the EEPROM. This re-validates the app space so it can be launched next time (line 395). If CRC checking is enabled this update can only occur if the programmed app space passes a CRC check (line 393).

On the occasions that either the SD cannot be mounted at power on or the EEPROM stored version number matches the AVRAPnnn number first found on the card (it's up to date) the bootloader then falls into the launch code at line 405

How the integrity of the app is checked before launch will depend on the build options used. In the simplest case it simply checks that the EEPROM stored version is not 0xFFFF (no app ever programmed or interruped during an update) - line 416 and that the very first word in flash is not 0xFFFF (no valid AVR program has 0xFFFF in location 0) - line 420.

If the CRC checking stuff is built in then the app is checked for a valid CRC before each launch (line 418 calling the stuff at lines 149..179).

The app entry is simply by a call through a function pointer set to 0x0000. There's an argument to say that I should watchdog reset at this point to reset SFRs but the bootloader has only really changed SPEN and some DDR bits away from default so I don't think it matters.

Enjoy.

Cliff

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

Thanx for the most comprehensive explanation to your code, clawson! I have tried to download the source file via https://spaces.atmel.com/svn/sdb... and username anonymous, but only a blank page pops up.

Can I use Release 1 and the replace the updated files by downloading them one after one?

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

Yup Release1 should be just fine. I'm surprised anonymous SVN access doesn't work but sadly I have no control over that as I'm using Atmel's site to host the code.

Release1 was at revision 20. HEAD is 21. This page shows what I changed between 20 and 21:

http://spaces.atmel.com/gf/proje...

Most of that are actually just text/comment changes after I got some very useful feedback from another user.

This is how main.c changed:

http://spaces.atmel.com/gf/proje...

and uart.c:

http://spaces.atmel.com/gf/proje...

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

Quote:

Cliff's sounds like he tried to find a middle ground ...

Revisiting my earlier statement, there seems to be a perfect example of the tradeoffs from just the limited info given in this thread.

Cliff wondered what could be done in a modest bootloader space, and chose a 2k partition as the target. leifindr would prefer smaller, say 1k partition.

Now, Cliff addressed the issue of specifying the boot image file name ...

Quote:

At power on it reads an existing location in EEPROM (the last 2 bytes) - line 261.

... and doing some version number comparison(s).

Consider that a 1k bootloader partition has about 500 AVR instruction words. Some instructions would be two word, so "there are less than 500 AVR instructions to work with". There is the flash erase/write, integrity checks, and the like for the actual bootloader process, and then there is the storage/commo interface which is an SD card in this case.

Now, back to the point: An AVR EEPROM read routine is about 12 words. 2.4% of total space right there. Add a few calling sequences and we might be up to 5% of total space. (yeah, I do realize that one could know inf interrupts are enabled or not, and also assume no EE writes so skip the ready test. Still some words; 10 words is 2%)

These are the kind of tradeoffs made. To squeeze into 1k you probably have to dispense with this type of nicety (EEPROM use).

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I use the sdbootloader now on an ATmega32U4, and it all seems to work pretty well apart from a minor issue; In my application program, Timer Interrupt 0 doesn't seem to work anymore, all other functions and interrupts are OK.

I have tried the different suggested ways of starting the app from the bootloader, but all with the same result. I suspect the app code for not being compeletely loaded, so I tried to enable the #define CRC_FLASH just to have a check (it still compiles at < 2k). But... using the srec_cat.exe isn't easy.

I have come across a manual for srec_cat (http://srecord.sourceforge.net/m...), but the options are so many.

Can anybody tell me in how to convert the Intel-HEX image into a Binary image with a CRC-16 appended?

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

Found the answer on http://spaces.atmel.com/gf/proje... :lol:

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

Quote:

Found the answer

Really? ;-)

BTW did you resolve the timer1 issue? There's nothing I can think of in the bootloader that would have any influence on the use of timer1, so you may well be right that it's not fully programming.

BTW during testing I either used JTAG or ISP to look at what was in the flash after programming to see if what ended up there was what I had planned (though I found an issue in AS6 in that it does not always update it's flash view windows as it presumably doesn't think the flash could change once the code is loaded?)

Oh and this may be obvious but the source and project files have various number hard coded that reflect the memory layout of a mega16 or a mega32. In things like my srec_cat example :

srec_cat $(MSBuildProjectDirectory)\$(Configuration)\$(Output File Name).hex -intel -fill 0xFF 0x0000 0x37FE --l-e-crc16 0x37FE -o AVRAP001.bin -binary

the 0x37FE will possibly need to be changed. That number is for a mega16 that has app space from 0x0000..0x37FF and the bootloader from 0x3800..0x3FFF. If you build the bootloader bigger/smaller it may be necessary to change the BOOTSZ and hence these boundary addresses. 0x37FE is (obviously?) the last 2 bytes of the app flash space and is the obvious place to put the 16bit CRC.

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

Hi clawson,

Yup, I did the necessary changes and it all work as a charm now. The Timer0 interrupt issue was on me; I forgot to program the EEPROM with some necessary values :lol:

The only remaining thing to resolve is the limitation of the AVRAPxxx.BIN being one of the 16 first files on the SD. My application writes multiple files to the SD, and when connected over USB to a PC the user is free to delete or add files (as a memory stick). I foresee a problem if the user deletes the AVRAPxxx.BIN and a new AVRAPxxx.BIN will be placed as file# 16+.

My app only use the SD root (no directories). Is there a simple way to extend the search for AVRAPxxx.BIN beyond the first 16? You suggest as comment in main.c,

Quote:
There is potential to wrap an outer loop around this one that does disk_read(RootDir + i)'s to consider more than one sector. Someone feeling REALLY brave could flesh this out still further to follow the cluster chain for the root dir but by the time you get to that point you are probably building code so large that you might as well just use ChaN's original avr_boot within pfsample.zip!

But I'm not sure if this will include directories as well (...which is not necessary in my app).

Last Edited: Fri. Oct 4, 2013 - 12:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I foresee a problem if the user deletes the AVRAPxxx.BIN and a new AVRAPxxx.BIN will be placed as file# 16+.

Don't worry. FAT allocation in both Windows and Linux (vfat) will simply scan the root for the first 0xE5 or 0x00 entry and use that. So as long as you delete/recopy it wil re-use the slot as it'll be the first "empty" (well 0xE5'd) one.

If you want to have it scan multiple sectors of root then put the disk_read() here in a loop:

		// ready to read the root directory sector
		disk_read(RootDir);
		
		// scan the root dir for "AVRAPnnn", entries are 32 bytes each
		// Note this will only scan one sector (the first 16 entries) of the root directory so it relies
		// on AVRAPnnn.BIN being positioned there. What's more it stops looking as soon as the AVRAP text
		// is found so if the directory held AVRAP003.BIN then AVRAP007.BIN the latter would never be
		// seen. It's therefore best to use an SD card that only ever contains a single AVRAPnnn.BIN, 
		// replace it completely if updating to a later version. If there are other files then as long as
		// the existing AVRAPnnn.BIN is deleted and then the new one copied it should re-use the early
		// directory slot that was being used previously.
		//
		// There is potential to wrap an outer loop around this one that does disk_read(RootDir + i)'s
		// to consider more than one sector. Someone feeling REALLY brave could flesh this out still further
		// to follow the cluster chain for the root dir but by the time you get to that point you are 
		// probably building code so large that you might as well just use ChaN's original avr_boot within
		// pfsample.zip!
		for (uint16_t i=0; i<512; i+=32) {
			if (mem_cmpP(&Buff[i], PSTR("AVRAP"), 5) == 0) {
				filever = ((Buff[i+5]-'0') << 8) | ((Buff[i+6]-'0') << 4) | (Buff[i+7]-'0');
...

Use disk_read(RootDir + N). As the root dir (in FAT32) is just a cluster chain then you are OK just incrementing N for a full cluster (so 64 sectors probably) but after that you would need to complicate the loop further by then adding FAT link tracking (as seen later where I read the data and CLUSTER_SUPPORT is enabled).

I sort of explained al that in the comment above. As I noted there:
but by the time you get to that point you are

probably building code so large that you might as well just use ChaN's original avr_boot within  pfsample.zip!
======================================================================================================

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

But what happens if the user deletes the AVRAPxxx.BIN and then copies another file onto the SD (or the app does it) before a new FW upgrade is necessary and a new AVRAPxxx.BIN is copied?

I have searched for methods to prevent the user from deleting the file, e.g by password protection. But cannot find any good solution. Is there a way around?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
attrib + file

But here's a mad idea...

.. buy TWO cards. Keep one for doing the updates and use the other for day to day logging. Just dog the app update one out of the draw every 3-6 months when you feel a f/w update is required.

Problem solved.

(and in your scenario, as I say, directory slot allocation is simply sequential so if you filled the "early slot" with something else then, yes, the app image you copy next will be put way down the end if there are no other reusable slots near the start).

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

If I was the only user, your suggestion would probably be OK. But the SD card is also a little hard to get at, so for any user to swap SD is unrealistic :?

Maybe I could name the files DO_NOT_DELETE_xxx.BIN? Then at least the user has got a warning :twisted:

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

I could even make the DO_NOT_DELETE_xxx.BIN file Hidden, then most people won't even see it :wink:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
DIR /A

will reveal hidden/system files.

One idea is to make it "not a file". The attribute bits for a FAT entry include 0x20 which sets it to be a "device". AFAIK this bit has never actually been used (in a project I used to be involved in we therefore used it to keep something hidden). You cannot, however set the bit simply by a DOS COPY/XCOPY/ATTRIB command so you would need to use code in the AVR (easiest) to read the dir sector, change the bit and then write it back.

BTW I wouldn't use anything but 8.3 names (i.e. non LFN) as they EAT directory entries otherwise!

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

Thanx for the tip, clawson! I'll stick to 8.3.

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

Quote:

But the SD card is also a little hard to get at, so for any user to swap SD is unrealistic

So then how are you going to get an updated firmware >>to<< the SD card?

As I follow this thread, you seem to be conflicted. At first you seemed to be aiming at "smallest code size" as the primary goal. As the thread progresses I get the feeling that more features than bare-bones are desired.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Up till now I have used a DFU bootloader (over USB). This takes 2k, and the rest of the flash (30k) is almost filled up. To avoid all the mess with the Flip bootloader and USB driver for all types of platforms I thought it was a good idea to use an SD bootloader instead.

Since the unit connects as a Mass Storage Device on any PC, the USB driver issue is history. And to drag-drop an update file to the SD card seens a good idea. Upon next boot, the FW update takes place and everybody is happy.

The unit writes files to the SD card continuously (it's a logger), and every month it logs data to a new file. That's why I am afraid that the user shall delete the AVRAPxxx.BIN and that it's place shall be occupied by a new log file.

Understand? But now it seems to work smoothly so far :D

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

If using 32U4 then the 2KB max limit is unassailable. So I guess the question is simply how much you can actually squeeze into the 2KB.

As it stands the build sizes for 32U4 are:

All options enabled:   2492 bytes (too big!)
-UART_DEBUG:           2132 bytes (360 bytes)
-FLOOD_RAM:            2116 bytes (16 bytes)
-CLUSTER_SUPPORT:      1610 bytes (506 bytes)
-CRC_FLASH:            1514 bytes (96 bytes)
-FAT32_SUPPORT:        1406 bytes (108 bytes)

UART_DEBUG is only really there for me so I imagine most people would turn that of before they start (though if it's not working it's useful if you can turn other stuff off so it fits). The big hitter there (not surprisingly) is CLUSTER_SUPPORT at 506 bytes. You only need that if the app image files are going to be larger than the cluster size. As I principally intended this bootloader for chips that are 32K or less (the ones that have 2K or smaller bootloader sections) and because 1GB+ cards will have 32K clusters you could usually switch CLUSTER_SUPPORT off. FLOOD_RAM, again is just for my debug but as it only costs 16 bytes it might as well stay on until one is <16 bytes over. The code works nicely without the CRC stuff (and it's simpler to build the app code) so that could be a useful 96 byte saving. As most 1GB+ cards are FAT32 not FAT16 then I'm guessing FAT32_SUPPORT always would be switched on.

I haven't tried it (yet!) but I'm guessing that to have the root reading code loop over 64(?) sectors is probably going to add back less than 100 bytes. 32KB of root directory can hold 1024 file entries (if no LFN) so as long as the cards aren't likely to have >1024 files in the root this should be worth doing. When (if) I get it to work I'll update SVN.

I'll probably update "Spaces" anyway with that size table above as I think it's likely to be useful to other "shoppers".

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

As I wrote earlier I compile this project in AVR Studio 4. I have installed Studio 6, but since I only now and then do AVR programming I find Studio 6 a little overcomplicated.

However, it seems like Studio 4 compiles to larger files than the sizes you have, clawson. Yes, I have the -Os on, so compilation should be size optimized. The 1514 bytes in the table above compiles to 1850 bytes in Studio 4.

But it still fits within the 2k (max) size in the 32U4.
Would it be advisable to run the compilation on Studio 6 or is there a setting in Studio 4 I have missed?

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

Studio 4 does not contain a C compiler. It's the compiler you use that may mostly influence code sizes. AS6 comes with a compiler (most recently 4.7.2). My sizes are based on that (and using all the settings I have in the supllied AS6.1 project files).

You can get Atmel's 4.7.2 toolchain to work with AS4. In fact if you have AS6 installed you should be able to persuade AS4 to use its compiler.

Personally, as AS6 is better in almost every way than AS4 I don't see any reason not to use it.

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

I've tried to compile the project in AS6.1, but the make-file(s) seems to be hard-coded for AS6.0 and folder "C:\Program Files\Atmel...".

Substituting "Program Files\Atmel\Atmel Studio 6.0" with "Programfiler (x86)\Atmel\Atmel Studio 6.1" (My PC runs Norwegian Win7) helps a little, but trying to locate avr-gcc.exe in the jungle of folders is a nightmare. At least for me.

So I've given it up for now :cry:

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

Quote:

but trying to locate avr-gcc.exe in the jungle of folders is a nightmare. At least for me.

In a Windows explorer, at C:\, type "filename:avr-gcc.exe" in the search box top right.

On a command prompt, with C:\ as the current directory, type "dir /s /b avr-gcc.exe".

Both procedures might take some time, depending on the size of your hard-disk content. But they will ultimately tell you where all instances of avr-gcc.exe is. Just go make a cup of coffee while your computer is working for you. :D

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

And so I did, Johan. Found it at "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin" (Puh!)

Now it compiles in a way, but ends up with

The command "rem if these cause an error just rem them or get my avr-source program
rem avr-source mmc.s
rem avr-source uart.s" exited with code 9009

If I double-click this message, an xml-file opens and highlights this line

Sorry, but this goes far beyond my knowledge of SW
:roll:

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

Quote:

The command "rem if these cause an error just rem them or get my avr-source program
rem avr-source mmc.s
rem avr-source uart.s" exited with code 9009

That's my build post-processing using my own tool (avr-source). Either copy that to your PATH somewhere or just remove those commands completely.

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

clawson,

I want to rebuild your bootloader a bit. What I want is to extend the search for the file entry beyond the first sector. In your original code you state:

		// There is potential to wrap an outer loop around this one that does disk_read(RootDir + i)'s
		// to consider more than one sector. Someone feeling REALLY brave could flesh this out still further
		// to follow the cluster chain for the root dir but by the time you get to that point you are 
		// probably building code so large that you might as well just use ChaN's original avr_boot within
		// pfsample.zip!

To do so, I have a couple of questions,

1) What should be the limitation for i if I wrap the outer loop?
2) If the file is found, is the cluster address absolute so I can us this code directly

					p16 = (uint16_t *)&Buff[i + DIR_FstClusLO];
					firstclust = *p16;
#ifdef FAT32_SUPPORT
					if (fat_offset == 2) {
						p16 = (uint16_t *)&Buff[i + DIR_FstClusHI];
						firstclust |=  (uint32_t)*p16 << 16;
					}
#endif					

My intention is to name all update files e.g. AVRAP.BIN, and then let the application delete this file itself after the bootloading. In this way I can omit the version check and EEPROM stuff.

Hope you can assist me a bit on the way :)

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

Quote:

What I want is to extend the search for the file entry beyond the first sector.

I'm doing that too (prompted by you).

1) As I say 64 would seem the obvious choice assuming 32KB clusters (because there are 64 sectors in a cluster) but one shouldn't really hard-code things like this. The BPB contains a field BPB_SecPerClus so you should use that to know how many to iterate over. I already read this to a variable called SecPerClus.

2) Yeah that code still works. A 32 byte directory entry is always:

http://en.wikipedia.org/wiki/Fil...

#define DIR_FstClusLO 26

So for FAT16 it reads [26]/[27] (ie 0x1A/0x1B) to get the first cluster. For FAT32 (that is fat_offset == 2) it additionally uses:

#define DIR_FstClusHI 20

so forms a 32bit cluster number using [20]/[21]/[26]/[27] (0x14/0x15/0x1A/0x1B).

Quote:

and then let the application delete this file itself after the bootloading.

The bootloader could do this - it just has to rewrite the sector where the file was found with the first byte of the 32 set to 0xE5. Of course you'd have to add a disk_writep() back to mmc.c to be able to do writes.

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

Since the USB Mass Storage algorithm is in the app, I thought it would be wise to let the app do the delete. Just in case the new app doesn't work properly you wouldn't be totally lost (or have to move the SD card to the PC slot).

Will you post your code when it's finished?

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

Quote:

Will you post your code when it's finished?

Yup. I've added a tracker item to the project:

http://spaces.atmel.com/gf/proje...

I'll keep that updated with progress. If you have an ID on "spaces" I notice that has a "Monitor item" option. I think you will then get updates posted to your account when anything changes (not sure if they can then trigger an external email?)

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

Just added the multi-sector-search, and it works OK. Needed some thinking to figure how to escape from the loop when programming was done, but I used a simple flag. Not too elegant, but it works :D Did the following additions/changes to main.c:

		uint8_t x = 0;
		uint8_t flashed = 0;
		do
		{
			disk_read(RootDir + x);


           // Same code as version 21 here

					}
					flashed = 1;
#ifdef CRC_FLASH					
					if (crc_app_ok())
					{
#endif						
						eeprom_update_word((uint16_t *)E2END - 1, filever);
#ifdef CRC_FLASH
					}
#endif
					break;
				}
			}
		}
		x++;
		} while(!flashed && (x < 64));

EDIT 1: The hard-coded (x < 64) should probably be replaced by (x < SecPerClus). If no AVRAP is present, hunting through 64 sectors for the file will take around 1 sec (at 8MHz MCU clock).

EDIT 2: Will an entry starting with 0x00 indicated that there are no entries beyond? Since deleting a file will mark it with 0xE5 I suppose this is the case. Then the search can be aborted once a 0x00-marked entry is found.

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

Note that I have committed revision 22 to SVN then tagged it as "Release2" at revision 23. The check-in comment was:

http://spaces.atmel.com/gf/proje...

and a diff of main.c is:

http://spaces.atmel.com/gf/proje...

As you can see the new stuff is added under ROOT_MULTISEC which may be defined (is by default) in the newly created configure.h:

http://spaces.atmel.com/gf/proje...

I did this independently of you but in the end our changes ended up being remarkably similar.

The project description including the table of sizes (and even the picture ;-)) is also updated here:

http://spaces.atmel.com/gf/proje...

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

Nice work, clawson!

From http://www.pjrc.com/tech/8051/id...

Quote:
Unused directory records are a result of deleting files. The first byte is overwritten with 0xE5, and later when a new file is created it can be reused. At the end of the directory is a record that begins with zero. All other records will be non-zero in their first byte, so this is an easy way to determine when you have reached the end of the directory.

Did you take this into account to shorten the search? I did it this way:
...
for (uint16_t i=0; i<512; i+=32)
{
   if(Buff[i] == 0x00)    // Reached last used entry...?
      flashed = 1;
			
   if (mem_cmpP(&Buff[i], PSTR("AVRAP"), 5) == 0)
   {
      filever = ((Buff[i+5]-'0') << 8) | ((Buff[i+6]-'0') << 4) | (Buff[i+7]-'0');
...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi
I tried to build it for an ATmega328p.
Had to change some registers in uart and SPMCSR instead of SPMCR.

The variable flashver gets overwritten so I think its a stack overrun.

When I place flashver = 0xffff;
before if ((flashver == 0xFFFF) || (flashver < filever)) {
then it flashes.
And if I add only some staff like a uart output it doesnt work any more. Reads crab from the SD card.
CRC had to be disabled.

I hope you can help me
Thanks and greetings from Germany
Chris

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

Sadly I don't have a 328 to test it with but I have some 168's I could try. What does the configure.h you are using look like?

As for stack over-run, I think that extremely unlikely. The only major RAM usage is the sector buffer:

BYTE Buff[512];	/* sector buffer */

In a 328 with 2K of SRAM I don't see how there might be RAM starvation. The only other user of RAM is really the automatics in main():

__attribute__((section(".init3"))) int main(void) {
    DSTATUS res;
    uint16_t * p16;
    uint32_t * p32;
    uint8_t SecPerClus;
    uint16_t BytesPerSec, RsvdSecCnt, BPBSec, filever, flashver;
    uint32_t FATSz;
    uint32_t RootDir, lba, firstclust;
#ifdef ROOT_MULTISEC	
    uint16_t root_count, offset;
    uint8_t done_update;
#endif	
#ifdef CLUSTER_SUPPORT	
    uint32_t thisclust;
#endif	
    uint8_t fat_offset;

If you add up the sizes you are only talking about a few tens of bytes. What's more the optimiser usually holds most of these in working registers not stack frame autos anyway.

Anyway I'll dig a 168 out and see if I can build a <2K version that works there.

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

Thanks for your reply
My configure.h:

#ifndef CONFIGURE_H_
#define CONFIGURE_H_

//##########################################################################
//#                                                CONFIGURATION                                                      #
//##########################################################################
//
// The following are used in asmfinc.S for bit-banging SPI to the SD card. These defaults are
// the same as hardware SPI (for mega16/32) so the same wiring can use real SPI once the
// application code starts:
#define SD_PIN      PINB
#define SD_PORT	    PORTB
#define SD_DDR	    DDRB
#define CS_PIN	    4
#define SCLK_PIN    7
#define DI_PIN      5 //i(n to SD card that is)
#define DO_PIN      6

// if the code cannot be programmed/run then the bootloader sits flashing an LED. The
// following two defines say where that LED is
#define LED_PORT	PORTD
#define LED_BIT		6

//  Use the following defines to configure exactly how the bootloader is built. At present the
//  bootloader, built for mega32, with all the optional parts disabled is 1,406 bytes long. It's
//  then up to you to choose which of the additional support you want to enable. But if you are
//  trying to stay under 2048 bytes you may have to be quite selective about which ones you
//  enable. If you have a 4K bootloader section (like this mega32) you can just turn everything
//  on. But otherwise here is your shopping list:
//
//                                                               Enabled by default
//       CRC_FLASH               96 bytes                     Yes
//       FAT32_SUPPORT       112 bytes                     Yes
//       CLUSTER_SUPPORT   442 bytes
//       ROOT_MULTISEC       150 bytes                     Yes
//       FLOOD_RAM              16 bytes
//       UART_DEBUG            374 bytes
//
//  See below for a complete description of each option. With items listed above enabled by
// default the bootloader builds to be 1764 bytes, easily fitting in a 2K BLS.

// define the following if the app images have been built using srec_cat and have a CRC-16 at
// the end of the padded image.
#define CRC_FLASH

// by default the code works for FAT16 (usually up to 2GB cards) to support both (ie include
// larger cards) define the following though it "costs" flash size for the bootloader
#define FAT32_SUPPORT

// if building for mega16 or other 16KB micro then the chances are the clusters on the card
// are also 16KB (32 sectors) so the AVRAPnnn.BIN file will fit within one cluster so there's
// no need for the bootloader to be able to understand FATs and follow FAT chains. If however
// this is built for a micro that might have 30K plus of code but stored on a card with 16KB clusters
// it will be necessary for the bootloader to be able to follow mutiple cluster files through the
// FAT so define this entry, though it "costs" more bootloader flash space-
//#define CLUSTER_SUPPORT

// the original code just read one sector of the root so AVRAP* had to be within the first 16
// directory entries. Make the following define to have it search then entire first cluster of the
// root instead (on FAT32 with 32KB clusters that will be 64 sectors so AVRAP can be in the
// first 1024 files now)
#define ROOT_MULTISEC

// for debug it's often useful to have RAM flooded with a known value so you can stop the debugger
// and see which regions have been written. Define the following to enable this and the following
// entries to say what byte to put in memory and, if necessary what the RAM start address is.
// The C header files have always had RAMEND but only recently do they also define RAMSTART
//#define FLOOD_RAM
#ifdef FLOOD_RAM
#ifndef RAMSTART
#define RAMSTART (0x0060)
#endif
#define FLOOD_VALUE 0x55
#endif

// define the following to pull in and enable the UART debug stuff. See uart.[hc]
#define UART_DEBUG

//##########################################################################
//#                                              END CONFIGURATION                                                #
//##########################################################################

#endif /* CONFIGURE_H_ */

The 168 has only 1024 words boot section.
So debugging is not easy because there is no space for the uart.
I will later try some thinks and I will change from Atmel Studio 6.1 to 6.2

Added my Code that works at the moment but when I add the CRC or change something else everything goes bad.

Attachment(s): 

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

As I noted:

All options enabled:   2596 bytes (too big for 2K!)
-CLUSTER_SUPPORT:      2154 bytes (442 bytes)
-FAT32_SUPPORT:        2042 bytes (112 bytes)
-UART_DEBUG:           1668 bytes (374 bytes)
-FLOOD_RAM:            1652 bytes (16 bytes)
-ROOT_MULTISEC         1502 bytes (150 bytes)
-CRC_FLASH:            1406 bytes (96 bytes)

So to get UART to fit turn off pretty much everything else. This may involve finding (or even formatting) a card to FAT16 if you turn off FAT32 support.

From your config you could certainly live without ROOT_MULTISEC - for a long time the bootloader worked happily before it was even implemented.

Obviously text in UART strings costs so don't use long text - maybe even just a single letter to identify a particular watchpoint.

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

Works great, apart from lba is found as 672. The correct sector is 640, so it only works for me by adding lba=640 after the code below.

All options in configure.h are off.

 

 

                    lba = firstclust - fat_offset; //lba=1
                    lba *= SecPerClus;// lba=64 
                    lba += RootDir;//lba=672 RootDir=608

 

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

Can you post a binary card image of enough to include up to the root dir? I guess that means something like:

sudo dd if=/dev/sdc of=sdimg.bin bs=512 count=700

I guess that will be a 350KB file.

 

It is rather curious that your 672->640 discrepancy is actually 32 - a very binary kind of number (but clearly half the secPerCluster figure?)

Last Edited: Fri. Nov 28, 2014 - 11:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't have sudo, but I guess all you need is the root dir, so have attached image of it.

 

There is only the one file there so not so much - all the root dir data (from 0x4C000 to 0x4C03F ) as text is:

 

E5 56 52 41 50 30 30 31 42 49 4E 20 10 13 A6 5D 78 45 78 45 00 00 8A 54 75 45 02 00 00 70 00 00 41 56 52 41 50 30 30 31 42 49 4E 20 10 13 A6 5D 78 45 7B 45 00 00 93 91 7B 45 02 00 00 70 00 00

 

Also attached image of sector 640, where the file is located. 

 

 

Attachment(s): 

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

but I guess all you need is the root dir

If I'd only wanted the root dir that is all I would have asked for. I want a card image. Most importantly are any MBR and the boot/BP sectors. But what I really wanted to do is dd your image to one of my cards then trace the code to see what mistake I had made in the location of the root dir.

 

At this stage I don't even know if we're talking FAT16 or FAT32 (though I'm guessing fat_offset=1 means it is not FAT32).

 

If nothing else give me the BPB.

 

PS Actually I don't understand the JPG in your picture. that seems to be suggesting that sector 640 is not the root directory but the first sector of the .bin file. You have missed out a level of indirection!

 

EDIT: Oh sorry, I think I now understand what you are saying. The root directory is found and the AVRAP file is found and then it gets the first cluster field of that file and then tries to offset that from the start of the data area and THAT's where the fault lies? I really, really, really could do with a card image here!!

Last Edited: Fri. Nov 28, 2014 - 12:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apologies, was in a hurry.

 

The attachment contains the first 700 sectors from a physical disk dump. It is Fat16.

 

Wondered if it could have to do with the formatting? Previously I had adapted the bootloader to read image files in the main application (space is tight, so getting a reader at around 1.5K was great) and it worked fine finding files.

 

The card now was formatted by Windows, so just tried with the HP USB formatter and then it gave lba=607. Still wrong. The SD Formatter 4.0 for SD_SDHC_SDXC - SD Association (which I thought had used for the succesful attempt in the reader) though still gives 672.

The allocation unit was 32K in all cases.

 

You can probably gather from the above that I don't have a clue as to what's going on. Could the card be dodgy? It is old but am getting another later today, so will test. Maybe you should not waste time on this until then.

Attachment(s): 

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

Well the is an error in sectordump.bin

 

It is FAT16 and fatGen103.doc says this about BPB_RsvdSecCnt:

Number of reserved sectors in the Reserved region of the volume

starting at the first sector of the volume. This field must not be 0.

For FAT12 and FAT16 volumes, this value should never be

anything other than 1. For FAT32 volumes, this value is typically

32. There is a lot of FAT code in the world “hard wired” to 1

reserved sector for FAT12 and FAT16 volumes and that doesn’t

bother to check this field to make sure it is 1. Microsoft operating

systems will properly support any non-zero value in this field.

The value in this disk image is actually 8. That isn't the reason why the first cluster calculation in my code is wrong but it does suggest this was formatted in a "non standard" way.

 

I'll continue to see if I can work out how my code differs from fatgen103.

Last Edited: Fri. Nov 28, 2014 - 04:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is weird.

 

In the program am getting RsvdSecCnt=1, so have uploaded the sectors from the sd. You definately should not get 8 now.

Attachment(s): 

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

Formatting as FAT32 works perfectly.

 

The extra 100 bytes doesn't matter so much, so I can use that.

 

Thanks.

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

Hi

Where can I get the source code?

on page:

https://spaces.atmel.com/gf/proj...

Empty
There are no files to download.

 

Thank's

 

Last Edited: Sun. Jun 4, 2017 - 09:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

selevo wrote:
There are no files to download.
Eh? 

 

https://spaces.atmel.com/gf/proj...

 

So just install SVN if you don't already have it then give the "anonymous" checkout request and it will pull all the files to your PC (with the added benefit that they're under revision control). 

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

Or click "releases" on the left and get the source as a zip.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Thank's

A couple of hours of  headache and I managed to download the files.

You could simply give a direct link to the zip archive
Without the use of SVN  project menage
This would save a million nerve cells and time to many people.

 

I hope for half a year to figure out how this works, compile and run on my knee

Last Edited: Sat. Jun 10, 2017 - 12:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> You could simply give a direct link to the zip archive
And then assume that the zip is the preferred variant? For some, SVN might be preferred.
And the ZIP is a release. What if someone wanted the current development version? What if someone wants to see the history? Etc.
Also, linking to the ZIPwould have ppl "land" on a page with no description whatsoever - don't you think it's better to land at the main page (with the description) and then have a choice of your own on where to go?
How hard was it to browse through the page and see what might lead to sources?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Sat. Jun 10, 2017 - 12:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To be honest I'd forgotten I'd even added Zip files and there's no guarantee they're going to be anyway up to date.
.
All professional engineers are going to be using SVN and/or Git anyway so it's pretty trivial to pull it as an SVN checkout and that way you KNOW you have the up to date files.

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

Dear Cliff aka clawson,

 

First of all, I hope that this thread is not dead and that you are still watching this ...

I have read all comments, as well as your project page. So I understand how it all fits together and what needs to be changed if you want to implement it yourself.

But since this is my first bootloader, I'm a bit stuck about how to program it.

I try to use an ATmega162, as far as I know it should also be able to work?

I also have a USBasp programmer and I have Arduino IDE as well as AS7. I managed to program a simple program (blinking led) via both programs, in AS7 by using avrdude so I do not know how srec_cat works.

 

I also managed to build to bootloader, but now I'm kinda stuck... Can you explain to me step by step how I program this bootloader? (Preferably in 1 of these programs)

 

Kind regards,

Gijs

Last Edited: Thu. Feb 8, 2018 - 11:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well if you built the bootloader you presumably have a HEX file? Just program that into the 162 in the same way that you program LED flashers or whatever else. The bootloader HEX file will have an address offset so instead of the code going to 0x0000 like the LED flasher it (hopefully!) goes to 14K so occupies the last 2K of the 162 (actually you may have an issue - does the 162 allow for 2K bootloaders? If not you need to trim the options back to make it build for 1K or less). When you use the USBAsp as well as programming the flash you also need to make a small adjustment to fuses. Activate the BOOTRST fuse and because the bootloader will almost certainly want the biggest bootloader space possible also make sure the BOOTSZ fuses are set to the maximum option.

 

Now when you apply power the AVR will start to run at the bootloader address (maybe 14K). As long as you have all the SPI wires connected up right then it should be able to read an SD card. Having used srec_cat to convert your LED flasher .hex file to a .bin file (and maybe pogram in a CRC if you are using that bit too) you write that BIN file to an SD card while it's plugged into your PC in a file called something like AVRAP005.bin then when the AVR starts and the bootloader runs it will "see" the file and because there isn't an app present yet it will open and read the file contents and SPM program them into the lower flash area. In future at power on the EEPROM of the AVR will tell it that it already has "005" in memory so it will skip the programming and just jump to the LED flasher at 0. But if you now change the BIN file on the card and now call it AVRAP006.BIN then the bootloader will see that 6 > 5 so it will reprogram and so on.

 

As I say it keeps the number of the "last programmed" BIN file in EEPROM so it can always tell whether it is up to date. You can erase EEPROM to make it reprogram at next start up.

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

Thanks for your answer, clawson.

I think I understand what you're saying, only I do not know if I'm doing that BOOTRST and SZ correctly.

But to answer your concern if the 162 allows a 2K bootloader;

Datasheet quote:

When the BOOTRST Fuse is unprogrammed, the boot section size set to 2K bytes and the IVSEL bit in the GICR Register is set before any interrupts are enabled, the most typical and general program setup for the Reset and Interrupt Vector Addresses is...

So I guess it does?

 

Between my previous post and now I have managed to get a bit further, please correct me if I did something wrong.
- Firwmare to BIN: I used to argument below to do this.

$(ProjectDir)Debug\$(TargetName).hex -intel -fill 0xFF 0x0000 0x37FE --l-e-crc16 0x37FE -o AVRAP001.bin -binary

 

- Then I managed to build the bootloader and tried to program it. I'll put the outputs as attachments.

As you can see in "Build output" it does build correctly and has a size of 1514 bytes, which corresponds to your specifications.

So next I tried to program it using the USBasp and the argument below.

avrdude -c usbasp -p atmega162 -e -U lock:w:0x3F:m -U efuse:w:0xFD:m -U hfuse:w:0xD4:m -U lfuse:w:0xE2:m -U flash:w:$(ProjectDir)Debug\$(TargetName).hex:i -U lock:w:0x0F:m

This argument is based on information from this site and the fuses are set for a 8MHz internal clock. I think I'm not doing anything with those BOOTRST and SZ fuses? Do I need to implement these here?

The argument seems to work, beyond the fact I get an error in the output file (see "BL output")

avrdude.exe: ERROR: address 0x7010 out of range at line 1 of C:\Users\gijsv\Desktop\Masterproef\Software\Bootloader\trunk\Debug\pfboot.hex

According to my calculation, this results in a file of 28 688 Bytes... WHAT????
So I'm pretty sure something is wrong somewhere... Then I went to check the size of pfboot.hex. I have been able to reduce this to 4.31KB by removing all superfluous code and comments.

 
So euhmm yeah... What's up with that? A bad argument? Or missing a setting somewhere?
I checked the optimization level it's optimized for size.

Attachment(s): 

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

In your build output this command is wrong:

		"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -o pfboot.elf  asmfunc.o main.o mmc.o   -Wl,-Map="pfboot.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mrelax -Wl,-section-start=.text=0x7000  -mmcu=atmega162 -nostartfiles  
		Finished building target: pfboot.elf

IN the section-start the .text section is being set to 0x7000 which is the right value for a 32K chip that has a 4K boot section (so boot starts at 0x7000) but in a 16K chip with a 2K boot section this should be set to 14K which is 0x3800.

 

In fact in the command:

$(ProjectDir)Debug\$(TargetName).hex -intel -fill 0xFF 0x0000 0x37FE --l-e-crc16 0x37FE -o AVRAP001.bin -binary

(which is right for 16K) the 0x37FE here is picked because it is 0x3800 (the boundary) minus 2 bytes (because the very last 2 bytes of "application" flash are where the CRC is placed).

 

So half your setup looks right for 16K and half is wrong.

 

I think I know where this comes from. I started the SD bootloader on a meag16 which has bootloader sizes of 256 bytes, 512 bytes, 1K and 2K but then the thing just tipped over 2K with all the options switched on. So I moved to a mega32 because it has bootloader sizes of 512 bytes, 1K, 2K and 4K and the last option let me grow things a bit bigger, 32K minus 4K is 28K and 28K happens to be 0x7000 which is where the number in your build came from.

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

Okay, thanks for your reply!

 

I see what you're talking about, but how do I change it?

I do not seem to find wher that valui is being set...

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

Well in the Project properties it'll be in the "linker" section. I assume I probably put it under "miscellaneous" ?

 

(having said that the project properties have a "Memories" section. I maybe have put a ".text=0xnnnn" there which ultimately gets converted into a -section-start.

 

I don't have access to AS7 right now so cannot easily check to see how I did it.

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

Fortunately enough I do ;)

 

In miscellaneous it says: "-nostartfiles"

In memory it says: ".text=0x3800"

 

So euhmmm? This should be correct, right?

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

Nope because of the stupid Atmel system ! In that "Memories" section they have some long winded comment which basically says "At Atmel, unlike in the whole of the reset of the universe for flash (but not RAM or EEPROM or anything else) we measure memory in WORDS not BYTES". The upshot of that is that a ".text=0x3800" entered here is converted by them to a -section-start=.text=0x7000 where they double the 0x3800 entered. So by implication to end up with the desired -section-start=.text=0x3800 the value you enter in "memories" will actually half of 0x3800. So try ".text=0x1C00" and in the build you should see it use 0x3800 in the section-start.

 

(and don't touch -nostartfiles, you MUST have that!)

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

Oh yeah didn't read that far down..

But yeah that did the trick, now after building it gives the 0x3800.

 

So I'm going to try and program it and will get back to you.

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

the word (16bit) comes because the AVR103(mega128) have more than 64Kbytes, so it was the easy way/hack to keep addr. to 4 digit hex.

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

Thanks a lot for your help clawson, I was able to program the bootloader successful.

Unfortunately, I get the flashing LED. So time for some debugging I guess... :)

 

Btw the BIN argument was correct, right?

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

Okay so I did some changes and the LED isn't flashing anymore... now it's constantly on.
What does this mean? Can't find any information about that, so I assume something is wrong or that it's stuck on something?

FYI: My firmware I'm trying to upload is a LED flashing on another pin.

If I take out the SD, it goes back to flashing. So that part still works.

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

I've actually forgotten!  Suggest you read the source to see what it is I do with LED.

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

Hi Clawson, 

 

Okay so I enabled UART (had to disable ROOT_MULTISEC for that).

This way I figured out that the LED is constantly on while the µC is "reading" the SD.

 

When I now look at the data coming from the UART I can see that the CRC isn't eaqual at the end. 

Quote:

App CRC= 1117
Flash CRC= FFFF

Could you help me out with this?
Earlier in the data I see the file name (line 123), so the µC seems to find the file. But what seems strange to me is a few lines earlier (lines 99-104):

Quote:

00 00 00 00 00 00 00 00 00 00 00 00 0D 0A 44 69  ..............Dis
73 6B 20 65 72 72 6F 72 FF 0D 0A 50 72 65 73 73
UART received:   sk error...Press 
20 61 6E 79 20 6B 65 79 20 74 6F 20 72 65 73 74   any key to resta
61 72 74 0D 0A 00 00 00 00 00 0
UART received: 0 00 00 00 00 00  art..............

I don't know if I have to worry about that and if that's causing the problem?

Anyway I'm using a 4GB SD, formatted in FAT32 with 16KB clusters. Tried 32KB clusters and FAT16 with 16KB (by reducing the size to 1GB), both having the same result.

 

I appreciate all help!

 

Attachment(s): 

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

If the CRC is wrong it sounds like the srec_cat command may be wrong. Try switching off CRC support for now to simplify things.
.
Your UART output shows the data being read from sectors and programmed so does your actual application contain SD reading code too. Those messages about disk error look like something in your own code in AVRAP001. BIN

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

Actually, now that I look at the text file it looks like your "app" is a copy of the bootloader itself??

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

No, my own code is a simple blinking LED.

Tested it before putting it on the SD and does work.

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

So, I disabled CRC support.

But the only difference I'm seeing is that the flashver is changing. So it does know the version from the app, but isn't running it.

 

Is it possibele it is either not leaving the bootloader or either doing a faulty programming?

My app itself is working correctly when I'm programming it's hex file directly.