NXP

LPC1788在外部RAM调试总结

2019-07-12 12:55发布

调试工具:MDK 4.72  JLink8
一、MDK设置
1、Target
                  图1
2.Asm

                 图2
  1处必须预定义NO_CRP,因为在LPC1788启动文件startup_LPC177x_8x.s中有如下代码

                 图3
  117-120这段代码是NXP公司的LPC1700系列的MCU特有的一段代码,其他公司的Cortex-M3 MCU的启动程序是没有这段代码的。这段代码是指定LPC1700的CRP加密级别的代码段,芯片上电后会自动读取0x02FC这一地址的值以确定加密方式,其中CRP_Key = 0xffffffff为0级加密,CRP_Key = 0x12345678为1级加密,CRP_Key = 0x87654321为2级加密,CRP_Key = 0x43218765为3级加密(最高级加密),3级加密将会禁止所有的ISP指令,也就是说,芯片将不能读写、不能擦除。
  如果在图2中的1处没有定义了NO_CRP,118-120行代码会被执行,即定义CRP_key,这会导致退出外部RAM调试时内核被锁,在MDK中的Debug Setting中无法检测到目标板;只能通过拉低P2[10]引脚后通过J_Flash软件的Target->Connect连接目标板,然后Erase Chip擦除目标板Flash,这样才能在Debug Setting中重新检测到目标板 3.Linker

                  图4 1)、如果图2中1处(使用Target对话框中的内存布局)打勾,则表示使用默认的分散加载文件生成映像文件,其内容为
                   图5
  其中图3中的地址1对应于Target对话框中Read/Only Memory Areas区内的默认存储空间的起始地址,默认为片内Flash;地址2是对应于arget对话框中Read/Write Memory Areas区内的默认存储空间的起始地址,默认为片内SRAM。如果此时图1Target对话框中的Read/Only Memory Areas和Read/Write Memory Areas区域的存储空间设置的不是默认值,则会出现编译错误。
  Link Control String中的内容为(工程名为Proj1):

                   图6
2)、如果图2中1处不打勾,并在3处选择了分散加载文件,则会按分散加载文件中的内容生成映像文件;此时Target对话框中指定的RO和RW存储空间无效。这次调试使用的分散加载文件内容为

                   图7
  将向量表和所有必须在root region中的library sections(如__main.o, __scatter*.o, __dc*.o, 和Region$$Table)放在起始地址为0x10000000,大小为0x10000的存储空间中(片内SRAM)中;将剩余的代码,读写数据和零初始化数据放大起始地址为0xA0000000,大小为0x1000000的存储空间(片外SDRAM)中。
  Link Control String中的内容如图2 ,分散加载文件名为SDRAM.sct。
3)、如果图2中1处不打勾,且3处没有选择分散加载文件,则会按2处的R/O Base和R/W Base生成映像文件;此时Target对话框中指定的RO和RW存储空间无效。
  Link Control String中的内容为(R/O Base和R/W Base如图2)

                   图8
4、Debug
这里写图片描述
                   图9
Load Application at Startup处不要打勾,在1处选择初始化命令脚本,内容为 INCLUDE MT48LC8M32LFB5.ini //INCLUDE SST39VF160_for_download.ini InitSDRAM(); // Initialize memory //EMC_NorFlashInit(); LOAD .FlashLcd_LQ043T3DX0A.axf INCREMENTAL // Download program /* RNR */ _WDWORD(0xE000ED98, 0x00000000); // Use No.0 MPU /* RBAR */ _WDWORD(0xE000ED9C, 0xA0000000); // Set MPU base addr /* RASR */ _WDWORD(0xE000EDA0, 0x03000031); // Set MPU size and permission /* SHCSR */ // _WDWORD(0xE000ED24, 0x00000100); // Enable memory managemeng fault /* MPU_CONTROL */ _WDWORD(0xE000ED94, 0x00000005); // Enable MPU /* VTOR */ _WDWORD(0xE000ED08, 0x10000000); // Set vector table offset SP = _RDWORD(0x10000000); // Set stack pointer PC = _RDWORD(0x10000004); // Set program counter   10-22行的关于MPU的设置一定要有,否则程序在SDRAM中的执行会出现错误,这是因为Cortex_M3处理器在0xA0000000-0xDFFFFFFF之间的存储空间的默认访问属性是不可执行的,是不可执行区,图中第16行代码通过设置MPU region属性及容量寄存器MPURASR,使其以0xA0000000为起始地址的32MB(MPURASR[5:1]=0b11000)存储空间为共享内存(MPURASR[26:24]=0b011),且此区允许取指(MPURASR[28]=0)。
  InitSDRAM()函数在MT48LC8M32LFB5.ini中,作用为初始化外部SDRAM,其内容为 FUNC void PinSel(int p1, int n1, int f1) { _WDWORD(0x4002C000 + (p1 * 32 + n1) * 4, 0x8 | f1); } FUNC void InitSDRAM(void) { int i; PinSel(2,16,1); PinSel(2,17,1); PinSel(2,18,1); PinSel(2,20,1); PinSel(2,24,1); PinSel(2,28,1); PinSel(2,29,1); PinSel(2,30,1); PinSel(2,31,1); for(i = 0; i < 32; i++) PinSel(3,i,1); for(i = 0; i < 21; i++) PinSel(4,i,1); PinSel(4,24,1); PinSel(4,25,1); PinSel(4,30,1); PinSel(4,31,1); /* PCONP |= 1 << 11 */ _WDWORD(0x400FC0C4, 0x04288FDE); // Power On EMC /* EMCCONTROL |= 1 */ _WDWORD(0x2009C000, 0x00000001); // Enable EMC /* EMCDLYCTL */ _WDWORD(0x400FC1DC, 0x00081818); // Config data read delay /* EMCCONFIG */ _WDWORD(0x2009C008, 0x00000000); // Little endian mode /* DYNAMICCONTROL */ _WDWORD(0x2009C020, 0x00000003); // Set normal self refresh mode, normal power mode // CE always HI // Enable clock out // Clock do not stop during idle /* DYNAMICREFRESH */ _WDWORD(0x2009C024, 0x0000001F); // refresh timing /* DYNAMICREADCONFIG */ _WDWORD(0x2009C028, 0x00000001); // read timing /* DYNAMICRP */ _WDWORD(0x2009C030, 0x00000002); // tRP /* DYNAMICRAS */ _WDWORD(0x2009C034, 0x00000003); // tRAS /* DYNAMICSREX */ _WDWORD(0x2009C038, 0x00000005); // tSREX /* DYNAMICAPR */ _WDWORD(0x2009C03C, 0x00000001); // tAPR /* DYNAMICDAL */ _WDWORD(0x2009C040, 0x00000005); // tDAL /* DYNAMICWR */ _WDWORD(0x2009C044, 0x00000003); // tWR /* DYNAMICRC */ _WDWORD(0x2009C048, 0x00000004); // tRC /* DYNAMICRFC */ _WDWORD(0x2009C04C, 0x00000004); // tRFC /* DYNAMICXSR */ _WDWORD(0x2009C050, 0x00000005); // tXSR /* DYNAMICRRD */ _WDWORD(0x2009C054, 0x00000001); // tRRD /* DYNAMICMRD */ _WDWORD(0x2009C058, 0x00000003); // tMRD /* DYNAMICCASRAS0 */ _WDWORD(0x2009C104, 0x00000303); // RAS/CAS Latency /* DYNAMICCONFIG0 */ _WDWORD(0x2009C100, 0x00004500); // Config device type as SDRAM // Config address mapping _sleep_(100); // Wait 100 ms /* DYNAMICCONTROL */ _WDWORD(0x2009C020, 0x00000183); // nop command _sleep_(100); // Wait 100 ms /* DYNAMICCONTROL */ _WDWORD(0x2009C020, 0x00000103); // pre-charge command // /* DYNAMICREFRESH */ // _WDWORD(0x2009C024, 0x00000002); // refresh timing _sleep_(100); // Wait 100 ms /* DYNAMICREFRESH */ _WDWORD(0x2009C024, 0x0000001F); // refresh timing /* DYNAMICCONTROL */ _WDWORD(0x2009C020, 0x00000083); // mode command _RDWORD(0xA0000000 | (0x32 << (2 + 2 + 8))); _sleep_(100); // Wait 100 ms /* DYNAMICCONTROL */ _WDWORD(0x2009C020, 0x00000003); // noamal command /* DYNAMICCONFIG0 */ _WDWORD(0x2009C100, 0x00084500); // enable buffer _sleep_(100); // Wait 100 ms } 5、Utilities

                  图片10
  1处不能打勾,这个选项的意思是在进入调试前先更新目标板,但是我们并没有配置目标板的flash,所以这个选项如果不去掉,在调试时就会弹出错误,大意是在xxxx地址没有找到算法。
6、Utilities Setting

                  图片11
  因为是在外部RAM中调试,所以1中不用加载Flash编程算法,左上角选择Erase Sectors或Do not Erase都可以。
  
二、问题总结 1、在外部RAM中调试,程序中不要有操作外部RAM的代码,初始化也不要有,包括对RAM相关引脚的操作,RAM的初始化和引脚的初始化要放到jlink的下载配置文件MT48LC8M32LFB5.ini中,主要是对LPC的寄存器进行相关配置。 2、在system_LPC177x_8x.c的SystemInit()函数中如图183-188行关于时钟选择设置部分要注释掉,因为LPC1788复位后是以IRC作为时钟源的,当将程序下载到外部RAM中时,外部RAM是在12MHz的IRC下运行的,所以更改CPU或EMC时钟会使程序在外部RAM运行出错 3、步骤
1)、Target或Linker
2)、Asm (LPC1788特有)
3)、Debug
4)、Utilities