TI的bootloader文档里讲过bootloader要用汇编语言来写,因为还没有建立c语言运行环境。但是,我看到网上有人用c语言弄的bootloader,于是我也试了试,但是一直有问题。
我用的DSP型号是c672x,采用的方法是写两个c文件,一个boot.c,一个appmain.c(自己的应用代码)。boot.c里装着void boot()函数。boot.c的代码放到Flash前1KB,appmain.c代码放到1KB以后位置。具体方法是这位朋友弄的http://wenku.baidu.com/view/5dd6cc62caaedd3383c4d354.html
c672x只有13跟地址线(包括em_ba1),所以Flash高位地址线需要扩展GPIO,这样读取Flash的时候,要手动换页。下面是我的boot.c的代码,顺序是:配置锁相环——配置emif——配置GPIO为高位地址线——for循环搬运代码——使用c_int00()函数寻找main函数入口。
最开始的时候,配置锁相的那部分代码是作为一个函数调用的,但是总出现问题,后来我直接把配置锁相代码拿到boot函数里了,去掉函数调用这一步。正常了。难道是因为bootloader里面没有设置堆栈?
boot.c中间有一段代码,是while输出方波死循环(已被注释掉),如果不注释的话,dsp上电执行到这一步,正常配置锁相、emif、gpio,然后输出所要的方波,但如果注释掉while死循环,就发现,虽然前面的都执行正确,但是搬运代码的for循环不正常,找不出规律,有时貌似一直在搬运,但是却不见gpio有所改变,所以又像没在搬运,但emif却一直在输出读信号。
成功过一次,上电,很快完成搬运,然后dsp对着sdram一顿疯狂操作(不是我主程序要求的),过了得五分钟才看到我主程序里要求的现象。
另外,这个dsp是好使的,因为我按照TI给的“Using the TMS320C672x Bootloader”这个文档的方法,是可以正常boot的。只是得使用AIS格式的数据流。
下面是我的boot.c代码:
//#include <stdio.h>
#define IRAM_ADDR 0x10000400 //内部RAM地址,从这里开始放用户应用代码
#define FLASH_ADDR 0x90000400 //Flash地址,404位置存放代码长度,从408开始存放用户代码
/****************************************************/
/*GPIO设置*/#define PFUNC1 0x45000010
#define PDIR1 0x45000014
#define PDOUT1 0x45000018/****************************************************/#define EMIF_A1CR 0xF0000010/****************************************************/
#pragma CODE_SECTION(boot,".bootload");
extern far void c_int00();
void boot()
{
unsigned int i;
unsigned int addr1;
unsigned char a13,a14,a15,a16,a17;
unsigned short int code_length;
/****************************************************///开始配置锁相(原来这部分代码是一个独立函数,在这个地方调用配置锁相函数)
#define TIBOOT_PLL_REG_BASE_ADDR (0x41000000u)
#define TIBOOT_PLL_PLLCSR (TIBOOT_PLL_REG_BASE_ADDR + 0x100u)
#define TIBOOT_PLL_PLLM (TIBOOT_PLL_REG_BASE_ADDR + 0x110u)
#define TIBOOT_PLL_PLLDIV0 (TIBOOT_PLL_REG_BASE_ADDR + 0x114u)
#define TIBOOT_PLL_PLLDIV1 (TIBOOT_PLL_REG_BASE_ADDR + 0x118u)
#define TIBOOT_PLL_PLLDIV2 (TIBOOT_PLL_REG_BASE_ADDR + 0x11Cu)
#define TIBOOT_PLL_PLLDIV3 (TIBOOT_PLL_REG_BASE_ADDR + 0x120u)
#define TIBOOT_PLL_PLLCMD (TIBOOT_PLL_REG_BASE_ADDR + 0x138u)
#define TIBOOT_PLL_PLLSTAT (TIBOOT_PLL_REG_BASE_ADDR + 0x13Cu)
#define TIBOOT_PLL_PLLALNCTL (TIBOOT_PLL_REG_BASE_ADDR + 0x140u)#define TIBOOT_PLLENABLE (0x01u)
#define TIBOOT_PLLDISABLE (0x00u)
#define TIBOOT_PLLPWRDN (0x02u)
#define TIBOOT_PLLPWRUP (0x00u)
#define TIBOOT_PLLOSCPWRDN (0x04u)
#define TIBOOT_PLLOSCPWRUP (0x00u)
#define TIBOOT_PLLRESET (0x08u)
#define TIBOOT_PLLRESETRELEASE (0x00u)
#define TIBOOT_PLLSTABLE (0x40u)
#define TIBOOT_PLLUNSTABLE (0x00u)
#define TIBOOT_PLLLOCKED (0x20u)
#define TIBOOT_PLLNOTLOCKED (0x00u)
/* FOR PLLCMD */
#define TIBOOT_PLLGOCLR (0x0000u)
#define TIBOOT_PLLGOSET (0x0001u)
/* FOR PLLSTAT */
#define TIBOOT_PLLGODONE (0x0000u)
#define TIBOOT_PLLGOWAIT (0x0001u)
/* FOR ALNCTL */
#define TIBOOT_PLLALN1 (0x0001u)
#define TIBOOT_PLLALN2 (0x0002u)
#define TIBOOT_PLLALN3 (0x0004u)
/* FOR PLLDIV0,1,2,3 and OSCDIV1 */
#define TIBOOT_DIVENABLED (0x8000u)
*(volatile unsigned int *)TIBOOT_PLL_PLLDIV0 = TIBOOT_DIVENABLED | 0x00000000;
*(volatile unsigned int *)TIBOOT_PLL_PLLM = 0x00000014;
*(volatile unsigned int *)TIBOOT_PLL_PLLDIV1 = TIBOOT_DIVENABLED | 0x00000001;
asm(" nop 4");
asm(" nop 4");
*(volatile unsigned int *)TIBOOT_PLL_PLLDIV2 = TIBOOT_DIVENABLED | 0x00000003;
asm(" nop 4");
asm(" nop 4");
*(volatile unsigned int *)TIBOOT_PLL_PLLDIV3 = TIBOOT_DIVENABLED | 0x00000003;
*(volatile unsigned int *)TIBOOT_PLL_PLLALNCTL = TIBOOT_PLLALN1 | TIBOOT_PLLALN2 | TIBOOT_PLLALN3;
*(volatile unsigned int *)TIBOOT_PLL_PLLCMD = TIBOOT_PLLGOSET;
while (*(volatile unsigned int *)TIBOOT_PLL_PLLSTAT == TIBOOT_PLLGOWAIT){
*(volatile unsigned int *)TIBOOT_PLL_PLLCMD = TIBOOT_PLLGOCLR;
}
for(i=0; i< 7;++i) {};
*(volatile unsigned int *)TIBOOT_PLL_PLLCSR = TIBOOT_PLLENABLE | TIBOOT_PLLRESETRELEASE;
for(i=0; i < 3850; ++i) {};
//配置锁相结束
/****************************************************/
配置emif
*(int *)EMIF_A1CR = ( 1 << 31) //WE Strobe mode | ( 0 << 30) // EW : Disable extended wait mode | ( 0 << 26) // W_SETUP : 10 ns @ 100 MHz | ( 9 << 20) // W_STROBE | ( 3 << 17) // W_HOLD | ( 0 << 13) // R_SETUP | ( 9 << 7) // R_STROBE | ( 3 << 4) // R_HOLD | ( 0 << 2) // TA | ( 1 << 0); // ASIZE : 16-bit data bus /****************************************************/ /*Flash高位地址线配置*/
*(int *)PFUNC1=(0xF<<28)//保留位必须写入0
|(0xE<<24)
|(0<<20)
|(0<<16)
|(0<<12)
|(0<<8)
|(3<<4)
|(0xF<<0);
*(int *)PDIR1=(0xF<<28)//保留位必须写入0
|(0xE<<24)
|(0<<20)
|(0<<16)
|(0<<12)
|(0<<8)
|(3<<4)
|(0xF<<0);
*(int *)PDOUT1=(0<<31)//AFSR_A17
|(1<<30)
|(0<<29)//ACLKR_A15
|(0<<28)//AFSX_A16
|(0<<27)//AHCLKX_A13
|(0<<26)//ACLKX_A14
|(1<<25)//AMUTE
|(0<<16)//Reserved_0
|(0<<6)//AXR15~AXR6
|(1<<5)//AXR5
|(0<<4)//AXR4
|(1<<3)//AXR3
|(0<<2)//AXR2
|(1<<1)//AXR1
|(0<<0);//AXR0 //while(1) //{ // *(int *)PDOUT1=*(int *)PDOUT1 | 0x01; // for(i=0;i<100;i++) // {} // *(int *)PDOUT1=*(int *)PDOUT1 & 0xfffffffe; // for(i=0;i<100;i++)//输出一个方波 // {} //}
//搬运代码的for循环
code_length=*(unsigned short *)(FLASH_ADDR+4);//这个位置存放着要搬运的代码长度
for(i=0;i<code_length;i++)
{
addr1=FLASH_ADDR+8+2*i;
addr1=addr1>>1;
a13=(addr1>>13) & 0x01;//地址线A13
a14=(addr1>>14) & 0x01;
a15=(addr1>>15) & 0x01;
a16=(addr1>>16) & 0x01;
a17=(addr1>>17) & 0x01;
*(int *)PDOUT1=(a17<<31)//AFSR_A17
|(1<<30)
|(a15<<29)//ACLKR_A15
|(a16<<28)//AFSX_A16
|(a13<<27)//AHCLKX_A13
|(a14<<26)//ACLKX_A14
|(1<<25)//AMUTE
|(0<<16)//Reserved_0
|(0<<6)//AXR15~AXR6
|(1<<5)//AXR5
|(0<<4)//AXR4
|(1<<3)//AXR3
|(0<<2)//AXR2
|(1<<1)//AXR1
|(0<<0);//AXR0 *(unsigned short *)(IRAM_ADDR+2*i)=*(unsigned short *)(FLASH_ADDR+8+2*i);
}
c_int00(); }
sun gang:
顶。。坐等大神指导
shenghui Rong:
回复 sun gang:
求大神制导,求官方说明……
nvshi li:
回复 shenghui Rong:
楼主您好!
偶想问下你的问题解决了吗?
user3460585:
楼主问题解决了没有?你按照TI的《Using the TMS320C672x Bootloader》可以正常boot?我有个小程序可以正常boot,但我的应用程序较大,没有boot成功?能否留个联系方式交流一下?