我正在考虑在未来的设计中使用恩智浦LPC4330微控制器,我们需要的功能之一是能够使用引导加载程序在现场更新闪存。在过去,我使用NXP IAP命令完成了此操作,但由于4330使用SPIFI闪存,因此IAP不可用。
从我收集的内容来看,似乎我的引导加载程序应用程序需要从RAM执行,然后我可以使用恩智浦的SPIFI库写入闪存。我的问题是:
使用IAR Embedded Workbench,如何创建一个程序,它将从闪存启动,然后开始通过RAM运行,以便我可以写入SPIFI芯片?我看过下面的例子,但目前还不清楚如何将它移植到LPC4330。我相信我已将代码复制到启动代码的RAM中,但不确定如何将中断向量表复制到RAM或如何从RAM开始执行。 https://www.iar.com/support/tech-notes/general/execute-in-ram-after-copying-from-flashrom-v5.20-and-later/
答案 0 :(得分:0)
我经常做的是编写主程序并仅将其链接到ram,制作完整的二进制文件。然后我为flash写了一个瘦shell程序,其整个工作就是复制和跳转。通常是几行汇编加上主程序的二进制文件的内容(我倾向于编写一个adhoc主机util来将主程序转换成.word或一个单词数组,如果使用C链接flash程序的话。
我没有使用IDE,因此无法帮助您使用特定工具,我认为它们具有ide调用的命令行工具,您可以使用它们和makefile。
答案 1 :(得分:0)
我弄清楚这是怎么做到的。使用问题中的链接来了解一般过程。
这是启动文件应该是什么样子。闪存中有一个中断向量表,所有中断向量都指向虚拟处理程序。然后在后面有一个存储在RAM中的中断向量表。
;Interrupt vector table in flash, will never be used since VTOR
;(interrupt vector table)will be mapped to RAM on startup
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
EXTERN SystemInit
PUBLIC __vector_table_RAM
PUBLIC __vector_table_0x1c
PUBLIC __Vectors
PUBLIC __Vectors_End
PUBLIC __Vectors_Size
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler
DCD HardFault_Handler
DCD MemManage_Handler
DCD BusFault_Handler
DCD UsageFault_Handler
__vector_table_0x1c
DCD 0
DCD 0
DCD 0
DCD 0
DCD SVC_Handler
DCD DebugMon_Handler
DCD 0
DCD PendSV_Handler
DCD SysTick_Handler
; External Interrupts
DCD Dummy_Handler_ROM ; 16 D/A Converter
DCD Dummy_Handler_ROM ; 17 CortexM0 (LPC43XX ONLY)
DCD Dummy_Handler_ROM ; 18 General Purpose DMA
DCD 0 ; 19 Reserved
DCD Dummy_Handler_ROM ; 20 ORed flash bank A, flash bank B, EEPROM interrupts
DCD Dummy_Handler_ROM ; 21 Ethernet
DCD Dummy_Handler_ROM ; 22 SD/MMC
DCD Dummy_Handler_ROM ; 23 LCD
DCD Dummy_Handler_ROM ; 24 USB0
DCD Dummy_Handler_ROM ; 25 USB1
DCD Dummy_Handler_ROM ; 26 State Configurable Timer
DCD Dummy_Handler_ROM ; 27 Repetitive Interrupt Timer
DCD Dummy_Handler_ROM ; 28 Timer0
DCD Dummy_Handler_ROM ; 29 Timer1
DCD Dummy_Handler_ROM ; 30 Timer2
DCD Dummy_Handler_ROM ; 31 Timer3
DCD Dummy_Handler_ROM ; 32 Motor Control PWM
DCD Dummy_Handler_ROM ; 33 A/D Converter 0
DCD Dummy_Handler_ROM ; 34 I2C0
DCD Dummy_Handler_ROM ; 35 I2C1
DCD Dummy_Handler_ROM ; 36 SPI (LPC43XX ONLY)
DCD Dummy_Handler_ROM ; 37 A/D Converter 1
DCD Dummy_Handler_ROM ; 38 SSP0
DCD Dummy_Handler_ROM ; 39 SSP1
DCD Dummy_Handler_ROM ; 40 UART0
DCD Dummy_Handler_ROM ; 41 UART1
DCD Dummy_Handler_ROM ; 42 UART2
DCD Dummy_Handler_ROM ; 43 UART3
DCD Dummy_Handler_ROM ; 44 I2S0
DCD Dummy_Handler_ROM ; 45 I2S1
DCD Dummy_Handler_ROM ; 46 SPI Flash Interface
DCD Dummy_Handler_ROM ; 47 SGPIO (LPC43XX ONLY)
DCD Dummy_Handler_ROM ; 48 GPIO0
DCD Dummy_Handler_ROM ; 49 GPIO1
DCD Dummy_Handler_ROM ; 50 GPIO2
DCD Dummy_Handler_ROM ; 51 GPIO3
DCD Dummy_Handler_ROM ; 52 GPIO4
DCD Dummy_Handler_ROM ; 53 GPIO5
DCD Dummy_Handler_ROM ; 54 GPIO6
DCD Dummy_Handler_ROM ; 55 GPIO7
DCD Dummy_Handler_ROM ; 56 GINT0
DCD Dummy_Handler_ROM ; 57 GINT1
DCD Dummy_Handler_ROM ; 58 Event Router
DCD Dummy_Handler_ROM ; 59 C_CAN1
DCD 0
DCD Dummy_Handler_ROM ; 61 ADCHS combined interrupt
DCD Dummy_Handler_ROM ; 62 ATIMER
DCD Dummy_Handler_ROM ; 63 RTC
DCD 0
DCD Dummy_Handler_ROM ; 65 WDT
DCD Dummy_Handler_ROM ; 66 M0SUB TXEVT
DCD Dummy_Handler_ROM ; 67 C_CAN0
DCD Dummy_Handler_ROM ; 68 QEI
;Interrupt vector table which will be placed in RAM
SECTION .vectors_RAM:CODE:ROOT(2)
EXTERN __iar_program_start
EXTERN SystemInit
PUBLIC __vector_table
PUBLIC __vector_table_0x1c
PUBLIC __Vectors
PUBLIC __Vectors_End
PUBLIC __Vectors_Size
DATA
__vector_table_RAM
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler
DCD HardFault_Handler
DCD MemManage_Handler
DCD BusFault_Handler
DCD UsageFault_Handler
DCD 0
DCD 0
DCD 0
DCD 0
DCD SVC_Handler
DCD DebugMon_Handler
DCD 0
DCD PendSV_Handler
DCD SysTick_Handler
; External Interrupts
DCD DAC_IRQHandler ; 16 D/A Converter
DCD M0APP_IRQHandler ; 17 CortexM0 (LPC43XX ONLY)
DCD DMA_IRQHandler ; 18 General Purpose DMA
DCD 0 ; 19 Reserved
DCD FLASH_EEPROM_IRQHandler ; 20 ORed flash bank A, flash bank B, EEPROM interrupts
DCD ETH_IRQHandler ; 21 Ethernet
DCD SDIO_IRQHandler ; 22 SD/MMC
DCD LCD_IRQHandler ; 23 LCD
DCD USB0_IRQHandler ; 24 USB0
DCD USB1_IRQHandler ; 25 USB1
DCD SCT_IRQHandler ; 26 State Configurable Timer
DCD RIT_IRQHandler ; 27 Repetitive Interrupt Timer
DCD TIMER0_IRQHandler ; 28 Timer0
DCD TIMER1_IRQHandler ; 29 Timer1
DCD TIMER2_IRQHandler ; 30 Timer2
DCD TIMER3_IRQHandler ; 31 Timer3
DCD MCPWM_IRQHandler ; 32 Motor Control PWM
DCD ADC0_IRQHandler ; 33 A/D Converter 0
DCD I2C0_IRQHandler ; 34 I2C0
DCD I2C1_IRQHandler ; 35 I2C1
DCD SPI_IRQHandler ; 36 SPI (LPC43XX ONLY)
DCD ADC1_IRQHandler ; 37 A/D Converter 1
DCD SSP0_IRQHandler ; 38 SSP0
DCD SSP1_IRQHandler ; 39 SSP1
DCD UART0_IRQHandler ; 40 UART0
DCD UART1_IRQHandler ; 41 UART1
DCD UART2_IRQHandler ; 42 UART2
DCD UART3_IRQHandler ; 43 UART3
DCD I2S0_IRQHandler ; 44 I2S0
DCD I2S1_IRQHandler ; 45 I2S1
DCD SPIFI_IRQHandler ; 46 SPI Flash Interface
DCD SGPIO_IRQHandler ; 47 SGPIO (LPC43XX ONLY)
DCD GPIO0_IRQHandler ; 48 GPIO0
DCD GPIO1_IRQHandler ; 49 GPIO1
DCD GPIO2_IRQHandler ; 50 GPIO2
DCD GPIO3_IRQHandler ; 51 GPIO3
DCD GPIO4_IRQHandler ; 52 GPIO4
DCD GPIO5_IRQHandler ; 53 GPIO5
DCD GPIO6_IRQHandler ; 54 GPIO6
DCD GPIO7_IRQHandler ; 55 GPIO7
DCD GINT0_IRQHandler ; 56 GINT0
DCD GINT1_IRQHandler ; 57 GINT1
DCD EVRT_IRQHandler ; 58 Event Router
DCD CAN1_IRQHandler ; 59 C_CAN1
DCD 0
DCD ADCHS_IRQHandler ; 61 ADCHS combined interrupt
DCD ATIMER_IRQHandler ; 62 ATIMER
DCD RTC_IRQHandler ; 63 RTC
DCD 0
DCD WDT_IRQHandler ; 65 WDT
DCD M0SUB_IRQHandler ; 66 M0SUB TXEVT
DCD CAN0_IRQHandler ; 67 C_CAN0
DCD QEI_IRQHandler ; 68 QEI
__Vectors_End
__Vectors EQU __vector_table
__Vectors_Size EQU __Vectors_End - __Vectors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
PUBWEAK NMI_Handler
PUBWEAK HardFault_Handler
PUBWEAK MemManage_Handler
PUBWEAK BusFault_Handler
PUBWEAK UsageFault_Handler
PUBWEAK SVC_Handler
PUBWEAK DebugMon_Handler
PUBWEAK PendSV_Handler
PUBWEAK SysTick_Handler
PUBWEAK DAC_IRQHandler
PUBWEAK M0APP_IRQHandler
PUBWEAK DMA_IRQHandler
PUBWEAK FLASH_EEPROM_IRQHandler
PUBWEAK ETH_IRQHandler
PUBWEAK SDIO_IRQHandler
PUBWEAK LCD_IRQHandler
PUBWEAK USB0_IRQHandler
PUBWEAK USB1_IRQHandler
PUBWEAK SCT_IRQHandler
PUBWEAK RIT_IRQHandler
PUBWEAK TIMER0_IRQHandler
PUBWEAK TIMER1_IRQHandler
PUBWEAK TIMER2_IRQHandler
PUBWEAK TIMER3_IRQHandler
PUBWEAK MCPWM_IRQHandler
PUBWEAK ADC0_IRQHandler
PUBWEAK I2C0_IRQHandler
PUBWEAK I2C1_IRQHandler
PUBWEAK SPI_IRQHandler
PUBWEAK ADC1_IRQHandler
PUBWEAK SSP0_IRQHandler
PUBWEAK SSP1_IRQHandler
PUBWEAK UART0_IRQHandler
PUBWEAK UART1_IRQHandler
PUBWEAK UART2_IRQHandler
PUBWEAK UART3_IRQHandler
PUBWEAK I2S0_IRQHandler
PUBWEAK I2S1_IRQHandler
PUBWEAK SPIFI_IRQHandler
PUBWEAK SGPIO_IRQHandler
PUBWEAK GPIO0_IRQHandler
PUBWEAK GPIO1_IRQHandler
PUBWEAK GPIO2_IRQHandler
PUBWEAK GPIO3_IRQHandler
PUBWEAK GPIO4_IRQHandler
PUBWEAK GPIO5_IRQHandler
PUBWEAK GPIO6_IRQHandler
PUBWEAK GPIO7_IRQHandler
PUBWEAK GINT0_IRQHandler
PUBWEAK GINT1_IRQHandler
PUBWEAK EVRT_IRQHandler
PUBWEAK CAN1_IRQHandler
PUBWEAK ADCHS_IRQHandler
PUBWEAK ATIMER_IRQHandler
PUBWEAK RTC_IRQHandler
PUBWEAK WDT_IRQHandler
PUBWEAK M0SUB_IRQHandler
PUBWEAK CAN0_IRQHandler
PUBWEAK QEI_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler
B NMI_Handler
SVC_Handler
B SVC_Handler
DebugMon_Handler
B DebugMon_Handler
PendSV_Handler
B PendSV_Handler
SysTick_Handler
B SysTick_Handler
HardFault_Handler
B HardFault_Handler
MemManage_Handler
B MemManage_Handler
BusFault_Handler
B BusFault_Handler
UsageFault_Handler
DAC_IRQHandler
M0APP_IRQHandler
DMA_IRQHandler
FLASH_EEPROM_IRQHandler
ETH_IRQHandler
SDIO_IRQHandler
LCD_IRQHandler
USB0_IRQHandler
USB1_IRQHandler
SCT_IRQHandler
RIT_IRQHandler
TIMER0_IRQHandler
TIMER1_IRQHandler
TIMER2_IRQHandler
TIMER3_IRQHandler
MCPWM_IRQHandler
ADC0_IRQHandler
I2C0_IRQHandler
I2C1_IRQHandler
SPI_IRQHandler
ADC1_IRQHandler
SSP0_IRQHandler
SSP1_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
UART3_IRQHandler
I2S0_IRQHandler
I2S1_IRQHandler
SPIFI_IRQHandler
SGPIO_IRQHandler
GPIO0_IRQHandler
GPIO1_IRQHandler
GPIO2_IRQHandler
GPIO3_IRQHandler
GPIO4_IRQHandler
GPIO5_IRQHandler
GPIO6_IRQHandler
GPIO7_IRQHandler
GINT0_IRQHandler
GINT1_IRQHandler
EVRT_IRQHandler
CAN1_IRQHandler
ADCHS_IRQHandler
ATIMER_IRQHandler
RTC_IRQHandler
WDT_IRQHandler
CAN0_IRQHandler
M0SUB_IRQHandler
QEI_IRQHandler
Default_IRQHandler
B Default_IRQHandler
/* CRP Section - not needed for flashless devices */
;;; SECTION .crp:CODE:ROOT(2)
;;; DATA
/* Code Read Protection
NO_ISP 0x4E697370 - Prevents sampling of pin PIO0_1 for entering ISP mode
CRP1 0x12345678 - Write to RAM command cannot access RAM below 0x10000300.
- Copy RAM to flash command can not write to Sector 0.
- Erase command can erase Sector 0 only when all sectors
are selected for erase.
- Compare command is disabled.
- Read Memory command is disabled.
CRP2 0x87654321 - Read Memory is disabled.
- Write to RAM is disabled.
- "Go" command is disabled.
- Copy RAM to flash is disabled.
- Compare is disabled.
CRP3 0x43218765 - Access to chip via the SWD pins is disabled. ISP entry
by pulling PIO0_1 LOW is disabled if a valid user code is
present in flash sector 0.
Caution: If CRP3 is selected, no future factory testing can be
performed on the device.
*/
;;; DCD 0xFFFFFFFF
;;;
; --------------------
; Dummy handler placed in ROM
Dummy_Handler_ROM
b Dummy_Handler_ROM
END
然后需要编辑链接器文件(.icf)以将所有只读项目放在ram(readwrite部分)中,如下所示。重要的一行是#34;通过复制"
进行初始化/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x14000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x14000140;
define symbol __ICFEDIT_region_ROM_end__ = 0x140FFFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x10000140;
define symbol __ICFEDIT_region_RAM_end__ = 0x10007FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define symbol RAM_vectors_start = 0x10000000;
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readonly, readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { section .intvec };
place at address mem:RAM_vectors_start { section .vectors_RAM };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
之后,剩下要做的就是将中断向量表从ROM重映射到RAM。在启用任何中断之前,这应该是应用程序执行的第一件事。代码应如下所示:
VTOR = (unsigned int) 0x10000000;