Synchronizing multiple tasks

Hello, I am currently developing software that initiates SPI communication between 2 SPI ports. I currently only have 1 task that accomplishes this (Figure 1): /* Task1 */ void vTask1(void *pvParameters) { spiDAT1_t dataconfig1_t;
dataconfig1_t.CS_HOLD   = FALSE;
dataconfig1_t.WDEL         = TRUE;
dataconfig1_t.DFSEL        = SPI_FMT_0;
dataconfig1_t.CSNR         = 0xF7;

for(;;)
{
    /* Initiate SPI2 Transmit and Receive through Interrupt Mode */
    spiSendAndGetData(spiREG2, &dataconfig1_t, 16, TX_Data_Slave, RX_Data_Slave);

    /* Initiate SPI1 Transmit and Receive through Polling Mode */
    spiTransmitAndReceiveData(spiREG1, &dataconfig1_t, 16, TX_Data_Master, RX_Data_Master);
}
} What I would like to do is split this task into two separate tasks. The first task will use the spiSendAndGet() function and the second will use the spiTransmitAndRecieveData() function. I believe creating two tasks from this one task won’t be too difficult. What I’m worried about is synchronizing the two tasks. I am relatively new to RTOS and I’m not too sure how I could make sure that the two tasks would not conflict with one another. Any information regarding this topic would be greatly appreciated! Calvin Wallen IV

Synchronizing multiple tasks

The two tasks would be using different SPI ports, so there would not be a hardware conflict. Can you be more specific about what it is you are worried will conflict?

Synchronizing multiple tasks

Edit: response was moved to Real Time Engineers ltd. reply thread

Synchronizing multiple tasks

Example: Task1 is responsible for the setup of the SPI1 (MASTER) register and Task2 is responsible for the setup of the SPI2 (SLAVE) register. Is it possible that Task1 could interfere with the execution of Task2 or vice versa? Or do the tasks execute simultaneously without any sort of timing issues?

Synchronizing multiple tasks

The tasks run independently. If they are writing to different registers then there is no problem. You would only get a problem if they wrote to the same register. I would recommend downloading the free pdf book here: http://www.freertos.org/Documentation/RTOS_book.html

Synchronizing multiple tasks

So this is my current attempt at implementing the above code as two separate tasks: spiDAT1t dataconfig1t; /* Define Task Handles */ xTaskHandle xTask1Handle; xTaskHandle xTask2Handle; uint16 TXDataMaster[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; uint16 RXDataMaster[16] = { 0 }; uint16 TXDataSlave[16] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 }; uint16 RXDataSlave[16] = { 0 }; /* Task1 */ void vTask1(void *pvParameters) { dataconfig1_t.CS_HOLD = FALSE; dataconfig1_t.WDEL = TRUE; dataconfig1_t.DFSEL = SPI_FMT_0; dataconfig1_t.CSNR = 0xF7;
for(;;)
{
    /* Initiate SPI2 Transmit and Receive through Interrupt Mode */
    spiSendAndGetData(spiREG2, &dataconfig1_t, 16, TX_Data_Slave, RX_Data_Slave);
}
} /* Task2 */ void vTask2(void *pvParameters) { dataconfig1_t.CS_HOLD = FALSE; dataconfig1_t.WDEL = TRUE; dataconfig1_t.DFSEL = SPI_FMT_0; dataconfig1_t.CSNR = 0xF7;
for(;;)
{
    /* Initiate SPI1 Transmit and Receive through Polling Mode */
    spiTransmitAndReceiveData(spiREG1, &dataconfig1_t, 16, TX_Data_Master, RX_Data_Master);
}
} /* USER CODE END */ /** @fn void main(void) * @brief Application main function * @note This function is empty by default. * * This function is called after startup. * The user can use this function to implement the application. */ /* USER CODE BEGIN (2) / / USER CODE END */ void main(void) { /* USER CODE BEGIN (3) */
spiInit();

/* Create Task 1 */
if (xTaskCreate(vTask1,"Task1", configMINIMAL_STACK_SIZE, NULL, 1, &xTask1Handle) != pdTRUE)
{
    /* Task could not be created */
    while(1);
}

/* Create Task 2 */
if (xTaskCreate(vTask2,"Task2", configMINIMAL_STACK_SIZE, NULL, 1, &xTask2Handle) != pdTRUE)
{
    /* Task could not be created */
    while(1);
}

/* Start Scheduler */
vTaskStartScheduler();

/* Run forever */
while(1);
/* USER CODE END */ } Initially, I only had one task which initiated both spi registers. Here I am trying to create two tasks which each initiate a different SPI port. I assumed that they would simply communicate properly with the same setup. However, this is not the case. When I run the code, RXDataSlave ends up with a scrambled assortment of the values from TXDataMaster; some values are missing and TXDataMaster is overwritten by different values; and RXDataMaster sometimes gets nothing and sometimes gets something similar to RXDataSlave. I’m thinking I have to have the two tasks communicate with each other in some way in order to prevent this from happening. I’m just not entirely sure how. I attached a snip of an example of what happens with the buffer data (it’s not consistent as the values change almost every time I run the program). The formatting is a bit off so you may have to just download it in order to view it if you need to.

Synchronizing multiple tasks

Is there anything the two tasks are sharing. You have only mentioned registers so far, and the registers for the two SPI ports are different. Are they sharing anything else? It sounds like they are using the same buffer, so one is overwriting the other. Also, are you doing the spi timing (toggling pins, etc.) in the software, or relying on the hardware peripherals to do that? If you are toggling pins then the timing could change when you have two tasks, and you need to check that the functions that toggle the pins are ‘thread safe’, which means they are not accessing the same registers or ports at the same time.

Synchronizing multiple tasks

So I think the problem is that the spiSendAndGetData() function is being called repeatedly while the spiTransmitAndReceive() function is being executed. I have the SPI2 function being triggered on both a high and a low (so always), and I have nothing allowing the transmit to finish (as you said). For now, I’m going to leave them in the same function and figure out a different application for a second task.

Synchronizing multiple tasks

https://www.youtube.com/watch?v=mtjcoL-sGEM&t=82s