This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
When posting the example code all formatting were lost, so here's an new attempt.
/* quick and dirty INFOB error demo
* unable to place more than 9bytes of const data into INFOB segment
* using CCE V3.1
* to verify the problem try to rebuild the project with variable8 and
* variable9 included
*/
#include <msp430x20x2.h>
/*-------------------------------------------------------------
* Macros
* ------------------------------------------------------------*/
#define FLASH_UNLOCK FCTL3 = FWKEY; FCTL1 = FWKEY + WRT;
#define FLASH_LOCK FCTL1 = FWKEY; FCTL3 = FWKEY + LOCK;
#define FLASH_WRITE_INFOB(destination, source) st( FLASH_UNLOCK_INFOB; destination = source; while (FCTL3 & BUSY ); FLASH_LOCK_INFOB; )
//--Calibration constants and user configuration values stored in INFOB Flash--
#pragma DATA_SECTION(variable1, ".infoB");
#pragma DATA_SECTION(variable2, ".infoB");
#pragma DATA_SECTION(variable3, ".infoB");
#pragma DATA_SECTION(variable4, ".infoB");
#pragma DATA_SECTION(variable5, ".infoB");
#pragma DATA_SECTION(variable6, ".infoB");
#pragma DATA_SECTION(variable7, ".infoB");
//#pragma DATA_SECTION(variable8, ".infoB");
//#pragma DATA_SECTION(variable9, ".infoB");
#pragma DATA_ALIGN(variable1, 8);
#pragma DATA_ALIGN(variable2, 8);
#pragma DATA_ALIGN(variable3, 16);
#pragma DATA_ALIGN(variable4, 8);
#pragma DATA_ALIGN(variable5, 8);
#pragma DATA_ALIGN(variable6, 16);
#pragma DATA_ALIGN(variable7, 8);
//#pragma DATA_ALIGN(variable8, 8);
//#pragma DATA_ALIGN(variable9, 16);
unsigned char variable1;
unsigned char variable2;
int variable3;
unsigned char variable4;
unsigned char variable5;
int variable6;
unsigned char variable7;
//unsigned char variable8;
//int variable9;
// -- local variable set --
unsigned char variable1LOCAL;
unsigned char variable2LOCAL;
int variable3LOCAL;
unsigned char variable4LOCAL;
unsigned char variable5LOCAL;
int variable6LOCAL;
unsigned char variable7LOCAL;
//unsigned char variable8LOCAL;
//int variable9;
/**********************************************************************//**
* from file flashUtils.c
*
* taken from MSP-EXP430F5438_User_Experience_CCE (slac227.zip)
**************************************************************************/
/**********************************************************************//**
* @brief Erases a bank in flash memory.
*
* @param FarPtr The pointer to the location in memory within the bank to
* be erased.
*
* @return none
**************************************************************************/
void flashEraseBank( unsigned long FarPtr)
{
FCTL3 = FWKEY;
while (FCTL3 & BUSY );
FCTL1 = FWKEY + MERAS;
__data20_write_char(FarPtr, 0x00); // Dummy write to start erase
while (FCTL3 & BUSY );
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
}
/**********************************************************************//**
* @brief Erases a single segment of memory containing the address FarPtr.
*
* @param FarPtr The address location within the segment of memory to be
* erased.
*
* @return none
**************************************************************************/
void flashEraseSegment(unsigned long FarPtr)
{
FCTL3 = FWKEY;
FCTL1 = FWKEY + ERASE;
__data20_write_char(FarPtr, 0x00); // Dummy write to start erase
while (FCTL3 & BUSY );
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
}
/**********************************************************************//**
* @brief Erases the (multiple) segment(s) of memory including address
* locations Memstart through Memend.
*
* @param Memstart The starting address location identifying a segment of
* memory to be erased
*
* @param Memend The ending address location identifying a segment of
* memory to be erased
*
* @return none
**************************************************************************/
void flashErase(unsigned long Memstart, unsigned long Memend)
{
unsigned long FarPtr = Memstart; // Start of record memory array
FCTL3 = FWKEY; // Unlock Flash memory for write
do
{
if ( (FarPtr & 0xFFFF) == 0x0000) // Use bit 12 to toggle LED
P1OUT ^= 0x01;
FCTL1 = FWKEY + ERASE;
__data20_write_char(FarPtr, 0x00); // Dummy write to activate
while (FCTL3 & BUSY ); // Segment erase
FarPtr += 0x0200; // Point to next segment
} while (FarPtr < Memend);
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
}
/*-------------------------------------------------------------------------*/
/**********************************************************************//**
* @brief Stores calibration and user-config data into INFOB flash
*
* @param none
*
* @return none
*************************************************************************/
void saveSettings(void)
{
flashEraseSegment((unsigned long)&variable1);
FLASH_UNLOCK;
variable1 = variable1LOCAL ;
variable2 = variable2LOCAL ;
variable3 = variable3LOCAL ;
variable4 = variable4LOCAL ;
variable5 = variable5LOCAL;
variable6 = variable6LOCAL ;
variable7 = variable7LOCAL;
//variable8 = variable8LOCAL;
//variable9 = variable9LOCAL;
FLASH_LOCK;
}
/**********************************************************************//**
* @brief Loads calibration and user-config data from INFOB flash.
*
* @param none
*
* @return none
*************************************************************************/
void loadSettings(void)
{
variable1LOCAL = variable1;
variable2LOCAL = variable2;
variable3LOCAL = variable3;
variable4LOCAL = variable4;
variable5LOCAL = variable5;
variable6LOCAL = variable6;
variable7LOCAL = variable7;
//variable8LOCAL = variable8;
//variable9LOCAL = variable9;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x01; // Set P1.0 to output direction
for (;;)
{
volatile unsigned int i;
P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR
loadSettings();
i = 50000; // Delay
do (i--);
while (i != 0);
variable1LOCAL++;
variable2LOCAL = 0xAA;
saveSettings();
}
}
The linker error "placement fails for object" means that it was unable to allocate that section to the memory region, typically because the section is larger than the available memory. In your case you need to ensure that all your variables allocated to infoB are within the available 0x40 for INFOB memory
Hi Aarti, thanks for the answer. Here is the memory map for the demo project:
MEMORY CONFIGURATION name origin length used unused attr fill This says, that 0x39 = 57bytes of INFOB memory is used by my application. I'm a little confused on that since I only placed 5 variables of type 'unsigned char' (--> 5bytes) and 2 variables of type 'int' (--> 4 bytes in total) in INFOB. That means 9bytes of variables placed in a segment which is 64bytes long should result in an available space of 55bytes. So, why is the linker allocating 57bytes for 9bytes of data? Is it possible that there's an error in the C compiler's user guide (SLAU132C, Nov 2008, see section 5.8.3; #pragma DATA_ALIGN (symbol, constant) with constant a power of 2 (?)? Because, when I change my variable defininition to
---------------------- -------- --------- -------- -------- ---- --------
SFR 00000000 00000010 00000000 00000010 RWIX
PERIPHERALS_8BIT 00000010 000000f0 00000000 000000f0 RWIX
PERIPHERALS_16BIT 00000100 00000100 00000000 00000100 RWIX
RAM 00000200 00000080 00000044 0000003c RWIX
INFOD 00001000 00000040 00000000 00000040 RWIX
INFOC 00001040 00000040 00000000 00000040 RWIX
INFOB 00001080 00000040 00000039 00000007 RWIX
INFOA 000010c0 00000040 00000000 00000040 RWIX
FLASH 0000f800 000007e0 000001e0 00000600 RWIX
..
RESET 0000fffe 00000002 00000002 00000000 RWIX
#pragma DATA_ALIGN(variable1, 1);
#pragma DATA_ALIGN(variable2, 1);
#pragma DATA_ALIGN(variable3, 2);
#pragma DATA_ALIGN(variable4, 1);
#pragma DATA_ALIGN(variable5, 1);
#pragma DATA_ALIGN(variable6, 2);
#pragma DATA_ALIGN(variable7, 1);
//#pragma DATA_ALIGN(variable8, 1);
//#pragma DATA_ALIGN(variable9, 2);
with constant representing the number of bytes used by the variable the map file looks like
MEMORY CONFIGURATION name origin length used unused attr fill and that's what I would expect (9bytes used by 9bytes of data). It would be nice if someone could clarify this issue. Rgds Gookbuster
---------------------- -------- --------- -------- -------- ---- --------
..
INFOD 00001000 00000040 00000000 00000040 RWIX
INFOC 00001040 00000040 00000000 00000040 RWIX
INFOB 00001080 00000040 00000009 00000037 RWIX
INFOA 000010c0 00000040 00000000 00000040 RWIX
Gookbuster said:
This says, that 0x39 = 57bytes of INFOB memory is used by my application. I'm a little confused on that since I only placed 5 variables of type 'unsigned char' (--> 5bytes) and 2 variables of type 'int' (--> 4 bytes in total) in INFOB. That means 9bytes of variables placed in a segment which is 64bytes long should result in an available space of 55bytes. So, why is the linker allocating 57bytes for 9bytes of data?
Is it possible that there's an error in the C compiler's user guide (SLAU132C, Nov 2008, see section 5.8.3; #pragma DATA_ALIGN (symbol, constant) with constant a power of 2 (?)? Because, when I change my variable defininition to
#pragma DATA_ALIGN(variable1, 1);
#pragma DATA_ALIGN(variable2, 1);
#pragma DATA_ALIGN(variable3, 2);
#pragma DATA_ALIGN(variable4, 1);
#pragma DATA_ALIGN(variable5, 1);
#pragma DATA_ALIGN(variable6, 2);
#pragma DATA_ALIGN(variable7, 1);
//#pragma DATA_ALIGN(variable8, 1);
//#pragma DATA_ALIGN(variable9, 2);with constant representing the number of bytes used by the variable the map file looks like
MEMORY CONFIGURATION
name origin length used unused attr fill
---------------------- -------- --------- -------- -------- ---- --------
..
INFOD 00001000 00000040 00000000 00000040 RWIX
INFOC 00001040 00000040 00000000 00000040 RWIX
INFOB 00001080 00000040 00000009 00000037 RWIX
INFOA 000010c0 00000040 00000000 00000040 RWIXand that's what I would expect (9bytes used by 9bytes of data). It would be nice if someone could clarify this issue.
The DATA_ALIGN pragma tells the compiler/linker to place the variable at an address location that is aligned on a boundary specified by the "constant" input.
Using your example below:
#pragma DATA_ALIGN(variable1, 8);
#pragma DATA_ALIGN(variable2, 8);
#pragma DATA_ALIGN(variable3, 16);
#pragma DATA_ALIGN(variable4, 8);
#pragma DATA_ALIGN(variable5, 8);
#pragma DATA_ALIGN(variable6, 16);
#pragma DATA_ALIGN(variable7, 8);
variable1 and variable2 need to be aligned on an 8-byte boundary, which means variable2 would not be nested right next to variable1 in the memory map. I suspect the address of variable1 and variable2 are :
0x00001080 : variable1
0x00001088 : variable2
Similarly, variable3 would need to be aligned on an 16-byte boundary, which actually would be 0x00001090.
Therefore, my expectation of the DATA_ALIGN() is aligned with the observations you have. Does this make sense?
Hi Brandon,
that's correct! My (expected) memory map look's like:
0x00001080 : variable1
0x00001081 : variable2
0x00001082 : variable3 (integer --> 2 bytes long --> uses address 0x00001082 and 0x00001083)
0x00001084 : variable4
...
Unfortuneately, the compiler's user manual is not precise on this point (although 1 is a power of two (2^0 = 1), Maybe an example would help [:)]
Thank's again for your support, rgds Gookbuster
**Attention** This is a public forum