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.

Erase segment problem in msp430f5418A

Hi,

I am planning to use the 64k flash area  starting from 0x10000 for logging some data from sensors.

I am running in to an issue when I try to erase segment no 64 onwards. ie offset of 64*512 = 0x8000

To erase a segment a write to the address 0x18000 is performed by the following code

#define FLASH_LOG_AREA_START (char *)0x10000

void eraseSegment (unsigned int segNo)
{
    char *Flash_ptr;        // Initialize Flash pointer

    Flash_ptr = FLASH_LOG_AREA_START;
    Flash_ptr += (segNo*FLASH_SEG_SIZE);

    FCTL3 = FWKEY;                            // Clear Lock bit
    FCTL1 = FWKEY+ERASE;                      // Set Bank Erase  bit - Segment
    *Flash_ptr = 0;                           // Dummy erase byte - pointer segment erase
    FCTL3 = FWKEY+LOCK;                       // Set LOCK bit
}

The problem seems to be that Flash_ptr does not contain 0x18000 when segment number is 64, instead it has 0x8000. I have checked that segNo is passed to the function correctly. The erase to 0x8000 erase part of my program, in lower 64k.

The problem is not there when segNo is less than 64. ie I am able to erase and program 0x 17E00 corresponding to seg 63.

I have enabled large data model and large memory model. So I assume that I should be getting 20 bit addresses.

I am using sys/bios, but I suppose it is no way related to that.

Please help me in resolving this issue. I am using CCSv5

Regards,

Jino

  • Jino Sebastian said:
    I have enabled large data model and large memory model. So I assume that I should be getting 20 bit addresses.

    Yes, but it is possible that the compiler clips 0x10000 to 16 bit as it is not marked to be a long value.

    The compiler first evaluates the expression and then casts it to the target type. The evaluation of constants is IMHO 16 bit by default unless you explicitely tell that it isn't.

    For the same reason, (segNo*FLASH_SEG_SIZE) will return an int, even if segNo should be >128.

    Add an "L" or "UL" size identifier to the constants and try again.

  • Thanks Jens for your suggestion.

    I tried this but still no luck. I have seen one of your posts regarding a similar issue and tried far pointer [char far *] but this also does not solve my issue.

    I will try with TI example code and see if I can get this to work.

    Regards,

    Jino

  • Jino Sebastian said:
    I tried this but still no luck.

    Hmmm, I didn't read your post carefully enough. You can go up to 0x17E00, sit isn't the addition itself.

    It's the (SegNo*FLASH_SEG_SIZE) expression that 'fails'. SegNo is an unsigned int, but FLASH_SEG_SIZE is a signed int (uless explicitedly declared to be unsigned).
    As a result., it looks like you get an signed int overflow, and what should be 0x8000 turns into -32768. which as result looks like 0x10000 is missing.

    Try declaring FLASH_SEG_SIZE explicitely as long

  • Hi Jens,

    I have tried this setting as well but still this fails.

    I have tried this same code without sys/bios and it started working.

    With sys/bios, however it fails. When I checked the sys/bios makefile src->Sysbios->Makefile the data model is specified as "restricted" eventhough project ->properties is specified as large.

    So it seems that sys/bios is overriding my Global settings.

    Searching for solution, I see this post

    http://e2e.ti.com/support/embedded/bios/f/355/t/235943.aspx
    It seems to suggest that I don't have a way to get the sys/bios with large data model ... ("Unfortunately, there is no RTSC target that supports the large data model")
    Regards,
    Jino

    http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/258699.aspx

  • Jino Sebastian said:
    With sys/bios, however it fails. When I checked the sys/bios makefile src->Sysbios->Makefile the data model is specified as "restricted" even though project ->properties is specified as large.

    You didn't mention you're running your code under SYS/BIOS. (Edit: you did, I just didn't see) Well I hadn't made a differene as I'm not familiar with it. I have my own colleciton of OS-like code (including a multitasker)

    It is possible that SYS/BIOS overrides large code model because this specific version doesn't work with large data model. Large data model has a serious impact on many aspects. Most of them can be handled by the compiler, but I guess that SYS/BIOS contains some assembly code as well, especially the task switching code, and this code needs to be significantly different for large data model.

    The workaround is what I have done soem tiem ago when there was no support for large data model in MSPGCC: write a dedicated function that takes a long argument, and passes it to some inline assembly code that generates the necessary 20 bit reads and writes.
    I think that IAR and maybe even CCS has some intrinsics that take a 32 bit argument and perform a 20 bit read or write of a byte or word, wrapped with blocked interrupts, so suitable for flash operation too.

    Thso intrinsics will then just repalce your data pointer access and the compielr generates the necessary code.

  • Hi Jens,

    "You didn't mention you're running your code under SYS/BIOS".

    Yes I did in the original post, even though I didn't expect the issue would be with the OS. ("I am using sys/bios, but I suppose it is no way related to that.")


    "The workaround is what I have done soem tiem ago when there was no support for large data model in MSPGCC: write a dedicated function that takes a long argument, and passes it to some inline assembly code that generates the necessary 20 bit reads and writes. "

    Thank you for the suggestion. I will try it, but may be a little time consuming since I am not familiar to assembly programming of MSP430


    Thanks,

    Jino




**Attention** This is a public forum