Jump to content

big arrays?


Thomas
 Share

Recommended Posts

Hallo!

It seems not possible to create large char-arrays with more than 256 elements.

Is this correct?

unsigned char myArray[256];    //ok

unsigned char myArray[257];    //I'll get "no more memory" compiler error

But:

unsigned char myArray0[256];

unsigned char myArray1[256];

work.

It seems it's not a problem of too less remainig memory (registers) but the addressing with only a 8bit.

Link to comment
Share on other sites

No, this is no handicap.

I just wanted to know this.

I contacted the programmer who wrote the PIC16 part of the sdcc project.

Sadly there is no complete documentation avaiable.

Especially not for code optimization. (How to programm, what to avoid etc.pp.) 

Btw. large arrays can be created in the linker script.

Link to comment
Share on other sites

Ok.

(Hoping that it's ok to publish private mail)

Vangelis Rokas wrote:

1.)

For example, when declaring functions with pointer arguments that you

already know they point at RAM memory, do not declare them like this:

void f(char *str);

but like this: void f(__data char *str);

The __data specifier uses only 2 bytes for the 'str' pointer, when it would

need 3 bytes (and more instructions to handle read/writing, etc...)

This is just the tip of the iceberg(!) but I don't have everything on hand

right now...

2.)  (large arrays)

This can be solved by tweaking the .lkr script.

Concatenate some DATABANK entries for example:

//DATABANK  NAME=gpr3      START=0x300          END=0x3FF

//DATABANK  NAME=gpr4      START=0x400          END=0x4FF

//DATABANK  NAME=gpr5      START=0x500          END=0x5FF

DATABANK  NAME=gpr345      START=0x300          END=0x5FF  // this creates

a segment 3 * 256 bytes

This way you could allocate the whole data ram of a pic in a single DATABANK

and allocate as much of it you can afford!!!! :-)

Greetings Thomas

Link to comment
Share on other sites

I'm not sure how the databank addresses relate to the C variables.

In C when you declare an array you are really allocating a portion of memory and storing the start of that portion in the array variable.  So:

unsigned char b[200];

means "allocate 200 bytes, and store the address of the start of that newly allocated block in b".

So b is really just a pointer to a memory location.  So the linker script above is just allocating the memory and giving it a name, but not doing it in C:

DATABANK  NAME=gpr345      START=0x300          END=0x5FF

Obviously the harder part is that you have to explicitly give it the start/end positions, which if you use C syntax to allocate the block the compiler/linker does it for you.

Just to complete the example: when you access an array element, like

b[200] = 5;

You are really saying "add 200*sizeof(any array element in b) to the address stored in b, and store 5 at that memory address".

Hope that makes sense stryd_one :).

Link to comment
Share on other sites

Ahhh lovely now I can relate it to some of the ASM I know :) (Which is probably what the compiler makes the arrays into heheh)

The thing I really don't get is how our array called 'b' matches up with the linker script, I mean, do we need to add the array's name and memory space to the linker every time we create an array?

Today I've got that "I should have stuck with ASM" feeling ;)

Link to comment
Share on other sites

don't worry stryd_one, I don't get it either.

Although it's interesting having read that such a possibility exists, I would leave my fingers from it. This sounds really dangerous, because it contains several traps to step into if you're changing smth later...

If you really need more than 256 array elements, it might be of wiser to group the items and use some #defines

(Besides 256 AINs? 256 LED's? No... maybe 256 DIN's? Man, that seems like button-hell ;D I just counted 110 keys on my computer's keyboard... )

Link to comment
Share on other sites

The thing I really don't get is how our array called 'b' matches up with the linker script, I mean, do we need to add the array's name and memory space to the linker every time we create an array?

Apparently only when it's >256 bytes (or maybe 256 elements, you'd have to try)

Link to comment
Share on other sites

Hi!

As audiocommander said, it's better to use groups of <=256 arrays.

On reason is that only a char (8-bit) is used instead of an 16bit int what

would require at least the doubled number of assembler commands.

(-> see the resulting *.asm file after compiling)

Ways to access a database defined like mentioned above:

1.) Use the absolute address:

unsigned char * ptr = 0x300;

ptr[0] = 0x08;

ptr[1] = 0x15;

...

2.) Use symbolic name, but I havn't tried this: (from Vangelis)

Another way to define a symbol at a specific databank would be to use the

'udata' pragma. The usage would be:

#pragma udata array_name gpr345_section

This would 'array_name' at gpr345_section DATABANK (which would that be...)

But then you would have to add one more line in the .lkr script file:

SECTION    NAME=gpr345_section    RAM=gpr345

Link to comment
Share on other sites

  • 1 month later...

Good news guys, I've been doing some experimentation and have figured out what's going on with all this drama about large data storage and arrays. I'll write a documentation on the wiki shortly with full instructions.

Before I do, I just need to find out some info about memory use on the 4620 so I can document that too.... But that's one for another thread.

In short: Arrays can be addressed with >8bit indexes, no problem, but they attempt to allocate more ram than is available. The symbolic name trick from vangelis (and the sdcc manual) posted previously works like a charm :)

Link to comment
Share on other sites

  • 1 year later...

I noticed that it's not possible to define a bitfield with more than 8 bits.

For the record:

Good news, I have just tested a 15-bit bitfield (15, not 16, to test correct alignment of odd sizes across bytes), and all accesses are correct :)

This was with a post 2.7.0 SDCC release.

Link to comment
Share on other sites

Well, a lot of us use those threads as reference points, especially a good newbie doing a search to find out info. Several of them are linked from wiki articles too... If I put this info in one thread, they may miss it, so it's in the threads where it was said that the limit was 8 bit, as an update to the existing doco.

Sorry for the annoyance, but it's important, for future reference :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...