Searching \ for '[PIC] large buffer in C18' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/microchip/devices.htm?key=pic
Search entire site for: 'large buffer in C18'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] large buffer in C18'
2009\03\25@060441 by Dumitru Stama

picon face
Hi,
what is the method to implement a large buffer for (let's say PIC18F2520) ?
I tried : unsigned char testbuffer[512]
I need it to read a sector and , of course, it gave an error.
Right now i have two 256 bytes buffers specifically inserted in GPR
sections using #pragma

Is there a nicer method which allows me to have only one large buffer ?
Thank you in advance

2009\03\25@061311 by solarwind

picon face
On Wed, Mar 25, 2009 at 5:04 AM, Dumitru Stama <spam_OUTspanacTakeThisOuTspamgmail.com> wrote:
> Hi,
> what is the method to implement a large buffer for (let's say PIC18F2520) ?
> I tried : unsigned char testbuffer[512]
> I need it to read a sector and , of course, it gave an error.
> Right now i have two 256 bytes buffers specifically inserted in GPR
> sections using #pragma
>
> Is there a nicer method which allows me to have only one large buffer ?
> Thank you in advance

First of all, you need to make sure you have enough RAM. And I think
there's an option to change memory model in the project options, so
change it to large memory model.

2009\03\25@062637 by Vitaliy

flavicon
face
Dumitru Stama wrote:
> what is the method to implement a large buffer for (let's say PIC18F2520)
> ?
> I tried : unsigned char testbuffer[512]
> I need it to read a sector and , of course, it gave an error.
> Right now i have two 256 bytes buffers specifically inserted in GPR
> sections using #pragma
>
> Is there a nicer method which allows me to have only one large buffer ?
> Thank you in advance

You need to modify the linker file:

http://www.firstwiki.net/index.php/Multi-bank_programming

2009\03\25@080353 by olin piclist

face picon face
Dumitru Stama wrote:
> what is the method to implement a large buffer for (let's say
> PIC18F2520) ? I tried : unsigned char testbuffer[512]

You also have to edit the linker file to combine enough banks to make a
contiguous region to hold your buffer.  In this case you want 512 bytes, so
you need to combine two banks.

Don't combine more banks, and don't forget to update the linker file later
if your buffer is shrunk to 256 bytes or less.  If you forget, individual
sections can straddle bank boundaries, producing some very hard to find
bugs.  Unfortunately there will be nothing warning you of this.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\03\25@110625 by Harold Hallikainen

face
flavicon
face

> Dumitru Stama wrote:
>> what is the method to implement a large buffer for (let's say
>> PIC18F2520) ? I tried : unsigned char testbuffer[512]
>
> You also have to edit the linker file to combine enough banks to make a
> contiguous region to hold your buffer.  In this case you want 512 bytes,
> so
> you need to combine two banks.
>
> Don't combine more banks, and don't forget to update the linker file later
> if your buffer is shrunk to 256 bytes or less.  If you forget, individual
> sections can straddle bank boundaries, producing some very hard to find
> bugs.  Unfortunately there will be nothing warning you of this.
>

Here's some of the linker script from my current project that shows this:

DATABANK   NAME=gpre       START=0x0            END=0x5F
DATABANK   NAME=gpr0       START=0x60           END=0xFF
DATABANK   NAME=gpr1       START=0x100          END=0x1FF
DATABANK   NAME=gpr2       START=0x200          END=0x2FF
DATABANK   NAME=gpr3       START=0x300          END=0xAFF//END=0x3FF
//DATABANK   NAME=gpr4       START=0x400          END=0x4FF
//DATABANK   NAME=gpr5       START=0x500          END=0x5FF
//DATABANK   NAME=gpr6       START=0x600          END=0x6FF
//DATABANK   NAME=gpr7       START=0x700          END=0x7FF
//DATABANK   NAME=gpr8       START=0x800          END=0xCFF//END=0x8FF
//DATABANK   NAME=gpr9       START=0x900          END=0x9FF
//DATABANK   NAME=gpr10      START=0xA00          END=0xAFF
DATABANK   NAME=gpr11      START=0xB00          END=0xBFF
DATABANK   NAME=gpr12      START=0xC00          END=0xCFF
DATABANK   NAME=gpr13      START=0xD00         END=0xEF3 //END=0xDFF
//DATABANK   NAME=gpr14      START=0xE00          END=0xEF3
DATABANK   NAME=dbgspr     START=0xEF4          END=0xEFF          PROTECTED
DATABANK   NAME=gpr15      START=0xF00          END=0xF5F
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED

SECTION    NAME=CONFIG     ROM=config
SECTION          NAME=DisplayBuffer     RAM=gpr3
SECTION        NAME=AccessRam        RAM=gpre


STACK SIZE=0x1f3 RAM=gpr13



Then in my code, I have the following, to place stuff in this section of RAM.



DisplayBuffer        udata
ByteCount        res        1                ; Count down the bytes we've sent this row of pixels. We
send 40 bytes per row
RowCount        res        1                ; Count down rows. We send 240 rows
DeadTopCount res 1                ; count the dead rows at the top of the screen
EndActiveCount res 1        ; This is decremented until it hits zero. Then we
send blank pixels
FsrSaveH        res 1                ; interrupt context save
FsrSaveL        res 1
pBitMapH        res 1                ; pointer in to bitmap. Next byte we will send to display
pBitMapL        res        1
BankSelSave        res 1

BitMap                res        d'1920'        ; bitmap we'll send to display


Im my C code, I have the following to reference the BitMap:


extern uint8_t BitMap[1920];    // defined in KopinDisplayAsm.asm





Harold



--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2009\03\25@122239 by Dumitru Stama

picon face
It's ok now, i joined two sections together to make 0x200 bytes of
linear space and i defined my 512 bytes buffer, i filled it randomly
and i dumped the hex values on RS232 and everything seems to be ok.
Thank you for your help.
Olin, what was are those strange things i might encounter and are very
hard to find and debug ? Can you help me with a small example, i
didn't quite understand what you told me and it seemed like a VERY
important topic to watch for in the future.


On Wed, Mar 25, 2009 at 12:13 PM, solarwind <.....x.solarwind.xKILLspamspam@spam@gmail.com> wrote:
{Quote hidden}

> -

2009\03\25@131816 by olin piclist

face picon face
Dumitru Stama wrote:
> Olin, what was are those strange things i might encounter and are very
> hard to find and debug ? Can you help me with a small example, i
> didn't quite understand what you told me and it seemed like a VERY
> important topic to watch for in the future.

Everything is fine now since you have a single array filling your 2-bank
memory region.

However, consider what will happen if later you get rid of the array but
forget to update the linker file accordingly.  Now you've got a single
memory region that is spread over 2 banks.  The compiler assumes that data
memory sections that are collections of individual small variables are in
the same bank.  The linker could fill up the 2 bank memory region with a
collection of such small sections, thereby causing one of them to straddle
the bank boundary.  This breaks the compiler banking assumptions, causing
very difficult to diagnose bugs.

The moral is, if you ever create memory sections of multiple banks, make
sure that the array that necessitated it straddles all the bank boundaries
within that memory region.  For example, if the array size is 257 to 512
bytes, glue together exactly 2 banks.  If it's 513 to 768 bytes, glue
together exactly 3 banks, etc.  Never ever glue together more banks than
needed because that could leave a bank boundary unused by the array where
the linker might place a small section accross it.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\03\25@133241 by peter green

flavicon
face
Olin Lathrop wrote:
{Quote hidden}

Better still make the region EXACTLY the size of your array and then
tell the linker that it is not to put stuff in there that it is not
explicitly told to (I'm sure the linker script has such an option and it
is used for things like the sfr regions in the default linker scripts)

IIRC you also have to access arrays over 256 bytes through a pointer
because C18 won't do the indexing correctly otherwise.


2009\03\25@140001 by olin piclist

face picon face
peter green wrote:
> Better still make the region EXACTLY the size of your array and then
> tell the linker that it is not to put stuff in there that it is not
> explicitly told to (I'm sure the linker script has such an option and
> it
> is used for things like the sfr regions in the default linker scripts)

It's called "protected".

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\03\25@140142 by olin piclist

face picon face
peter green wrote:
> Better still make the region EXACTLY the size of your array and then
> tell the linker that it is not to put stuff in there that it is not
> explicitly told to (I'm sure the linker script has such an option and
> it
> is used for things like the sfr regions in the default linker scripts)

Oops, hit send too fast last time.  You can declare a memory region
PROTECTED, but then the array won't automatically go there either.  You will
have to define a named section for the memory region in the linker file,
then explicitly put the array into this named section in the source code.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\03\25@175803 by Dumitru Stama

picon face
Thanks Olin, i got it. After reading all posts i did this :

In the linker file i defined this zone of exactly two banks :
DATABANK   NAME=sector     START=0x300          END=0x4FF          PROTECTED
And then a section to use this protected banks :
SECTION    NAME=sector_buffer     RAM=sector

In my code i did this :
#pragma udata sector_buffer
unsigned char sectorbuffer[512];
#pragma udata

Tested and it works well, even with the usual indexing. I don't think
i really need a pointer to access this buffer.
Thanks again for the tips, i hope this will work well in the end.



On Wed, Mar 25, 2009 at 8:00 PM, Olin Lathrop <.....olin_piclistKILLspamspam.....embedinc.com> wrote:
> peter green wrote:
>> Better still make the region EXACTLY the size of your array and then
>> tell the linker that it is not to put stuff in there that it is not
>> explicitly told to (I'm sure the linker script has such an option and
>> it
>> is used for things like the sfr regions in the default linker scripts)
>
> It's called "protected".
>

2009\03\25@182414 by William \Chops\ Westfield

face picon face

>> what is the method to implement a large buffer for (let's say
>> PIC18F2520) ? I tried : unsigned char testbuffer[512]
>
> You also have to edit the linker file to combine enough banks to  
> make a
> contiguous region to hold your buffer.


I'm SO tempted for forward this discussion to the PIC vs AVR  
architectural discussion (but I guess everyone who cares would have  
already seen it anyway.)

 :-)
BillW

More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...