LPC1769 flash, memory mapping

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1769 flash, memory mapping

2,281 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Fri Mar 15 12:36:24 MST 2013
Hi,

I'm trying to write some bytes to the flash memory of the LPC1769 but this always fails with the message "SRC_ADDR_NOT_MAPPED".

The test code is:

uint32_t test = 123456;

printf("prepare: %u\n", u32IAP_PrepareSectors(16, 16));
printf("written: %u\n", u32IAP_CopyRAMToFlash(0x00010000, (uint32_t) test, 256));


and the functions

uint32_t u32IAP_PrepareSectors(uint32_t u32StartSector, uint32_t u32EndSector)
{
    uint32_t u32Status;
    uint32_t au32Result[5];
    uint32_t au32Command[5];

    if (u32EndSector < u32StartSector)
    {
        u32Status = IAP_STA_INVALD_PARAM;
    }
    else
    {
        au32Command[0] = IAP_CMD_PREPARE_SECTORS;
        au32Command[1] = u32StartSector;
        au32Command[2] = u32EndSector;

        IAP_EXECUTE_CMD(au32Command, au32Result);

        u32Status = au32Result[0];
    }
    return u32Status;
}

uint32_t u32IAP_CopyRAMToFlash(uint32_t u32DstAddr, uint32_t u32SrcAddr, uint32_t u32Len)
{
    uint32_t au32Result[5];
    uint32_t au32Command[5];

    au32Command[0] = IAP_CMD_COPY_RAM_TO_FLASH;
    au32Command[1] = u32DstAddr;
    au32Command[2] = u32SrcAddr;
    au32Command[3] = u32Len;
    au32Command[4] = SystemCoreClock / 1000UL;    /* Core clock frequency in kHz */

    IAP_EXECUTE_CMD(au32Command, au32Result);

    return au32Result[0];
}


what does this SRC_ADDR_NOT_MAPPED mean?

thanks!
inspire
0 Kudos
14 Replies

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fiuba1 on Mon Jun 17 15:34:05 MST 2013

Quote: inspire
aw the global variable solves the problem! I struggled hours with this! Although I don't completely understand why there is a problem with local variables. They placed are in a different memory location, but both local and global variables are on the stack, right?

thanks a lot!!!



Hi Inspire,
Can you provide the full test code for writing to the firmware? I tried to duplicate your approach but something's missing... the function "u32IAP_EraseSectors" for once; dunno if sthg else.

Or alternatively, where can I download the complete IAP libraries (.c / .h) from?

I'm also trying to accomplish my first writing into 1769's firmware and experiencing the usual troubles of the beginning of the lerning curve :)

Thanks a lot.
Matt
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by plexus on Mon Apr 22 06:58:32 MST 2013

Quote: plexus
Hi, I've followed your sequence of posts and have one query.

Is it possible to edit the linker template to avoid program code to be written into sector 29 this way ensuring that we can write data into it without messing up with program?

Thanks



Figured it out. If you reduce the memory size in the memory editor to keep the last 32k out the linker will not use it to put program in. This way sector 29 will be free to save data.
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by plexus on Mon Apr 22 06:14:54 MST 2013
Hi, I've followed your sequence of posts and have one query.

Is it possible to edit the linker template to avoid program code to be written into sector 29 this way ensuring that we can write data into it without messing up with program?

Thanks
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Sun Mar 17 08:03:20 MST 2013
ah alright, thanks a lot for your hints and help!
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat Mar 16 08:47:21 MST 2013

Quote: inspire
I mean the last end address is 0x0007 FFFF. The  LPC1769 has 512 kB flash memory, so it has sectors 22 to 29, doesn't it?



My LPC1769 even has 30 sectors :eek:


Quote: inspire
You are right, the programm code shouldn't be overwritten by something else. But how can I figure out which flash memory regions are "safe"?



Look in your map file to see how much flash is used ;)

My programs are often < 480kB, so sector 29 (LPC1769) is my favorite to store my stuff in :)

It's also a good idea to do an IAP sector blank check before erasing / writing. Storing a pattern at the first bytes of your data sector helps you to see if (your) non blank sector has been used for something else. But usually no one touches sector 29, so it's a 'safe' sector :)
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Sat Mar 16 08:27:59 MST 2013
I mean the last end address is 0x0007 FFFF. The LPC1769 has 512 kB flash memory, so it has sectors 22 to 29, doesn't it?

You are right, the programm code shouldn't be overwritten by something else. But how can I figure out which flash memory regions are "safe"?
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat Mar 16 07:58:57 MST 2013

Quote: inspire
okay, one last question

:eek:


Quote: inspire
okay, one last question:
The first flash memory start address is 0x0000 0000 and the last address is 0x0007 FFFF.



You've a 512kB Flash :confused:


Quote: inspire
The active interrupt vectors are from 0x0000 0000 to 0x0000 0400 and  their content shouldn't be changed. But shouldn't 0x0000 0401 be  accessable again? For example, when I write some values into 0x00001000  (sector 1), the LPC runs into a hard fault.



I'm not sure what you map file is telling you about flash usage of your program. Sector 1 is the second sector which begins at 4kB.

So if your code is >4kB you are writing funny values in a flash region which your LPC is trying to execute :o
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Sat Mar 16 07:34:57 MST 2013
okay, one last question:
The first flash memory start address is 0x0000 0000 and the last address is 0x0007 FFFF.
The active interrupt vectors are from 0x0000 0000 to 0x0000 0400 and their content shouldn't be changed. But shouldn't 0x0000 0401 be accessable again? For example, when I write some values into 0x00001000 (sector 1), the LPC runs into a hard fault.
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Sat Mar 16 05:27:58 MST 2013
oh I didn't know that there is a memory region besides the heap and stack :O thanks for your help, now it works perfectly!
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Mar 15 16:59:33 MST 2013

Quote: inspire
...but both local and global variables are on the stack, right?


 
:eek:

Since when :confused:

http://mbed.org/handbook/Memory-Model
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Fri Mar 15 16:07:39 MST 2013
aw the global variable solves the problem! I struggled hours with this! Although I don't completely understand why there is a problem with local variables. They placed are in a different memory location, but both local and global variables are on the stack, right?

thanks a lot!!!
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Mar 15 15:38:12 MST 2013
And which address has your test?

Hint: Look in your map file and then make your test global ;)
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by inspire on Fri Mar 15 15:31:24 MST 2013
ah my bad, of course this is not working, sorry. This must be an address, so of course

printf("written: %u\n", u32IAP_CopyRAMToFlash(0x00010000, (uint32_t) &test, 256));


But this gives the same message "SRC_ADDR_NOT_MAPPED".

The whole main.c file:
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>

// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP;

#include <stdio.h>

#include "IAP/IAP.h"

int main(void) {

    SystemCoreClockUpdate();

    uint32_t test = 123456;

    __disable_irq();

    printf("prepare: %u\n", u32IAP_PrepareSectors(16, 16)); // success
    printf("erase: %u\n", u32IAP_EraseSectors(16, 16)); // success

    printf("prepare: %u\n", u32IAP_PrepareSectors(16, 16)); // success
    printf("written: %u\n", u32IAP_CopyRAMToFlash(0x00010000, (uint32_t) &test, 256)); // "SRC_ADDR_NOT_MAPPED"

    __enable_irq();

    while (1) {
    }

    return 0;
}


To complete the IAP.c file from my first post, here are the used macros:
/* IAP Command Status Codes */
#define IAP_STA_CMD_SUCCESS                                 0
#define IAP_STA_INVALID_COMMAND                             1
#define IAP_STA_SRC_ADDR_ERROR                                 2
#define IAP_STA_DST_ADDR_ERROR                                 3
#define IAP_STA_SRC_ADDR_NOT_MAPPED                         4
#define IAP_STA_DST_ADDR_NOT_MAPPED                         5
#define IAP_STA_COUNT_ERROR                                 6
#define IAP_STA_INVALID_SECTOR                                 7
#define IAP_STA_SECTOR_NOT_BLANK                            8
#define IAP_STA_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION     9
#define IAP_STA_COMPARE_ERROR                                 10
#define IAP_STA_BUSY                                         11
#define IAP_STA_INVALD_PARAM                                 12

/* Define the flash page size, this is the minimum amount of data can be written in one operation */
#define IAP_FLASH_PAGE_SIZE_BYTES                            256
#define IAP_FLASH_PAGE_SIZE_WORDS                            (IAP_FLASH_PAGE_SIZE_BYTES >> 2)

/* IAP Command Definitions */
#define    IAP_CMD_PREPARE_SECTORS            50
#define    IAP_CMD_COPY_RAM_TO_FLASH        51
#define    IAP_CMD_ERASE_SECTORS            52
#define    IAP_CMD_BLANK_CHECK_SECTORS        53
#define    IAP_CMD_READ_PART_ID            54
#define    IAP_CMD_READ_BOOT_ROM_VERSION    55
#define    IAP_CMD_COMPARE                    56
#define    IAP_CMD_REINVOKE_ISP            57
#define IAP_CMD_READ_SERIAL_NUMBER        58

/* IAP boot ROM location and access function */
#define IAP_ROM_LOCATION                0x1FFF1FF1UL
#define IAP_EXECUTE_CMD(a, b)            ((void (*)())(IAP_ROM_LOCATION))(a, b)


have a nice weekend!
0 Kudos

1,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Mar 15 13:12:58 MST 2013
#1 Please post complete sources, not just code snippets ;)

#2 Your source address is uint32_t test = 123456; :eek:

That's 0x1E240 and probably a flash address. For that operation you need a Copy_Flash_to_Flash function :p
0 Kudos