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.

TMS320F28377D: 你好,我利用EMIF写入SRAM存在一个问题:当我一次写入32750个数据,程序正常运行,当我一次写入50000个数据,程序在调试界面直接卡死,调试窗口的值不进行更新,写入80000个数据则直接崩溃,是什么问题呢??

Part Number: TMS320F28377D


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