This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
1.主程序main:初始化SYSCTRL,GPIO,CPUTIMER,CAN,PIEVECT,EPWM后进入主循环,主循环有时间片子程序,Can接收发送子程序,IO控制子程序。
上位机发送CAN命令后,Can接收发送子程序收到命令后,跳转到BOOT程序。
2.BOOT程序:初始化SYSCTRL,GPIO,CPUTIMER,CAN,PIEVECT后进入BOOT主循环,BOOT主循环有时间片子程序,Can接收发送子程序.
BOOT程序接收到上位机发送的CANBOOT 数据,进行烧写,接收一帧数据然后烧写一帧数据。接收并烧写完毕后所有CAN数据后,等待15秒跳转后主程序main.
/*;*********************************************************************** FILENAME: BOOT.c TITLE: bootloader function AUTHOR: PROJECT: rectifier PUBLIC: none PRIVATE: none **************************************************************************/ #include "driverlib.h" #include "f28004x_device.h" // Headerfile Include File #include "f28004x_examples.h" // DSP28 Examples Include File #include "F021_F28004x_C28x.h" #include "flash_programming_f28004x.h" #include "device.h" //---- Standard headers --- #include <stdio.h> #define MaxBlockLength 0x0800 #define EraseFlashLength 0x5000 #define Start_Of_Application 0x081000 #define Application_CRC 0x087F7F /************************************************************************* * * FUNCTION NAME: Application_Valid * * DESCRIPTION: CRC-16 check program space is ok? * * PARAMETERS: NONE * * RETURNS: Uint16 * * CAVEATS: NONE * ************************************************************************/ //����У��:CRC[Start_Of_Application,Application_CRC-1]-->[Application_CRC]��... #pragma CODE_SECTION(Application_Valid,"FlashBoot");//Flash28_API Uint16 Application_Valid(void) { return(0); } /******************************************************************** *��ѯͨ������ **********************************************************************/ #pragma CODE_SECTION(GET_DATA,"Flash28_API");//FlashBoot void GET_DATA(void) { } //���ݷ��ʹ��� #pragma CODE_SECTION(SEND_DATA,"Flash28_API");//FlashBoot void SEND_DATA(void) { } /************************************************************************* * FUNCTION NAME: void CallFlashAPI (void) * * DESCRIPTION: * * PARAMETERS: NONE * * RETURNS: NONE * * CAVEATS: NONE **************************************************************************/ #pragma CODE_SECTION(CallFlashAPI,"Flash28_API");//FlashBoot void CallFlashAPI (void) { //��ʱ���� //uint32 u32Index = 0; // uint16 i = 0; Uint16 *uiDataBuf;//,*Flash_ptr; Uint32 *Flash_ptr; //Uint16 Status,Status_Verify; //FLASH_ST FlashStatus; Fapi_StatusType oReturnCheck; Fapi_FlashStatusType oFlashStatus; Fapi_FlashStatusWordType oFlashStatusWord; //uint32 *Buffer32; //������ʼ�� uiSendOk = 0; uiRecvOk =0; uiCanErrorCount = 0; ulCanBootDest.ulData = Start_Of_Application; uiCanBootBlockLength = MaxBlockLength; ulCanBootBlockAddr.ulData = Start_Of_Application; //Flash_ptr = (Uint16 *)ulCanBootBlockAddr.ulData; Flash_ptr = (Uint32 *)ulCanBootBlockAddr.ulData; //�ƶ�ID�� uiSendID = 0x0; // Initialize the Flash API by providing the Flash register base address // and operating frequency. // This function is required to initialize the Flash API based on System frequency // before any other Flash API operation can be performed. // This function must also be called whenever System frequency or RWAIT is changed. oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 100); if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for possible errors //Example_Error(oReturnCheck); } // Initialize the Flash banks and FMC for erase and program operations. // Fapi_setActiveFlashBank() function sets the Flash banks and FMC for further // Flash operations to be performed on the banks. // Note: It does not matter which bank is passed as the parameter to initialize. // Both Banks and FMC get initialized with one function call unlike F2837xS. // Hence there is no need to execute Fapi_setActiveFlashBank() for each bank. // Executing for one bank is enough. oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0); if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for possible errors //Example_Error(oReturnCheck); } //��ѭ�� for(;;) { //*************��ʱ��************************* //ServiceDog(); if (CpuTimer0Regs.TCR.bit.TIF) // 5mS flag { CpuTimer0Regs.TCR.bit.TIF = 1; uiCanErrorCount ++; if(uiCanErrorCount >=3000)//60s { Application_Entry_Point(); } } GET_DATA(); if(uiRecvOk ==1) { if(uiSendID ==0) {//0x10AA,������Ч if(ulCanBootMDH.uiData.uiLD != 0x10AA) ulCanBootMDL.uiData.uiHD |= 0x80F2; } else if((uiSendID>=1)&&(uiSendID<=8)) { } else if(uiSendID==9) {//read DEST_H ulCanBootDest.uiData.uiHD = ulCanBootMDH.uiData.uiLD; } else if(uiSendID==10) {//read DEST_L ulCanBootDest.uiData.uiLD = ulCanBootMDH.uiData.uiLD; SEND_DATA(); //����Ϊ�Ȼ����ݺ�erase,10s time uiRecvOk = 0; // Erase Flash Bank0 sector5...1 //oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)Bzero_Sector5_start); oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)Bzero_Sector4_start); oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)Bzero_Sector3_start); oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)Bzero_Sector2_start); oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)Bzero_Sector1_start); // Wait until FSM is done with erase sector operation while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){} if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for possible errors //Example_Error(oReturnCheck); //__asm(" ESTOP0"); uiSendID = 0; ulCanBootMDL.uiData.uiHD |= 0x80F8; } } else if(uiSendID==11) { uiCanBootBlockLength = ulCanBootMDH.uiData.uiLD; if(uiCanBootBlockLength == 0) { if(1) { //ulCanBootMDL.uiData.uiHD |= 0x80F8; SEND_DATA(); DELAY_US(5000);//5ms Application_Entry_Point(); } else { ulCanBootMDL.uiData.uiHD |= 0x80F8; SEND_DATA(); uiRecvOk = 0 ; uiSendID = 0 ; } } } else if(uiSendID==12) {//read block data address high 16bits ulCanBootBlockAddr.uiData.uiHD = ulCanBootMDH.uiData.uiLD; } else if(uiSendID==13) {//read block data address low 16bits ulCanBootBlockAddr.uiData.uiLD = ulCanBootMDH.uiData.uiLD; if(ulCanBootBlockAddr.uiData.uiLD +uiCanBootBlockLength > (Uint16)(Application_CRC+1))//0x7000 ulCanBootMDL.uiData.uiHD |= 0x80F2; Flash_ptr = (Uint32 *)ulCanBootBlockAddr.ulData; uiDataBuf = (Uint16 *)0x0000; } else if((uiSendID>=0x0E)&&(uiSendID <= 0x0D + uiCanBootBlockLength)) {//block data *uiDataBuf = ulCanBootMDH.uiData.uiLD;//ÿ�ֽڶ�д //for(i=0, u32Index = Bzero_Sector6_start; // (u32Index < (Bzero_Sector6_start + 1/*WORDS_IN_FLASH_BUFFER*/)) && // (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8) //{ //oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index, uiDataBuf+i, 8, 0, 0, Fapi_AutoEccGeneration); oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)Flash_ptr, uiDataBuf, 1, 0, 0, Fapi_ReadDataOnly); // Wait until the Flash program operation is over while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy); if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for possible errors //Example_Error(oReturnCheck); //__asm(" ESTOP0"); ulCanBootMDL.uiData.uiHD |= 0x80F8; } else Flash_ptr++; // Read FMSTAT register contents to know the status of FSM after // program command to see if there are any program operation related errors /* oFlashStatus = Fapi_getFsmStatus(); if(oFlashStatus != 0) { //Check FMSTAT and debug accordingly //FMSTAT_Fail(); __asm(" ESTOP0"); } // Verify the programmed values. Check for any ECC errors. // The program command itself does a verify as it goes. // Hence program verify by CPU reads (Fapi_doVerify()) is optional. //oReturnCheck = Fapi_doVerify((uint32 *)u32Index, 4, Buffer32+(i/2),&oFlashStatusWord); //u32Index=Flash_ptr-1; oReturnCheck = Fapi_doVerify((uint32 *)(Flash_ptr-1), 1, (uint32*)uiDataBuf,&oFlashStatusWord); if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for possible errors //Example_Error(oReturnCheck); __asm(" ESTOP0"); }*/ //} if(uiSendID == 0x0D + uiCanBootBlockLength ) { if(ulCanBootMDL.ulData == 0x03F000FF) { SEND_DATA(); uiSendID = 0x000B; uiRecvOk = 0; } else { uiSendID = 0x0000; } } } } SEND_DATA(); } }// end of CallFlashAPI(void) /************************************************************************* * FUNCTION NAME: void BOOT_MAIN (void) * * DESCRIPTION: bootloader entry * * PARAMETERS: NONE * * RETURNS: NONE * * CAVEATS: NONE **************************************************************************/ #pragma CODE_SECTION(BOOT_MAIN,"FlashBoot"); void BOOT_MAIN (void) { InitSysCtrl();//PLL,enable Dog,InitPeripheralClocks //ʹ�ܿ��Ź�2015.09.02 //EnableDog(); //ServiceDog(); // Initalize GPIO: detail info in the DSP280x_Gpio.c file InitGpio(); // Clear all interrupts and initialize PIE vector table: Disable CPU interrupts DINT; // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; /*------------------------------------------------------------------ Copy API Functions into SARAM The flash API functions MUST be run out of internal zero-waitstate SARAM memory. This is required for the algos to execute at the proper CPU frequency. If the algos are already in SARAM then this step can be skipped. DO NOT run the algos from Flash DO NOT run the algos from external memory ------------------------------------------------------------------*/ // Copy the Flash API functions to SARAM // We must also copy required user interface functions to RAM. MemCopyPointer(&Flash28_API_LoadStart, &Flash28_API_LoadEnd, &Flash28_API_RunStart); MemCopyPointer(&BootRamfuncsLoadStart, &BootRamfuncsLoadEnd, &BootRamfuncsRunStart); //MemCopyPointer(&RamfuncsLoadStart11, &RamfuncsLoadEnd11, &RamfuncsRunStart11); asm(" RPT #7 || NOP"); InitFlash(); InitECap(); //Ӧ�ó������_main() // Application_Entry_Point(); // by dyj at 2008.08.28 // Initialize CPU Timers To default State: InitCpuTimers(); InitECan(); //CAN�������: CallFlashAPI(); return; }
按照你的设计来说,应该是不需要用到BOOT ROM的吧?如果没有用到BOOT ROM,将LaunchPad上的BOOT模式选择开关打到FLASH boot mode试一下。
2)后来我修改了0Xd00寄存器数据为0x5AFF FFFF
0x0D00寄存器是指向量表中的Reset中断向量吗?
1.按照我的设计是不需要BOOTROM,但是我需要带仿真器单步查找问题。
我的问题您清楚了吗?
我的问题关键是:自己的上位机CAN下载FLASH后,如果不断电,是烧写成功的。一断电就不能重新启动了。所以我需要查BOOTROM这段程序。
实验已经证明,如果修改了0XD00的数据,就可以启动。这个说明我用上位机烧写的FLASH是成功的,只是在重新启动时被BOOTBOM卡住了。
0x0D00寄存器是指向量表中的Reset中断向量吗?-----0XD00是对应BOOTROM需要的EMU-BOOTPIN-CONFIG地址。
我的问题关键是:自己的上位机CAN下载FLASH后,如果不断电,是烧写成功的。一断电就不能重新启动了。所以我需要查BOOTROM这段程序。
1)首先我用CCS10.0加载调试程序时,点击ccs菜单''CPU RESER",程序进入0x3fc7a5,然后运行,程序停止在BOOTROM中的一段''WAIT-BOOT"中。
3)如果我用CCS DEBUG下载.out文件到280049开发板,开发板断电后再上电,主程序启动正常(因为可以看到CAN通信读取数据到我的上位机)。
我对上面这些陈述的理解就是:插着仿真器的时候,就会出现你描述的这些错误;而不连接仿真器的时候,也就是standalone的时候,是可以正常工作的。
我可以这样理解吗?
1.自己的上位机CAN下载FLASH后,如果不断电,是烧写成功的,主程序启动正常。一断电就不能重新启动主程序。
2.用CCS DEBUG下载.out文件到280049开发板,开发板断电后再上电,主程序启动正常
这个问题其实挺难通过调试器来排查的。因为插着仿真器和不插仿真器的时候BOOT的流程不一样。0x0D00 - EMU-BOOTPIN-CONFIG寄存器是只有在连接仿真器的时候才起作用的。
我建议在两种烧录方式烧录之后,分别将内存中的固件读取出来,比较一下有什么差异。
通过can升级的.out文件和通过调试器烧录的.out文件是同一个吧?升级的程序和芯片内之前的程序都是一样的结构吧?这个文件既包含主程序,也包含boot程序,那boot部分会重新擦写吗?
这个问题其实挺难通过调试器来排查的。因为插着仿真器和不插仿真器的时候BOOT的流程不一样。0x0D00 - EMU-BOOTPIN-CONFIG寄存器是只有在连接仿真器的时候才起作用的。
我建议在两种烧录方式烧录之后,分别将内存中的固件读取出来,比较一下有什么差异。
通过can升级的.out文件和通过调试器烧录的.out文件是同一个吧?升级的程序和芯片内之前的程序都是一样的结构吧?这个文件既包含主程序,也包含boot程序,那boot部分会重新擦写吗?
-------------------------------------------------------------------
在两种烧录方式烧录之后,分别将内存中的固件读取出来,对比过了,FLASH内容没有差异。。。。
因为插着仿真器在0XD00写入0XA5XX XXXX就进入单机上电模式,和不插仿真器的时候BOOT的流程就类似了,目前只能这样查问题。
我目前比较尴尬的是CAN下载程序后,必须要用仿真器改写0XD00地址内容才能跑起来。。。。。。。。。。。。。。
EMU-OTP-BOOTPIN-CONFIG--------0XD00可以改,这个Z1-OTP-BOOTPIN-CONFIG(0x0005F008)在CCS/Memory Browser里改不了。在On-chip-flash设置里,也没有修改这个0x5F008的地址,但是可以修改0X5F00A。
另外请问一下:4.6.2 BOOT ROM User OTP中的0x7800C 0x7800D在On Chip Flash修改了以后是否就会在0X5F008显示出修改的数据?
就是他们的数据在stand alone模式下会是关联的?
谢谢。