DSPRelated.com
Forums

Re: CodeWarrior 4 Upgrading

Started by MW Ron September 30, 2002
wrote:

> There seems to be some confusion here. We got the eval package through our
> distributor, and they told us that this was a good deal because we get (and
> I quote) "...a years support & free upgrades for a year".
>
> Now a Metrowerks representative is contradicting that.

I don't know your circumstances. There may be extenuating circumstances.
This needs to be handled on a case by case basis.

> Of course, I don't know who is at fault here, but I do not like what I am
> hearing.
>
> It now looks like we are obliged to pay the full price just to be able to
> create production intent code. Whatever else, this is not a good public
> relations exercise by Metrowerks/Motorola.

I know that Metrowerks has historically done the right thing for our
customers and has always been fair. I just can't comment, without knowing
all of the details and your case/circumstance may be unique.

If you can send me more information, I'd be happy to work with you to find
a fair and equitable solution.

Ron

--

Ron Liechty,
Ombudsman for Metrowerks Corporation



The work-around for this bug is described below:

1) For every build target in every product, select "Write constant data to
.rodata section" in the "{Target} Settings > Code Generation > M56800 Processor"
settings.

2) For every build target in every product, edit the "linker.cmd" file so that
every place that has a ".data" section will also have the corresponding
".rodata" section.
Example:
#*******************************************************************************
.ApplicationConstData :
{
const.c (.rodata) # <==== ADDED for bug fix
const.c (.data)
appconstP.c (.rodata) # <==== ADDED for bug fix
appconstP.c (.data)

} > .pConstFlash
#*******************************************************************************

Regards,

Art Johnson
Senior Systems Analyst
PMC Prime Mover Controls Inc.
3600 Gilmore Way
Burnaby, B.C., Canada
V5G 4R8
Phone: 604 433-4644
FAX: 604 433-5570
Email:
http://www.pmc-controls.com

-----Original Message-----
From: Roberts, Drew [mailto:]
Sent: Tuesday, October 01, 2002 6:49 AM
To: Art Johnson
Subject: RE: [motoroladsp] Re: CodeWarrior 4 Upgrading Art

I agree with you about upgrading and its cost (or costs by not upgrading),
but version 5, although a step up is causing other problems. The "new"
feature you discuss, regarding const data, is interesting. We are using
805's and 807's running on internal memory and noticed the same thing. What
is the workaround? It is not causing us a problem at the moment, but the
805 project is new and I'm sure that having the const data taking up
internal ram will bite us in the end.

Thanks
Drew Roberts
Software Project Engineer
Nordson Corp.

-----Original Message-----
From: Art Johnson [mailto:]
Sent: Tuesday, October 01, 2002 9:22 AM
To: wdhaan;
Cc: Kevin Ackerley (E-mail); Ed Baillie (E-mail); Greg Clark
Subject: RE: [motoroladsp] Re: CodeWarrior 4 Upgrading While I agree that CodeWarrior 5 produces poorer code than 4.0.2 in this
example, when changing data in any shared resource (like a GPIO port or
globally shared memory), one should never assume that the compiler will
generate code that performs the operation atomically (ie as one indivisible
operation). This is particularly important when you are using a RealTime
Operating System (RTOS) (we use the DSPOS RTOS in all our applications).

The generally accepted way of coding to prevent this sort of problem with a
shared resource is shown by the following example from one of our programs:

#define Sci0_Tx_Connect( ) \
{ \
register WORD interrupt; \
interrupt = Disable_Int(); \
g_p_dspregs->pwma.pmout &= ~SCI0_TX_ENABLE_BIT; \
Enable_Int(interrupt); \
}

#define Sci0_Tx_Disconnect( ) \
{ \
register WORD interrupt; \
interrupt = Disable_Int(); \
g_p_dspregs->pwma.pmout |= SCI0_TX_ENABLE_BIT; \
Enable_Int(interrupt); \
}

The functions Disable_Int() and Enable_Int() are provided by the DSPOS
library. In this example, we are using one output on PWMA to control the
Transmit Enable pin of an RS-485 transceiver for the SCI0 serial port.

In any case, as I mentioned before, the very serious bugs that exist in
CodeWarrior 4.x and earlier mean that you are taking a big risk of having
your program crash in an unpredictable manner. We stumbled upon the "local
variable bug inside a function" almost by accident. It was discovered when
we were tracking down a completely different CodeWarrior bug. Our software
could easily have been sent out with this "time bomb" embedded in it.

For the above reasons, anyone with an older version of CodeWarrior should
upgrade to version 5.0 with the 5.0.2 patch.

I agree with you, that in my 26+ years experience I have never seen a
compiler as buggy as CodeWarrior. While no product this complex is ever
"perfect", the bugs we keep finding go way beyond what is acceptable. The
Metrowerks compiler writers apparently don't even understand basic ANSI C
concepts like the meaning of the keywords "volatile" or "const". This is
not exotic, high-level stuff, it's basically kindergarten-level C
programming. You might expect these sorts of problems in Version 1.0 of
some product, but they should not exist in a "mature" product like Version
5.0 (which we recently had to buy to get some other bugs fixed). They even
deliberately introduced a bug into Version 5.0 (Compiler/linker puts const
data into X RAM) that contravenes the ANSI C standard meaning of "const".
They refused to fix this bug (they think it's actually a "new, improved
feature"), but gave us a work-around that cost me weeks of work to change
every build target of every project we have here.

I'm sure we'll never know how much all this extra time and effort has cost
our company (both in direct development costs and lost sales due to delayed
product launches), but I'm sure it's well over $100,000. Forcing us to pay
for an upgrade rather than issuing patches to version 4.x is just adding
insult to injury. Maybe that's the price you have to pay to design in
leading-edge devices ... Regards,

Art Johnson
Senior Systems Analyst
PMC Prime Mover Controls Inc.
3600 Gilmore Way
Burnaby, B.C., Canada
V5G 4R8
Phone: 604 433-4644
FAX: 604 433-5570
Email:
http://www.pmc-controls.com
-----Original Message-----
From: wdhaan [mailto:]
Sent: Tuesday, October 01, 2002 12:55 AM
To:
Subject: [motoroladsp] Re: CodeWarrior 4 Upgrading Hi,

Upgrade from Codewarrior 4 to 5?
I did it, but I returned to version 4.0.2, due to the following new
bug in version 5:

*********** C-listing

#define GPIOD_BASE 0x13E0 // Table 3-36 for DSP56F807
#define GPIO_D_DR *(WORD *) (0x1+GPIOD_BASE)
GPIO_D_DR |= 0x02; // set GPIO-D1 to 1

*********** Assembly listing Codewarrior version 4.0.2

orc #2,X:13e1

*********** Assembly listing Codewarrior version 5

movei #5089,R0
nop
move X:(R0),X0
orc #2,X0 ; <=== What happens
if here an interrupt occurs?
move X0,X:(R0)

The problem of this bug is not the additional memory nor the
additional execution time,
but the problem is if during the main program an interrupt function
occurs, which sets f.e. GPIO-D7.
In this case the main program resets the GPIO-D7 value, just set by
the interrupt function.
In this way you get software bugs, which are difficult to reproduce
and difficult to find!

This is only one bug of my Codewarrior bug collection (most of them
have not been solved in version 5). I have sent them to Metrowerks,
but only very few have been answered (some after half a year). I have
14 years experience in developing embedded software, but I have never
used a compiler with so many bugs as Codewarrior. We paid the full
price for Codewarrior version 4 and my supplier understood that I was
not willing to pay a cent for version 5, so I got the upgrade to
version 5 for free. However now I use version 4.0.2 for compilation
and version 5 for debugging

Kind regards, Wim de Haan Exendis B.V.
W.J. de Haan
P.O.box 56, 6710 BB Ede
Keesomstraat 4, 6716 AB Ede
The Netherlands.
Tel: +31- 318 - 676305

_____________________________________
Note: If you do a simple "reply" with your email client, only the author of
this message will receive your answer. You need to do a "reply all" if you
want your answer to be distributed to the entire group.

_____________________________________
About this discussion group:

To Join:

To Post:

To Leave:

Archives: http://www.yahoogroups.com/group/motoroladsp

More Groups: http://www.dsprelated.com/groups.php3 ">http://docs.yahoo.com/info/terms/
_____________________________________
Note: If you do a simple "reply" with your email client, only the author of
this message will receive your answer. You need to do a "reply all" if you
want your answer to be distributed to the entire group.

_____________________________________
About this discussion group:

To Join:

To Post:

To Leave:

Archives: http://www.yahoogroups.com/group/motoroladsp

More Groups: http://www.dsprelated.com/groups.php3 ">http://docs.yahoo.com/info/terms/


The "local variable bug inside a function" is described below, taken from my bug
report to Metrowerks:

===============================================
Bug #1:

Here's the source code in one part of the program that generates incorrect
assembly code. The "interrupt" value is a local variable declared inside the
function:
interrupt = Disable_Int();
Ext_Flash_Write_Word( SST39LF2_4_800A_SDP_ADDR1, SST39LF2_4_800A_SDP_DATA1 );
Ext_Flash_Write_Word( SST39LF2_4_800A_SDP_ADDR2, SST39LF2_4_800A_SDP_DATA2 );
Ext_Flash_Write_Word( SST39LF2_4_800A_SDP_ADDR3, SST39LF2_4_800A_CMD3_PROGRAM
);
Ext_Flash_Write_Word( perw_chip_addr, test2 );
Enable_Int(interrupt);

Ext_Flash_Write_Word() is a macro. The assembly code generated by CodeWarrior
is shown below.

Here's the "interrupt = Disable_Int();" code:
P:000004DF: E9C80102 jsr 0x000102
P:000004E1: 91F9 move Y0,X:(SP-0x0007)
Disable_Int() is at address 0x000102 and the "interrupt" local variable has been
assigned to X:(SP-0x0007).

.
. (Code from the macros not shown)
.

Now here's the "Enable_Int(interrupt);" code:
P:0000052F: 87C70FFF movei #4095,B1
P:00000531: F35460B3 move X:0x60b3,Y1
P:00000533: F15460B2 move X:0x60b2,Y0
P:00000535: 7603 and B1,Y0
P:00000536: 8801 move Y0,R0
P:00000537: B03A moves X:0x003a,X0
P:00000538: D0402000 move X0,X:(R0+0x2000)
P:0000053A: 8103 move Y1,Y0
P:0000053B: E9C80106 jsr 0x000106
Enable_Int() is at address 0x000106. Note that the "interrupt" value was loaded
from X:0x60b3, not from X:(SP-0x0007) where it was saved!!!

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

Regards,

Art Johnson
Senior Systems Analyst
PMC Prime Mover Controls Inc.
3600 Gilmore Way
Burnaby, B.C., Canada
V5G 4R8
Phone: 604 433-4644
FAX: 604 433-5570
Email:
http://www.pmc-controls.com
-----Original Message-----
From: Wim de Haan [mailto:]
Sent: Tuesday, October 01, 2002 7:26 AM
To: Art Johnson
Subject: RE: [motoroladsp] Re: CodeWarrior 4 Upgrading Dear Art,

Thank you for your mail. Of course I understand your solution/work around,
with disabling interrupts.
However this ought not to be necessary if a processor has an atomic
instruction for changing one bit in a port (I admit this is wishful thinking
when using Codewarrior).

You mentioned a "local variable bug inside a function". Which bug do you
exactly mean. Do you mean the bug/undocumented feature, that for a function
a kind of stack frame is built at addresses 0x30..0x3F (in assembly called
mr0..mr15). This stack frame is saved on stack at next function entry.
Or do you mean the bug in the listing below?

Kind regards, Wim de Haan Exendis B.V.
W.J. de Haan
P.O.box 56, 6710 BB Ede
Keesomstraat 4, 6716 AB Ede
The Netherlands.
Tel: +31- 318 - 676305
/*
The following interrupt functions are not well compiled, as only the
registers used
by the interrupt function itself, are stored on stack.
However the registers used by library functions called from interrupt
functions
are not saved on stack.
This causes unpredictable strange effects for the main function were those
registers are used.
*/

void Bug1_interrupt_function(void);
void Bug2_interrupt_function(void);

unsigned U1, U2;
#pragma interrupt
void Bug1_interrupt_function(void)
{// At function entry the LA and LC registers are not saved

U1=U2%10;// This uses the ARTREMU16Z asm function,
// which uses "do" instruction, so LA and LC are destroyed
//Even if LA and LC were saved, HWS is not saved, so interrupt on interrupt
can cause
//hardware stack overflow
}

unsigned long L1, L2;
#pragma interrupt
void Bug2_interrupt_function(void) //EVEN MORE WORSE
{// At function entry the Y0, Y1, LA, LC registers are not saved

L1=L2/31;// This uses the ARTDIVU32UZ asm function,
// which uses Y0 and Y1 registers and "do" instruction, so Y0, Y1,
LA, LC are destroyed
//Even if Y0, Y1, LA, LC were saved, HWS is not saved, so interrupt on
interrupt can cause
//hardware stack overflow
} GLOBAL FBug1_interrupt_function
ORG P:
FBug1_interrupt_function:
lea (SP)+
move N,X:(SP)+
move Y0,X:(SP)+
move Y1,X:(SP)
movei #10,Y1
move X:FU2,Y0
jsr ARTREMU16Z
move Y0,X:FU1
pop Y1
pop Y0
pop N
rti GLOBAL FBug2_interrupt_function
ORG P:
FBug2_interrupt_function:
lea (SP)+
move N,X:(SP)+
move A0,X:(SP)+
move A1,X:(SP)+
move A2,X:(SP)+
move B0,X:(SP)
move B1,X:(SP)+
move B2,X:(SP)+
movei #0,B
movei #31,B0
push B0
push B1
move X:FL2+1,A
move X:FL2,A0
jsr ARTDIVU32UZ
pop
pop
move A1,X:FL1+1
move A0,X:FL1
pop B2
pop B1
pop B0
pop A2
pop A1
pop A0
pop N
rti

; From library file rtrem16.asm

ARTREMU16Z:

tstw y1
bge nohighbit2
cmp y1,y0
blo Done4
sub y1,y0
bra Done4
nohighbit2:
clr A ; clear A
move y0,a0 ; save dividend in a0
clr B
move y1,b1 ; Save divisor in B

do #16,endloop2
div y1,A ; form quotient in a0 remainder in a1
endloop2:
tst A
bge around4
add B,A ; fix remainder
around4:
move a1,y0 ; save rem in y0
Done4:
rts ; From library file artdivu32uz.asm

ARTDIVU32UZ:
clr B ; clear register for resulting quotient
; bfset #$0100,omr ; make sure the CC bit is set

move a0,y0
move a1,y1 ; move A to y1:y0
move x:(sp-2),a
move x:(sp-3),a0 ; load divisor into A
bfclr #1,sr ; clear the carry bit

move #32,LC ; I don't know why I can't use immediate #32
do LC,endloop
rol y0
rol y1
bcc notthisbit
asl B
bfset #1,b0
bra around
notthisbit:
asl B
around:
sub A,B ; If carry is clear, sub was
OK.
bcc nottoobig ; otherwise, restore B
add A,B
nottoobig:
bfchg #1,sr ; reverse cc bit
nop
nop
endloop:
rol y0
rol y1
move y1,A ; move result to A
move y0,a0

IF REV_B
; bfclr #$0100,omr ; set CC setting to 36 bits
ENDIF

rts

-----Original Message-----
From: Art Johnson [mailto:]
Sent: dinsdag 1 oktober 2002 15:22
To: wdhaan;
Cc: Kevin Ackerley (E-mail); Ed Baillie (E-mail); Greg Clark
Subject: RE: [motoroladsp] Re: CodeWarrior 4 Upgrading While I agree that CodeWarrior 5 produces poorer code than 4.0.2 in this
example, when changing data in any shared resource (like a GPIO port or
globally shared memory), one should never assume that the compiler will
generate code that performs the operation atomically (ie as one indivisible
operation). This is particularly important when you are using a RealTime
Operating System (RTOS) (we use the DSPOS RTOS in all our applications).

The generally accepted way of coding to prevent this sort of problem with a
shared resource is shown by the following example from one of our programs:

#define Sci0_Tx_Connect( ) \
{ \
register WORD interrupt; \
interrupt = Disable_Int(); \
g_p_dspregs->pwma.pmout &= ~SCI0_TX_ENABLE_BIT; \
Enable_Int(interrupt); \
}

#define Sci0_Tx_Disconnect( ) \
{ \
register WORD interrupt; \
interrupt = Disable_Int(); \
g_p_dspregs->pwma.pmout |= SCI0_TX_ENABLE_BIT; \
Enable_Int(interrupt); \
}

The functions Disable_Int() and Enable_Int() are provided by the DSPOS
library. In this example, we are using one output on PWMA to control the
Transmit Enable pin of an RS-485 transceiver for the SCI0 serial port.

In any case, as I mentioned before, the very serious bugs that exist in
CodeWarrior 4.x and earlier mean that you are taking a big risk of having
your program crash in an unpredictable manner. We stumbled upon the "local
variable bug inside a function" almost by accident. It was discovered when
we were tracking down a completely different CodeWarrior bug. Our software
could easily have been sent out with this "time bomb" embedded in it.

For the above reasons, anyone with an older version of CodeWarrior should
upgrade to version 5.0 with the 5.0.2 patch.

I agree with you, that in my 26+ years experience I have never seen a
compiler as buggy as CodeWarrior. While no product this complex is ever
"perfect", the bugs we keep finding go way beyond what is acceptable. The
Metrowerks compiler writers apparently don't even understand basic ANSI C
concepts like the meaning of the keywords "volatile" or "const". This is
not exotic, high-level stuff, it's basically kindergarten-level C
programming. You might expect these sorts of problems in Version 1.0 of
some product, but they should not exist in a "mature" product like Version
5.0 (which we recently had to buy to get some other bugs fixed). They even
deliberately introduced a bug into Version 5.0 (Compiler/linker puts const
data into X RAM) that contravenes the ANSI C standard meaning of "const".
They refused to fix this bug (they think it's actually a "new, improved
feature"), but gave us a work-around that cost me weeks of work to change
every build target of every project we have here.

I'm sure we'll never know how much all this extra time and effort has cost
our company (both in direct development costs and lost sales due to delayed
product launches), but I'm sure it's well over $100,000. Forcing us to pay
for an upgrade rather than issuing patches to version 4.x is just adding
insult to injury. Maybe that's the price you have to pay to design in
leading-edge devices ... Regards,

Art Johnson
Senior Systems Analyst
PMC Prime Mover Controls Inc.
3600 Gilmore Way
Burnaby, B.C., Canada
V5G 4R8
Phone: 604 433-4644
FAX: 604 433-5570
Email:
http://www.pmc-controls.com
-----Original Message-----
From: wdhaan [mailto:]
Sent: Tuesday, October 01, 2002 12:55 AM
To:
Subject: [motoroladsp] Re: CodeWarrior 4 Upgrading Hi,

Upgrade from Codewarrior 4 to 5?
I did it, but I returned to version 4.0.2, due to the following new
bug in version 5:

*********** C-listing

#define GPIOD_BASE 0x13E0 // Table 3-36 for DSP56F807
#define GPIO_D_DR *(WORD *) (0x1+GPIOD_BASE)
GPIO_D_DR |= 0x02; // set GPIO-D1 to 1

*********** Assembly listing Codewarrior version 4.0.2

orc #2,X:13e1

*********** Assembly listing Codewarrior version 5

movei #5089,R0
nop
move X:(R0),X0
orc #2,X0 ; <=== What happens
if here an interrupt occurs?
move X0,X:(R0)

The problem of this bug is not the additional memory nor the
additional execution time,
but the problem is if during the main program an interrupt function
occurs, which sets f.e. GPIO-D7.
In this case the main program resets the GPIO-D7 value, just set by
the interrupt function.
In this way you get software bugs, which are difficult to reproduce
and difficult to find!

This is only one bug of my Codewarrior bug collection (most of them
have not been solved in version 5). I have sent them to Metrowerks,
but only very few have been answered (some after half a year). I have
14 years experience in developing embedded software, but I have never
used a compiler with so many bugs as Codewarrior. We paid the full
price for Codewarrior version 4 and my supplier understood that I was
not willing to pay a cent for version 5, so I got the upgrade to
version 5 for free. However now I use version 4.0.2 for compilation
and version 5 for debugging

Kind regards, Wim de Haan Exendis B.V.
W.J. de Haan
P.O.box 56, 6710 BB Ede
Keesomstraat 4, 6716 AB Ede
The Netherlands.
Tel: +31- 318 - 676305