如题所示,当我一次写入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);
}

