14 firmware application information, 1 general design considerations, 1 multitasking – Maxim Integrated 71M6534 Energy Meter IC Family Software User Manual
Page 77: 2 synchronization, 3 bank switching, Firmware application information, General design considerations, Multitasking, Synchronization, Bank switching

71M653X Software User’s Guide
5.14 FIRMWARE APPLICATION INFORMATION
5.14.1
General Design Considerations
5.14.1.1 Multitasking
The meter appears to do many things at once. How does this happen?
Each “task” is a subroutine call in the main loop in Main\main.c: main_run(). The tasks are called repeatedly by the
main loop, giving each of them many opportunities to use the MPU. They usually check for “data present”, and then
either exit or process the data and then exit. Prominent examples include: meter_run() in meter\meter.c (the
meter’s main process), cli() in cli\cli.c (the command line interface’s process), stm_run() in Util\stm.c (the
software timers’ update task).
This scheme is well suited to such a small system, but it also has problems when an IO process must wait for input or
output. This happens in only two major subsystems, the serial command line interface, and the metering system.
While the serial command logic is waiting for another serial character, it calls a subset of the main loop, in Main\main.c
main_background()
. main_background() does all of the meter’s main loop except for serial protocols. In that
way, the meter keeps “running” while the serial IO is “waiting.”
The main metering routine, Meter\meter.c meter_run(), skips most of its logic until a flag, ce_update, is set. At
this point meter_run() runs to completion. meter_run() performs many calculations. These calculations stop the
rest of the main loop from running for up to several hundred milliseconds (depends on clock speed). This delay is
nearly impossible for a person to see, so it does not affect human I/O at all. The time-critical machine I/O during this
period is handled by interrupts that buffer data for the main loop.
5.14.1.2 Synchronization
Interrupts do the work that needs immediate attention, then set a flag or count to start code that runs in the main loop.
To keep the main loop simple, the flag, the routine to run in the main loop, and the interrupt code should be defined in
the class’s .c file. The main loop should just call the “run” routine continually.
Software timers (Util\stm.c, .h) are started by an interrupt that counts every 10 milliseconds in real time. In the main
loop, stm_run() decrements software timer variables and runs the associated callback routine if a timer expires.
stm_run()
calculates the real interval since its last invocation in order to reduce jitter.
The code also has a shared, calibrated delay loop routine, in IO/delay.c. It’s calibrated in the normal clock modes, and
runs at reasonable rates in all clock modes, including brownout mode.
State machines are invoked in the main loop. The main loop will just call a “run” routine with no parameters and no
returns. No state variables or other state-machine logic will be defined in the main loop.
5.14.1.3 Bank Switching
The code has to be able to grow to fill the 128KB to 256KB memory space of this chip. So, it is bank-switched.
Keil’s standard bank-switching schemes were all tested for speed, and then the fastest was left installed. See
Util\L51_BANK.A51, for the modified Keil assembly file that performs the bank switching.
The selected Keil scheme sets the bank-sfr register FL_BANK directly, from code. Keil’s bank-switching scheme has
the linker build a table of global subroutine entry-points in common memory. Calls to global subroutines are actually to
an entry in the table, which switches the bank and jumps to the the bank-switching routines. The SUG has more
details, including debugging suggestions.
Fast interrupts has to be in the common page, so that their code is always available. Slower interrupts have a
trampoline in the common page that performs a bank-switching call to the main interrupt code. This permits entire
modules to be placed in different banks, so that the code’s functionally-pure structure doesn’t have to be damaged in
order to do bank-switching. The trampolines are in Meter\io653x.c, with other shared interrupt logic.
v1.1v1.1
TERIDIAN Proprietary
77 of 116
© Copyright 2005-2008 TERIDIAN Semiconductor Corporation