请教:用JLINK调试片外flash的ARM
我的板子是At91SAM9260,外扩Norflash,以前程序下载到Norflash运行总不对,都说JLINK调试爽,于是从淘宝上买了个的JLINK,折腾了一下午,发现不是很会用。程序的症状是启动不正常,主晶振没有起振,而且好像根本没有进入LowlevelInit()函数,用的IAR5.20.
连接Jlink后,识别芯片,一切正常。
点击Download and Debugging,出现与用Wiggler一样的现象,直接跑飞,最后停在汇编00000004地址处,也不能像传说中那样在flash中设置断点。
用Jlink调试片外flash的话,9260的BMS脚接高还是低呢?接低的话下载地址对应就不正确,接高的话,0X0处又没有中断向量了。难道要用其他软件将程序下载到Flash中再用Jlink调试?
另外,用Jlink能不能调试启动代码,即在启动程序X.S文件和LowlevelInit.C中设置断点?
请指教,谢谢。 该死的攻击者,害的俺积分少了一半 我也是哦,很多问题都不知道是J-LINK的问题,还是IDE的设置问题..
上手起来都很困难啊~~~~ 貌似Jlink不支持片外flash无限断点 等待楼主的答案 最新实验:用Jlink附带的JFlash将生成的.bin文件下载到片外Flash中,再调试,只能设置一个断点,而且不能调试启动代码部分 to ch2003_23
这不是J-link的问题,而是所有的ICE都会碰到的问题。
1)AT91SAM7和SAM9的nSRST是需要配置寄存器才能用作外部复位输入的,因此在调试前,需要先配置寄存器,从而可以让JTAG ICE复位目标CPU,如果是IAR环境,需要在.mac文件里配置。
2) 对于9260而言,BMS拉高,则先运行片内ROM的程序,若启动条件都不满足,如dataflash,uart,usb等,则运行死循环程序,JTAG ICE可方便地对其进行控制;BMS拉高,则会运行CS0所选中的16bit Nor Flash,若Nor Flash为空,则会进入取指异常,此时JTAG ICE就很难对其控制了。
因此,如果CS0的Nor Flash为空时,可以把BMS拉高调试,这样JTAG ICE的初始化会运行比较长的时间。
比较好的方法是写一个小程序,完成初始化(GPIO,EBI,SDRAM,PLL。。。),然后死循环,将这个小程序烧录到Nor Flash中去,然后将BMS拉低,以后就可以用JTAG ICE很迅速地调试了。
3) 个人以为,对于外扩Flash作为程序存储器的ARM,一般会外扩RAM,那么调试程序时完全可以定位在片外的RAM中进行,release时再定到到Flash中,完全没有必要在片外Flash中设置硬件断点。
4) 关于9260的启动向量区问题,完全可以remap片内SRAM到0地址,那么中断向量想怎么改就怎么改了。。。 多谢【6楼】 taoist前辈:
看了你的话,又学到了很多,谢谢。
用Jlink调试Norflash的原因是,我的板子不能从Norflash启动运行,即BMS拉低时,下载到Norflash中的程序不能正确执行,主晶振没有起振,程序好像还是运行在慢时钟下,LED闪烁的频率与理论值差好多。所以想用Jlink调试看看程序到底执行启动代码的LowlevelInit.C了吗?但是好像调试时不能定位到LowlevelInit.C。IAR的icf文件和mac文件都是参考9260EK改的,而且在片内RAM中调试没有问题。
另外您说的4) 关于9260的启动向量区问题,完全可以remap片内SRAM到0地址,那么中断向量想怎么改就怎么改了。。。
不是很理解,中断向量不是定位到0x0处吗?怎么能想怎么改就怎么改?
企盼回复,谢谢 to ch2003_23
程序能跑起来,基本上就是软件问题了。。。没看到具体现象,我也没啥建议
提醒一下,在切换晶振时要特别当心总线的速度
中断向量区,永远是那些地址(0、4、8、...),但里面的值可以改呀。比如,想在SDRAM中调试,可以这样写。。。
org 0
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0xE59FF018 ; mov pc,
dc32 0x20000000
dc32 0x20000004
dc32 0x20000008
dc32 0x2000000C
dc32 0x20000010
dc32 0x20000014
dc32 0x20000018
dc32 0x2000001C
上述的写法,实际上就把向量区由0x00000000移到了0x20000000。。。 taoist前辈帮我看看程序到底哪儿的毛病吧,我上传全被的工程文件,IAR5.2版本,很简单的一个LED程序,主程序应该没啥问题,主要是看看启动部分和ICF配置文件。
下面先上传一个Jlink调试的反汇编开始intvec部分:
http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_419102.JPG
intvec (原文件名:intvec.JPG)
下面的是单步执行第一步后的反汇编:
http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_419103.JPG
first step (原文件名:first step.JPG) 完整的LEd测试小程序,IAR5.20
test程序ourdev_419104.rar(文件大小:98K) (原文件名:09.2.16.rar)
请taoist和各位大虾帮忙看看吧,这个怪毛病折磨了好久了,谢谢 to ch2003_23
不好意思,我的9260板子在公司,今晚没法帮你试,你试试我这个工程吧。。。
点击此处下载 ourdev_419128.rar(文件大小:40K) (原文件名:taoist-9260.rar) 好的,我先看看你的工程,谢谢啊 支持,多多努力 今天按照taoist的程序,可以实现在片外的SRAM调试,结果也对。
但是最后要在片外SRAM中跑的话,应该先将程序下载到Norflash中,然后将要执行的代码Copy到Sram中执行,但是现在的问题还是程序在Norflash中没法跑。
不知道是不是连接配置文件Icf文件的问题?下面贴出我写的程序下载到片外Norflash中并执行的配置文件,大伙看看对不对?
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x10000000;//Norflash基地址
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__= 0x10000100;
define symbol __ICFEDIT_region_ROM_end__ = 0x101FFFFF;
define symbol __ICFEDIT_region_RAM_start__= 0x00200040;
define symbol __ICFEDIT_region_RAM_end__ = 0x00200FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_svcstack__ = 0x100;
define symbol __ICFEDIT_size_irqstack__ = 0x100;
define symbol __ICFEDIT_size_fiqstack__ = 0x40;
define symbol __ICFEDIT_size_undstack__ = 0x40;
define symbol __ICFEDIT_size_abtstack__ = 0x40;
define symbol __ICFEDIT_size_heap__ = 0x0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:;
define region RAM_region = mem:;
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize{ section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP }; IAR的.mac文件:大虾们看看有毛病不?谢谢!!!!!!!!!
/*********************************************************************
*
* execUserReset() : JTAG set initially to Full Speed
*/
execUserReset()
{
__message "------------------------------ execUserReset ---------------------------------";
CheckNoRemap();
__PllSetting(); //* Init PLL
__message "-------------------------------Set PC Reset ----------------------------------";
__writeMemory32(0xD3,0x98,"Register"); //*Set CPSR
__writeMemory32(0x10000000,0xB4,"Register");//*Set PC (R15)
}
/*********************************************************************
*
* execUserPreload() : JTAG set initially to 32kHz
*/
execUserPreload()
{
__message "------------------------------ execUserPreload ---------------------------------";
__writeMemory32(0xD3,0x98,"Register"); //*Set CPSR
__PllSetting(); //* Init PLL
__AIC(); //* Init AIC
__initSRAM();
__initNorflash();
CheckNoRemap(); //* Set the RAM memory at 0x0020 0000 & 0x0000 0000
Watchdog(); //* Watchdog Disable
//*Get the Chip ID(AT91C_DBGU_C1R & AT91C_DBGU_C2R
__mac_i=__readMemory32(0xFFFFF240,"Memory");
__message " ---------------------------------------- Chip ID 0x",__mac_i:%X;
if ( __mac_i == 0x019803A1){__message " Chip ID for AT91SAM9260";}
else { __message " Chip ID for unknown !!";}
__mac_i=__readMemory32(0xFFFFF244,"Memory");
__message " ---------------------------------------- Extention 0x",__mac_i:%X;
}
/*********************************************************************
*
* __PllSetting()
* Function description
* Initializes the PMC.
* 1. Enable the Main Oscillator
* 2. Configure PLL
* 3. Switch Master
*/
__PllSetting()
{
if ((__readMemory32(0xFFFFFC30,"Memory")&0x3) != 0 ) {
//* Disable all PMC interrupt ( $$ JPP)
//* AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) //(PMC) Interrupt Disable Register
//* pPmc->PMC_IDR = 0xFFFFFFFF;
__writeMemory32(0xFFFFFFFF,0xFFFFFC64,"Memory");
//* AT91C_PMC_PCDR((AT91_REG *) 0xFFFFFC14) //(PMC) Peripheral Clock Disable Register
__writeMemory32(0xFFFFFFFF,0xFFFFFC14,"Memory");
// Disable all clock only Processor clock is enabled.
__writeMemory32(0xFFFFFFFE,0xFFFFFC04,"Memory");
// AT91C_PMC_MCKR((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
__writeMemory32(0x00000001,0xFFFFFC30,"Memory");
__sleep(10000);
// write reset value to PLLA and PLLB
// AT91C_PMC_PLLAR ((AT91_REG *) 0xFFFFFC28) // (PMC) PLL A Register
__writeMemory32(0x00003F00,0xFFFFFC28,"Memory");
// AT91C_PMC_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL B Register
__writeMemory32(0x00003F00,0xFFFFFC2C,"Memory");
__sleep(10000);
__emulatorSpeed(0); //* Set JTAG speed to full speed
__message "------------------------------- PLLEnable -----------------------------------------";
} else {
__message " ********* Core in SLOW CLOCK mode ********* "; }
}
/*********************************************************************
*
* _Watchdog()
*
* Function description
* Clear Watchdog
*/
Watchdog()
{
//* Watchdog Disable
// AT91C_BASE_WDTC->WDTC_WDMR= AT91C_SYSC_WDDIS;
__writeMemory32(0x00008000,0xFFFFFD44,"Memory");
__message "------------------------------- Watchdog Disable ------------------------------------";
}
/*********************************************************************
*
* CheckRemap()
*
* Function description
* Check the Remap.
*/
CheckNoRemap()
{
// AT91C_MATRIX_MRCR ((AT91_REG *) 0xFFFFEF00) // (MATRIX)Master Remp Control Register
__mac_i=__readMemory32(0xFFFFEF00,"Memory");
__message "----- AT91C_MATRIX_MRCR: 0x",__mac_i:%X;
if ( ((__mac_i & 0x01) == 0) || ((__mac_i & 0x02) == 0)){
__message "------------------------------- The Remap is NOT ----------------------------";
} else {
__message "------------------------------- The Remap is done & UNREMAP ----------------------------";
__writeMemory32(0x00000000,0xFFFFEF00,"Memory");
__mac_i=__readMemory32(0xFFFFEF00,"Memory");
__message "----- AT91C_MATRIX_MRCR: 0x",__mac_i:%X;
}
}
__initSRAM()
{
// Configure EBI Chip select
__writeMemory32(0x00010038,0xFFFFEF1C,"Memory");//CS1配置为外围静态RAM
//PIOC
__writeMemory32(0xFFFF0000,0xFFFFF870,"Memory");
__writeMemory32(0x00000000,0xFFFFF874,"Memory");
__writeMemory32(0xFFFF0000,0xFFFFF804,"Memory");
__writeMemory32(0x00000001,0xFFFFEC10,"Memory");
__writeMemory32(0x07070703,0xFFFFEC14,"Memory");
__writeMemory32(0x00070007,0xFFFFEC18,"Memory");
__writeMemory32(0x00072003,0xFFFFEC1C,"Memory");
}
__initNorflash()
{
__writeMemory32(0x00000001,0xFFFFEC00,"Memory");
__writeMemory32(0x07070703,0xFFFFEC04,"Memory");
__writeMemory32(0x00070007,0xFFFFEC08,"Memory");
__writeMemory32(0x00071003,0xFFFFEC0C,"Memory");
} 你可以先用J-flash把程序烧到flash,然后用快捷栏里最右边的debug without downloading试一下。。。
跑flash要把BMS拉低 谢谢taoist,按照你的方法将程序下载到Norflash中后,将BMS拉低然后debug without downloading,还是不行,系统还是没能跑起来,LED的闪烁周期竟然是1S钟,而且每16S系统复位一次,串口发出的数据也都是00
LED本来的程序是:
AT91C_BASE_PIOC->PIO_CODR|=0x1<<0;
for(i=1000;i>0;i--);
AT91C_BASE_PIOC->PIO_SODR|=0x1<<0;
for(i=1000;i>0;i--);
同样的程序在RAM中调试时闪烁周期为500uS。 发现跑Flash程序时,PLL竟然倍不上,系统一直运行在慢时钟下,下面是在Flash中调试时的Log输出显示:
.mac文件就是15楼给出的。
Segger JLink ARM JTAG
Wed Feb 18 16:16:23 2009: ------------------------------ execUserPreload ---------------------------------
Wed Feb 18 16:16:23 2009:********* Core in SLOW CLOCK mode *********
Wed Feb 18 16:16:28 2009: ----- AT91C_MATRIX_MRCR: 0x00000000
Wed Feb 18 16:16:28 2009: ------------------------------- The Remap is NOT ----------------------------
Wed Feb 18 16:16:28 2009: ------------------------------- Watchdog Disable ------------------------------------
Wed Feb 18 16:16:28 2009:---------------------------------------- Chip ID 0x019803A1
Wed Feb 18 16:16:28 2009:Chip ID for AT91SAM9260
Wed Feb 18 16:16:29 2009:---------------------------------------- Extention 0x00000000
Wed Feb 18 16:16:29 2009: 964 bytes with download suppressed
Wed Feb 18 16:16:29 2009: Loaded debugee: C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\09.2.16\Debug\Exe\test.out
Wed Feb 18 16:16:29 2009: Target reset
Wed Feb 18 16:16:29 2009: ------------------------------ execUserReset ---------------------------------
Wed Feb 18 16:16:30 2009: ----- AT91C_MATRIX_MRCR: 0x00000000
Wed Feb 18 16:16:30 2009: ------------------------------- The Remap is NOT ----------------------------
Wed Feb 18 16:16:30 2009:********* Core in SLOW CLOCK mode *********
Wed Feb 18 16:16:32 2009: -------------------------------Set PC Reset ---------------------------------- 你的程序里有没有倍频PLL????? 有啊,在LowLevelInit(Void)这个函数中有的:这个函数就是套用的IAR中的例程
/* Initialize main oscillator
****************************/
AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
/* Initialize PLLA at 200MHz (198.656) */
AT91C_BASE_PMC->PMC_PLLAR = BOARD_CKGR_PLLA
| BOARD_PLLACOUNT
| BOARD_MULA
| BOARD_DIVA;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA));
// Initialize PLLB for USB usage (if not already locked)
if (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB)) {
AT91C_BASE_PMC->PMC_PLLBR = BOARD_USBDIV
| BOARD_CKGR_PLLB
| BOARD_PLLBCOUNT
| BOARD_MULB
| BOARD_DIVB;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB));
}
/* Wait for the master clock if it was already initialized */
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
/* Switch to fast clock
**********************/
/* Switch to main oscillator + prescaler */
AT91C_BASE_PMC->PMC_MCKR = BOARD_PRESCALER;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
/* Switch to PLL + prescaler */
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) 当我把时钟初始化部分放在main()中时,发现主晶振可以起振了,PLLA、B也Lock了,就是当把PLL赋给MCK时就不行,程序就跑飞了,程序如下:
/* Initialize main oscillator
****************************/
AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
/* Initialize PLLA at 200MHz (198.656) */
AT91C_BASE_PMC->PMC_PLLAR = BOARD_CKGR_PLLA
| BOARD_PLLACOUNT
| BOARD_MULA
| BOARD_DIVA;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA));
// Initialize PLLB for USB usage (if not already locked)
if (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB)) {
AT91C_BASE_PMC->PMC_PLLBR = BOARD_USBDIV
| BOARD_CKGR_PLLB
| BOARD_PLLBCOUNT
| BOARD_MULB
| BOARD_DIVB;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB));
}
/* Wait for the master clock if it was already initialized */
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
/* Switch to fast clock
**********************/
/* Switch to main oscillator + prescaler */
AT91C_BASE_PMC->PMC_MCKR = BOARD_PRESCALER | AT91C_PMC_PRES_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
/* Switch to PLL + prescaler */
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));//这一句死活不能通过执行
还请诸位大虾指教,谢谢 我用的笨方法:如果程序已经可以下载到flash,直接把pc改为flash的首地址,根据反汇编,对照system.map跟踪下去,然后看看跑飞在什么地方,分析跑飞前各寄存器状态 谢谢【22楼】 yplin27
已经找出来程序跑飞在这个地方:
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));//这一句死活不能通过执行
就是只要将PLL赋给MCK,然后等待MCK Ready,接着程序就跑飞
真是奇怪了,怎么会出现这种情况? 请问大家能不能用IAR+JLINK调试dataflash 到目前了解到的dataflash只是个存储代码的介质,但是我用IAR442的例子flash(还有iram)选项来调试9261,提示说没找到AT45DX 这是什么原因?
如果9261裸机,应用程序存放在dataflash,复位后检测BMS为高,从内部ROM启动,内部ROM会自己将dataflash里面的代码搬到哪里去运行?内部ram还是外部sdram?
可能问题不是很清楚,但是总的疑问是:9261裸机的时候,代码是怎么启动的,需不需要自己做bootloader 我也遇到了和23楼一样的情况,请问你的解决了吗? 回复【23楼】ch2003_23 风子
谢谢【22楼】 yplin27
已经找出来程序跑飞在这个地方:
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));//这一句死活不能通过执行
就是只要将PLL赋给MCK,然后等待MCK Ready,接着程序就跑飞
真是奇怪了,怎么会出现这种情况?
-----------------------------------------------------------------------
你好,请教同样的问题! 回LS:
一直没能解决,所以从放弃使用IAR改用Keil了 回复【27楼】ch2003_23 风子
-----------------------------------------------------------------------
sign~~
我的程序都编好了,没办法再改其他编译软件了。
请教一下,你实现的是NORFLASH上电后,代码搬到SRAM还是SDRAM呀 这个我是初始化好外部内存,然后下载到内存跑起来的。俺是2440 我现在的问题是,开启一个定时器中断,jlink在sdram中调试,在中断代码里加了一个断点,好嘛,再也不中断了……全速运行是可以的,在任务中加断点也不影响,不知为何啊。 这个学习好机会啊! 我也在搞这个,不过是AT91SAM7SE512的,用jlink调试出现类似问题!
页:
[1]