Other Parts Discussed in Thread: MSP430F6659
Using MSP430 compiler v15.12.2.LTS created code to initialize a RAM array in a MSP430F6659 device from byte address 0x0F0000 to 0x0FBFFF, but found that the generated code set the "Vacant memory access interrupt flag" due to writing to an (incorrect) memory address which isn't mapped.
The following standalone program was created to illustrate the problem:
#include <stdio.h>
#include <stdint.h>
#include <msp430.h>
#define RAM2_ORIGIN 0xF0000UL
#define RAM2_SIZE_BYTES 0xC000U
static void ram_fill_works (void)
{
uint16_t test_pattern_index;
uint8_t *dma_source_test_data = (uint8_t *) RAM2_ORIGIN;
for (test_pattern_index = 0; test_pattern_index < RAM2_SIZE_BYTES; test_pattern_index++)
{
*dma_source_test_data = (test_pattern_index >> 4u) & 1u;
dma_source_test_data++;
if (SFRIFG1 & VMAIFG)
{
for (;;)
{
}
}
}
}
static void ram_fill_fails (void)
{
uint16_t test_pattern_index;
uint8_t *const dma_source_test_data = (uint8_t *) RAM2_ORIGIN;
for (test_pattern_index = 0; test_pattern_index < RAM2_SIZE_BYTES; test_pattern_index++)
{
dma_source_test_data[test_pattern_index] = (test_pattern_index >> 4u) & 1u;
if (SFRIFG1 & VMAIFG)
{
for (;;)
{
}
}
}
}
/*
* main.c
*/
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
/* Clear any previous vacent memory access */
if (SFRIFG1 & VMAIFG)
{
SFRIFG1 &= ~VMAIFG;
}
ram_fill_works ();
ram_fill_fails ();
printf ("Test passed\n");
return 0;
}
The ram_fill_fails() function is the failure case, which generates the "Vacant memory access interrupt flag", whereas the ram_fill_works() function doesn't generate a "Vacant memory access interrupt flag". The following CCS 6.1.3 debugger screenshot shows the state upon which the ram_fill_fails() function has stopped on a breakpoint after detecting that a "Vacant memory access interrupt flag" had occurred (i.e. when the VMAIFG bit in the SFRIFG1 register has been set):
The register values of interest are:
- R12 is the dma_source_test_data pointer, which has the correct value of 0x0F0000
- R13 is the test_pattern_index, which has the value 0x008000
- R15 is the last address in the dma_source_test_data[] array written to, which is 0x0E8000. This is the incorrect address, which triggered the "Vacant memory access interrupt flag". Since the test_pattern_index is unsigned the expected address to write to is 0x0F8000.
Not sure if ram_fill_fails() is showing a bug in the compiler, or if ram_fill_fails() is written in a way to invoke "undefined behavior".
The CCS 6.1.3 project is attached. The --data_model is set to the default of "restricted".
