MAJOR BUG IN ALL COMPILERS FOR P18

Discuss about beta versions of mikroPascal compiler.
Post Reply
Author
Message
yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

MAJOR BUG IN ALL COMPILERS FOR P18

#1 Post by yo2lio » 29 May 2008 22:14

Hi,

After few months of searching, finally I got the BUG !!! 8)

Was discovered today 29 May 2008 at 23.25 local time.

It's talk about inc(x) instruction where x is word or integer , at P18 MCU , when x is located (split ed) in 2 banks of memory !!!!

I can't take into account where compiler put my variables in memory ...

Chance for happened this is very small , but this problem give unpredictable result ... specially in big programs with a lot of variables.

Example :

Code: Select all

program test;

var my_important_data : byte; absolute $100;
    data_wu : word; absolute $1FF;

begin
  my_important_data := 0;
  data_wu := 0;
  while true do
    begin
      inc(data_wu);
    end;
end.
data_wu is split ed between bank 1 and 2.

Take a look in asm :

Code: Select all

;TEST.ppas,11 :: 			inc(data_wu);
$0012	$0101	    			MOVLB	1
$0014	$4BFF	    			INFSNZ	_data_wu, 1, 1
$0016	$0102	    			MOVLB	2
$0018	$2B00	    			INCF	_data_wu+1, 1, 1
Conclusion : running this code , my_important_data variables is incremented too. :oops: :oops: :oops:

Work around :

Code: Select all

procedure inc_w(var data_w : word);
begin
  FSR2Ptr := @data_w;
  asm
    INFSNZ POSTINC2,f
    INCF INDF2,f
  end;
end;
Or depend of MCU , force global byte variables at first locations of each bank :

Code: Select all

var
    bug_a : byte; absolute $060;
    bug_b : byte; absolute $100;
    bug_c : byte; absolute $200;
    bug_d : byte; absolute $300;
    bug_e : byte; absolute $400;
    bug_f : byte; absolute $500;
    etc ...
and somewhere in code , at the beginning for example , put this :

Code: Select all

  bug_a := bug_a;
  bug_b := bug_b;
  bug_c := bug_c;
  bug_d := bug_d;
  bug_e := bug_e;
  bug_e := bug_e;
Tested in MikroPascal, MikroBasic, MikroC all versions !
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

bruno
Posts: 767
Joined: 10 Sep 2005 02:10
Location: Lyon, France
Contact:

#2 Post by bruno » 30 May 2008 08:47

Hi Florin,

Do you mean :
the compiler assigns variables on a memory bank boundary by itself ?
or
the compiler does not check boundary violations when memory location is assigned by user ?
Bruno
Bored with 7-segment ? Try the [url=http://www.micro-examples.com/public/microex-navig/doc/079-touchclock.html]TouchClock[/url]

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#3 Post by yo2lio » 30 May 2008 09:06

Hi,

It's talk about when compiler put 16 bit variables in boundary bank, by itself, .... and increment instructions ( or addition) is used for this variable ...

Take to me months to isolate this problem.
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#4 Post by zristic » 30 May 2008 10:04

Hi Florin,

We had analyzed the problematic code you provided. In case of absolute we cannot do much, it is intentionally put that a large variable is split over two banks. All we can and will do in this case is to issue a warning in the future.

For the regular code without absolute, we have a mechanism which prevents this from happening. I tried several variations of codes and in each case the linker managed to move longer variables away from page boundaries.

Can you provide us the code without absolute which demonstrates the problem?

Thanks.

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#5 Post by yo2lio » 30 May 2008 11:17

Hi,

You are right, at small programs everything it's ok , but ... MCU 18F452, MP 8.1 :

Code: Select all

program test;

var array_1 : array[234] of byte;
    array_2 : array[128] of word;
 
begin 
  inc(array_1[80]);
  inc(array_2[0]);
end.
ASM :

Code: Select all

$0000	$EF04	F000			GOTO	_main
$0008	$	_main:
;TEST.ppas,6 :: 			begin
;TEST.ppas,15 :: 			inc(array_1[80]);
$0008	$2A65	    			INCF	_array_1+80, 1, 0
;TEST.ppas,16 :: 			inc(array_2[0]);
$000A	$0100	    			MOVLB	0
$000C	$4BFF	    			INFSNZ	_array_2+0, 1, 1
$000E	$0101	    			MOVLB	1
$0010	$2B00	    			INCF	_array_2+1, 1, 1
$0012	$	TEST_L_0:
;TEST.ppas,17 :: 			end.
$0012	$D7FF	    			BRA	$
Maybe the right solutions can be : instead of :

Code: Select all

INFSNZ	_array_2+0, 1, 1
INCF	_array_2+1, 1, 1
change to :

Code: Select all

INCF _array_2+0, 1, 1
CLRF WREG,0
ADDWFC _array_2+1, 1, 1
Can tell you, at big programs , which use a lot of RAM (in my case more than 3000 bytes) , sometime this problems appear, program can work ok at first impression, up to one point , and then after few day's or weeks system (MCU) crash , apparently without any reason.
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#6 Post by yo2lio » 30 May 2008 12:05

I don't want to bother you too much .... Sorry ...

Another example :

Code: Select all

program test;

type TNtp = Record
     Rfc   : dWord;
     Unix  : dWord;
     Year  : word;
     Month : byte;
     Day   : word;
     Hour  : byte;
     Min   : word;
     Sec   : word;
     Str   : string[36];
end;

var TTime : array [5] of TNtp;

begin
  inc(TTime[4].Min);
end.
Asm :

Code: Select all

$0000	$EF04	F000			GOTO	_main
$0008	$	_main:
;TEST.ppas,17 :: 			begin
;TEST.ppas,18 :: 			inc(TTime[4].Min);
$0008	$0100	    			MOVLB	0
$000A	$4BFF	    			INFSNZ	_ttime+234, 1, 1
$000C	$0101	    			MOVLB	1
$000E	$2B00	    			INCF	_ttime+235, 1, 1
$0010	$	TEST_L_0:
;TEST.ppas,19 :: 			end.
$0010	$D7FF	    			BRA	$
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#7 Post by zristic » 30 May 2008 12:29

yo2lio wrote:I don't want to bother you too much .... Sorry ...
You are not, come on...


Ok, the case is detected, it is problematic only with arrays. We will fix this as soon as possible.

Thanks for discovering this ugly bug.

Beer?

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#8 Post by yo2lio » 30 May 2008 13:15

zristic wrote:Beer?
:wink: Yes, maybe will make you a visit soon !

Question : how can you handle variables from record type ?

It's very possible if have a array of record type , one of variables from this array (word) to be split ed between two banks !

In this case, in my opinion, compiler can't handle situations.

What do you think about changing the :

Code: Select all

INFSNZ   variables+0,F
INCF   variables+1,F
with :

Code: Select all

INCF variables+0,F
CLRF WREG,0
ADDWFC variables+1,F
If the variables is split ed between two banks this can resolve situation.

:?:
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#9 Post by zristic » 30 May 2008 13:26

yo2lio wrote: :wink: Yes, maybe will make you a visit soon !
Great, looking forward to see you.
Question : how can you handle variables from record type ?

It's very possible if have a array of record type , one of variables from this array (word) to be split ed between two banks !
We will fix it in the way that the possible address for an array element is such that the array element does not get broken over two banks, regardless of the element size.
In this case, in my opinion, compiler can't handle situations.
It will be able to handle it. At the moment no.
What do you think about changing the :

Code: Select all

INFSNZ   variables+0,F
INCF   variables+1,F
with :

Code: Select all

INCF variables+0,F
CLRF WREG,0
ADDWFC variables+1,F
Nice suggestion, but too expensive in terms of code size.

We have already found a nice way to fix the problem, though it has to be tested very well before we release it.

Post Reply

Return to “mikroPascal Beta testing”