Jump to content

MIOS_Bankstick_WritePage in a loop; need to wait?


This N°9

Recommended Posts

hi,

I have some question concerning bankstick MIOS_Bankstick_WritePage:

- does the function return immediately and the 64 bytes are written

  in background, or do I have to check for a flag or something until

  I can call the function again? is the MIOS_BOX_STAT.BS_AVAILABLE

  the magic flag which I have to poll after each writepage?

why I'am asking: In my application I have a current_preset - array (size 64 bytes)

and a function that writes it to the stick with MIOS_BANKSTICK_WritePage. If

I write the preset to any preset-storage-address (preset_num << 6),

everything works fine. But if I call the same store-function in a loop to init

all the 16 presets on the stick, I get very strange results.. I do this in the main-loop (USER_Tick).

if I just init one preset, all works fine again.

- what's the point about the 'verifiy' - option, when/what for do I need it or not?

  is the verify for writepage done for every byte, or do I just get an error when

  the whole content is equal?

thanks,

this

Link to comment
Share on other sites

MIOS_Bankstick_WritePage is a blocking function, you can be sure that the programming process has finished when the function is exit.

See also this programming example.

You have to ensure, that no IRQ routine accesses the BankStick while it is accessed from the "main" program, of course... regardless if the content is read or written.

"Verify" just reads and compares the written content. I used it in the early days to doublecheck if BankStick writes are reliable. They are - therefore I mostly disable it in my own application meanwhile.

Best Regards, Thorsten.

Link to comment
Share on other sites

ok, I found it:

it's about the building of the storage-address. wrong use of bitshift leads to

interesting results (different if I call the same code from Tick or from DIN_Notify...):

this works not (I inserted some LCD code to get a debug output):

void preset_store(unsigned char num) __wparam{
	unsigned int addr = ((unsigned int)num) << 6;
	//unsigned int addr = num*64;
	MIOS_LCD_Clear();
	MIOS_LCD_CursorSet(0);
	MIOS_LCD_PrintBCD2(num);
	MIOS_LCD_PrintCString(" - ");
	MIOS_LCD_PrintBCD5(addr);
	MIOS_BANKSTICK_WritePage(addr, current_preset);
	}
output for num==10 when I call it in DIN_NotifyToggle: 10 - 64 and for calls from Tick: 10 - 0 this one works:
void preset_store(unsigned char num) __wparam{
	unsigned int addr = num;
	addr <<= 6;
	MIOS_LCD_Clear();
	MIOS_LCD_CursorSet(0);
	MIOS_LCD_PrintBCD2(num);
	MIOS_LCD_PrintCString(" - ");
	MIOS_LCD_PrintBCD5(addr);
	MIOS_BANKSTICK_WritePage(addr, current_preset);
	}
10 - 640 2 - 128 etc. but this works NOT!!:
void preset_store(unsigned char num) __wparam{
	unsigned int addr = num;
	//addr <<= 6;
	MIOS_BANKSTICK_WritePage(addr << 6, current_preset);
	}
finally, this variant works:
void preset_store(unsigned char num) __wparam{
	unsigned int addr = num;
	addr <<= 6;
	MIOS_BANKSTICK_WritePage(addr, current_preset);
	}

it took me hours to come to this ;-)

Link to comment
Share on other sites

it took me hours to come to this ;-)

I bet it did!

SDCC is *really* picky about parentheses... Can you try these? I've commented my changes.

However... it behaving differently when called from the tick or notify functions, is really strange... And really, they all should work. What version of SDCC are you using? Can you do 'sdcc -v' and paste the output?

It kinda seems like an SDCC bug...

void preset_store(unsigned char num) __wparam{
	unsigned int addr = (((unsigned int)num) << 6); // parentheses added here
	//unsigned int addr = num*64;
	MIOS_LCD_Clear();
	MIOS_LCD_CursorSet(0);
	MIOS_LCD_PrintBCD2(num);
	MIOS_LCD_PrintCString(" - ");
	MIOS_LCD_PrintBCD5(addr);
	MIOS_BANKSTICK_WritePage(addr, current_preset);
	}
void preset_store(unsigned char num) __wparam{
	unsigned int addr = ((unsigned char)num); // Typecast added here
	//addr <<= 6;
	MIOS_BANKSTICK_WritePage((addr << 6), current_preset); // parentheses here
	}

Edit: I'd love to see the output asm if you still have it handy! (yes, I can make it myself, but i'm busy :( )

Link to comment
Share on other sites

Can you do 'sdcc -v' and paste the output?

here it is:

this@this-laptop:~$ sdcc -v

SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.0 #4 818 (Jan 18 2008) (UNIX)

MIOS_BANKSTICK_WritePage((addr << 6), current_preset); // parentheses here

this one I already tried, makes no difference.

However... it behaving differently when called from the tick or notify functions, is really strange... And really, they all should work.

I'dont exactly know where notify is called, but I think it's from a timer - callback, not from the main-loop? This could make the difference.

It kinda seems like an SDCC bug...

could be. I'll study the sdcc-manual once more, there are specials about

passing parameters to functions etc. I could imagine that bit-shifts have special

things to take are about too.

I'd love to see the output asm if you still have it handy!

ok, i start with the current, woking version:

; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	162; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	163; main.c	unsigned int addr = num;
	CLRF	r0x01
;	.line	164; main.c	addr <<= 6;
	RRCF	r0x01, F
	RRCF	r0x00, F
	RRCF	r0x01, F
	RRCF	r0x00, F
	RRCF	r0x01, W
	ANDLW	0xc0
	XORWF	r0x00, W
	XORWF	r0x00, F
	XORWF	r0x00, W
	MOVWF	r0x01
;	.line	165; main.c	MIOS_BANKSTICK_WritePage(addr, current_preset);
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x03
	MOVLW	LOW(_current_preset)
	MOVWF	r0x02
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN	
your first proposition (Debug - Output: num==6 -> addr==64): NOT working:
; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	170; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	171; main.c	unsigned int addr = (((unsigned int)num) << 6); // parentheses added here
	CLRF	r0x01
	RRCF	r0x01, W
	MOVWF	r0x03
	RRCF	r0x02, W
	MOVWF	r0x02
	RRCF	r0x03, F
	RRCF	r0x02, F
	RRCF	r0x03, W
	ANDLW	0xc0
	XORWF	r0x02, W
	XORWF	r0x02, F
	XORWF	r0x02, W
	MOVWF	r0x03
;	.line	177; main.c	MIOS_BANKSTICK_WritePage(addr, current_preset);
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x01
	MOVLW	LOW(_current_preset)
	MOVWF	r0x00
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN	
your second proposition (Debug - Output: num==6 -> addr==348): this one works only if I have the debug code uncommented (!). the funny thing is, that the debug output is correct too. If the shift would appear after passing the value, this would not be the case. so this one WORKS:
; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	170; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	171; main.c	unsigned int addr = ((unsigned char)num);
	MOVFF	r0x00, r0x01
	CLRF	r0x02
;	.line	172; main.c	MIOS_LCD_Clear();
	CALL	_MIOS_LCD_Clear
;	.line	173; main.c	MIOS_LCD_CursorSet(0);
	MOVLW	0x00
	CALL	_MIOS_LCD_CursorSet
;	.line	174; main.c	MIOS_LCD_PrintBCD2(num);
	MOVF	r0x00, W
	CALL	_MIOS_LCD_PrintBCD2
;	.line	175; main.c	MIOS_LCD_PrintCString(" - ");
	MOVLW	UPPER(__str_0)
	MOVWF	POSTDEC1
	MOVLW	HIGH(__str_0)
	MOVWF	POSTDEC1
	MOVLW	LOW(__str_0)
	CALL	_MIOS_LCD_PrintCString
	MOVLW	0x02
	ADDWF	FSR1L, F
;	.line	176; main.c	MIOS_LCD_PrintBCD5((addr << 6));// parentheses here
	RRCF	r0x02, W
	MOVWF	r0x03
	RRCF	r0x00, W
	MOVWF	r0x00
	RRCF	r0x03, F
	RRCF	r0x00, F
	RRCF	r0x03, W
	ANDLW	0xc0
	XORWF	r0x00, W
	XORWF	r0x00, F
	XORWF	r0x00, W
	MOVWF	r0x03
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	CALL	_MIOS_LCD_PrintBCD5
	INCF	FSR1L, F
;	.line	177; main.c	MIOS_BANKSTICK_WritePage((addr << 6), current_preset);// parentheses here
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x02
	MOVLW	LOW(_current_preset)
	MOVWF	r0x01
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN
..while this one is NOT working!! :
; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	170; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	171; main.c	unsigned int addr = ((unsigned char)num);
	CLRF	r0x01
;	.line	177; main.c	MIOS_BANKSTICK_WritePage((addr << 6), current_preset);// parentheses here
	RRCF	r0x01, W
	MOVWF	r0x03
	RRCF	r0x02, W
	MOVWF	r0x02
	RRCF	r0x03, F
	RRCF	r0x02, F
	RRCF	r0x03, W
	ANDLW	0xc0
	XORWF	r0x02, W
	XORWF	r0x02, F
	XORWF	r0x02, W
	MOVWF	r0x03
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x01
	MOVLW	LOW(_current_preset)
	MOVWF	r0x00
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN	
the typecast on assign nor the parentheses on passing make any difference. this one works again:
; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	170; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	171; main.c	unsigned int addr = num;
	MOVFF	r0x00, r0x01
	CLRF	r0x02
;	.line	172; main.c	MIOS_LCD_Clear();
	CALL	_MIOS_LCD_Clear
;	.line	173; main.c	MIOS_LCD_CursorSet(0);
	MOVLW	0x00
	CALL	_MIOS_LCD_CursorSet
;	.line	174; main.c	MIOS_LCD_PrintBCD2(num);
	MOVF	r0x00, W
	CALL	_MIOS_LCD_PrintBCD2
;	.line	175; main.c	MIOS_LCD_PrintCString(" - ");
	MOVLW	UPPER(__str_0)
	MOVWF	POSTDEC1
	MOVLW	HIGH(__str_0)
	MOVWF	POSTDEC1
	MOVLW	LOW(__str_0)
	CALL	_MIOS_LCD_PrintCString
	MOVLW	0x02
	ADDWF	FSR1L, F
;	.line	176; main.c	MIOS_LCD_PrintBCD5(addr << 6);// parentheses here
	RRCF	r0x02, W
	MOVWF	r0x03
	RRCF	r0x00, W
	MOVWF	r0x00
	RRCF	r0x03, F
	RRCF	r0x00, F
	RRCF	r0x03, W
	ANDLW	0xc0
	XORWF	r0x00, W
	XORWF	r0x00, F
	XORWF	r0x00, W
	MOVWF	r0x03
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	CALL	_MIOS_LCD_PrintBCD5
	INCF	FSR1L, F
;	.line	177; main.c	MIOS_BANKSTICK_WritePage(addr << 6, current_preset);// parentheses here
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x02
	MOVLW	LOW(_current_preset)
	MOVWF	r0x01
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN	
...and this one is NOT working:
; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	170; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	171; main.c	unsigned int addr = num;
	CLRF	r0x01
;	.line	177; main.c	MIOS_BANKSTICK_WritePage(addr << 6, current_preset);// parentheses here
	RRCF	r0x01, W
	MOVWF	r0x03
	RRCF	r0x02, W
	MOVWF	r0x02
	RRCF	r0x03, F
	RRCF	r0x02, F
	RRCF	r0x03, W
	ANDLW	0xc0
	XORWF	r0x02, W
	XORWF	r0x02, F
	XORWF	r0x02, W
	MOVWF	r0x03
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x01
	MOVLW	LOW(_current_preset)
	MOVWF	r0x00
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN	
one more.. this is not working :
; ; Starting pCode block
S_main__preset_store	code
_preset_store:
;	.line	163; main.c	void preset_store(unsigned char num) __wparam{
	MOVFF	FSR2L, POSTDEC1
	MOVFF	FSR1L, FSR2L
	MOVFF	r0x00, POSTDEC1
	MOVFF	r0x01, POSTDEC1
	MOVFF	r0x02, POSTDEC1
	MOVFF	r0x03, POSTDEC1
	MOVFF	r0x04, POSTDEC1
	MOVWF	r0x00
;	.line	164; main.c	unsigned int addr = num;
	CLRF	r0x01
;	.line	166; main.c	MIOS_BANKSTICK_WritePage((addr <<= 6), current_preset);
	RRCF	r0x01, W
	MOVWF	r0x03
	RRCF	r0x02, W
	MOVWF	r0x02
	RRCF	r0x03, F
	RRCF	r0x02, F
	RRCF	r0x03, W
	ANDLW	0xc0
	XORWF	r0x02, W
	XORWF	r0x02, F
	XORWF	r0x02, W
	MOVWF	r0x03
	MOVLW	HIGH(_current_preset)
	MOVWF	r0x01
	MOVLW	LOW(_current_preset)
	MOVWF	r0x00
	MOVLW	0x80
	MOVWF	r0x04
	MOVF	r0x04, W
	MOVWF	POSTDEC1
	MOVF	r0x01, W
	MOVWF	POSTDEC1
	MOVF	r0x00, W
	MOVWF	POSTDEC1
	MOVF	r0x03, W
	MOVWF	POSTDEC1
	MOVF	r0x02, W
	CALL	_MIOS_BANKSTICK_WritePage
	MOVLW	0x04
	ADDWF	FSR1L, F
	MOVFF	PREINC1, r0x04
	MOVFF	PREINC1, r0x03
	MOVFF	PREINC1, r0x02
	MOVFF	PREINC1, r0x01
	MOVFF	PREINC1, r0x00
	MOVFF	PREINC1, FSR2L
	RETURN	

so It looks like the bitshift needs to be

on a separate line..

I let it be your job to interpret the asm..

Link to comment
Share on other sites

cocerning bitshift, I only found this in the SDCC-manual:

8.1.8     Bit-shifting Operations.

Bit shifting is one of the most frequently used operation in embedded programming. SDCC tries to implement

bit-shift operations in the most ef?cient way possible, e.g.:

       unsigned char i;

       ...

       i > >= 4;

       ...

generates the following code:

       mov    a,_i

       swap   a

       anl    a,#0x0f

       mov    _i,a

In general SDCC will never setup a loop if the shift count is known. Another example:

       unsigned int i;

       ...

       i > >= 9;

       ...

will generate:

       mov    a,(_i + 1)

       mov    (_i + 1),#0x00

       clr    c

       rrc    a

       mov    _i,a

8.1.9     Bit-rotation

A special case of the bit-shift operation is bit rotation, SDCC recognizes the following expression to be a left

bit-rotation:

       unsigned char i;                      /* unsigned is needed for rotation */

       ...

       i = ((i < < 1) | (i > > 7));

       ...

will generate the following code:

       mov    a,_i

       rl     a

       mov    _i,a

SDCC uses pattern matching on the parse tree to determine this operation.Variations of this case will also be

recognized as bit-rotation, i.e.:

       i = ((i > > 7) | (i < < 1)); /* left-bit rotation */

Link to comment
Share on other sites

Yeh, I think the only part of the manual that really applies here, is the part where they say something about chars not being promoted to int for arithmetic (as they usually are). I think it's in the compliance section?

SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.0 #4 

Still haven't upgraded to 2.8? You should. I'm sure I told you about this last time ;)

I'dont exactly know where notify is called, but I think it's from a timer - callback, not from the main-loop? This could make the difference.

Memory is saved and restored in ISR's anyway, but it's called from a flag.

this one works only if I have the debug code uncommented (!).

Optimizer bug.

so It looks like the bitshift needs to be

on a separate line..

Well, putting it in parentheses should do the same thing, that's why it's weird.

So, more and more, it's looking like an SDCC bug, So I figure, "I wonder if my latest SDCC build does the same thing?" well guess what I get:

error: multiple sections using address 0
Here's the code that produced it:
// $Id: main.c 333 2008-05-10 20:49:56Z tk $
/*
 * MIOS SDCC Wrapper
 *
 * ==========================================================================
 *
 *  Copyright (C) <year>  <name> (<email>)
 *  Licensed for personal non-commercial use only.
 *  All other rights reserved.
 * 
 * ==========================================================================
 */
/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////

#include <cmios.h>
#include <pic18fregs.h>


unsigned char testval;
unsigned char current_preset[64] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};

void preset_storeb(unsigned char num) __wparam{
	unsigned int addr = num;
	addr <<= 6;
	MIOS_BANKSTICK_WritePage(addr, current_preset);
	}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after startup to initialize the 
// application
/////////////////////////////////////////////////////////////////////////////
void Init(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS in the mainloop when nothing else is to do
/////////////////////////////////////////////////////////////////////////////
void Tick(void) __wparam
{
preset_storeb(testval);
}

/////////////////////////////////////////////////////////////////////////////
// This function is periodically called by MIOS. The frequency has to be
// initialized with MIOS_Timer_Set
/////////////////////////////////////////////////////////////////////////////
void Timer(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when the display content should be 
// initialized. Thats the case during startup and after a temporary message
// has been printed on the screen
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Init(void) __wparam
{
  MIOS_LCD_Clear();
  MIOS_LCD_CursorSet(0x00);
  MIOS_LCD_PrintCString("Hello World!");
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called in the mainloop when no temporary message is shown
//  on screen. Print the realtime messages here
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Tick(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called by MIOS when a complete MIDI event has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
testval = evnt0;
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has been received
// which has been specified in the MIOS_MPROC_EVENT_TABLE
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has not been completly
// received within 2 seconds
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyTimeout(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI byte has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedByte(unsigned char byte) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS before the shift register are loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Prepare(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after the shift register have been loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Finish(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam
{
}

ARGH!!I never saw this error before you joined ;)

Link to comment
Share on other sites

Still haven't upgraded to 2.8? You should. I'm sure I told you about this last time

yes, I know.. but currently I'm using the Ubuntu dist, and I'am lazy. I should

build it from the source..

Memory is saved and restored in ISR's anyway, but it's called from a flag.

hm.. called from a flag? what's this?

Well, putting it in parentheses should do the same thing, that's why it's weird.

I'am really a asm-analphabet, you don't see anything that could explain this in the asm-code?

error: multiple sections using address 0

you get this on compiling? I can compile your test-code without any problems.. maybe

I shouldn't update my sdcc... :-)

this@this-laptop:~/mios/trunk/apps/this_testapp$ make
rm -rf _output/*
rm -rf _output
rm -rf *.cod *.map *.lst
rm -rf *.hex
mkdir -p _output
/bin/bash /home/this/mios/trunk/bin/mios-gpasm -c -p p18f452 -I./src -I /home/this/mios/trunk/include/asm -I /home/this/mios/trunk/include/share -I                /home/this/mios/trunk/modules/app_lcd/dummy -DDEBUG_MODE=0  -DSTACK_HEAD=0x37f -DSTACK_IRQ_HEAD=0x33f -I /home/this/mios/trunk/modules/mios_wrappe               r /home/this/mios/trunk/modules/mios_wrapper/mios_wrapper.asm  -o _output/mios_wrapper.o
/bin/bash /home/this/mios/trunk/bin/mios-gpasm -c -p p18f452 -I./src -I /home/this/mios/trunk/include/asm -I /home/this/mios/trunk/include/share -I                /home/this/mios/trunk/modules/app_lcd/dummy -DDEBUG_MODE=0   /home/this/mios/trunk/modules/app_lcd/dummy/app_lcd.asm -o _output/app_lcd.o
/bin/bash /home/this/mios/trunk/bin/mios-sdcc -c -mpic16 -p18f452 --fommit-frame-pointer --optimize-goto --optimize-cmp --disable-warning 85 --oban               ksel=2  -I./src -I /home/this/mios/trunk/include/c -I /home/this/mios/trunk/include/share -DDEBUG_MODE=0  main.c -o _output/main.o
/home/this/mios/trunk/bin/mios-gpasm modifies _output/main.asm, result in _output/main__mios-gpasm-tmp.asm
gplink -s /home/this/mios/trunk/etc/lkr/p18f452.lkr -m -o project.hex  /home/this/mios/trunk/lib/libsdcc.lib /home/this/mios/trunk/lib/pic18f452.li               b _output/mios_wrapper.o _output/app_lcd.o _output/main.o

ARGH!!I never saw this error before you joined

some people could hate me for this property :-)

Link to comment
Share on other sites

error: multiple sections using address 0

I updated to the version 2.8.4 of SDCC, now I get the same

error as you *arghhh*.

besides, I have to do a typecast on passing the address of my array now:

MIOS_BANKSTICK_ReadPage(addr,current_preset);

-->

main.c:105: error 78: incompatible types

I have to write:

MIOS_BANKSTICK_ReadPage(addr,(char*)current_preset);

...and the compiler option --optimize-goto is no more present in 2.8.4:

at 1: warning 117: unknown compiler option '--optimize-goto' ignored

At the base of your test-code, I will analyze what causes the "error: multiple sections using address 0"

seems to be the linker that throws it:

make
rm -rf _output/*
rm -rf _output
rm -rf *.cod *.map *.lst
rm -rf *.hex
mkdir -p _output
/bin/bash /home/this/mios/trunk/bin/mios-gpasm -c -p p18f452 -I./src -I /home/this/mios/trunk/include/asm -I /home/this/mios/trunk/include/share -I /home/this/mios/trunk/modules/app_lcd/dummy -DDEBUG_MODE=0  -DSTACK_HEAD=0x37f -DSTACK_IRQ_HEAD=0x33f -I /home/this/mios/trunk/modules/mios_wrapper /home/this/mios/trunk/modules/mios_wrapper/mios_wrapper.asm  -o _output/mios_wrapper.o
/bin/bash /home/this/mios/trunk/bin/mios-gpasm -c -p p18f452 -I./src -I /home/this/mios/trunk/include/asm -I /home/this/mios/trunk/include/share -I /home/this/mios/trunk/modules/app_lcd/dummy -DDEBUG_MODE=0   /home/this/mios/trunk/modules/app_lcd/dummy/app_lcd.asm -o _output/app_lcd.o
/bin/bash /home/this/mios/trunk/bin/mios-sdcc -c -mpic16 -p18f452 --fommit-frame-pointer --optimize-goto --optimize-cmp --disable-warning 85 --obanksel=2  -I./src -I /home/this/mios/trunk/include/c -I /home/this/mios/trunk/include/share -DDEBUG_MODE=0  main.c -o _output/main.o
at 1: warning 117: unknown compiler option '--optimize-goto' ignored
gplink -s /home/this/mios/trunk/etc/lkr/p18f452.lkr -m -o project.hex  /home/this/mios/trunk/lib/libsdcc.lib /home/this/mios/trunk/lib/pic18f452.lib _output/mios_wrapper.o _output/app_lcd.o _output/main.o
error: multiple sections using address 0
make: *** [project.hex] Fehler 1

If I can't fix it, I'll go back to the old SDCC that works for me..

Link to comment
Share on other sites

@stryd_one

error: multiple sections using address 0

I modified your testapp (just this line):

MIOS_BANKSTICK_ReadPage(addr,current_preset);//-->error: multiple sections using address 0

MIOS_BANKSTICK_ReadPage(0x00,current_preset);//-->error: multiple sections using address 0

MIOS_BANKSTICK_ReadPage(addr,0);//-->error: multiple sections using address 0

MIOS_BANKSTICK_ReadPage(0x00,0);//-->no error, compliles and links

the error occurs also if I never call "preset_storeb".

I switched back from SDCC 2.8.4 to the official Kubuntu package 2.7.0, this one

complies my app, and it works without problems on my MIDI-box.

Link to comment
Share on other sites

I just tried to search on google for similar threads, and found this:

http://osdir.com/ml/compilers.sdcc.user/2007-10/msg00030.html

they talk about interrupt handlers, I did not read it really carefully,

because I'am tired and have to to to bed, It's just a quick shot try,

maybe there's some usefull info.

In my example the error occurs on calling MIOS_BANKSTICK_ReadPage

with some var param, so maybe there's something in the MIOS kernel

that was accepted or ignored or interpreted differently by the older

SDCC compiler?

Link to comment
Share on other sites

  • 2 weeks later...

Yep, compiler error.

My toolchain was screwy but that was my fault (I broke it and I knew that) but once it was fixed, the above code *all* works with sdcc 2.8.0. However, 2.8.4 (the snapshot) is no good. Grab the working one here: sdcc-2.8.0-setup.exe

Would you like to file the bug report?

Link to comment
Share on other sites

Ok, I see.

I think we should not mix up the bitshift - subject with the

"error: multiple sections using address 0" subject. The latter

appears also with no bitshift at all.

MIOS_BANKSTICK_ReadPage(addr,current_preset);//-->error: multiple sections using address 0
MIOS_BANKSTICK_ReadPage(0x00,current_preset);//-->error: multiple sections using address 0
MIOS_BANKSTICK_ReadPage(addr,0);//-->error: multiple sections using address 0
MIOS_BANKSTICK_ReadPage(0x00,0);//-->no error, compliles and links

It seems like the parameter passing (and all that follows) causes the problem.

And maybe all the MIOS - environment is needed to reproduce the problem.

I will take your test-application and make a distribution, which I can post as a standalone-

package for the SDCC - developpers to (hopefully) reproduce the issue.

Link to comment
Share on other sites

The latter appears also with no bitshift at all.

With 2.8.0 ? I didn't see that myself... Anyway, as I said in the bug report, I had seen this behaviour in other code but had not been able to narrow it down... So I'm not singling this out to be a bitshift-related error, that's just one example of how to reproduce the error. If you can provide further examples to them, that can only help :)

Link to comment
Share on other sites

With 2.8.0 ?

no, this was with 2.8.4. now I'am a bit confused, because you write the code compliled & linked with 2.8.0 ?

is there also a problem with 2.8.0 ?

Insert Quote

@stryd_one

Quote

error: multiple sections using address 0

I modified your testapp (just this line):

MIOS_BANKSTICK_ReadPage(addr,current_preset);//-->error: multiple sections using address 0

MIOS_BANKSTICK_ReadPage(0x00,current_preset);//-->error: multiple sections using address 0

MIOS_BANKSTICK_ReadPage(addr,0);//-->error: multiple sections using address 0

MIOS_BANKSTICK_ReadPage(0x00,0);//-->no error, compliles and links

the error occurs also if I never call "preset_storeb".

I switched back from SDCC 2.8.4 to the official Kubuntu package 2.7.0, this one

complies my app, and it works without problems on my MIDI-box.

Link to comment
Share on other sites

no, this was with 2.8.4. now I'am a bit confused, because you write the code compliled & linked with 2.8.0 ?

Exactly - 2.8.0 is good. 2.8.4 is a snapshot build with bugs like the one you posted above. 2.7.0 is OK, but has other bugs, what with being an older version and all.

Link to comment
Share on other sites

ok, I cooked the shit down, a can confirm that with 2.8.0 everthing works fine.

2.8.5, the latest snapshot, causes the problems. check this sample code (check code in init & read comments):

// $Id: main.c 333 2008-05-10 20:49:56Z tk $
/*
 * MIOS SDCC Wrapper
 *
 * ==========================================================================
 *
 *  Copyright (C) <year>  <name> (<email>)
 *  Licensed for personal non-commercial use only.
 *  All other rights reserved.
 * 
 * ==========================================================================
 */
/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////

#include <cmios.h>
#include <pic18fregs.h>

unsigned char current_preset[64];
const unsigned char current_preset_const[64]= {
	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,

	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,

	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,

	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8,
	8,8,8,8,8
	};

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after startup to initialize the 
// application
/////////////////////////////////////////////////////////////////////////////
void Init(void) __wparam{
	unsigned int addr = 0x20;

	//the comments after the code lines apply with sdcc 2.8.4 / 2.8.5 --
	//with sdcc 2.8.0 all the lines compile & link without any problems

	MIOS_BANKSTICK_WritePage(addr, (char*)current_preset);// -> linker error error: multiple sections using address 0
	MIOS_BANKSTICK_WritePage(0x10, (char*)current_preset);// -> linker error error: multiple sections using address 0
	MIOS_BANKSTICK_WritePage(addr,&(current_preset[0]));// -> linker error error: multiple sections using address 0
	MIOS_BANKSTICK_WritePage(addr,0);//compiles & links
	MIOS_BANKSTICK_WritePage(addr,(char*)current_preset_const);//compiles and links. address to const in codespace
	}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS in the mainloop when nothing else is to do
/////////////////////////////////////////////////////////////////////////////
void Tick(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is periodically called by MIOS. The frequency has to be
// initialized with MIOS_Timer_Set
/////////////////////////////////////////////////////////////////////////////
void Timer(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when the display content should be 
// initialized. Thats the case during startup and after a temporary message
// has been printed on the screen
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Init(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called in the mainloop when no temporary message is shown
//  on screen. Print the realtime messages here
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Tick(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called by MIOS when a complete MIDI event has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has been received
// which has been specified in the MIOS_MPROC_EVENT_TABLE
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has not been completly
// received within 2 seconds
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyTimeout(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI byte has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedByte(unsigned char byte) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS before the shift register are loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Prepare(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after the shift register have been loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Finish(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam
{
}

I made two release packages, one I compliled with 2.8.0, one with 2.8.5. so all

that is needed to analyze the problem is included. The problem has nothing to

do with bitshift-issues.

It's interesting that when addressing a const array, the linker does not complain,

but when addressing a variable 64-char-array, it throws the error. I removed

everything that is not really necessary to cook down the problem. there is

a 64 byte var array, and a 64 byte const array, all other stuff happens in

function "init". I added a file named SHELL.txt to the failing release package

which contains the shell output of the make-command.

@stryd_one:

I just commented the bug report with the files attached to this post. It

now appears as follow-up to your bug-report on the sourceforge-site.

I hope this will help.-

test_sdcc.2.8.0.tar.bz2.zip

test_sdcc.2.8.5.tar.bz2.zip

test_sdcc.2.8.0.tar.bz2.zip

test_sdcc.2.8.5.tar.bz2.zip

Link to comment
Share on other sites

Well no, not really a makefile issue at all...

it was an issue where SDCC was broken... twice actually.

The first break was that the --asm parametr was completely ignored. That was an accident.

That was done attemting to "fix" sdcc, so that it would accept bad paths (which were illegal in windows, maybe *nix too), which, even if you ignore the first, accidental 'break', additionally broke sdcc for perfectly good makefiles, like ours.

No need to alter our makefile here, as Raphael has wisely returned sdcc to it's old behaviour.

It kinda seems like an SDCC bug...

Been here, done this before ;)

It's important to realise that SDCC is heavily developed, so bugs can appear and be fixed very regularly. If you're using a nightly build, you have to watch out for new bugs, and if you're using a release build, then you should use the latest one available. That's why I told you a few times before this thread to update to 2.8 ;)

Edit: gotta wait till tomorrow for the new windoze snapshot. How's it work on *nix?

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...
×
×
  • Create New...