you appear not to fully understand how queues work. No, your system does NOT work “normal” or as expected. Your Tx task keeps filling up the queue until it runs out of space, after that, new messages are dropped because you do not check the return value of xQueueSend with no timeout. You may want to study the documentation closer.
Would you please share your complete application code and share how you expect it to work? Do not add random vTaskDelay
calls unless you want them to be in the application.
@aggarg I reduced the code to two task:
- prvTxTask: It only prints “Entering task tx” and “Leaving task tx”, with a delay of 500ms between the those message.
- Video_DMA_App: It waits to take the semaphore released by WriteCallBack function, then print a message.
I don’t use queues anymore.
My questions is why prvTxTask stop when i add interruptions in the function SetupIntrSystem_WR_RD()
int main( void )
{
int Status;
SemVDMARd = xSemaphoreCreateBinary();
SemVDMAWr = xSemaphoreCreateBinary();
if(xTaskCreate( prvTxTask, ( const char * ) "Tx", 2*configMINIMAL_STACK_SIZE, NULL, 1, &xTxTask ) != pdPASS)//1
{
xil_printf("Tx Task was not created\r\n");
for(;;);
}
if( xTaskCreate( vTask_Video_DMA_App, ( const char * ) "VDMA", 10*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 3, &xHandler_VDMA ) != pdPASS )
{
xil_printf("VDMA Task was not created\r\n");
for(;;);
}
vTaskStartScheduler();
for( ;; );
}
static void prvTxTask( void *pvParameters )
{
for( ;; )
{
xil_printf("Entering Task Tx\r\n");
vTaskDelay(pdMS_TO_TICKS(500));
xil_printf("Leaving Task Tx\r\n");
}
}
void vTask_Video_DMA_App(void *args){
int status;
int Index;
u32 Addr;
XAxiVdma myVDMA;
ptr_myVDMA = &myVDMA;
XAxiVdma_Config *config = XAxiVdma_LookupConfig(XPAR_AXIVDMA_0_DEVICE_ID);
XAxiVdma_DmaSetup ReadCfg;
XAxiVdma_DmaSetup WriteCfg;
uint32_t VDMA_TaskEnterCounter = 0;
uint32_t VDMA_TookSmphr = 0;
uint32_t VDMA_TaskExitCounter = 0;
xil_printf("Task VDMA Started\r\n");
if(SemVDMARd==NULL){
xil_printf("Could not create semaphore SemVDMARd\n");
for(;;);
}
if(SemVDMAWr==NULL){
xil_printf("Could not create semaphore SemVDMAWr\n");
for(;;);
}
status = XAxiVdma_CfgInitialize(&myVDMA, config, config->BaseAddress);
if(status != XST_SUCCESS){
xil_printf("DMA Initialization failed");
for(;;);
}
status = XAxiVdma_SetFrmStore(&myVDMA, myVDMA.MaxNumFrames, XAXIVDMA_WRITE);
if (status != XST_SUCCESS) {
xil_printf(
"Setting Frame Store Number Failed in Write Channel"
" %d\r\n", status);
for(;;);
}
status = XAxiVdma_SetFrmStore(&myVDMA, myVDMA.MaxNumFrames, XAXIVDMA_READ);
if (status != XST_SUCCESS) {
xil_printf(
"Setting Frame Store Number Failed in Read Channel"
" %d\r\n", status);
for(;;);
}
// READ CHANNEL CONFIG
ReadCfg.VertSizeInput = VSize;
ReadCfg.HoriSizeInput = HSize*Bytes_Per_Data;
ReadCfg.Stride = HSize*Bytes_Per_Data;
ReadCfg.FrameDelay = 0;
ReadCfg.EnableCircularBuf = 1;
ReadCfg.EnableSync = 1;
ReadCfg.PointNum = 0;
ReadCfg.EnableFrameCounter = 0;
ReadCfg.FixedFrameStoreAddr = 0;
ReadCfg.GenLockRepeat = 0;
status = XAxiVdma_DmaConfig(&myVDMA, XAXIVDMA_READ, &ReadCfg);
if (status != XST_SUCCESS) {
xil_printf("Read channel config failed %d\r\n", status);
for(;;);
}
Addr = (u32)&(Buffer[0]);
for(Index = 0; Index < myVDMA.MaxNumFrames; Index++) {
ReadCfg.FrameStoreStartAddr[Index] = Addr;
Addr += FrameSize;
}
status = XAxiVdma_DmaSetBufferAddr(&myVDMA, XAXIVDMA_READ,ReadCfg.FrameStoreStartAddr);
if (status != XST_SUCCESS) {
xil_printf("Read channel set buffer address failed %d\r\n", status);
for(;;);
}
XAxiVdma_IntrEnable(&myVDMA, XAXIVDMA_IXR_COMPLETION_MASK, XAXIVDMA_READ);
WriteCfg.VertSizeInput = VSize;
WriteCfg.HoriSizeInput = HSize*Bytes_Per_Data;
WriteCfg.Stride = HSize*Bytes_Per_Data;
WriteCfg.FrameDelay = 0;
WriteCfg.EnableCircularBuf = 1;
WriteCfg.EnableSync = 1;
WriteCfg.PointNum = 0;
WriteCfg.EnableFrameCounter = 0;
WriteCfg.FixedFrameStoreAddr = 0;
WriteCfg.GenLockRepeat = 0;
status = XAxiVdma_DmaConfig(&myVDMA, XAXIVDMA_WRITE, &WriteCfg);
if (status != XST_SUCCESS) {
xil_printf("Write channel config failed %d\r\n", status);
for(;;);
}
Addr = (u32)&(Buffer[0]);
for(Index = 0; Index < myVDMA.MaxNumFrames; Index++) {
WriteCfg.FrameStoreStartAddr[Index] = Addr;
Addr += FrameSize;
}
status = XAxiVdma_DmaSetBufferAddr(&myVDMA, XAXIVDMA_WRITE,WriteCfg.FrameStoreStartAddr);
if (status != XST_SUCCESS) {
xil_printf("write channel set buffer address failed %d\r\n", status);
for(;;);
}
XAxiVdma_IntrEnable(&myVDMA, XAXIVDMA_IXR_COMPLETION_MASK, XAXIVDMA_WRITE);
memset((void *)Buffer, 0,FrameSize);
Xil_DCacheFlush();
//Xil_DCacheFlushRange(WriteFrameAddr, FRAME_HORIZONTAL_LEN * FRAME_VERTICAL_LEN * WriteCount);
status = SetupIntrSystem_WR_RD(&myVDMA, WRITE_INTR_ID, READ_INTR_ID);
if (status != XST_SUCCESS) {
xil_printf(
"Setup interrupt system failed %d\r\n", status);
for(;;);
}
status = XAxiVdma_DmaStart(&myVDMA, XAXIVDMA_WRITE);
if (status != XST_SUCCESS) {
xil_printf("Start Write transfer failed %d\r\n", status);
for(;;);
}
status = XAxiVdma_DmaStart(&myVDMA,XAXIVDMA_READ);
if (status != XST_SUCCESS) {
if(status == XST_VDMA_MISMATCH_ERROR) xil_printf("Start Read transfer failed %d\r\n",status);
for(;;);
}
// Binary semaphores are set in main()
for(;;){
if( xSemaphoreTake( SemVDMAWr, portMAX_DELAY) == pdTRUE ){
xil_printf("VDMA: Semphr took \r\n");
}
}
}
static void WriteCallBack(void *CallbackRef, u32 Mask)
{
static BaseType_t xHigherPriorityTaskWoken2 = pdFALSE;
static int counterTx = 0;
xHigherPriorityTaskWoken2 = pdFALSE;
counterTx++;
//xSemaphoreGiveFromISR(SemVDMAWr, &xHigherPriorityTaskWoken2);
if(counterTx > 30){
counterTx = 0;
xSemaphoreGiveFromISR(SemVDMAWr, &xHigherPriorityTaskWoken2);
}
portYIELD_FROM_ISR( xHigherPriorityTaskWoken2);
}
static void WriteErrorCallBack(void *CallbackRef, u32 Mask)
{
xil_printf("W_ERR\r\n");
}
static void ReadCallBack(void *CallbackRef, u32 Mask)
{
static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
static int counterRx = 0;
xHigherPriorityTaskWoken = pdFALSE;
counterRx++;
if(counterRx>100){
xSemaphoreGiveFromISR(SemVDMARd, &xHigherPriorityTaskWoken);
}
portYIELD_FROM_ISR( xHigherPriorityTaskWoken);
}
static void ReadErrorCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("R_ERR\r\n");
}
static int SetupIntrSystem_WR_RD(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId, u16 WriteIntrId)
{
int Status;
configSETUP_TICK_INTERRUPT();
/* Instance of the Interrupt Controller */
XScuGic *IntcInstancePtr = &xInterruptController;
Status = xPortInstallInterruptHandler( ReadIntrId, (XInterruptHandler) XAxiVdma_ReadIntrHandler, AxiVdmaPtr);
Status = xPortInstallInterruptHandler( WriteIntrId, (XInterruptHandler) XAxiVdma_WriteIntrHandler, AxiVdmaPtr);
XScuGic_SetPriorityTriggerType(IntcInstancePtr, ReadIntrId, 0xA0, 0x3);//(configMAX_API_CALL_INTERRUPT_PRIORITY + 1) << portPRIORITY_SHIFT
XScuGic_SetPriorityTriggerType(IntcInstancePtr, WriteIntrId, 0xA0, 0x3);
//Xil_ExceptionInit();
// Connect the interrupt controller interrupt handler to the hardware interrupt handling logic in the processor.
//Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,IntcInstancePtr);
Xil_ExceptionEnable();//Enable interrupts in the Processor.
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL, ReadCallBack, (void *)AxiVdmaPtr, XAXIVDMA_READ);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR, ReadErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_READ);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL, WriteCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR, WriteErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);
vPortEnableInterrupt(ReadIntrId);
vPortEnableInterrupt(WriteIntrId);
return XST_SUCCESS;
}
This is what you meant with
thanks in advanced
I would recommend that you relocate all of your dma initialization into main() before you start the scheduler. Once the scheduler is started, interrupts are enabled which may interfere with a lot of things when your dma is not yet fully initialized.
The tasks in the current code look okay and you do not need to add any more vTaskDelay. As @RAc suggested, try moving the DMA init code to main.