Discussion Forum

How to assign initial values in code memory with specific location?

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Ryan Ho
Posted
4-Sep-2008 08:28 GMT
Toolset
C51
New! How to assign initial values in code memory with specific location?

I want to define some values in code memory with specific location. For example

code unsigned char MyArray[] _at_ 0xF000 = {0x01, 0x02};


After that, I can use "MyArray[0]" and "MyArray[1]" to access the memory at 0xF000 and 0xF001.
How can I achieve this?

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 08:44 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

I normally store version and copyright information at a fixed location in the ROM image - And always do it by using an assembler module.

For example:

;Within assembly file

         Public MyArray

         Cseg At 0F000h

MyArray:
         Db   01h,02h

;Within C file
extern char code MyArray[];
...
  Val = MyArray[1];
...

I may have a few minor semantics wrong here (because I'm doing it from memory), but I hope it shows the basics.

Read-Only
Author
Ryan Ho
Posted
4-Sep-2008 08:52 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

I know this kind of memory allocation. But I want to achieve this in C file. Is it possible?
For example, I want to define an array in 2 dimension.
MyArray[][2] =
{ {0xABCD, 0x01},
{0x1234, 0x02},
};
In assembly, I have to do :
DB 0xCD
DB 0xAB
DB 0x01
DB 0x34
DB 0x12
DB 0x02

The '0xABCD' is an index, if divided into 2 bytes, it will be very difficult to read for programmers.

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 09:07 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

I've never looked into doing this in C (for the C51), so I don't know if it is possible there.

But, again, I have done a similar thing with structures in assembler.

You could, for example, do something like:

;Within assembly file

         Public MyArray

         Cseg At 0F000h

MyArray:
         Dw   0ABCDh,00001h
         Dw   01234h,00002h
;Within C file
extern int code MyArray[][2];
...
  Val = MyArray[0][1];
...

I think you have to be a bit careful in your description, because it now looks like what you are wanting is an array of structures; i.e., element 0 is an int, element 1 is a char etc.

You can order the source in the assembler to make it more 'programmer friendly' and, so long as you have the C external declaration correct, you can access that data in any way you want.

Read-Only
Author
Ryan Ho
Posted
4-Sep-2008 09:32 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

In my case, the first element is 2-byte data and the second element is 1-byte data. So in C file, I have to use "unsigned char" to read the data and re-merge them to 2-byte data.
Thanks for your fast reply. I've got a better way to program.

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 09:40 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

"I've got a better way to program."

Please let us know what the way is - Most of us here are always ready to learn.

Read-Only
Author
Ryan Ho
Posted
4-Sep-2008 09:49 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

"Better way" means better than current programming style. i.e. {0xABCD, 0x01}.
My current programming CSEG AT 0xF000
ADDR_LBYTE: DB 0xCD
ADDR_HBYTE: DB 0xAB
DATA_BYTE: DB 0x01

But now, I can re-write to : CSEG AT 0xF000
ADDR_: DW 0xABCD
DATA_BYTE: DB 0x01

It's much friendly to programmers. I just need to change the parsing algorithm to reverse high-low byte order.

I found some guys said KeilC does not support initial values in fixed allocation. If this is true, I think I've got the best way to program my firmware.

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 10:02 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

I understand.

DW stores data of a word with the high byte first - I thought there was an equivalent to store the low byte first. Can't remember it though. Might even have been another assembler???

Maybe someone else knows it - Or can correct me.

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 10:17 GMT
Toolset
C51
New! Another thought

If you want the data to be 'easy to read' in the source code, consider using macros.

Read-Only
Author
Andy Neil
Posted
4-Sep-2008 12:28 GMT
Toolset
C51
New! RE: I found some guys said...

"I found some guys said KeilC does not support initial values in fixed allocation."

You don't need "some guys" to tell you that - Keil themselves clearly state it in their documentation:

http://www.keil.com/support/man/docs/c51/c51_le_absvarloc.htm

"If this is true"

Yes, it does exactly what it says on the tin!

"I think I've got the best way to program my firmware."

Maybe not "best", but perfectly acceptable!

Read-Only
Author
Jack Sprat
Posted
4-Sep-2008 09:53 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

I've never looked into doing this in C (for the C51), so I don't know if it is possible there.

It can be done in 'C', at least in the sense that no assembly language is required to achieve it. The defining declaration and initialisation needs to be placed in a separate source file and included in the project. The linker project options can then be modified to locate the resulting segment at the required address.

If multiple objects are required at sequential addresses (as though they were contained in a structure) it is necessary to check the 'keep variables in order' box in the options for the source file or the entire project.

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 10:10 GMT
Toolset
C51
New! RE: How to assign initial values in code memory with specific location?

"The linker project options can then be modified to locate the resulting segment at the required address."

Yes, I'd forgotten that option. I've done it that way a number of times before, but have nearly always ended up going back to my assembler 'comfort zone'!

Read-Only
Author
erik malund
Posted
4-Sep-2008 14:54 GMT
Toolset
C51
New! WOW

at a fixed location in the ROM image - And always do it by using an assembler module

I do the very same.

Erik

Read-Only
Author
Silly Sausage
Posted
4-Sep-2008 15:02 GMT
Toolset
C51
New! RE: WOW

Erik,

We're like two peas in a pod ;)

Read-Only
Author
Andy Neil
Posted
4-Sep-2008 09:00 GMT
Toolset
C51
New! RTFM!

Go to the description of _at_ in the manual:

http://www.keil.com/support/man/docs/c51/c51_le_absvarloc.htm

At the bottom of the page is a list of Related Knowledgebase Articles - and one of them is titled "INITIALIZING AN ABSOLUTELY LOCATED VARIABLE"

If you follow that link, you will also find links to previous threads on the same subject...

Read-Only
Author
Andy Neil
Posted
4-Sep-2008 09:14 GMT
Toolset
None
New! RE: I want to define some values in code memory with specific location

It would be helpful if you would explain why you want to do this.

If you explained what you're actually trying to achieve, people may well be able to offer more appropriate suggestions.

Yes, the are perfectly valid reasons to do this (Per has already given one) - but there are also very many cases where it is not necessary at all...

Read-Only
Author
Per Westermark
Posted
4-Sep-2008 10:28 GMT
Toolset
None
New! RE: I want to define some values in code memory with specific location

"(Per has already given one)"

LOL. Sorry, I'm not posting under the Silly Sausage alias :)

But storing a checksum, version etc at a fixed location allows a firmware updater to verify that the correct file is downloaded, and that it hasn't been broken in transfer.

It can also be used by the actual application to validate itself and possibly generate an alarm if a checksum error is found. If the unit is operating dangerous equipment, it may be very important that the firmware decides to lock up if a checksum test fails, do avoid endangering human life.

With internal tests using crc or stupid checksums, the need for an absolute location can be removed by making sure that the crc or checksum always results in zero. But that makes it impossible to use the checksum/crc as an additional control that a file has the correct version. Without automatic build tools, the developer may have forgotten to step the printed version number...

Next Thread | Thread List | Previous Thread Start a Thread | Settings