• No results found

5.3 Microcontroller

5.3.2 Memories

The ATmega16 uses a Harvard architecture as every AVR microcontroller. In a Harvard architecture, the memories and buses for program and data are separated.

Hence, the memory of the ATmega16 microcontroller is divided into three memory spaces:

• data memory space,

• EEPROM memory space, and

• program memory space.

The ATmega16 SRAM memory comprises 1120 bytes. Figure 5.2 shows the SRAM data memory space of the ATmega16. The first 96 bytes contain the register file and the I/O registers. The registers are used by the core to conduct calculations and to store values. The I/O registers are used to access certain features and devices of the ATmega16 microcontroller such as timers, I/O ports, or interrupts. The internal data SRAM is accessed through the last 1024 bytes. It is used to store variable values and the stack.

The EEPROM memory is nonvolatile and can be used by the developer to store values permanently. Its size is 512 bytes, and it is 8 bit wide.

The program memory stores the program. Its size is 16 kB, and it is 16 bit wide.

SRAM Data Memory

The SRAM data memory space is modeled as two byte arrays, each 8 bit wide. The first array stores the actual value of each memory location, for example, register, I/O register, or variable. The second array records whether a memory location contains a deterministic or a nondeterministic value. It is used to realize lazy states (see also Sect. 5.2). A byte in the second array is called the to be determinized mask (TBDM ) of a memory location. It records that nondeterminism, introduced by abstraction techniques, has to be resolved for the corresponding memory location.

The TBDM is not used to model the nondeterminism generated by the I/O registers.

Whether an I/O register generates a nondeterministic value or not is implemented within special Register classes (see Sect. 5.3.5 and 5.3.6).

The TBDM records whether each bit is nondeterministic or not. Some bits of a memory location can be nondeterministic while others are deterministic. When a bit in the TBDM is zero, its value is deterministic, and hence, the corresponding

5.3 Microcontroller

R0

R31 R30 R29 ...

R2 R1 Register File

$00

$3F

$3E

$3D ...

$02

$01 I/O Registers

$0000

$001F

$001E

$001D ...

$0002

$0001 Data Address Space

$0020

$005F

$005E

$005D ...

$0022

$0021

$045F

$045E ...

$0061

$0060 Internal SRAM

Figure 5.2: ATMEL ATmega16 data memory map [4].

5 State Space Building in [mc]square

Microcontroller

Registers / I/O Registers

SRAM Data Memory

Access Registers Access Data Array Access Internal Data SRAM

Figure 5.3: Different accesses to the SRAM data memory.

value stored within the first array is used. When a bit is one in the TBDM, it is nondeterministic. Its value in the first array is not used and is set to zero. Therefore, large parts of both arrays hold zeros. In fact, some parts of the second array are zero all the time. This seems to double the memory consumption to 2 kB for the data memory space, but these two arrays can be compressed very efficiently via one of the compression methods implemented within [mc]square.

As described before, the SRAM data memory space contains three memory regions (see Fig. 5.2):

• register file,

• I/O memory (I/O registers), and

• internal data SRAM.

Accesses to these three memory regions are handled differently. Figure 5.3 shows the different accesses to the SRAM data memory space. The parts representing the internal data SRAM are accessed directly because they do not require special treatment. The parts storing the values of registers and I/O registers are accessed through specific Register classes. These classes are needed because some registers have access restrictions, involve side-effects, or generate nondeterminism. An example for registers with access restrictions are reserved registers. I/O registers often involve side-effects, for instance, activation of interrupts or timers. This may lead to nondeterminism in other I/O registers. The special Register classes are

5.3 Microcontroller

used to observe restrictions, to conduct changes including side-effects, and to handle nondeterminism.

There are different types of registers. There are Register classes representing general-purpose working registers, registers that cannot store nondeterministic values, registers having reserved bits, and special purpose I/O registers. These different classes encapsulate the logic behind the respective registers. That is, if a write access to a register occurs, the corresponding handles the memory addresses that have to be written and the side-effects that have to be executed. The same is done when registers are read. For instance, certain I/O registers can return nondeterministic values depending on the values of other I/O registers. We describe details of I/O registers representing I/O ports in Sect. 5.3.5 and timers in Sect. 5.3.6.

These special Register classes do not store values. They are only used to access the arrays storing the values. Microcontroller states can be saved and restored by copying the underlying byte arrays.

EEPROM Data Memory

We have modeled the EEPROM data memory as a byte array that cannot be accessed directly. All accesses to it are made through certain I/O registers. These I/O registers are modeled by special classes, which effect the actual changes. The EEPROM data memory does not store nondeterministic values. Hence, a second array is not needed. As the EEPROM does not usually change much during runtime, only changes made relative to its initial values are stored in the microcontroller state.

Flash Program Memory

The flash program memory is modeled as a 16 bit array because ATmega instructions are 16 or 32 bits wide. The flash memory can be read directly, but when writing to it, certain I/O registers are used to determine what is to be done, for example, delete page, write page, or write into temporary buffer. The flash memory does not store nondeterministic values because it contains the program. As it can be written during runtime, the program may change itself. Hence, we had to implement an on-the-fly disassembler. Since an on-the-fly disassembler is rather slow, we implemented a two-staged approach. When the state space creation is started, the initial flash memory is disassembled into an assembly program (see Sect. 5.4). The instructions of this assembly program are used in all states where the page in program memory holding the current instruction was not changed. Whenever an instruction is to be executed that resides in a page in program memory that is changed, the on-the-fly disassembler is used to disassemble the current instruction. This combines the performance of a static approach with the ability to handle self-modifying code.

5 State Space Building in [mc]square

Like the EEPROM data memory, the program memory is not stored in every single microcontroller state completely, but it is stored as differences to the initial flash memory.

Related documents