如题所示,当我一次写入37250个16bit的数据,调试正常如下
当我一次性写入50000个16bit的数据,调试界面如下,调试窗口的变量不进行更新
当我一次性写入80000个16bit的数据,程序直接崩溃,无法开始运行,只能暂停或者结束调试
我的程序流程大概如下:28377对两块SRAM实现乒乓操作:CPU1首先对SRAM1进行写入数据,然后同时CPU2对SRAM2进行数据读取并写入,然后CPU1对SRAM2进行写入数据,同时CPU2对SRAM1进行数据读取并写入,只是一个简单的乒乓操作,代码如下,请问是什么问题呢??很急!!!!辛苦尽快给我参考意见,感谢!!!
CPU1代码
#include "device.h" #include "F28x_Project.h" #include "board.h" #include <driverlib.h> #define ASRAM_CS2_START_ADDR 0x100000//手册规定CS2起始地址 #define ASRAM_CS3_START_ADDR 0x300000//与FPGA通信 #define ASRAM_CS4_START_ADDR 0x380000 #define data_length 80000//测试的单次写入极限 void data_write(void); void initEMIFA(void); void setupEMIF1PinmuxAsync16Bit(void); EMIF_AsyncTimingParams tparam; //数据缓存数组 uint16_t data_CS2[data_length] = {0};//存储的均为字(Word,16bit) uint16_t data_CS4[data_length] = {0}; //IPC通信变量 IPC_MessageQueue_t messageQueue; IPC_Message_t TxMsg, RxMsg; uint16_t current_buffer=0;//0-CS2 1-CS4 #pragma DATA_SECTION(data_CS2,"data_CS2"); #pragma DATA_SECTION(data_CS4,"data_CS4"); /** * main.c */ void main(void) { int i=0; Device_init(); // Initialize device clock and peripherals Device_initGPIO(); // Initialize GPIO and configure the GPIO pin as a push-pull output Interrupt_initModule(); // Initialize PIE and clear PIE registers. Disables CPU interrupts. IER = 0x0000; //CPU级中断使能 IFR = 0x0000; //清除CPU级中断标志 Interrupt_initVectorTable(); // Initialize the PIE vector table with pointers to ISR Board_init(); //启动CPU2代码 #ifdef _STANDALONE #ifdef _FLASH // Send boot command to allow the CPU02 application to begin execution //IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);//这是bit-field库 IPC_setBootMode(IPC_CPU1_L_CPU2_R, C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH); #else // Send boot command to allow the CPU02 application to begin execution //IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM); IPC_setBootMode(IPC_CPU1_L_CPU2_R, C1C2_BROM_BOOTMODE_BOOT_FROM_RAM); #endif #endif // // Clear any IPC flags if set already // IPC_clearFlagLtoR(IPC_CPU1_L_CPU2_R, IPC_FLAG_ALL); // // Initialize message queue // IPC_initMessageQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_INT1, IPC_INT1); // // Synchronize both the cores // IPC_sync(IPC_CPU1_L_CPU2_R, SYNC_FLAG); EINT; // Enable Global Interrupt (INTM) ERTM; // Enable real-time interrupt (DBGM) initEMIFA(); TxMsg.command = 0; TxMsg.address = 0; // TxMsg.dataw1 = current_buffer;//当前的缓冲区 0:CS2_SRAM 1:CS4_SRAM TxMsg.dataw2 = 1;//校验,看数据传输是否正确 for (;;) { EMIF_selectMaster(EMIF1CONFIG_BASE, EMIF_MASTER_CPU1_G);//CPU1独占 CPU2只能读不能写 //实时更新current_buffer的值 TxMsg.dataw1 = current_buffer;//当前的缓冲区 0:CS2_SRAM 1:CS4_SRAM data_write();//CPU1写入SRAM EMIF_selectMaster(EMIF1CONFIG_BASE, EMIF_MASTER_CPU1_NG);//CPU1NG CPU2可以选为主控 IPC_sendMessageToQueue(IPC_CPU1_L_CPU2_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE, &TxMsg, IPC_BLOCKING_CALL); GPIO_togglePin(myGPIO99); DELAY_US(1000000); } } /* * CS2_SRAM、CS4_SRAM交替写入5555、AAAA * 调用次数 current_buffer 操作SRAM 写入值(修正后) 1 0 CS2 0x5555 2 1 CS4 0x5555 3 0 CS2 0xAAAA 4 1 CS4 0xAAAA * */ void data_write(void) { int i=0; static int CS2=0;//0-5555 1-AAAA static int CS4=0;//0-5555 1-AAAA //模拟发送的递增数据 uint16_t increaseData = 0; //乒乓 if(current_buffer==0) { if(CS2==0) { for(i=0;i<data_length;i++) { data_CS2[i]=0x5555; } } else { for(i=0;i<data_length;i++) { data_CS2[i]=0xAAAA; } } CS2 ^= 1; } else { if(CS4==0) { for(i=0;i<data_length;i++) { data_CS4[i]=0x5555; } } else { for(i=0;i<data_length;i++) { data_CS4[i]=0xAAAA; } } CS4 ^= 1; } //此处使用异或 不同为1 相同为0 //切换缓冲区 current_buffer ^= 1; } void setupEMIF1PinmuxAsync16Bit(void) { uint16_t i; GPIO_setPinConfig(GPIO_28_EM1CS4N); GPIO_setPinConfig(GPIO_29_EM1SDCKE); GPIO_setPinConfig(GPIO_30_EM1CLK); GPIO_setPinConfig(GPIO_31_EM1WEN); // GPIO_setPinConfig(GPIO_32_EM1CS0N);//CS0只能用于SDRAM,电路图连接的SRAM1,无法使用 GPIO_setPinConfig(GPIO_33_EM1RNW); GPIO_setPinConfig(GPIO_34_EM1CS2N); GPIO_setPinConfig(GPIO_35_EM1CS3N); GPIO_setPinConfig(GPIO_36_EM1WAIT); GPIO_setPinConfig(GPIO_37_EM1OEN); // // Selecting address lines. // GPIO_setPinConfig(GPIO_38_EM1A0); GPIO_setPinConfig(GPIO_39_EM1A1); GPIO_setPinConfig(GPIO_40_EM1A2); GPIO_setPinConfig(GPIO_41_EM1A3); GPIO_setPinConfig(GPIO_44_EM1A4); GPIO_setPinConfig(GPIO_45_EM1A5); GPIO_setPinConfig(GPIO_46_EM1A6); GPIO_setPinConfig(GPIO_47_EM1A7); GPIO_setPinConfig(GPIO_48_EM1A8); GPIO_setPinConfig(GPIO_49_EM1A9); GPIO_setPinConfig(GPIO_50_EM1A10); GPIO_setPinConfig(GPIO_51_EM1A11); GPIO_setPinConfig(GPIO_52_EM1A12); GPIO_setPinConfig(GPIO_86_EM1A13); GPIO_setPinConfig(GPIO_87_EM1A14); GPIO_setPinConfig(GPIO_88_EM1A15); GPIO_setPinConfig(GPIO_89_EM1A16); GPIO_setPinConfig(GPIO_90_EM1A17); // // Selecting data lines. //21-16都没用,电路采用的SRAM是16bit的,只需要D0-D15即可 GPIO_setPinConfig(GPIO_63_EM1D21); GPIO_setPinConfig(GPIO_64_EM1D20); GPIO_setPinConfig(GPIO_65_EM1D19); GPIO_setPinConfig(GPIO_66_EM1D18); GPIO_setPinConfig(GPIO_67_EM1D17); GPIO_setPinConfig(GPIO_68_EM1D16); GPIO_setPinConfig(GPIO_69_EM1D15); GPIO_setPinConfig(GPIO_70_EM1D14); GPIO_setPinConfig(GPIO_71_EM1D13); GPIO_setPinConfig(GPIO_72_EM1D12); GPIO_setPinConfig(GPIO_73_EM1D11); GPIO_setPinConfig(GPIO_74_EM1D10); GPIO_setPinConfig(GPIO_75_EM1D9); GPIO_setPinConfig(GPIO_76_EM1D8); GPIO_setPinConfig(GPIO_77_EM1D7); GPIO_setPinConfig(GPIO_78_EM1D6); GPIO_setPinConfig(GPIO_79_EM1D5); GPIO_setPinConfig(GPIO_80_EM1D4); GPIO_setPinConfig(GPIO_81_EM1D3); GPIO_setPinConfig(GPIO_82_EM1D2); GPIO_setPinConfig(GPIO_83_EM1D1); GPIO_setPinConfig(GPIO_85_EM1D0); // // Setting DQM and Bank Select lines. // // GPIO_setPinConfig(GPIO_88_EM1DQM0);//复用为地址线 // GPIO_setPinConfig(GPIO_89_EM1DQM1);//复用为地址线 // GPIO_setPinConfig(GPIO_90_EM1DQM2);//复用为地址线 // GPIO_setPinConfig(GPIO_91_EM1DQM3);//复用为地址线 GPIO_setPinConfig(GPIO_92_EM1BA1); GPIO_setPinConfig(GPIO_93_EM1BA0); GPIO_setPinConfig(GPIO_94_EM1A21); // // Setup async mode and enable pull-ups for Data pins. // GPIO84电路有上拉?什么作用? for(i=69; i<=85;i++) { if(i != 84) { GPIO_setPadConfig(i, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(i, GPIO_QUAL_ASYNC); } } } /* * EMIF1CLK = CPU1SYSCLK * 无访问保护 */ void initEMIFA(void) { // // Configure to run EMIF1 on full Rate. (EMIF1CLK = CPU1SYSCLK) // SysCtl_setEMIF1ClockDivider(SYSCTL_EMIF1CLK_DIV_1);//不分频 // // Grab EMIF1 For CPU1. // 是否可以CPU1写CPU2读?grab是什么意思 EMIF_selectMaster(EMIF1CONFIG_BASE, EMIF_MASTER_CPU1_G);//CPU1独占 CPU2只能读不能写 // // Disable Access Protection. (CPU_FETCH/CPU_WR/DMA_WR) // EMIF_setAccessProtection(EMIF1CONFIG_BASE, 0x0);//000 无访问保护 // // Commit the configuration related to protection. Till this bit remains // set, contents of EMIF1ACCPROT0 register can't be changed. // EMIF_commitAccessConfig(EMIF1CONFIG_BASE); // // Lock the configuration so that EMIF1COMMIT register can't be changed // any more. // EMIF_lockAccessConfig(EMIF1CONFIG_BASE); // // Configure GPIO pins for EMIF1. // setupEMIF1PinmuxAsync16Bit();//为什么有些注释掉? // // Configures Normal Asynchronous Mode of Operation. // 配置 为 异步正常模式。 EMIF_setAsyncMode(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET, EMIF_ASYNC_NORMAL_MODE); EMIF_setAsyncMode(EMIF1_BASE, EMIF_ASYNC_CS3_OFFSET, EMIF_ASYNC_NORMAL_MODE); EMIF_setAsyncMode(EMIF1_BASE, EMIF_ASYNC_CS4_OFFSET, EMIF_ASYNC_NORMAL_MODE); // // Disables Extended Wait Mode. // 禁用 扩展等待模式:即,访问超时时间是固定的,不会因为等待信号延长。 EMIF_disableAsyncExtendedWait(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET); EMIF_disableAsyncExtendedWait(EMIF1_BASE, EMIF_ASYNC_CS3_OFFSET); EMIF_disableAsyncExtendedWait(EMIF1_BASE, EMIF_ASYNC_CS4_OFFSET); // // Configure EMIF1 Data Bus Width. // 设置 数据总线宽度为 16 位 EMIF_setAsyncDataBusWidth(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET, EMIF_ASYNC_DATA_WIDTH_16); EMIF_setAsyncDataBusWidth(EMIF1_BASE, EMIF_ASYNC_CS3_OFFSET, EMIF_ASYNC_DATA_WIDTH_16); EMIF_setAsyncDataBusWidth(EMIF1_BASE, EMIF_ASYNC_CS4_OFFSET, EMIF_ASYNC_DATA_WIDTH_16); // // Configure the access timing for CS2 space. // 配置 读写时序参数 tparam.rSetup = 0; tparam.rStrobe = 14; // tparam.rStrobe = 3; // tparam.rHold = 0; tparam.rHold = 1; tparam.turnArnd = 1; tparam.wSetup = 0; tparam.wStrobe = 14; tparam.wHold = 0; EMIF_setAsyncTimingParams(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET, &tparam); EMIF_setAsyncTimingParams(EMIF1_BASE, EMIF_ASYNC_CS3_OFFSET, &tparam); EMIF_setAsyncTimingParams(EMIF1_BASE, EMIF_ASYNC_CS4_OFFSET, &tparam); }
CPU2代码
#include "device.h" #include "F28x_Project.h" #include "board.h" #include <driverlib.h> #define ASRAM_CS2_START_ADDR 0x100000//手册规定CS2起始地址 #define ASRAM_CS3_START_ADDR 0x300000//与FPGA通信 #define ASRAM_CS4_START_ADDR 0x380000 #define data_length 80000 EMIF_AsyncTimingParams tparam; //数据缓存数组 uint16_t data_CS2_CPU2[data_length] = {0};//存储的均为字(Word,16bit) uint16_t data_CS4_CPU2[data_length] = {0}; uint16_t CS2; uint16_t CS4; bool status = false; IPC_MessageQueue_t messageQueue; IPC_Message_t TxMsg, RxMsg; uint16_t IPCCount; volatile uint16_t dataReadyFlag = 0;//CPU1发消息确认FLAG volatile uint16_t dataSource = 0; // 0: CS4_SRAM, 1: CS2_SRAM 与CPU1相反避免BUFFER冲突 #pragma DATA_SECTION(data_CS2_CPU2,"data_CS2_CPU2"); #pragma DATA_SECTION(data_CS4_CPU2,"data_CS4_CPU2"); __interrupt void IPC_1_ISR(void); /** * main.c */ void main(void) { int i=0; Device_init(); // Initialize device clock and peripherals Device_initGPIO(); // Initialize GPIO and configure the GPIO pin as a push-pull output Interrupt_initModule(); // Initialize PIE and clear PIE registers. Disables CPU interrupts. IER = 0x0000; //CPU级中断使能 IFR = 0x0000; //清除CPU级中断标志 Interrupt_initVectorTable(); // Initialize the PIE vector table with pointers to ISR Board_init(); // // Clear any IPC flags if set already // IPC_clearFlagLtoR(IPC_CPU2_L_CPU1_R, IPC_FLAG_ALL); // // Initialize message queue // IPC_initMessageQueue(IPC_CPU2_L_CPU1_R, &messageQueue, IPC_INT1, IPC_INT1); // // Synchronize both the cores. // IPC_sync(IPC_CPU2_L_CPU1_R, SYNC_FLAG); EINT; // Enable Global Interrupt (INTM) ERTM; // Enable real-time interrupt (DBGM) for (;;) { if (dataReadyFlag) { dataReadyFlag = 0; // 清除标志 if (dataSource == 0) { // 从 CS4_SRAM 中读取数据进行运算 与CPU1相反避免BUFFER冲突 //processDataFromCS2(); //现在只是读取数组中的一个元素 //问题:怎么直接调用CPU1写入的数组,若是CPU2读取再写入涉及到主控权的更换,现在只读取了一个数据 //跑通之后,CPU1写完数据即可尝试释放主控(CPU1_NG),CPU2再次获取主控进行读取和写入再释放主控(CPU1_NG),借用例程的写法 CS4=*((uint16_t*)ASRAM_CS4_START_ADDR);//(uint16_t*)把地址强转为uint16_t for(i=0;i<data_length;i++) { data_CS2_CPU2[i]=*(((uint16_t*)ASRAM_CS2_START_ADDR)+i); } // data_CS4[0]=1; } else { // 从 CS2_SRAM 中读取数据进行运算 //processDataFromCS4(); CS2=*((uint16_t*)ASRAM_CS2_START_ADDR);//(uint16_t*)把地址强转为uint16_t // data_CS2[0]=1; for(i=0;i<data_length;i++) { data_CS4_CPU2[i]=*(((uint16_t*)ASRAM_CS4_START_ADDR)+i); } } EMIF_selectMaster(EMIF1CONFIG_BASE, EMIF_MASTER_CPU1_NG);//CPU1NG CPU1可以选为主控 } } } // // IPC ISR for Flag 1 // C28x core sends data with message queue using Flag 0 // __interrupt void IPC_1_ISR(void) { EMIF_selectMaster(EMIF1CONFIG_BASE, EMIF_MASTER_CPU2_G);//CPU2独占 CPU1只能读不能写 // // Read the message from the message queue // IPC_readMessageFromQueue(IPC_CPU2_L_CPU1_R, &messageQueue, IPC_ADDR_CORRECTION_ENABLE, &RxMsg, IPC_NONBLOCKING_CALL); if(RxMsg.dataw2 == 1) { status = true; dataSource = RxMsg.dataw1;//获取CPU1的currentbuffer dataReadyFlag = 1; } IPCCount++; // // Send response message // // TxMsg.command = IPC_CMD_RESP; // TxMsg.address = 0; // Not used // TxMsg.dataw1 = status ? TEST_PASS : TEST_FAIL; // TxMsg.dataw2 = RxMsg.dataw2; // Use the message identifier from the received message // // IPC_sendMessageToQueue(IPC_CPU2_L_CPU1_R, &messageQueue, IPC_ADDR_CORRECTION_DISABLE, // &TxMsg, IPC_NONBLOCKING_CALL); // // Acknowledge the flag // IPC_ackFlagRtoL(IPC_CPU2_L_CPU1_R, IPC_FLAG1); // // Acknowledge the PIE interrupt. // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); }
你好,程序卡死的问题解决了,但是程序崩溃的原因还没找到,数组一旦超过65536就会崩溃,调试的时候无法运行程序,主动给他暂停之后CPU1和CPU2程序都会卡在下图所示位置中
一直卡在这个for循环,请问这是什么语句?会不会是这个length上限是65536?length的定义我看是length_t,但是length_t找不到定义