lpc1788 如何在sdram调试程序
用stm32的时候,习惯在sram上调试程序,省去flash下载的麻烦现在用lpc1788后,也打算在sdram上调试程序了,结果好几天了还是没有搞定如何在sdram调试程序
flash上运行时,sdram可以正常运行,但是现在用sdram调试,第一条指令初始化是正常的,但是运行就跑飞,出现错误:
**JLink Warning: T-bit of XPSR is 0 but should be 1. Changed to 1
我用的调试配置文件如下,是从程序上的时钟和sdram配置改的,也参考了网上的意见,但是网上也没有看到有人在sdram上调试成功的
lpc1788_debug_sdram.ini
/******************************************************************
* File: LPC43XX_E_SDRAM_KEIL_DEBUG.ini
*
* Date: October 2012 Author: NXP
*
* KEIL µVision INI file for initialisation of LPC43xx when debugging code
* running from external SDRAM @ 0x28000000. The SDRAM must be initialized
* before the debugger can load the image to it.
* This use case is just for debugging, in a real application the code
* which goes into SDRAM will come from an external flash and the startup
* code needs to initialize the SDRAM and relocate the image.
*
* This script initializes the SDRAM on the KEIL MCB4300 board.
*
******************************************************************/
FUNC void Setup (unsigned int region) {
region &= 0xFF000000;
//_WDWORD(0x40043100, 0); // Set the shadow pointer to zero (can't map SDRAM to 0)
SP = _RDWORD(region); // Setup Stack Pointer
PC = _RDWORD(region + 4); // Setup Program Counter
_WDWORD(0xE000ED08, region); // Set the vector table offset
}
FUNC void Clock_Setup (void) {
_WDWORD(0x400FC1A0, 0x00000021); // Enable the crystal oscillator
while((_RDWORD(0x400FC1A0) & (1<<6)) == 0); // delay wait for oscillator to start
_WDWORD(0x400FC10C, 0x00000001); // select crystal oscillator
_WDWORD(0x400FC084, 0x00000009); // Configure PLL0 to multiply x 10 for 120 MHz operation from 12 MHz crystal
_WDWORD(0x400FC080, 0x00000001); // PLL0 Enable
_WDWORD(0x400FC08C, 0x000000AA); //
_WDWORD(0x400FC08C, 0x00000055); //
while((_RDWORD(0x400FC088) & (1<<10)) == 0); // Wait for PLOCK0
_WDWORD(0x400FC104, 0x00000101); //PLL0 not divide as the cpuclock
_WDWORD(0x400FC100, 0x00000001); //cpuclock / 2 as the emcclock
_WDWORD(0x400FC0C4, 0x00000800); //emcclock enable
_WDWORD(0x400FC1B0, 0x00000003); //120M support
}
FUNC void LPC1788_setupEmc (void)
{
// Setup pins for external data/address bus
_WDWORD(0x4002C180, (1 << 9)|1); // D0,P3.0
_WDWORD(0x4002C184, (1 << 9)|1); // D1,P3.1
_WDWORD(0x4002C188, (1 << 9)|1); // D2,P3.2
_WDWORD(0x4002C18C, (1 << 9)|1); // D3,P3.3
_WDWORD(0x4002C190, (1 << 9)|1); // D4,P3.4
_WDWORD(0x4002C194, (1 << 9)|1); // D5,P3.5
_WDWORD(0x4002C198, (1 << 9)|1); // D6,P3.6
_WDWORD(0x4002C19C, (1 << 9)|1); // D7,P3.7
_WDWORD(0x4002C1A0, (1 << 9)|1); // D8,P3.8
_WDWORD(0x4002C1A4, (1 << 9)|1); // D9,P3.9
_WDWORD(0x4002C1A8, (1 << 9)|1); // D10, P3.10
_WDWORD(0x4002C1AC, (1 << 9)|1); // D11, P3.11
_WDWORD(0x4002C1B0, (1 << 9)|1); // D12, P3.12
_WDWORD(0x4002C1B4, (1 << 9)|1); // D13, P3.13
_WDWORD(0x4002C1B8, (1 << 9)|1); // D14, P3.14
_WDWORD(0x4002C1BC, (1 << 9)|1); // D15, P3.15
_WDWORD(0x4002C200, (1 << 9)|1); // A0,P4.0
_WDWORD(0x4002C204, (1 << 9)|1); // A1,P4.1
_WDWORD(0x4002C208, (1 << 9)|1); // A2,P4.2
_WDWORD(0x4002C20C, (1 << 9)|1); // A3,P4.3
_WDWORD(0x4002C210, (1 << 9)|1); // A4,P4.4
_WDWORD(0x4002C214, (1 << 9)|1); // A5,P4.5
_WDWORD(0x4002C218, (1 << 9)|1); // A6,P4.6
_WDWORD(0x4002C21C, (1 << 9)|1); // A7,P4.7
_WDWORD(0x4002C220, (1 << 9)|1); // A8,P4.8
_WDWORD(0x4002C224, (1 << 9)|1); // A9,P4.9
_WDWORD(0x4002C228, (1 << 9)|1); // A10, P4.10
_WDWORD(0x4002C22C, (1 << 9)|1); // A11, P4.11
_WDWORD(0x4002C230, (1 << 9)|1); // A12, P4.12
_WDWORD(0x4002C234, (1 << 9)|1); // A13, P4.13
_WDWORD(0x4002C238, (1 << 9)|1); // A14, P4.14
_WDWORD(0x4002C264, (1 << 9)|1); // WEN, P4.25
_WDWORD(0x4002C140, (1 << 9)|1); // CAS, P2.16
_WDWORD(0x4002C144, (1 << 9)|1); // RAS, P2.17
_WDWORD(0x4002C148, (1 << 9)|1); // CLK, P2.18
_WDWORD(0x4002C150, (1 << 9)|1); // DYCS,P2.20
_WDWORD(0x4002C160, (1 << 9)|1); // CKE, P2.24
_WDWORD(0x4002C170, (1 << 9)|1); // DMQ0,P2.28
_WDWORD(0x4002C174, (1 << 9)|1); // DMQ1,P2.29
_WDWORD(0x400FC1DC, 0x00001010); // (0x1010+1)* 250ps
// Initialize EMC
_WDWORD(0x2009C000, 0x00000001); // CONTROL=1 = Enable EMC
_WDWORD(0x2009C008, 0x00000000); // CONFIG=0
_WDWORD(0x2009C100, 0x00000680); // DYNAMICCONFIG0
_WDWORD(0x2009C104, 0x00000202); // DYNAMICRASCAS0
_WDWORD(0x2009C028, 0x00000001); // DYNAMICREADCONFIG
_WDWORD(0x2009C030, 0x00000001); // DYNAMICRP
_WDWORD(0x2009C034, 0x00000003); // DYNAMICRAS
_WDWORD(0x2009C038, 0x00000000); // DYNAMICREX
_WDWORD(0x2009C03C, 0x00000001); // DYNAMICAPR
_WDWORD(0x2009C040, 0x00000005); // DYNAMICDAL
_WDWORD(0x2009C044, 0x00000001); // DYNAMICWR
_WDWORD(0x2009C048, 0x00000004); // DYNAMICRC
_WDWORD(0x2009C04C, 0x00000004); // DYNAMICRFC
_WDWORD(0x2009C050, 0x00000005); // DYNAMICXSR
_WDWORD(0x2009C054, 0x00000001); // DYNAMICRRD
_WDWORD(0x2009C058, 0x00000001); // DYNAMICMRD
_WDWORD(0x2000C020, 0x00000183); // DYNAMICCONTROL - NOP
_WDWORD(0x2000C020, 0x00000103); // DYNAMICCONTROL - PRECHARGE_ALL
_WDWORD(0x2000C024, 0x0000001D); // DYNAMICREFRESH = 1D
_WDWORD(0x2009C020, 0x00000083); // DYNAMICCONTROL - MODE
_RDWORD(0xA0000000 | (0x23<<12));// Write 16-bit SDRAM Mode register burst 8- this is a read as requested by the SDRAM spec
_WDWORD(0x2009C020, 0x00000000); // DYNAMICCONTROL - NORMAL
_WDWORD(0x2009C100, 0x00080680); // DYNAMICCONFIG0
}
FUNC void mpu_region_setup(unsigned int a_addr,
unsigned int a_region,
unsigned int a_size,
unsigned int a_ap,
unsigned int a_mem_attrib,
unsigned int a_srd,
unsigned int a_XN,
unsigned int a_enable)
{
// Setup procedure for each region
unsigned int temp;
temp = (a_addr & 0xFFFFFFE0) | (a_region & 0xF) | 0x10 ;
_WDWORD(0xE000ED9C, temp); // RBAR
temp = ((a_XN & 0x1)<<28) | ((a_ap & 0x7)<<24) | ((a_mem_attrib & 0x3F)<<16) | ((a_srd&0xFF)<<8) | ((a_size & 0x1F)<<1)| (a_enable & 0x1) ;
// temp = ((a_ap & 0x7)<<24) | ((a_size & 0x1F)<<1)| (a_enable & 0x1) ;
_WDWORD(0xE000EDA0, temp); // RASR
_WDWORD(0xE000ED94, 1); // MPU enable
}
Clock_Setup();
//# Initialize the external memory interface. If booting in EMC mode,
//# the bootloader initializes the EMC, but enables only A.
LPC1788_setupEmc();
//# The LOAD command downloads the image to the memory region specified by the linker script as load region.
LOAD %L INCREMENTAL
//mpu_region_setup( 0xA0000000,
// 7, // always reprogramming MPU region 7
// 0x18,//32MB
// 3, // full access
// 0, // strongly ordered, shareable
// 0, // subregion disabled
// 0, // allow instruction execution
// 1) ; // region enabled
mpu_region_setup( 0xA0000000,0,0x18,3,7,0,0,1);
//# Get ready to execute image in the given memory region
Setup(0xA0000000);
这个是分散加载的段设置 方法是思路是对的。
1. 检查SDRAM是否可以正常读写
2. 检查MPU配置是允许SDRAM执行
3. 下载费不了几个时间,也就调些硬件驱动时用得多些,没必要折腾自己不熟悉的。 需要配置MPU myxiaonia 发表于 2015-9-22 15:32
这个是分散加载的段设置
记得论坛上有的,但是现在不怎么用1788了,忘记在哪了 LQS1200 发表于 2015-9-22 20:44
记得论坛上有的,但是现在不怎么用1788了,忘记在哪了
你有没有使用过调试程序啊,我找遍了各个角落,,,有人提出过相同的需求,却没有看到过完整确切的答案 myxiaonia 发表于 2015-9-22 21:19
你有没有使用过调试程序啊,我找遍了各个角落,,,有人提出过相同的需求,却没有看到过完整确切的答案 ...
明天问下先,不知道还有没有 本帖最后由 myxiaonia 于 2015-9-22 22:38 编辑
在程序装载后,更新sp,pc等我发现xpsr的t位一直为0,而cm3必须为1(thumb模式),我强制设置为1还是为0
就是这个罪魁祸首,奇怪的是寄存器窗口xpsr显示值是0x81000000,这里t位是1,展开后t位却为0
贴两张截图
原来是vtor设置最多0-28位,并且29位还是code或者ram指示器 这样的话设置为0xa0000000效果成了0x20000000 工程还没找到,参考下http://blog.csdn.net/waitig1992/article/details/38561867 本帖最后由 myxiaonia 于 2015-9-23 10:46 编辑
LQS1200 发表于 2015-9-23 08:46
工程还没找到,参考下http://blog.csdn.net/waitig1992/article/details/38561867
这是你的博客吗我看过啊嘿嘿但是怎么忽略了在sdram调试成功的经验,估计是外部ram没有写明是sdram就晃眼了。。。回家测试下看看
我之前写外部字库到sst39v1602也是用的这个博客上的norflash配置ini,当时这个很快就搞成功了,用上这个配置文件立马ok myxiaonia 发表于 2015-9-23 10:42
这是你的博客吗我看过啊嘿嘿但是怎么忽略了在sdram调试成功的经验,估计是外部ram没有写明是sdram就 ...
不是,没那么高手 终于搞定了,贴出正确的配置文件,后来者不用再走弯路,感谢楼上兄弟贴出的博客地址,让我增强信心,因为之前在网上没有找到在sdram调试程序的先例,方向不明朗信心很受打击
基本配置过程就是那样,问题出在两处:emc操作寄存器,DYNAMICCONTROL 地址写错了,时钟配置寄存器里,没有使能外设时钟和gpio时钟,好低级的错误。。。。越是低级错误排错越是匪夷所思,血的教训。。。
/******************************************************************
* File: LPC43XX_E_SDRAM_KEIL_DEBUG.ini
*
* Date: October 2012 Author: NXP
*
* KEIL µVision INI file for initialisation of LPC43xx when debugging code
* running from external SDRAM @ 0x28000000. The SDRAM must be initialized
* before the debugger can load the image to it.
* This use case is just for debugging, in a real application the code
* which goes into SDRAM will come from an external flash and the startup
* code needs to initialize the SDRAM and relocate the image.
*
* This script initializes the SDRAM on the KEIL MCB4300 board.
*
******************************************************************/
FUNC void Setup (unsigned int region) {
region &= 0xFF000000;
// _WDWORD(0x40043100, 0); // Set the shadow pointer to zero (can't map SDRAM to 0)
SP = _RDWORD(region); // Setup Stack Pointer
PC = _RDWORD(region + 4); // Setup Program Counter
_WDWORD(0xE000ED08, region); // Set the vector table offset
}
FUNC void Clock_Setup (void) {
_WDWORD(0x400FC1A0, 0x00000021); // Enable the crystal oscillator
// while((_RDWORD(0x400FC1A0) & (1<<6)) == 0); // delay wait for oscillator to start
_sleep_ (100); // Wait for main oscillator to stabilize _WDWORD(0x400FC10C, 0x00000001); // select crystal oscillator
_WDWORD(0x400FC084, 0x00000009); // Configure PLL0 to multiply x 10 for 120 MHz operation from 12 MHz crystal
_WDWORD(0x400FC080, 0x00000001); // PLL0 Enable
_WDWORD(0x400FC08C, 0x000000AA); //
_WDWORD(0x400FC08C, 0x00000055); //
// while((_RDWORD(0x400FC088) & (1<<10)) == 0); // Wait for PLOCK0
_sleep_ (100); // Wait for PLOCK0
_WDWORD(0x400FC104, 0x00000101); //PLL0 not divide as the cpuclock
_WDWORD(0x400FC100, 0x00000001); //cpuclock / 2 as the emcclock
_WDWORD(0x400FC18A, 0x00000002); //cpuclock / 2 as the pclock
_WDWORD(0x400FC0C4, 0x00008800); //emcclock gpio enable
_WDWORD(0x400FC1B0, 0x00000003); //120M support
}
FUNC void LPC1788_setupEmc (void)
{
// Setup pins for external data/address bus
_WDWORD(0x4002C180, (1 << 9)|1); // D0,P3.0
_WDWORD(0x4002C184, (1 << 9)|1); // D1,P3.1
_WDWORD(0x4002C188, (1 << 9)|1); // D2,P3.2
_WDWORD(0x4002C18C, (1 << 9)|1); // D3,P3.3
_WDWORD(0x4002C190, (1 << 9)|1); // D4,P3.4
_WDWORD(0x4002C194, (1 << 9)|1); // D5,P3.5
_WDWORD(0x4002C198, (1 << 9)|1); // D6,P3.6
_WDWORD(0x4002C19C, (1 << 9)|1); // D7,P3.7
_WDWORD(0x4002C1A0, (1 << 9)|1); // D8,P3.8
_WDWORD(0x4002C1A4, (1 << 9)|1); // D9,P3.9
_WDWORD(0x4002C1A8, (1 << 9)|1); // D10, P3.10
_WDWORD(0x4002C1AC, (1 << 9)|1); // D11, P3.11
_WDWORD(0x4002C1B0, (1 << 9)|1); // D12, P3.12
_WDWORD(0x4002C1B4, (1 << 9)|1); // D13, P3.13
_WDWORD(0x4002C1B8, (1 << 9)|1); // D14, P3.14
_WDWORD(0x4002C1BC, (1 << 9)|1); // D15, P3.15
_WDWORD(0x4002C200, (1 << 9)|1); // A0,P4.0
_WDWORD(0x4002C204, (1 << 9)|1); // A1,P4.1
_WDWORD(0x4002C208, (1 << 9)|1); // A2,P4.2
_WDWORD(0x4002C20C, (1 << 9)|1); // A3,P4.3
_WDWORD(0x4002C210, (1 << 9)|1); // A4,P4.4
_WDWORD(0x4002C214, (1 << 9)|1); // A5,P4.5
_WDWORD(0x4002C218, (1 << 9)|1); // A6,P4.6
_WDWORD(0x4002C21C, (1 << 9)|1); // A7,P4.7
_WDWORD(0x4002C220, (1 << 9)|1); // A8,P4.8
_WDWORD(0x4002C224, (1 << 9)|1); // A9,P4.9
_WDWORD(0x4002C228, (1 << 9)|1); // A10, P4.10
_WDWORD(0x4002C22C, (1 << 9)|1); // A11, P4.11
_WDWORD(0x4002C230, (1 << 9)|1); // A12, P4.12
_WDWORD(0x4002C234, (1 << 9)|1); // A13, P4.13
_WDWORD(0x4002C238, (1 << 9)|1); // A14, P4.14
_WDWORD(0x4002C264, (1 << 9)|1); // WEN, P4.25
_WDWORD(0x4002C140, (1 << 9)|1); // CAS, P2.16
_WDWORD(0x4002C144, (1 << 9)|1); // RAS, P2.17
_WDWORD(0x4002C148, (1 << 9)|1); // CLK, P2.18
_WDWORD(0x4002C150, (1 << 9)|1); // DYCS,P2.20
_WDWORD(0x4002C160, (1 << 9)|1); // CKE, P2.24
_WDWORD(0x4002C170, (1 << 9)|1); // DMQ0,P2.28
_WDWORD(0x4002C174, (1 << 9)|1); // DMQ1,P2.29
_WDWORD(0x400FC1DC, 0x00001010); // (0x1010+1)* 250ps
// Initialize EMC
_WDWORD(0x2009C000, 0x00000001); // CONTROL=1 = Enable EMC
_WDWORD(0x2009C008, 0x00000000); // CONFIG=0
_WDWORD(0x2009C100, 0x00000680); // DYNAMICCONFIG0
_WDWORD(0x2009C104, 0x00000202); // DYNAMICRASCAS0
_WDWORD(0x2009C028, 0x00000001); // DYNAMICREADCONFIG
_WDWORD(0x2009C030, 0x00000001); // DYNAMICRP
_WDWORD(0x2009C034, 0x00000003); // DYNAMICRAS
_WDWORD(0x2009C038, 0x00000000); // DYNAMICREX
_WDWORD(0x2009C03C, 0x00000001); // DYNAMICAPR
_WDWORD(0x2009C040, 0x00000005); // DYNAMICDAL
_WDWORD(0x2009C044, 0x00000001); // DYNAMICWR
_WDWORD(0x2009C048, 0x00000004); // DYNAMICRC
_WDWORD(0x2009C04C, 0x00000004); // DYNAMICRFC
_WDWORD(0x2009C050, 0x00000005); // DYNAMICXSR
_WDWORD(0x2009C054, 0x00000001); // DYNAMICRRD
_WDWORD(0x2009C058, 0x00000001); // DYNAMICMRD
_WDWORD(0x2009C020, 0x00000183); // DYNAMICCONTROL - NOP
_sleep_(100);
_WDWORD(0x2009C020, 0x00000103); // DYNAMICCONTROL - PRECHARGE_ALL
_sleep_(100);
_WDWORD(0x2009C024, 0x0000001D); // DYNAMICREFRESH = 1D
_WDWORD(0x2009C020, 0x00000083); // DYNAMICCONTROL - MODE
_RDWORD(0xA0000000 | (0x23<<12));// Write 16-bit SDRAM Mode register burst 8- this is a read as requested by the SDRAM spec
_WDWORD(0x2009C020, 0x00000003); // DYNAMICCONTROL - NORMAL
_WDWORD(0x2009C100, 0x00080680); // DYNAMICCONFIG0
_sleep_(100);
}
FUNC void mpu_region_setup(unsigned int a_addr,
unsigned int a_region,
unsigned int a_size,
unsigned int a_ap,
unsigned int a_mem_attrib,
unsigned int a_srd,
unsigned int a_XN,
unsigned int a_enable)
{
// Setup procedure for each region
unsigned int temp;
temp = (a_addr & 0xFFFFFFE0) | (a_region & 0xF) | 0x10 ;
_WDWORD(0xE000ED9C, temp); // RBAR
temp = ((a_XN & 0x1)<<28) | ((a_ap & 0x7)<<24) | ((a_mem_attrib & 0x3F)<<16) | ((a_srd&0xFF)<<8) | ((a_size & 0x1F)<<1)| (a_enable & 0x1) ;
_WDWORD(0xE000EDA0, temp); // RASR
_WDWORD(0xE000ED24, 1<<18); // usage fault enable
_WDWORD(0xE000ED94, 5); // MPU enable
}
Clock_Setup();
LPC1788_setupEmc();
LOAD %L INCREMENTAL
mpu_region_setup( 0xA0000000,0,0x18,3,7,0,0,1);
Setup(0x10000000);
搞定了就好,恭喜{:smile:} 按你的方法还是调不出,SDRAM是好的,你看看对不对
LR_IROM1 0x10000000 0x00010000{ ; load region size_region
ER_IROM1 0x10000000 0x00010000{; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 0xA0010000 UNINIT 0x00010000{; RW data
.ANY (+RW +ZI)
}
}
LR_ROM1 0xA0000000 0x00010000{
ER_ROM1 0xA0000000 0x00010000{; load address = execution address
.ANY (+RO)
}
} 已搞惦了 楼主文件有错误 R8C 发表于 2015-12-18 22:58
楼主文件有错误
哦 请指出哪里有错误? 错误地方:
_WDWORD(0x400FC18A, 0x00000002); //cpuclock / 2 as the pclock
正确应该是:
_WDWORD(0x400FC1A8, 0x00000002); //cpuclock / 2 as the pclock
页:
[1]