Forums

Help overcome IAR linker error restoring DCO calibration values in INFOA Flash

Started by colin_garlick March 25, 2007
Having accidentally erased the calibration values from INFOA Flash.
It sounds simple enough, that for simple convenience I'd ideally
like to be able to restore the values I was careful enough to write
down (for the ONLY board I'll be using), as a conditional build
option.

However, there appears to be a linker segment clash, I can't figure
out how to avoid. It works links with predictable results, if I move
the array down 8-bytes. So I guess the problem is due to the
competeing CALIB definition in the standard IAR header files. Can
anybody suggest how I coud trick the compiler into generating the
desired build-image ?

#pragma constseg=INFOA
const unsigned int calib[] @0x10F8 {
0x8ED8, // CALDCO_16MHZ & CALBC1_16MHZ
0x8E68, // CALDCO_12MHZ & CALBC1_12MHZ
0x8D50, // CALDCO_8MHZ & CALBC1_8MHZ
0x869C // CALDCO_1MHZ & CALBC1_1MHZ
};
#pragma constsegault

Linker error[e24]: Segment DATA16_AC (seg part no 21, symbol "calib"
in module "ta_uart", address [10f8-10ff]) overlaps segment
DATA16_AN (seg part no 19, symbol "CALDCO_16MHZ" in
module "ta_uart", address [10f8-10f8])

Many thanks,

Colin,

Beginning Microcontrollers with the MSP430

colin_garlick wrote:
> Having accidentally erased the calibration values from INFOA Flash.
> It sounds simple enough, that for simple convenience I'd ideally
> like to be able to restore the values I was careful enough to write
> down (for the ONLY board I'll be using), as a conditional build
> option.
>
> However, there appears to be a linker segment clash, I can't figure
> out how to avoid. It works links with predictable results, if I move
> the array down 8-bytes. So I guess the problem is due to the
> competeing CALIB definition in the standard IAR header files. Can
> anybody suggest how I coud trick the compiler into generating the
> desired build-image ?
>
> #pragma constseg=INFOA
> const unsigned int calib[] @0x10F8 > {
> 0x8ED8, // CALDCO_16MHZ & CALBC1_16MHZ
> 0x8E68, // CALDCO_12MHZ & CALBC1_12MHZ
> 0x8D50, // CALDCO_8MHZ & CALBC1_8MHZ
> 0x869C // CALDCO_1MHZ & CALBC1_1MHZ
> };
> #pragma constsegault
>
> Linker error[e24]: Segment DATA16_AC (seg part no 21, symbol "calib"
> in module "ta_uart", address [10f8-10ff]) overlaps segment
> DATA16_AN (seg part no 19, symbol "CALDCO_16MHZ" in
> module "ta_uart", address [10f8-10f8])

Hi Colin!

The linker will treat your array and the definition in the header file
as two distinct variables that are placed at the same location, hence
the linker error.

I would try to use only one definition throughout the application, since
you need the initial value you can't use the CALDCO_16MHZ symbol.

-- Anders Lindgren, IAR Systems

Ps. You don't need both #pragma constseg and the @0x10f8 notation. In
fact, the "constseg" pragma is provided for backward compatibility only,
in modern a IAR compiler you can write '@ 0x10f8' or '@ "INFOA"'.

--
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.
Most of the current F20xx chips have a silicon bug (called FLASH16).
If you try to erase/write to locked flash (i.e., INFOA at 0x10C0-
0x10FF), it will erase/write part of the main-Flash at 0xFC40-0xFC7F
instead of the INFOA at 0x10C0-0x10FF. Thus make sure that you enable
the Allow erase/write access to locked flash memory (under
Project => Options => FET Debugger).

If your religion allows you to use assembly code, you can use the
following code.

RSEG INFOA
ORG 0x38
DC16 0x8ED8
DC16 0x8E68
DC16 0x8D50
DC16 0x869C
END

I know. This is not ANSII stuff. But it is simple and it works.

--- In m..., Anders Lindgren
wrote:
>
> colin_garlick wrote:
> >
> >
> > Having accidentally erased the calibration values from INFOA
Flash.
> > It sounds simple enough, that for simple convenience I'd ideally
> > like to be able to restore the values I was careful enough to
write
> > down (for the ONLY board I'll be using), as a conditional build
> > option.
> >
> > However, there appears to be a linker segment clash, I can't
figure
> > out how to avoid. It works links with predictable results, if I
move
> > the array down 8-bytes. So I guess the problem is due to the
> > competeing CALIB definition in the standard IAR header files. Can
> > anybody suggest how I coud trick the compiler into generating the
> > desired build-image ?
> >
> > #pragma constseg=INFOA
> > const unsigned int calib[] @0x10F8 > > {
> > 0x8ED8, // CALDCO_16MHZ & CALBC1_16MHZ
> > 0x8E68, // CALDCO_12MHZ & CALBC1_12MHZ
> > 0x8D50, // CALDCO_8MHZ & CALBC1_8MHZ
> > 0x869C // CALDCO_1MHZ & CALBC1_1MHZ
> > };
> > #pragma constsegault
> >
> > Linker error[e24]: Segment DATA16_AC (seg part no 21,
symbol "calib"
> > in module "ta_uart", address [10f8-10ff]) overlaps segment
> > DATA16_AN (seg part no 19, symbol "CALDCO_16MHZ" in
> > module "ta_uart", address [10f8-10f8])
>
> Hi Colin!
>
> The linker will treat your array and the definition in the header
file
> as two distinct variables that are placed at the same location,
hence
> the linker error.
>
> I would try to use only one definition throughout the application,
since
> you need the initial value you can't use the CALDCO_16MHZ symbol.
>
> -- Anders Lindgren, IAR Systems
>
> Ps. You don't need both #pragma constseg and the @0x10f8 notation.
In
> fact, the "constseg" pragma is provided for backward compatibility
only,
> in modern a IAR compiler you can write '@ 0x10f8' or '@ "INFOA"'.
>
> --
> Disclaimer: Opinions expressed in this posting are strictly my own
and
> not necessarily those of my employer.
>