Xmega CRC

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

Hi,

I want to add a CRC verification to the hex files, and to verify the CRC in the bootloader while updating firmware.

How can I calculate and add the result to the hex file?

 

Thanks,

Arkadi.

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

You can't put the hex file's CRC in the hex file, because it would change the CRC... But you can calculate the CRC of a hex file and compare it to one calculated by the firmware.

 

Have a look at my bootloader: https://github.com/mojo-chan/hid...

 

The PC software can calculate XMEGA compatible CRCs.

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

mojo-chan wrote:

But you can calculate the CRC of a hex file and compare it to one calculated by the firmware.

 

Where I store the result of the calculation?

 

I thought that I can calculate the hex file crc and store and add another 32-bit with result in the end of the hex-file and ignore it when making the calculation in the firmware

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

mojo-chan wrote:
You can't put the hex file's CRC in the hex file, because it would change the CRC...

This is nothing to do with Xmega but just to say that I do this to embed a CRC into some code read by a bootloader:

 

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

 

This is for a 16K AVR (mega16 in fact) what I am doing here is simply saying "take the .hex file, however long it is, and pad it out with 0xFf all the way to 0x37FE (two bytes below the bootloader) then calculate a CRC over those 14,334 bytes and put the result in the next two bytes - those two before the bootloader starts". So every time I have a 14,336 (14K) image where the code is in 14K-2 bytes and then the CRC is in the last 2 bytes to complete the full 14K. I send this to the bootloader and it then programs 14,334 bytes and then calculates the CRC over those and compares to the next 2 bytes in the image. The data is only intact if those two agree. At subsequent power-ons I do the same thing so that if the image were ever "damaged" I would recognise it and not launch the damaged app code.

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

Ah, sorry, I made an assumption that you were using the XMEGA special 24 bit NVM CRC function.

 

Clawson's method works if you calculate the CRC yourself. You use the XMEGA NVM's built in CRC function is always operates on the entire app or boot sections, so you can't modify them in any way. Doing a software driven CRC with the CRC peripheral is pretty fast though, especially if you can bump up to 32MHz. It only takes a few seconds.

 

However, as an alternative, you could add the CRC to the EEPROM instead. The hex file can include data for the EEPROM, although you may need to check your programming app to make sure it supports it. I think you have to do something special with atprogram, from memory.

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

I don't have a total picture of how it works for the XMEGA(or rather the compiler and linker) but this

You can't put the hex file's CRC in the hex file, because it would change the CRC 

 

Is not true, you can make it so the hole file (code and CRC) will give a known number (0 or -1).

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

I made an assumption that you were using the XMEGA

Oh he was. I was just responding to your comment about the fact you cannot embed a CRC in a load image. You can if you APPEND it beyond the area that is checked. (or, as you say, in an alternative place like EEPROM).

 

I don't know how the Xmega CRC thing works - can you specify start/length or start/end to have it only check a region or is it fixed in its belief that it will always check the entire app area? If you can specify a region you obviously have it look at everything BUT the checksum.

 

(that's why I prefixed my reply with "this is nothing to do with Xmega..")

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

or why not make a CRC of the hole chip (perhaps without bootloader), I will assume that there are 0xff in all none used locations. 

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

I will try  to explain in more details.

I made a DFU Bootloader that write page_size buffer to "special section" (some validation space)

after all the data is written it resets the xmega, checks if new data was written and then make a CRC check and write the verified data from the validation section to the final address.

 

The way I understand from you is that when I have the hex file, I need to calculate its CRC and save it in the EEPROM.

Then after reset, to calculate the CRC from the validation section and to compare it to the EEPROM value?

 

I understood it right?

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

clawson wrote:

 

This is nothing to do with Xmega

 

clawson, what is the right way to do it with Xmega?

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

arkadi wrote:
The way I understand from you is that when I have the hex file, I need to calculate its CRC and save it in the EEPROM. Then after reset, to calculate the CRC from the validation section and to compare it to the EEPROM value? I understood it right?

Yup, that's what I understood him to be suggesting.

 

The key thing is getting the same CRC calculation on the PC as the Xmega will do. For that you need to know the "polynomial" and the starting value (and whether the data is "augmented"). You want to be able to calculate on the PC the same result as the Xmega is also going to get for any given data. Convert the .hex to binary then read that data using a C (or other language) program on the PC and have it put the data through a CRC calculation.

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

I will add:

Remember that you can use the AVR simulator to find the CRC value. (no need for PCcode) . 

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

clawson wrote:

I don't know how the Xmega CRC thing works - can you specify start/length or start/end to have it only check a region or is it fixed in its belief that it will always check the entire app area? If you can specify a region you obviously have it look at everything BUT the checksum.

 

So there are two CRC functions on XMEGA, just to add to the confusion. The NVM controller has one that can be used on the app or boot sections. It does the whole section, you can't control it. It spits out a 24 bit CRC, and my bootloader has code to calculate that value on a .hex file.

 

The other CRC function is from the CRC peripheral. It can calculate a standard CCITT 16 bit or 32 bit checksum. You have to feed it manually though, so it's a lot slower than the NVM CRC. You can of course control the exact bytes it checks.

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

arkadi wrote:

The way I understand from you is that when I have the hex file, I need to calculate its CRC and save it in the EEPROM.

Then after reset, to calculate the CRC from the validation section and to compare it to the EEPROM value?

 

That's correct. You need to calculate the CRC for the .hex file, write that into EEPROM and then have your firmware check it.

 

There is an alternative to using EEPROM. The XMEGA range has a "User Signature Row", which is a special page in flash memory designed to store calibration data. You can put the CRC in there, and it won't accidentally be erased if you are using the EEPROM for other things.

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

mojo-chan wrote:

clawson wrote:

I don't know how the Xmega CRC thing works - can you specify start/length or start/end to have it only check a region or is it fixed in its belief that it will always check the entire app area? If you can specify a region you obviously have it look at everything BUT the checksum.

 

So there are two CRC functions on XMEGA, just to add to the confusion. The NVM controller has one that can be used on the app or boot sections. It does the whole section, you can't control it. It spits out a 24 bit CRC, and my bootloader has code to calculate that value on a .hex file.

 

The other CRC function is from the CRC peripheral. It can calculate a standard CCITT 16 bit or 32 bit checksum. You have to feed it manually though, so it's a lot slower than the NVM CRC. You can of course control the exact bytes it checks.

 

Hey, I tried to use crc function from your git but it doesn't make the same result as in Xmega hardware.

 

In The Xmega I use:

CRC.CTRL |= CRC_RESET_RESET1_gc;
CRC.CTRL  =  CRC_SOURCE_FLASH_gc;
nvm_issue_flash_range_crc(flash_start, flash_end);

And in the PC I add function to convert raw binary file to buffer:

   char source[100000];
   for (int i = 0; i < len; i++) {
        fread(&ch, 1, 1, ifile);
        source[i]=ch;
    }
    crc = crc32(source, len);

 

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

What XMEGA is it? IIRC some of the newer ones, like the E5, let you do a different CRC on a range of flash memory. It looks like that is what you are doing.

 

The one in my code is only for the special CRC that the NVM controller does of the entire app or boot sections. It can't do part of the section.

 

Remind me to check tomorrow...

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

Hey mojo,

I have atxmega256a3u, it looks like the NVM has a command for range CRC32, here is the ASF implementation code:


/**
 * \brief Issue flash range CRC command
 *
 * This function sets the FLASH range CRC command in the NVM.CMD register.
 * It then loads the start and end byte address of the part of FLASH to
 * generate a CRC-32 for into the ADDR and DATA registers and finally performs
 * the execute command.
 *
 * \note Should only be called from the CRC module. The function saves and
 *       restores the NVM.CMD register, but if this
 *       function is called from an interrupt, interrupts must be disabled
 *       before this function is called.
 *
 * \param start_addr  end byte address
 * \param end_addr    start byte address
 */
void nvm_issue_flash_range_crc(flash_addr_t start_addr, flash_addr_t end_addr)
{
	uint8_t old_cmd;
	// Save current nvm command
	old_cmd = NVM.CMD;

	// Load the NVM CMD register with the Flash Range CRC command
	NVM.CMD = NVM_CMD_FLASH_RANGE_CRC_gc;

	// Load the start byte address in the NVM Address Register
	NVM.ADDR0 = start_addr & 0xFF;
	NVM.ADDR1 = (start_addr >> 8) & 0xFF;
#if (FLASH_SIZE >= 0x10000UL)
	NVM.ADDR2 = (start_addr >> 16) & 0xFF;
#endif

	// Load the end byte address in NVM Data Register
	NVM.DATA0 = end_addr & 0xFF;
	NVM.DATA1 = (end_addr >> 8) & 0xFF;
#if (FLASH_SIZE >= 0x10000UL)
	NVM.DATA2 = (end_addr >> 16) & 0xFF;
#endif

	// Execute command
	ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm);

	// Restore command register
	NVM.CMD = old_cmd;
}

 

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

Ah yes, I'm using the NVM_CMD_APP_CRC (0x38) and BOOT_CRC (0x39). You use NVM_CMD_FLASH_RANGE_CRC (0x3A).

 

Try the APP_CRC command, that works with my code. Then check your code... For example, are you using the right address range?

 

My code is tested on a 256A3U, but not with the FLASH_RANGE_CRC command, only the other two.

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

hi all, 

 

i'm working on fota(xmega 256a3bu) and i'm also stuck on verifying bin image.

 

so from ftp server i'm moving bin file to external flash and

then from boot as per the fota flag moving it to app section.

 

in boot i want do a first check as:

if fota flag is set // if app section is corrupted.

 

to check app section i want crc functionality.(using crc driver for xmega)

/**
 * \brief Perform a CRC-32 calculation on the entire flash memory, on only
 * the application section, on only the boot section, or on a selectable range
 * of the flash memory.
 *
 * This function setups the type of CRC to perform and configures the memory
 * range to perform the CRC on, and starts the CRC via the NVM module.
 * When the calculation is done, the function disables the CRC module and
 * returns the checksum.
 * For CRC on the boot or application section, start address and length are not
 * needed.
 *
 * \note In the flash range mode, an even number of bytes is read. If the user
 * selects a range with an odd number of bytes, an extra byte will be read, and
 * the checksum will not correspond to the selected range.
 *
 * \param crc_type      what kind of CRC to do perform on the NVM module: \ref
 *                      CRC_FLASH_RANGE, \ref CRC_BOOT or \ref CRC_APP
 * \param flash_addr    address of first byte in flash to perform CRC on
 * \param length        number of bytes to perform CRC on
 *
 * \return checksum    CRC-32 checksum
 */
uint32_t crc_flash_checksum(NVM_CMD_t crc_type, flash_addr_t
		flash_addr, uint32_t length)
{
	if ((length == 0) && (crc_type == CRC_FLASH_RANGE)) {
		return 0;
	}

	Assert((crc_type == CRC_FLASH_RANGE) || (crc_type == CRC_BOOT) ||
			(crc_type == CRC_APP));

	// Initialize CRC for flash
	crc_reset();
	/* Set CRC32 enable bit to ensure correct reading of the resulting
	 * checksum */
	crc_32_enable();
	crc_set_source(CRC_SOURCE_FLASH_gc);

	if (crc_type == CRC_FLASH_RANGE) {
		nvm_issue_flash_range_crc(flash_addr, flash_addr + length - 1);
	} else {
		nvm_issue_command(crc_type);
	}

	// Disable CRC and return checksum
	return crc_checksum_complete();
}

 

the above code will basically give me crc of app section.

i'm calling the function as:

 

cheksum_1 = crc_flash_checksum(CRC_APP,flash_start_addr,flash_len);

 

start_addr = 0x00000;

flash_len = 256000;

 

is it wright way to call?

 

and after the checksum is returned from the function, with what should i compare it?

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

Mehul9 wrote:
and after the checksum is returned from the function, with what should i compare it?
From the other thread where we were discussing it that is kind of part of the issue. In my use of a CRC I was not using built in CRC of AVR (as "mega" didn't have this) so for the AVR part I just did a soft CRC. But the point is that the CRC you read out has to match the CRC you put in. So in my case I was originally generating the CRC on a PC using the srec_cat program and the point was that I had to ensure my mega AVR implementation implemented the same polynomial and behaviour (which was actually much trickier to achieve than you might expect!)

 

If in your case you have an automated CRC generator in the Xmega itself then the task you face is that the code you generate and deliver is going to have to have the CRC calculated on it externally using the same polynomial that the Xmega uses natively.

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


clawson, this is the part i'm confused ..

 

how should i go move forward on this?

 

 

this was all there in datasheet.

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

hi mojo chan can you help me with this.....

 

how should i move ahead from this point?

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

CLawson has given you the answer. How are you calculating the crc that gets appended to your binary image? This has very little to do with the xmega at this point.

I Googled online crc calculator

or for srec

http://srecord.sourceforge.net/m...

 

Last Edited: Fri. Sep 4, 2020 - 01:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i am just converting the hex obtained from atmel studio 7 to .bin file by avr gcc command..

 

and using that file..

 

at this point i'm not using any srec_cat command.

 

 

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

How do you propose to calculate the crc for the file?

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

this is what i'm asking for.... how should i add a crc into a binary file....

 

i don't have any idea on this srec_cat command ....

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

"Dare to be naïve." - Buckminster Fuller

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

Mehul9 wrote:
this is what i'm asking for.... how should i add a crc into a binary file....
Well this is the thing. You need some tool that can generate a checksum for some arbitrary data and then some mechanism to then add the result into the data itself (usually bolted onto the end). Here's a very simple kind of example:

D:\test\test\Debug>type test.hex
:1000000033C0000039C0000037C0000035C0000018
:1000100033C0000031C000002FC000002DC0000020
:100020002BC0000029C0000027C0000025C0000030
:1000300023C0000021C000001FC000001DC0000040
:100040001BC0000019C0000017C0000015C0000050
:1000500013C0000011C000000FC000000DC0000060
:100060000BC0000009C0000011241FBECFEFD8E074
:10007000DEBFCDBF03D006C0C3CF089580E090E0BF
:0800800008950895F894FFCFE4
:00000001FF

D:\test\test\Debug>avr-objcopy -I ihex -O binary test.hex test.bin

D:\test\test\Debug>md5sum test.bin
071448467708c425de60f80c9384e89f *test.bin

It starts with an AVR program text.hex. I used avr-objcopy simply because it's a tool that makes it very easy to do Hex to Binary conversions to convert test.hex to test.bin. Then I happen to have a checksumming tool (well MD5 is technically a "hash" not a "checksum") and ran that on the data to I know that 0x071448467708c425de60f80c9384e89f is a hash of the data (a number that uniquely identifies that data). Now an MD5 hash is a "big number". It's actually 128 bits which is far more than your typical 16 or 32 bits for a CRC but the idea is the same. I have test.bin which is:

D:\test\test\Debug>dir test.bin
 Volume in drive D is DATA
 Volume Serial Number is 1CF4-86D6

 Directory of D:\test\test\Debug

04/09/2020  15:16               136 test.bin

136 bytes of AVR code and now I would need to "glue" this additional identity onto the data. I guess I could have just piped the output of the hash/CRC program into a second file then joined them:

D:\test\test\Debug>md5sum test.bin > test.md5

D:\test\test\Debug>copy /b test.bin + test.md5 test.all
test.bin
test.md5
        1 file(s) copied.

so now I have:


PS D:\test\test\Debug> dir test.all

    Directory: D:\test\test\Debug

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       04/09/2020     15:23            180 test.all

PS D:\test\test\Debug> format-hex test.all

           Path: D:\test\test\Debug\test.all

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   33 C0 00 00 39 C0 00 00 37 C0 00 00 35 C0 00 00  3À..9À..7À..5À..
00000010   33 C0 00 00 31 C0 00 00 2F C0 00 00 2D C0 00 00  3À..1À../À..-À..
00000020   2B C0 00 00 29 C0 00 00 27 C0 00 00 25 C0 00 00  +À..)À..'À..%À..
00000030   23 C0 00 00 21 C0 00 00 1F C0 00 00 1D C0 00 00  #À..!À...À...À..
00000040   1B C0 00 00 19 C0 00 00 17 C0 00 00 15 C0 00 00  .À...À...À...À..
00000050   13 C0 00 00 11 C0 00 00 0F C0 00 00 0D C0 00 00  .À...À...À...À..
00000060   0B C0 00 00 09 C0 00 00 11 24 1F BE CF EF D8 E0  .À...À...$.¾ÏïØà
00000070   DE BF CD BF 03 D0 06 C0 C3 CF 08 95 80 E0 90 E0  Þ¿Í¿.Ð.ÀÃÏ.•€àà
00000080   08 95 08 95 F8 94 FF CF 30 37 31 34 34 38 34 36  .•.•ø”.Ï07144846
00000090   37 37 30 38 63 34 32 35 64 65 36 30 66 38 30 63  7708c425de60f80c
000000A0   39 33 38 34 65 38 39 66 20 2A 74 65 73 74 2E 62  9384e89f *test.b
000000B0   69 6E 0D 0A                                      in..

So I have one file that has both the binary of the program and the hash/checksum/CRC on the end. But there are several things wrong with this. I don't really want the hash/checksum in MD5 format, I don't want it stored in ASCII and I don't want it just arbitrarily stored on the end of the program data as at readback time I would have no idea where the code ends and the checksum is stored.

 

This is why srec_cat is such a good choice as it knows about all these kind of hurdles and has clever ways to work around them. In a single command like:

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

In this command it's saying "here is a .hex file in Intel format straight out of the build. I'd like you to read it into a virtual memory space then fill any unused data area from the end to location 37FE with 0xFF (to pad it with known data) then I would like you to perform a little endian CRC16 over that data and havig come up with a result add that into the virtual memory image at location 0x37FE/37FF and finally I would like you to write out the data to a file called AVRAP001.bin and make that binary rather than Hex format".

All that in a single command! This is the power of the srec_cat tool. It knows how to read Intel, it knows how to create a virtual memory image and pad it, it knows how to add a CRC into that and then it knows how to write the result out as binary.

 

Now you could achieve the same in a scripting language like Python (I've done the very same for Motorla SRecord stuff in Python) but as someone went to all the trouble of creating srec_cat (part of the "Srecord tools") then it may not be necessary to reinvent the wheel unless you have some requirement that srec_cat could not cater for.

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

Thanks clawson,

after reading different threads and different suggestion, i think that the solution you have suggested is the best one...

 

 

 

first I'll try to install srec_cat im my windows machine...

 

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

In post #23 there was a link to an example.

 

This looks like where to download the utility:

 

https://sourceforge.net/projects...

Last Edited: Sat. Sep 5, 2020 - 06:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm following the steps provided for installing srec on windows but i'm facing a lot of issue.

 

is there anyone who have tried srec install on windows....please help..

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

"install"? There's no "install"ing required is there?  You just put the files into some directory on your machine. Make sure that it is in PATH and then you can run the command from a Command Prompt anywhere on the PC

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

as i have visited http://srecord.sourceforge.net/w...

 

it says that before using srec you require 3 piece of software installed 

 

MinGW

boost library

libgcrypt library

 

I'm stuck at boost library

 

..is there any simpler way as you were saying..put some directories

 

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

You want the win32 rather than the source.

https://sourceforge.net/projects...

 

Spend some time and read the instructions. It took me literally minutes - and i had to fire up Windows as I use a mac.

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

okay... got it

 

so i was trying to built srec from source code instead i can use the .exe file which is available in zip folder i have downloaded from the link you have shared.

 

right???

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

Yes.

-Sam

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

i'm running it on win 7  64 bit.

 

as per the instruction i dont think it will work on 64 bit right??

 

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

I'm on a mac and can't test it out (maybe one of the others can), but I think it'll run just fine (windows x64 can run x86 apps).

Why don't you just try it out and see, then ask questions on the forum if it doesn't run? 

-Sam

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

It seemed to run without a problem on win7 64bit. I didn’t get it to do anything useful though.

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

i have already tried..and i was not seeing anything.

 

so i'm trying xp mode for win 7.

 

btw i found below note on keil.com

 

Note: This utility program is a DOS application! It requires 8.3 naming convention for file names and paths and it does not run on 64Bit Windows versions! However, you can execute it in the XP mode (Virtual PC) of Windows 7 if necessary.

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


I could have sworn that Atmel packaged a copy of srec_cat in with AS7 in the GNU utilities - maybe I just dreamt that? Let me check...

 

EDIT: yup, thought so, it wasn't a dream after all...

 Directory of C:\Program Files (x86)\Atmel\Studio\7.0\shellutils

04/09/2019  11:55            36,616 basename.exe
04/09/2019  11:55            75,528 cat.exe
04/09/2019  11:55            97,032 chgrp.exe
04/09/2019  11:55            94,984 chmod.exe
04/09/2019  11:55            99,080 chown.exe
04/09/2019  11:55            37,640 chroot.exe
04/09/2019  11:55            38,664 cksum.exe
04/09/2019  11:55            39,176 comm.exe
04/09/2019  11:55           143,112 cp.exe
04/09/2019  11:55            89,352 csplit.exe
04/09/2019  11:55            51,976 cut.exe
04/09/2019  11:55           141,576 date.exe
04/09/2019  11:55           100,616 dd.exe
04/09/2019  11:56            94,984 df.exe
04/09/2019  11:56           193,800 dir.exe
04/09/2019  11:56            43,784 dircolors.exe
04/09/2019  11:56            37,128 dirname.exe
04/09/2019  11:56           121,608 du.exe
04/09/2019  11:56            38,152 echo.exe
04/09/2019  11:56            37,128 env.exe
04/09/2019  11:56            40,712 expand.exe
04/09/2019  11:56            75,528 expr.exe
04/09/2019  11:56            44,296 factor.exe
04/09/2019  11:56            30,984 false.exe
04/09/2019  11:56            43,784 fmt.exe
04/09/2019  11:56            39,688 fold.exe
04/09/2019  11:56           141,576 gdate.exe
04/09/2019  11:56            38,152 gecho.exe
04/09/2019  11:56           148,232 ginstall.exe
04/09/2019  11:56           115,464 gln.exe
04/09/2019  11:56            82,184 gmkdir.exe
04/09/2019  11:56            38,152 grmdir.exe
04/09/2019  11:56           109,320 gsort.exe
04/09/2019  11:56            86,280 head.exe
04/09/2019  11:56            38,664 hostid.exe
04/09/2019  11:56            36,616 hostname.exe
04/09/2019  11:56            41,224 id.exe
04/09/2019  11:56           148,232 install.exe
04/09/2019  11:56            53,512 join.exe
04/09/2019  11:56            41,736 kill.exe
04/09/2019  11:56            44,808 link.exe
04/09/2019  11:56           115,464 ln.exe
04/09/2019  11:56            37,128 logname.exe
04/09/2019  11:56           193,800 ls.exe
04/09/2019  11:56           338,184 make.exe
04/09/2019  11:56            55,048 md5sum.exe
04/09/2019  11:56            82,184 mkdir.exe
04/09/2019  11:56            74,504 mkfifo.exe
04/09/2019  11:56            80,648 mknod.exe
04/09/2019  11:56           151,816 mv.exe
04/09/2019  11:56            39,176 nice.exe
04/09/2019  11:56            79,112 nl.exe
04/09/2019  11:56            41,224 nohup.exe
04/09/2019  11:56            99,080 od.exe
04/09/2019  11:56            39,176 paste.exe
04/09/2019  11:56            71,944 pathchk.exe
04/09/2019  11:56            82,184 pinky.exe
04/09/2019  11:56           134,408 pr.exe
04/09/2019  11:56            36,104 printenv.exe
04/09/2019  11:56            58,120 printf.exe
04/09/2019  11:56           124,168 ptx.exe
04/09/2019  11:57            74,504 pwd.exe
04/09/2019  11:57            73,480 readlink.exe
04/09/2019  11:57           122,120 rm.exe
04/09/2019  11:57            38,152 rmdir.exe
04/09/2019  11:57            39,688 seq.exe
04/09/2019  11:57            38,664 setuidgid.exe
04/09/2019  11:57            55,048 sha1sum.exe
04/09/2019  11:57           100,104 shred.exe
04/09/2019  11:57            40,712 sleep.exe
04/09/2019  11:57           109,320 sort.exe
04/09/2019  11:57            85,256 split.exe
04/09/2019  11:57         1,454,872 srec_cat.exe
04/09/2019  11:57            88,840 stat.exe
04/09/2019  11:57            62,728 stty.exe
04/09/2019  11:57            91,400 su.exe
04/09/2019  11:57            49,416 sum.exe
04/09/2019  11:57            36,104 sync.exe
04/09/2019  11:57           105,224 tac.exe
04/09/2019  11:57           101,128 tail.exe
04/09/2019  11:57            37,640 tee.exe
04/09/2019  11:57            76,040 test.exe
04/09/2019  11:57            91,912 touch.exe
04/09/2019  11:57            56,072 tr.exe
04/09/2019  11:57            30,984 true.exe
04/09/2019  11:57            39,688 tsort.exe
04/09/2019  11:57            36,616 tty.exe
04/09/2019  11:57            46,856 uname.exe
04/09/2019  11:57            41,736 unexpand.exe
04/09/2019  11:57            45,832 uniq.exe
04/09/2019  11:57            37,640 unlink.exe
04/09/2019  11:57            45,320 uptime.exe
04/09/2019  11:57            48,392 users.exe
04/09/2019  11:57           193,800 vdir.exe
04/09/2019  11:57           113,416 wc.exe
04/09/2019  11:57            86,280 who.exe
04/09/2019  11:57            37,640 whoami.exe
04/09/2019  11:57            36,104 yes.exe
04/09/2019  11:57            82,184 [.exe
              99 File(s)      8,935,464 bytes

Bottom line... there's no building/installing/whatever to be done. If you have AS7 on Windows you already have srec_cat.exe. There are two ways to use it. One would be to add C:\Program Files (x86)\Atmel\Studio\7.0\shellutils to you PATH in which case you could not only use it but all those other "goodies" in that same directory (shame no "grep" though!!). Or you can start AS7 then from the Tools menu use Command Prompt and that launches a shell that already has the directory in the PATH:

 

Last Edited: Mon. Sep 7, 2020 - 12:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

now i have the binary sitting on the external flash...how i can do the crc calculation on the 256kb - (16 bytes for crc) of bin file data?

 

 

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

Surely crc32 gives you 4 bytes for the crc?

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

Mehul9 wrote:
now i have the binary sitting on the external flash...how i can do the crc calculation on the 256kb - (16 bytes for crc) of bin file data?
If (as I chose to do) you are going to use srec_cat to calculate and put a CRC into the data then to verify it you are going to need the AVR to perform the SAME calculation to "undo" it. I did that here:

 

https://github.com/wrightflyer/sdbootloader/blob/master/main.c#L359

 

The code I have there performs the same CRC as the --l-e-crc16 option on the srec_cat command line. While I think it's documented elsewhere that the 16 bit polynomial is 0x1021 what caused me to lose a few follicles is that they use it in "augmented" mode which bascially means that after you have fed all the actual data into the CRC you then push in two additional 0x00 at the end. Even sitting an staring at the srec_cat source code it took me a while to twig that this was what was going on !!

 

You can see the augmentation in this:

    for (uint16_t i=0; i < CODE_LEN; i++) {
        crc = updcrc(pgm_read_byte(i), crc);
    }
    // augment
    crc = updcrc(0, updcrc(0, crc)); // <<<<<<<<<<<<<<< Augmentation

 

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

hi clawson,

 

#ifdef CRC_FLASH
static uint16_t updcrc(uint8_t c, uint16_t crc)
{
    uint8_t flag;
    for (uint8_t i = 0; i < 8; ++i)
    {
        flag = !!(crc & 0x8000);
        crc <<= 1;
        if (c & 0x80)
        crc |= 1;
        if (flag)
        crc ^= 0x1021;
        c <<= 1;
    }
    return crc;
}

uint8_t crc_app_ok(void) {
    uint16_t crc = 0xFFFF;
    for (uint16_t i=0; i < CODE_LEN; i++) {
        crc = updcrc(pgm_read_byte(i), crc);
    }
    // augment
    crc = updcrc(0, updcrc(0, crc));
    #ifdef UART_DEBUG
    UART_putsP(PSTR("App CRC= "), crc);
    UART_putsP(PSTR("Flash CRC= "), pgm_read_word(CODE_LEN));
    #endif
    return (pgm_read_word(CODE_LEN) == crc);
}
#endif

can you help me with this.....

 

not able to figure out what exactly this part is doing?

 

 

 

 

my flash memory location starts from 0x080001  and now i have 256kb(size of my app section) of bin file sitting with srec crc16 included.

how the above code is going to work..

Last Edited: Fri. Oct 2, 2020 - 07:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mehul9 wrote:
not able to figure out what exactly this part is doing?
Do you understand the basics of how CRC works and what a "polynomial" is? If not you won't really understand the CRC generation code until you first understand what it's trying to implement. As always, Wikipedia is a good source of knowledge:

 

https://en.wikipedia.org/wiki/Cy...

https://en.wikipedia.org/wiki/Co...

 

Having read that know that in:

      crc ^= 0x1021;

0x1021 is the polynomial. Compare that to, for example, this:

 

https://www.nongnu.org/avr-libc/...

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

Hi clawson,

 

static uint16_t updcrc(uint8_t c, uint16_t crc)
{
	uint8_t flag;
	for (uint8_t i = 0; i < 8; ++i)
	{
		flag = !!(crc & 0x8000);
		crc <<= 1;
		if (c & 0x80)
		crc |= 1;
		if (flag)
		crc ^= 0x1021;
		c <<= 1;
	}
	return crc;
}


uint8_t crc_app_ok(void) {

uint16_t crc = 0xFFFF;
uint16_t loop_ctr = 0;
uint16_t xx;
uint16_t yy;
uint8_t backup_read_fota[FLASH_PAGE_SIZE];
long long  page_location=0;

	for (xx=0; xx < 500; xx++ )
	{
		loop_ctr = loop_ctr +1;
		user_debug_1("\r\n loop_ctr = %d ",loop_ctr);
		SP_ReadFlashPage(&backup_read_fota,page_location); //read 512 bytes from app and store in backup_read_fota.
		
                if (xx == 499)
		{
			for (yy=0; yy < 510; yy++)
			{
				crc = updcrc(backup_read_fota[yy], crc);
				user_debug_1("\r\n DATA = %x",backup_read_fota[yy]);
				user_debug_1("\r\n crc last = %x",crc);
			}
		} 
		else
	   {
		for (yy=0; yy < 512; yy++)
		{
			crc = updcrc(backup_read_fota[yy], crc);
			user_debug_1("\r\n data = %x",backup_read_fota[yy]);
			
			user_debug_1("\r\n crc last = %x",crc);		}
	   }
		
		page_location = page_location + 512;
		
	}
	// augment
	crc = updcrc(0, updcrc(0, crc));

	user_debug_1("\r\n App CRC= %x",crc);
}

 

 

 

the final results of crc does not matches.....is it the problem with polynomial?

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

Does not match WHAT?

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

Some debugging is required methinks. Try doing the crc on only a handful of bytes. Then you can step through the crc calculation and hopefully see where it goes wrong.  Once you've validated the code with a handful of bytes, success is more likely on 1000's of bytes.

 

Having been working on a bootloader with crcs and encryption recently, I've had similar issues.