11 putting constants in banks, 12 write-protecting flash in the 653x, Putting constants in banks – Maxim Integrated 71M6534 Energy Meter IC Family Software User Manual
Page 40: Write-protecting flash in the 653x

71M653X Software User’s Guide
In practice, the Keil linker tries to save space in the page table. So, it only puts global functions into the page table if
they are in a bank area and are called from outside the bank. Often, function pointers are used for callback routines.
In these cases, the linker often does not detect the true caller and so cannot detect the cross-bank function call. Then,
it places a banked address into the code that sets the function pointer. If this is executed from another bank, the code
jumps to code in the current, wrong bank!
Using overlay commands informs the linker of the actual caller, so it can detect cross-bank calls.
To increase reliability, the demo code that sets a function pointer also checks to make sure that the pointer is in
common memory rather than a bank. The code looks like this:
if (((uint16_t)fn_ptr) > 0x7FFF) // only accept functions in common
{
main_software_error (); // report a software error at a central breakpoint.
return NULL; // indicate a failure to the caller
}
4.9.11
Putting Constants in Banks
Space in the common code area can be precious. It often helps to put large tables in a different code bank. The
TERIDIAN Demo Code, places the help text, CE code and the CE’s data initialization table into banked flash.
In order for this to work, every reference to the data must be from the same bank or from common.
In the demo code, the largest set of constant tables is the help text. The help text (CLI\Help.c) is in the same bank as
the printing routines, which copy the text into RAM for use by the serial interrupts (see CLI\io.c). Since the help text is
in the same bank as the accessing routines, no other special coding is needed.
In the demo code, the CE code is referenced from the Meter\ce.c. ce.c could not be placed in the last bank with the
tables because it also has a very fast interrupt, ce_busy_isr(), so ce.c was placed in common. Also, the CE code is in
the last bank, so the code in ce.c had to explicitly switch it in to read it.
Designers must be careful that any code in common is smaller than the data table! Some systems may need a library
routine in common to copy part of the banked data to RAM for use by banked code.
Next, the data should be located in the desired bank, using compiler and linker’s BANK commands. (See the compiler
and linker command figures, 0-2, 0-3)
The code using the banked data should include Util\bank.h, which defines switchbank() to access banked data.In
the code that accesses the data, the bank must be switched in. For example, when the demo code copies the starting
data for the CE (ce_init() in Meter\ce.c), it executes the following code:
switchbank (BANK_CE);
memcpy_cer (
(int32x_t *)CE_DATA_BASE,
(int32r_t *)&CeData[0],
(uint8_t)(0xff & NumCeData)
);
switchbank ()
sets the bank register without side effects for other bank switching. It is defined in Util\bank.h.
BANK_CE
is the bank number containing the CE initialization table (in Main_6531\options.h or Main_6534\Options.h).
memcpy_cer ()
copies 32-bit words from code to CE memory. CE_DATA_BASE is the start of CE memory, 0x0000
in XDATA in 71M653x ICs. CeData[] is the array of 32-bit integers containing the CE’s default data. NumCeData is
the count of data words in the table, a constant value that precedes the CE default data table.
4.9.12
Write-Protecting Flash in the 653X
Besides safety interlocks in software that prevent accidental write operations to flash, the 71M653x ICs also have a
write-protection mechanism implemented in hardware. Some systems might permit code or customization tables to be
downloaded to flash, and designers might wish to assure that this process cannot corrupt other code or data.
v1.1v1.1
TERIDIAN Proprietary
40 of 116
© Copyright 2005-2008 TERIDIAN Semiconductor Corporation