Task Scheduling minimum and tick rate

I have a microblaze design that instances an AXI IIC on a spartan series device. I have two tasks, one that manages the iic control, and the other that manages other peripherals. I want to schedule the iic peripheral task so that an iic controller can always read from it and write to it. What I’m afraid of is the scheduler interrupting the task while it’s polling on the AXI IIC registers and performing functions.

I’m having trouble googling the right terms for it but I’m trying to figure out how to tell the freeRTOS kernel to always check on this task under a certain amount of time. I’m thinking less than a 400khz iic cycle. I can’t use taskENTER_CRITICAL() because i2c transactions take waaaay too long to finish and I would hang up the other task. My microblaze runs at 100mhz so it has plenty of horsepower to check in on the iic peripheral handling code.

I also had to change my tick_rate from 100 to 100000 in my BSP to get better results. I know I’m having issues in task switching because if my only task is the IIC peripheral task, I never get any iic errors from my controller. It seems I’m missing certain iic data when my task is sleeping because another task is being performed.

So I guess my tl;dr for this is how do I tell freertos “Hey, make sure to check in on this task every 2.5 microseconds to collect or send data”

I think you don’t quite understand how RTOSes work.

Normally, if a device has an IIC controller, then a properly written IIC driver will be interrupt based, with the controller asserting an interrupt every time th processor needs to ‘service’ the device.

1 Like

The higher the tick rate the better time resolution but the more time you waste in kernel code when there is nothing to do. It is normally best to use a low tick rate then write your application code so it is event driven (so it responds immediately in accordance with whatever priorities you set) regardless of the tick rate. In your case I suggest handling the i2c using dma so there is minimum cpu time required - second best if dma is not available would be to use interrupt handlers to manage Rx ant Tx then only use a task to start a Tx or when a whole message has been received. In the latter case the task waits without using any cpu time for an event from the isr telling it a message is ready - hence event driven.

1 Like

Thanks for the good and quick feedback. I may have to go back and rethink my design then. The whole reason I’m using an rtos is to make use of a scheduler. So I’m my mind I was using it sorry of line Linux where each thread is my two applications, and I use a mutex around a data structure to transfer data between the tasks.

I’m using the xilinx polling mode examples for the hardware drivers, hence why my tasks are always running. They have to be the same priority otherwise the one with the higher priority anyways runs.

I don’t have any dma sources available, but it’s sounding like I should really switch to interrupt driven events to make this robust. The only interrupt in the entire design is my truck timer.

And yes, as I’ve increased the tick timer even faster eventually I’m spending too much time in the kernel and it completely fails to handle the iic data.

I might need to revisit some of my basic rtos guides again. It seems I’ve been going about this all wrong

If the priority of the I2C task is higher than any other task, then it will not be preempted by other tasks. It will still get interrupted, but no other task will get scheduled while it is runnable.

For I2C or SPI transfers, I have the thread initiate the transfer then wait for a semaphore or event group (different apps), and in the interrupt callback, I either release the semaphore or send an event. This results in the scheduler waking up the task when the transfer is complete, preempting any other task that is running at the time. For slave mode, you simply block and the interrupt handler callback wakes the thread up, or the interrupt callback initiates the slave response itself.