Home/Support/Support Forum/Issue with XMEM Checksum Calculation
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

Issue with XMEM Checksum Calculation

0 votes
I am running Dynamic C 9.62 on Win 10 and device is RCM3315.

I am having an issue when calculating checksum over XMEM using fs_checksum_x().
In Dynamic C the information says that XMEM Code Base is BC00 and Top is 48B6C.
Same values are returned when using prog_param.XCB.aaa.a.addr/base (see code below).
However, when looking at ".org" file the Base is 1C200h and Top is 48B6Fh.

Why are the values different between DC info and .org file?

And when running I see some sections before 1C200h come out different every time it is run.

What is in those sections?
Code:
#memmap xmem #use "FS2.lib" #define CHECK_BLOCK_SIZE 0x800 FSchecksum rabbitChecksum; xmem void CalculateChecksum (void) { int bytestogo, checklen, repeat, leftover; long checkaddr; unsigned long xmembotaddr, xmemtopaddr, xmemsize; rabbitChecksum = 0; xmembotaddr = 0x0ffffful & ((unsigned long)prog_param.XCB.aaa.a.addr + ((unsigned long)prog_param.XCB.aaa.a.base<<12)); xmemtopaddr = 0x0ffffful & ((unsigned long)prog_param.XCE.aaa.a.addr + ((unsigned long)prog_param.XCE.aaa.a.base<<12)); xmemsize = xmemtopaddr - xmembotaddr; xmemtopaddrg = xmemtopaddr; xmembotaddrg = xmembotaddr; xmemsizeg = xmemsize; repeat = 0; leftover = 0; repeat = (int)(xmemsize/INT_MAX); leftover = (int)(xmemsize%INT_MAX); if(repeat == 0) { bytestogo = leftover; } else { bytestogo = INT_MAX; } checkaddr = xmembotaddr; while(repeat + 1) { if(repeat == 1) {bytestogo = leftover;} else {bytestogo = INT_MAX;} while (bytestogo) { if (bytestogo > CHECK_BLOCK_SIZE) checklen = CHECK_BLOCK_SIZE; else checklen = bytestogo; fs_checksum_x(&rabbitChecksum, checkaddr, checklen); checkaddr += checklen; bytestogo -= checklen; } repeat--; } }
asked May 27 in Rabbit by dbabayev New to the Community (9 points)

Please log in or register to answer this question.

2 Answers

0 votes
I was able to get it consistent when BIOS Memory Setting changed from "Code and BIOS in Flash, Run in RAM" to "Code and BIOS in Flash".

Any Idea why?

I am worried about this because there were projects that preferred one or the other setting. Don't remember why.

Any advice will help.
Thanks!
answered May 27 by dbabayev New to the Community (9 points)
0 votes
Perhaps the MAP file will help identify what's located at various addresses. You can also reference Bios/Rabbitbios.map to see some of the BIOS mapping.

You might also need to look at Samples/MEMORY_USAGE.C to understand the memory mapping of flash and RAM, in order to determine what's located before 1C200h.

On boards that can "Run in RAM", there's a RAM configured to hold a copy of the program, but some of that RAM might be used for other purposes (xalloc, for example) and that could explain why memory contents before 1C200h change.
answered May 28 by TomCollins Veteran of the Digi Community (2,222 points)
Thank you for info.

How do I read the ***** in the address?
How is this memory segmented?

-------------------------------------------------------------------------------------------------------
xmemcode    | XCOD u  |         | 0e:e200 - 6e:efff  60e00h | 0e:e200 - 3a:e6de  2c4dfh |
            |         |         | 1c200h  - 7cfffh          | 1c200h  - 486deh          |
-------------------------------------------------------------------------------------------------------

And in MAP file:

//Segment           Origin     Size
Root Code           00:0000    004023
Root Data           10:bdff    002b27
Xmem Code           0e:e200    02c4e0


Map says that code is in fe:e4bc to ff:e794 and then starts back from 00:e4fd and continues to 3a:e6bb.
But there also seem to be some global data in that section 10:b741 to 10:22a5.

How do I decipher the address segments with *****?
I'll try to attach the map files.
If you can, please compare the to the Run_in_RAM for BIOS and code.
For segmented addresses like 10:b741, you add three zeros to the first byte and then add to the second value: 0x10000+0xb741 = 0x1b741. 0x0e000 + 0xe200 = 0x1c200.

If you need more help figuring out your map file, email me directly.  My address is my name with a dot in the middle and "at digi.com" at the end.
Hi Tom,
I emailed you the map files with Code in Flash and Code in Flash, Run in RAM settings. Please see if you can compare them and tell me why such differences and over what range of xmem I should be calculating checksum.

Also there is still an issue even with the different build option selected.
Build option of “Code in Flash” did solve checksum consistency on a single build, but checksum is not consistent on consecutive builds.
So the section that we calculate checksum over in xmem has changing data from build to build.

Thank you for your time!
I'll reply to your email separately, but on the issue of the checksum changing between builds, there is a "struct progStruct" embedded in the firmware image between the BIOS and your program that includes things that change from compile to compile, including the time it took to compile the program and a timestamp of when it was compiled.  Those fields aren't present in the DC 10 version of the structure.

If you do a hex compare of two .bin files, you should be able to identify the section that changes between compiles.  Your program should be able to identify the starting address of that struct, and skip over the appropriate number of bytes when calculating a checksum.

Note that the structure isn't fully documented in the Dynamic C libraries.  You'll have to use the .bin comparison to determine how many bytes to skip when calculating the checksum.
...