Hi,
I'm using KEIL uVISION4 + SEGGER J-Link for programming NXP LPC1764 device. I have developed C code for programming flash using IAP, and I came to point when I can successful programming sectors 1 to 17 of our LPC1764. Our algorithm is:
#include <LPC17xx.H> // LPC17xx definitions #include <stdio.h> #define IAP_LOCATION 0x1FFF1FF1 #define Target_sector 2 //start sector #define End_target_sector 2 //end sector #define f_CCLK 2000 //core frequency #define Mem_size 4096 //how many Bytes will be writes into Flash, can be 256/512/1024/4096 #define Flash_sector_0 0x00000000 #define Flash_sector_1 0x00001000 #define Flash_sector_2 0x00002000 #define Flash_sector_3 0x00003000 static char* sector_start_adress[] = { (char*)Flash_sector_0, (char*)Flash_sector_1, (char*)Flash_sector_2, (char*)Flash_sector_3, }; int iap_program(int start,int end,char *target_addr,char *source_addr,long size,int f_core) { unsigned int IAP_command[5]; unsigned int IAP_result[5]; int Result_prepare; typedef void(*IAP)(unsigned int[], unsigned int[]); IAP iap_entry; iap_entry=(IAP) IAP_LOCATION; //prepare sector for erase IAP_command[0] = 50; IAP_command[1] = (unsigned int)start; //Start sector IAP_command[2] = (unsigned int)end; //End sector iap_entry(IAP_command,IAP_result); Result_prepare = IAP_result[0]; //erase sector IAP_command[0] = 52; IAP_command[1] = (unsigned int)start; //Start sector IAP_command[2] = (unsigned int)end; //End sector IAP_command[3] = f_core; iap_entry(IAP_command,IAP_result); Result_prepare = IAP_result[0]; //prepare sector for writing IAP_command[0] = 50; IAP_command[1] = (unsigned int)start; //Start sector IAP_command[2] = (unsigned int)end; //End sector iap_entry(IAP_command,IAP_result); Result_prepare = IAP_result[0]; //writing to FLASH IAP_command[0] = 51; IAP_command[1] = (unsigned int)target_addr; IAP_command[2] = (unsigned int)source_addr; IAP_command[3] = size; IAP_command[4] = f_core; iap_entry(IAP_command,IAP_result); return IAP_result[0]; } int main () //Main Program { int Result_x; static char mem[Mem_size] = {'T','E','S','T'}; //data buffer - data array with size depends on constant Mem_size __disable_irq(); //disable irq //start, end addr for prepare, destination address in flash, source address in RAM, number of bytes, CPU clock Result_x=iap_program(Target_sector,End_target_sector,sector_start_adress[Target_sector],mem,sizeof(mem),f_CCLK); __enable_irq(); //enable irq return Result_x; }
As I wrote, we can successful program Flash from sector 1 to 17. We can't program sector 0 because there is stored compiled program and after run program(erase sector 0 - we have logically all's 1 => missing code instruction for executing) there isn't present expected data.
So, I have some questions:
How can be stored compiled code(shown above) into RAM and run it from this location(results in storing data to address 0x0)? Does this option lies only in Keil IDE destination settings? Or is it needed to put some new commands into my main() structure? If yes, which one?
Thanks for your answers! Best regards,
Milan Muller
See the linker user guide - "scatter loading".
Hi Tamir,
thank you for your answer! I'm going to read something about scatter-loading. Don't you have some clear example which can I compare and eventually apply for my usage?
Best regards, Milan Muller
RW_RAM2 0xA0100000 0x10000 { ; RW data *armlib* (+RO) SBL_IAP.O (+RO) MAIN.o (+RO) MSCUSER.o (+RO) WDT.o (+RO) NOR_FLASH_APP.o (+RO) }
I'm reading something about scatter loading and using it in uVISION - It looks very complicated for me, because I don't find any similar and illustratively example(which regions I need to use in scatter load file desription).
So, when I'm looking in uVISION4 menu - Project - Options for target - Linker, there is two options for putting program into RAM - I can use manually wroted scatter file or checked the option "Use memory layout from target region"(in this situation the scatter file is automatically generated and used with respect of memory regions sets in tab "Target").
My question is - is this two options equivalent and can be program stored into RAM without writing my own scatter file?
I was trying to configure target tab like this:
www.freeimagehosting.net/.../b1fac4331f.jpg
, but my attempts failed - after project build and downloads it into device, I have obtained the error message : No Algorithm found for: 10000000H - 10000377H Partial Programming Done (areas with no algorithms skipped! Partial Verify OK (areas with no algorithms skipped!
I also used ASM macros RAM_INTVEC REMAP RAM_MODE for remap the vectors to internal RAM. Where may be a problem?
Thanks for your answer/ Best regards,
You have to write a scatter file.
Note that when running code in RAM, you need two copies of the code. One copy in the flash. And the startup code must then know that the code is intended for use in RAM, and copy the code to RAM on startup.
The dialog box doesn't have fields to specify what RAM address you want code copied to.
It's a big difference between writing code that boots from flash and runs in RAM, and writing code that gets downloaded and run directly from RAM. Several of the Keil examples do the second. In that case, the debugger sends the program directly to RAM, and then sets the PC to the start of the program without any flash having been involved.
In your case, when you try to fool the tools by giving RAM addresses in the ROM boxes, you get an error about flash algorithm - since they expect to find flash at the address you specified.
I think you can find some nice examples by just searching forum posts. Running special functions from RAM has been discussed a number of times before.
As Per says, you must not place RAM addresses in the uv4 dialog boxes. Go to the "linker" tab, and disable the "use memory layout from target dialog". This scatter loading code snippet already posted above:
makes sure the startup code automatically copies the specified modules from ROM into RAM when the controller starts (as part of "__main"). Note that my external RAM starts at 0xA0000000.
I hope it helps you - this is a whole scatter loading file I use. Note that it includes some features not introduced by default by the Keil examples, such as loading code into RAM and application of the preprocessor on the scatter file. Also note that this example contains TWO load regions - one for internal flash, the other for a NOR flash (LR_IROM1 and LR_IROM2).
#! armcc -E -I "..\..\Bootloader\src" -I"..\..\common\src" -DSCATTER_FILE_PREPROCESSOR -DFMM #include "boot_firmware.h" #include "exceptions.h" #include "FMM_data_interface.h" #include "firmware_power_failure.h" ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* ; Application code always starts at 0x28000 and has a maximum allowed size of 0x56000 bytes (344 KB) ; so that it can theoretically strech from the begining of sector 12 until the end of sector 27 LR_IROM1 0x10000 0x6CFFF { ; load region size_region FMMAPP1 +0 0x1000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } SOFTWARE_EVENT SOFTWARE_EVENT_FUNCTION_LOCATION FIXED {; this region is used to export the software event function for quick invocation ; by the firmware in case of a failure SOFTWARE_EVENT.o (swe_section) } SIGNAL_EVENT SIGNAL_EVENT_FUNCTION_LOCATION FIXED {; this region is used to export the software event function for quick invocation ; by the firmware in case of a failure FIRMWARE_TO_APP_RTX_SIGNAL_ROUTE.o (+RO) } SOFTWARE_EVENT_INIT SOFTWARE_EVENT_INIT_FUNCTION_LOCATION FIXED { SOFTWARE_EVENT.o (swe_init_section) } POWER_FAILURE_HANDLER POWER_FALURE_HANDLER_LOCATION FIXED { POWER_FAILURE_IMPL.o (power_failure_section) } ER_IROM3 +0 0x69FFF { ; load address = execution address .ANY (+RO) } ; ****************************************************************************************************** ; * DO NOT MAP ANYTHING TO THE FIRST 0x40 BYTES OF INTERNAL RAM - RESERVED FOR REMAPPING VECTOR TABLE! * ; ****************************************************************************************************** RW_IRAM2_1 0x40000000 UNINIT { ; RW data } RW_IRAM_FIRMWARE 0x40000040 UNINIT { ; RW data used by firmware - not to be accessed by application! APPLICATION_IRAM_DUMMY.o (+RW +ZI) } IRAM_RTX 0x40002040 0xE000 { RT_EVENT.o (+RW +ZI) RT_HAL.o (+RW +ZI) RT_LIST.o (+RW +ZI) RT_MAILBOX.o (+RW +ZI) RT_MEMBOX.o (+RW +ZI) RT_MUTEX.o (+RW +ZI) RT_ROBIN.o (+RW +ZI) RT_SEMAPHORE.o (+RW +ZI) RT_SYSTEM.o (+RW +ZI) RT_TASK.o (+RW +ZI) RT_TIME.o (+RW +ZI) RT_TIMER.o (+RW +ZI) RTX_CONFIG.o (+RW +ZI) .ANY (+RW +ZI) } RW_IRAM3 0x7FE00000 0x00004000 { LPC24_EMAC.o (+ZI +RW) } ; ********************************************************************************************************* ; * DO NOT MAP ANYTHING TO THE FIRST 0x48 BYTES OF EXTERNAL RAM - RESERVED FOR BOOTLOADER IAP DESCRIPTOR! * ; ********************************************************************************************************* RW_XFREE1 0xA0000048 0x11FFFB8 { ; RW data .ANY (+RW +ZI) } RAM_DRIVE 0xA1200000 0x400000 { ; ***************************************************************** ; * DO NOT MAP ANYTHING INTO THIS REGION - RESERVED FOR RAM DRIVE * ; ***************************************************************** } SOFTWARE_EVENT_ZERO_INIT_DATA.o 0xA1FFA1E0 UNINIT { SOFTWARE_EVENT.o (non_init_2) } RW_DATA_INTERFACE START_UART2_RX_BUFFER_DATA 0x60000 { ; **************************************** ; * DO NOT MAP ANYTHING INTO THIS REGION * ; **************************************** ; DOING SO WILL BREAK THE DATA INTERFACE BETWEEN ; THE DCU APPLICATION AND DCU FIRMWARE ; SEE ABSOLUTE LOCALIZATION OF VARIABLES HERE ; IN 'DCU_DATA_INTERFACE.C' } RW_APPLICATION_IAP_BUFFER APPLICATION_IAP_BUFFER_ADDRESS 0x14CCCC { ; = address of APPLICATION_IAP_BUFFER_ADDRESS ; DO NOT PLACE ANYTHING IN THIS REGION - USED FOR IN APPLICATION PROGRAMMING } RW_FIRMWARE_IAP_BUFFER FIRMWARE_IAP_BUFFER_ADDRESS 0x26000 { ; = address of FIRMWARE_IAP_BUFFER_ADDRESS ; DO NOT PLACE ANYTHING IN THIS REGION - USED FOR IN APPLICATION PROGRAMMING } RW_XFREE2 +0 0x4FE1E0 { .ANY (+RW +ZI) } RW_XRAM_RESERVED 0xA1FFEC00 0x3F8 { } RW_XRAM_HRST HOST_RESET_COMMAND UNINIT { ;= address of HOST_RESET_COMMAND } RW_XRAM_USBCON IGNORE_RESET_USB_CONNECTIVITY UNINIT { ;= address of IGNORE_RESET_USB_CONNECTIVITY } } ; ******************************************************************** ; * ACCESS TO THE NOR FLASH IS SLOWER THAN TO LPC2478 INTERNAL FLASH * ; * DO NO MAP ANY TIME CRITICAL CODE HERE (COMPRESSOR CONTROL ETC.) * ; * USE RAM REGION "ER_NOR_FLASH_RAM_ZONE" TO MAP MODULES TO RAM FOR * ; * FAST EXECUTION * ; ******************************************************************** LR_IROM2 0x80000000 0x400000 { ; load region size_region FMMAPP2 0x80000000 0x00400000 { ; load address = execution address SYSTEM_ERROR_CODES.o APP_CENTAC_V4_FILE_INFO.o } ; ********************************************************************* ; * These modules are executed in RAM (but stored in the NOR flash) * ; * This code is copied into RAM by overriding the "__main" function * ; * so that the scatter loading process of the application can access * ; * the NOR flash. See "main.c" * ; ********************************************************************* ER_NOR_FLASH_RAM_ZONE 0xA1100000 0x400000 { APP_MACHINE_ID.o APP_SOFTWARE_UPDATE.o APP_IO_CFG.o APP_VAR_INIT.o SOFTWARE_EVENT.o APP_OPTION_MODULE.o APP_FEATURE_LST.o } }
First of all thanks for your clues!
I have one very formal but the more important question. I'm using KEIL MDK-ARM v4.11 evaluation software suite and I'm not sure if the uVISION(part of suite) can use scatter file. I'm asking because there (http://www.keil.com/demo/limits.asp) is write : "The linker does not accept scatter-loading description files for sophisticated memory layouts. The --scatter command line option is disabled"
It seems(from this limitation) that scatter file cannot be used.
However, when I'm looking into Options for target/ Linker tab/ Linker control string, there is wroted command --scatter with the name and path to the scatter file defined in the same window. I have done some attempts to change load region in auto-generated scatter file(rewrite LR_IROM1 start address) and download it into device. The result was that compiled code was stored on address specified in scatter file and not to address 0x0 in flash - I'm confused!
Has the evaluation version of MDK-ARM v4.11 limitation in using of scatter file or not?
Thanks for yout answer! Regards, Milan Muller
I wrote scatter file, which (I suppose) store minimal start code in the Sector 0 and the rest of code(execution program IAP_access.c) in RAM:
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x00000000 0x00020000 { ; load region size_region ER_IROM1 0x00000000 0x00020000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) } ; Do not map anything to the first 64 Bytes of RAM - interrupts vectors RW_IRAM1 0x10000040 0x00004000 { ; RW data .ANY (+RO) .ANY (+RW +ZI) } }
I configure uVISION Project/ Options for target as follows: -tab Asm : --Define: here I wrote macroes RAM_INTVEC REMAP RAM_MODE --all other parameters left blank (no checked checkbox, no additional parameters)
-tab Linker: --I used scatter file as shown above -- R/O Base : 0x10000000 -- R/W Base : 0x10000000 -- Other checkbox, except "Report 'might..,", are not checked -- no additional Misc controls parameters was write
-tab Utilities: --here is chosen J-Link as Targer driver for Programming --no check option "Update Target...", all others parameters in window are blanked ---button Settings: ----tab Flash Download: ----- RAM for Algorithm : Start 0x10000000 Size 0x4000 ----- Programming algorithm LPC17xx 128kB flash, address range 00000000H-0001FFFFH
I build project with these settings and download it into device by running command "Download". I assume that after downloads the program into device I will see programmed data (TEST string) on the specific sector (in my option - sector 0). But the result is, that no changes was made in flash region. I change the destination sector to the first sector, downloads program into device and also no TEST string was wrote to sector 1.
I'm in dark... Where lies the problem now? Is it needed to write something new commands to default startup_LPC17xx.s file(I don't change it)?
Thank you! Regards, Milan Muller
has somebody any solution for my problem (describe above)? I will be grateful for any clearly uVISION example, where scatter file will be used.
Please, help me! Regards,