Jump to content
Sign in to follow this  
LasseT

Sb V7.0 Crossing Ram Bank Problem -idx 2 Option

Recommended Posts

I have been using the SB V7.0 for a few days and it looks very promising !

I found some small problems when I used the large array feature.

The first time I observed this was when I used a 'struct' spanning 300 'something' bytes in total.

 

I created some small test programs with int and long variables and found some problems when using the option -idx 2.

This was the easy way to describe the observation.

 

If the test programs where compiled with the default -idx 1 everything works ok but if I use the option -idx 2 I will have a linker error and it looks like the compilation runs ok (I only guess on the last statement).

 

My target chip is a 18F67J60 so I have quit a lot of memory. The use of large arrays will make my life easy (at least when it comes to programming :-) ).

 

I have some more comments in the test programs but I think they are very self explained :-)

 

/Lasse T

 

== This is the output from the test1.c using option -idx 2=======

===========================================

 

Building...

"C:\Program Files\SourceBoost\boostc_pic18.exe" SB7_test1.c -t PIC18F67J60 -idx 2 -obj Debug -d _DEBUG

BoostC Optimizing C Compiler Version 7.00 (for PIC18 architecture)

http://www.sourceboost.com

Copyright© 2004-2010 Pavel Baranov

Copyright© 2004-2010 David Hobday

 

Licensed to "me Lasse T" under Single user Full License for 2 node(s)

Limitations: PIC18 max code size:Unlimited, max RAM banks:Unlimited, Non commercial use only

 

 

SB7_test1.c

 

success

 

"C:\Program Files\SourceBoost\boostlink_pic.exe" /ld "C:\Program Files\SourceBoost\lib\large" libc.pic18.lib Debug\SB7_test1.obj /t PIC18F67J60 -idx 2 /d "C:\PIC_SB_v7\Debug" /p SB7_test1

Error: Failed to allocate memory for var 'd113' at address:0x000001FF crosses RAM banks

 

BoostLink Optimizing Linker Version 7.00

http://www.sourceboost.com

Copyright© 2004-2010 Pavel Baranov

Copyright© 2004-2010 David Hobday

 

 

 

 

failure

error: failed

Done

 

 

==================

Then we run the same "program" but the option is now the default -idx 1

=====================================

 

Building...

"C:\Program Files\SourceBoost\boostc_pic18.exe" SB7_test1.c -t PIC18F67J60 -idx 1 -obj Debug -d _DEBUG

BoostC Optimizing C Compiler Version 7.00 (for PIC18 architecture)

http://www.sourceboost.com

Copyright© 2004-2010 Pavel Baranov

Copyright© 2004-2010 David Hobday

 

Licensed to "me Lasse T" under Single user Full License for 2 node(s)

Limitations: PIC18 max code size:Unlimited, max RAM banks:Unlimited, Non commercial use only

 

 

SB7_test1.c

 

success

"C:\Program Files\SourceBoost\boostlink_pic.exe" -idx 1 /ld "C:\Program Files\SourceBoost\lib" libc.pic18.lib Debug\SB7_test1.obj /t PIC18F67J60 /d "C:\PIC_SB_v7\Debug" /p SB7_test1

BoostLink Optimizing Linker Version 7.00

http://www.sourceboost.com

Copyright© 2004-2010 Pavel Baranov

Copyright© 2004-2010 David Hobday

 

 

Building CASM file

Memory Usage Report

===================

RAM available:3808 bytes, used:519 bytes (13.7%), free:3289 bytes (86.3%),

Heap size:3192 bytes, Heap max single alloc:127 bytes

ROM available:131064 bytes, used:2092 bytes (1.6%), free:128972 bytes (98.4%)

 

 

 

success

Done

 

=========Comment added October 7th by LasseT

 

Just another testprogram for -idx 2

 

The long array works perfect! No problems with that what so ever.

I let a long array start and span a lot of RAM banks. Testing all RAM bank crossings.

If you are tired of this skip down to the BUT statement below.

 

===============

 

Building...

SourceBoost7\boostc_pic18.exe" SB7_test77.c -t PIC18F67J60 -idx 2 -obj Debug -d _DEBUG

BoostC Optimizing C Compiler Version 7.00 (for PIC18 architecture)

 

SourceBoost7\boostlink_pic.exe" /ld "C:\Program Files\SourceBoost7\lib\large" libc.pic18.lib Debug\SB7_test77.obj /t PIC18F67J60 -idx 2 /d C:\Users\uablto\Documents\workspace\Debug /p SB7_test77

BoostLink Optimizing Linker Version 7.00

 

 

Building CASM file

Memory Usage Report

===================

RAM available:3808 bytes, used:2048 bytes (53.8%), free:1760 bytes (46.2%),

Heap size:1662 bytes, Heap max single alloc:127 bytes

ROM available:131064 bytes, used:2054 bytes (1.6%), free:129010 bytes (98.4%)

 

The memory layout is as follows:

 

Adr variable

0x001 char i

0x002 bulk[94] start

0x05F bulk[94] ends

0x060/61 int e0

0x062 -- 0x178 int e1 to e139

0x179/17A int e140

0x17B/17C int d0

0x17D -- 0x17C int d1 to d64

0x1FD/1FE int d65

0x1FF start of large[LONG] array just before a RAM bank end

0x7FD end of large [LONG] array just before a RAM bank end

0x7FE/7FF is used by the for loop as a address pointer

 

===============================

 

BUT:

 

If you change the large[LONG] array length one byte (in this test from 1535 to 1536)

this will push for loop address pointer one byte up and the compiler/linker will

try to use 0x7FF and 0x800 for the pointer. The compilation runs OK but the linker

will have some problem with this as can be seen in the printout.

 

 

 

Error: Failed to allocate memory for var '' at address:0x000007FF crosses RAM banks

 

BoostLink Optimizing Linker Version 7.00

http://www.sourceboost.com

Copyright© 2004-2010 Pavel Baranov

Copyright© 2004-2010 David Hobday

 

 

 

 

failure

error: failed

Done

 

=========================================================================

 

I can not help with a solution but I can clearly see the problem. And I'm very sure that if I had

the compiler/linker sourcecode I could not help anyway :-)

 

=======================================================================

 

// Lasse T

SB7_test1.c

SB7_test2.c

SB7_test77.c

Edited by LasseT

Share this post


Link to post
Share on other sites
I added a new testprogram to the original posting. Maybe it will help some.

 

Regards,

Lasse T

Lasse I'm not sure if anyone got back to you on this. There are several instructions such as POSTINC and POSTDEC that only use 8 bits of address so there will be a problem if they operate on a variable that crosses a bank boundary such as an int or long starting at 0x000007FF. POSTDEC for example will operate on the first byte and then decrement the address which will just wrap around to the other end of the bank.

 

Pavel and Dave were aware of this when developing v7 and probably that's why they added the linker error (just guessing). They also looked at some potential solutions such as the linker trying to make sure multi-byte variables did not cross bank boundaries but this is a lot trickier with, for example, a pointer to one type that is cast to a larger type, or how the ptr will be assigned, so the linker may not know ahead of time. I'm not sure what solutions were ultimately implemented - perhaps Pavel or Dave has time to chime in here? I'm guessing the linker error was added when variables could not be moved to a safer place.

 

Your struct may also contribute to the problem (or caused the linker error). If one variable within the struct was aligned so to cross a bank, the linker would have to do a special allocation for the entire struct, which may be impossible. I'm curious how other compilers/linkers have dealt with this issue. It may be a limitation of the PIC18 devices that if you use large arrays, you have to pay close attention to alignment.

 

Best,

Henry

Share this post


Link to post
Share on other sites

Henry,

Pavel and Dave were aware of this when developing v7 and probably that's why they added the linker error (just guessing). They also looked at some potential solutions such as the linker trying to make sure multi-byte variables did not cross bank boundaries but this is a lot trickier with, for example, a pointer to one type that is cast to a larger type, or how the ptr will be assigned, so the linker may not know ahead of time. I'm not sure what solutions were ultimately implemented - perhaps Pavel or Dave has time to chime in here? I'm guessing the linker error was added when variables could not be moved to a safer place.

Three senarios:

1) Array that is <= 256 bytes long, must lie within a single bank, can be array of any size data or structure.

2) Array that is > 256 and <= 512 bytes long, aligned so no element crosses a bank, can be array of any size data or structure.

3) Array that is > 512 bytes long, no element crosses a bank, alignment is dictated by element size, can be array of any size data or structure whose size must be 2^n.

 

Regards

Dave

Share this post


Link to post
Share on other sites

LasseT,

I added a new testprogram to the original posting. Maybe it will help some.

 

Regards,

Lasse T

I can reproduce the issue, things are not as they should be :-(

 

Regards

Dave

Share this post


Link to post
Share on other sites

LasseT

I added a new testprogram to the original posting. Maybe it will help some.

 

Regards,

Lasse T

This has been fixed and will be in the next release.

 

Regards

Dave

Share this post


Link to post
Share on other sites

POSTINC pops over bank boundaries just fine. It is not limited to stay in an 8 bit range. I use it in my logic analyzer code to sample 3936 samples (uses 15+ banks). It just counts up as a 12-bit value in the 18F2620 part. You can see the code here:

 

http://www.tedrossin.0sites.net/Electronic...l#LogicAnalyzer

 

Look for the label "Sample5000KHz". This is the big chunk of movf PORTB,w followed by movwf POSTINC0 repeated 3936 times to implement 5M Samples/sec mode.

 

Ok I broke down and found the place in the Microchip data sheet that says this about POSTINC which really makes my case:

Operations on the FSRs with POSTDEC, POSTINC and PREINC affect the entire register pair; that is, rollovers of the FSRnL register from FFh to 00h carry over to the FSRnH register. On the other hand, results of these operations do not change the value of any flags in the STATUS register (e.g., Z, N, OV, etc.).

 

 

I added a new testprogram to the original posting. Maybe it will help some.

 

Regards,

Lasse T

Lasse I'm not sure if anyone got back to you on this. There are several instructions such as POSTINC and POSTDEC that only use 8 bits of address so there will be a problem if they operate on a variable that crosses a bank boundary such as an int or long starting at 0x000007FF. POSTDEC for example will operate on the first byte and then decrement the address which will just wrap around to the other end of the bank.

 

Pavel and Dave were aware of this when developing v7 and probably that's why they added the linker error (just guessing). They also looked at some potential solutions such as the linker trying to make sure multi-byte variables did not cross bank boundaries but this is a lot trickier with, for example, a pointer to one type that is cast to a larger type, or how the ptr will be assigned, so the linker may not know ahead of time. I'm not sure what solutions were ultimately implemented - perhaps Pavel or Dave has time to chime in here? I'm guessing the linker error was added when variables could not be moved to a safer place.

 

Your struct may also contribute to the problem (or caused the linker error). If one variable within the struct was aligned so to cross a bank, the linker would have to do a special allocation for the entire struct, which may be impossible. I'm curious how other compilers/linkers have dealt with this issue. It may be a limitation of the PIC18 devices that if you use large arrays, you have to pay close attention to alignment.

 

Best,

Henry

 

 

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
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...
Sign in to follow this  

×