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.

AM5718: DSP核无法在Hwi中断回调函数中调用MCSPI_transfer

Part Number: AM5718
Other Parts Discussed in Thread: SYSBIOS

TI的工程师,你好。

我在使用MCSPI的时候遇到了这样一个问题,在Task中使用MCSPI_transfer没有任何问题(EDMA传输),但是在Hwi或者定时器中断回调函数中调用时就无法运行了,值得注意的是,中断回调函数是可以在正常情况下使用的,运行错误日志如下:

[t=0x02abab8e] ti.sysbios.knl.Semaphore: ERROR: line 289: assertion failure: A_badContext: bad calling context. Must be called from a Task.
[ 0.058] ti.sysbios.knl.Semaphore: line 289: assertion failure: A_badContext: bad calling context. Must be called from a Task.
[ 0.058] xdc.runtime.Error.raise: terminating execution

初始化参数配置如下:

MCSPI_Handle tMcpi;

MCSPI_Params tMcSpiParams;


MCSPI_Params_init(&tMcSpiParams);
tMcSpiParams.frameFormat = SPI_POL0_PHA0;
tMcSpiParams.transferTimeout = 0xffff;
tMcSpiParams.bitRate = MCSPI_OUT_FREQ;
tMcSpiParams.dataSize = 8;
tMcSpiParams.mode = SPI_MASTER;
tMcSpiParams.transferCallbackFxn = NULL;//atCbFxn[tInstance];
tMcSpiParams.transferMode = SPI_MODE_CALLBACK;

tMcpi = MCSPI_open(tInstance, tInstance, &tMcSpiParams);

传输参数配置如下:

SPI_Transaction tTransaction;
tTransaction.status = SPI_TRANSFER_STARTED;
tTransaction.count = 20;
tTransaction.txBuf = &tmptxbuff[0];
tTransaction.rxBuf = &tmprxbuff[0];
MCSPI_transfer(tMcpi, &tTransaction);

而我查看了MCSPI_transfer的使用说明,有这样一句描述:

In SPI_MODE_CALLBACK, MCSPI_transfer() does not block task execution and calls a MCSPI_CallbackFxn. This makes the MCSPI_tranfer() safe to be used within a Task, Swi, or Hwi context. The SPI_Transaction structure must stay persistent until the MCSPI_transfer function has completed!

可是MCSPI_transfer函数为什么不能在回调函数中使用呢?

  • ti.sysbios.knl.Semaphore: ERROR: line 289: assertion failure: A_badContext: bad calling context. Must be called from a Task.

    先看一下提示中的报错,是否有用到Semaphore

    另外如何在HWI的回调函数中使用的?

  • 感谢回复!

    1、我在HWI中断回调函数中只调用了MCSPI_transfer(),当transferCallbackFxn 不为空时,EDMA回调函数中只有一个system_printf();我研究了一下MCSPI_transfer函数内部实现,看到下层调用MCSPI_transfer_v1时调用了SPI_osalPendLock(object->mutex,SemaphoreP_WAIT_FOREVER),也就是说,只要我调用了MCSPI_transfer函数,就一定会用到Semaphore,那这样就说明API说明有误了。

    2、Hwi中断函数中的内容如下:

    SPI_Transaction tTransaction;
    tTransaction.status = SPI_TRANSFER_STARTED;
    tTransaction.count = 20;
    tTransaction.txBuf = &tmptxbuff[0];
    tTransaction.rxBuf = &tmprxbuff[0];
    MCSPI_transfer(tMcpi, &tTransaction);

    问题:

    1、能否实现在中断中使用SPI传输?

    2、如果不能在中断中使用SPI传输,那么如何才能实现高频率触发SPI传输?

  • 我在英文论坛看到一个类似的帖子,您可以在英文论坛发帖吗?建议到英文论坛咨询一下产品线专家。

    e2e.ti.com/.../am3358-cannot-call-spi_transfer-in-hwi-context

  • 谢谢你的回复,Nancy。

    我看了这个帖子,但修改TI的源代码并不是好的解决办法,另外,我不能在英文论坛上发帖。

    并且,我还测试了在一个没有延时的任务中调用MCSPI_transfer函数,并且在传输结束后控制IO口翻转,结果示波器测试出IO口翻转频率仅仅只有4khz左右,而SPI的频率为48Mhz,当我屏蔽掉这个函数后,仅仅只做IO口翻转,测试出的IO口翻转频率为600khz-1300khz左右,说明MCSPI_transfer的延时很大;

    1、那么是不是无法做到高频率(100khz-200khz)触发SPI传输?

    2、这样的话是不是在中断回调函数中调用就不太合理了?