LPC2148 IAP programming program

Publisher:敬亭山人Latest update time:2020-03-04 Source: eefocusKeywords:LPC2148  IAP Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1 Introduction

Following the previous ADS simple program compilation analysis, we obtained a relatively independent compiled program creation method that can run on ucos ii. The following is to study how to update the user program to the high-level flash (the bottom level is the ucos ii program).


2 Code Description

Refer to the LPC2148 data sheet, LPC2148 supports IAP mode, that is, user programming mode. Refer to Zhou Ligong's AN070701, iap-yingyong.pdf and combine with the LPC21xx manual (Zhou Ligong's manual corresponds to LPC2300), and make your own programming function. The following is a detailed description:


First, referring to the data, the chip can call the IAP burning function by writing the corresponding command to the address 0x7FFFFFF1. The default process of powering on the chip to move the program code is not discussed here. Zhou Ligong's data explains how ARM switches to the THUMB instruction set working state:


The IAP program is Thumb code, located at address 0x7FFF FFF0. The instruction to implement state transition in the ARM system is "BX Addr". The lowest bit (bit0) of the target address Addr is only used to determine the final state. The actual "destination address = Addr & 0xFFFF FFFE".


In fact, the BX assembly command has been explained in the previous ADS simple program compilation analysis, that is, if the lowest bit of the jump instruction is 1, it will enter THUMB mode. Here, the command address is set to 0x7FFFFFF1 to enter THUMB mode. In fact, it jumps to 0x7FFFFFF0.


Here you need to set the ARM/Thumb Interworking under the ATPCS tab in the ARM C Compiler of ADS, otherwise the state cannot be switched and IAP cannot be executed.


There is such a macro definition in ucos ii:


#define iap_entry(a, b)             ((void (*)())(0x7ffffff1))(a, b)

1

That is, the entry point for calling IAP in the form of a function.


The user manual of LPC21XXX states that when jumping to 0x7FFFFFF1, r0 stores the address of the command array and r1 stores the address of the return value array. In C language, it is agreed that the first parameter of a function call is stored in r0 and the second parameter is stored in r1, so an IAP call can be implemented in the following way:


static unsigned long command[5], result[3];

unsigned long IAP_PREPARE(unsigned long start, unsigned long end)

{

    OS_ENTER_CRITICAL();

    command[0] = IAP_PREPARE_SECTOR;

    command[1] = start;

    command[2] = end;

    iap_entry(command, result);

    OS_EXIT_CRITICAL();

    return result[0];

}


In this example, the command array is the command array passed to r0, and r1 is the command array that receives the results. In C language, the array name is the address. OS_ENTER_CRITICAL() is to let ucos ii disable interrupts, because it cannot be interrupted during the burning process, otherwise an error will occur. If you do not use ucos, you can do without these commands. In the command array, the corresponding functions of the corresponding array members are agreed upon. For details, please refer to the LPC21XXX user manual.


Before burning or erasing a sector, you must use a command to prepare the corresponding sector. That is, the code of the above program. However, the flash sectors of ARM are not of equal length. Referring to the data sheet, the following code can return the corresponding sector number through the address. Other chips can also modify it in the same way:


/*********************************

** Function name: get_sector

** Function: Calculate the sector number where the address is located.

** Entry parameter: addr address

** Export parameter: sector sector number

**********************************/

static int get_sector(unsigned int addr)

{

    if(addr <= 0x000fff) return 0;

    if(addr <= 0x001fff) return 1;

    if(addr <= 0x002fff) return 2;

    if(addr <= 0x003fff) return 3;

    if(addr <= 0x004fff) return 4;

    if(addr <= 0x005fff) return 5;

    if(addr <= 0x006fff) return 6;

    if(addr <= 0x007fff) return 7;

    if(addr <= 0x00ffff) return 8;

    if(addr <= 0x017fff) return 9;

    if(addr <= 0x01ffff) return 10;

    if(addr <= 0x027fff) return 11;

    if(addr <= 0x02ffff) return 12;

    if(addr <= 0x037fff) return 13;

    if(addr <= 0x03ffff) return 14;

    if(addr <= 0x047fff) return 15;

    if(addr <= 0x04ffff) return 16;

    if(addr <= 0x057fff) return 17;

    if(addr <= 0x05ffff) return 18;

    if(addr <= 0x067fff) return 19;

    if(addr <= 0x06ffff) return 20;

    if(addr <= 0x077fff) return 21;

    if(addr <= 0x078fff) return 22;

    if(addr <= 0x079fff) return 23;

    if(addr <= 0x07afff) return 24;

    if(addr <= 0x07bfff) return 25;

    if(addr <= 0x07cfff) return 26;

    return 0xff;

}


This design implements three functions of IAP, namely prepare sector, erase sector, and write sector. The following are the descriptions:


2.1 Prepare sector function:

/******************************************************************************************

** Function name: IAP_PREPARE

** Function: IAP operation buffer selection, code is 50.

** Entry parameter: start starting sector

** end end sector

** Export parameter: IAP operation status code

** IAP return value (result buffer)

******************************************************************************************/

unsigned long IAP_PREPARE(unsigned long start, unsigned long end)

{

    OS_ENTER_CRITICAL();

    command[0] = IAP_PREPARE_SECTOR;

    command[1] = start;

    command[2] = end;

    iap_entry(command, result);

    OS_EXIT_CRITICAL();

    return result[0];

}


If the returned code is not 0, it indicates an error. For the specific meaning, please refer to the data manual.


2.2 Erase sector function:

/******************************************************************************************

** Function name: EraseSector

** Function: Erase sector, command code 52.

** Entry parameter: start starting sector

** end end sector

** Export parameter: IAP operation status code

** IAP return value (result buffer)

******************************************************************************************/

unsigned long IAP_ERASER(unsigned long start,unsigned long end)

{

    OS_ENTER_CRITICAL();

    command[0] = IAP_ERASE_SECTOR; // Set command word

    command[1] = start; // Set parameters

    command[2] = end;

    command[3] = IAP_FCCLK;

    iap_entry(command, result); // Call IAP service program

    OS_EXIT_CRITICAL();

    return(result[0]); // Return status code

}


The FCCLK here needs to be modified according to the chip settings, and the unit is KHz.


2.3 Write sector function

/******************************************************************************************

** Function name: IAP_COPY

** Function: Copy RAM data to FLASH, command code 51.

** Entry parameters: dst destination address, i.e. FLASH start address, with 256 bytes as the boundary

** src source address, that is, RAM address, the address must be word-aligned

** no The number of bytes to copy is 256/512/1024/4096

** Export parameter: IAP operation status code

** IAP return value (result buffer)

******************************************************************************************/


unsigned long IAP_COPY(unsigned long dst, unsigned long src, unsigned long no)

{

    OS_ENTER_CRITICAL();

    command[0] = IAP_COPY_RAM_TO_FLASH;

    command[1] = dst;

    command[2] = src;

    command[3] = no;

    command[4] = IAP_FCCLK;

    iap_entry(command, result);

    OS_EXIT_CRITICAL();

    return(result[0]); // Return status code

}


The FCCLK here needs to be modified according to the chip settings, and the unit is KHz. 

In addition, it should be noted that the function of writing sectors does not write the entire sector at once, but can be repeatedly written to multiple locations in segments, such as writing the first 256 bytes for the first time, and then continuing to write 1024 bytes again. It only needs to comply with the address alignment requirements and the number of words written to be a multiple of 256. In addition, it is stated in the reference that the content to be burned in the memory must be in the on-chip RAM. In my application, all variable definitions are in RAM without any problems. If there is off-chip memory or other on-chip space such as the USB stack is used, this needs to be noted.


3 Appendix

Below is the complete IAP function file:


#define iap_entry(a, b)             ((void (*)())(0x7ffffff1))(a, b)

#define IAP_PREPARE_SECTOR      50

#define IAP_COPY_RAM_TO_FLASH   51

#define IAP_ERASE_SECTOR        52

#define IAP_FCCLK Fcclk / 1000; //(fill in your own main frequency)

/******************************************************************************************

** Function name: IAP_PREPARE

** Function: IAP operation buffer selection, code is 50.

** Entry parameter: start starting sector

** end end sector

** Export parameter: IAP operation status code

** IAP return value (result buffer)

******************************************************************************************/

static unsigned long command[5], result[3];


unsigned long IAP_PREPARE(unsigned long start, unsigned long end)

{

    OS_ENTER_CRITICAL();

    command[0] = IAP_PREPARE_SECTOR;

    command[1] = start;

    command[2] = end;

    iap_entry(command, result);

    OS_EXIT_CRITICAL();

    return result[0];

}


/******************************************************************************************

** Function name: EraseSector

** Function: Erase sector, command code 52.

** Entry parameter: start starting sector

** end end sector

** Export parameter: IAP operation status code

** IAP return value (result buffer)

******************************************************************************************/

unsigned long IAP_ERASER(unsigned long start,unsigned long end)

{

    OS_ENTER_CRITICAL();

    command[0] = IAP_ERASE_SECTOR; // Set command word

    command[1] = start; // Set parameters

    command[2] = end;

    command[3] = IAP_FCCLK;

    iap_entry(command, result); // Call IAP service program

    OS_EXIT_CRITICAL();

    return(result[0]); // Return status code

}



/******************************************************************************************

[1] [2]
Keywords:LPC2148  IAP Reference address:LPC2148 IAP programming program

Previous article:LPC2138 startup.s
Next article:A brief analysis of embedded MCU hardware design solutions

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号