Electronic – Embedded system task scheduling for data aquisition on a CAN network

cani2cinterruptsstate-machinesstm32

I'm struggling with the concept of how to schedule my tasks.

My Setup:
STM32F103 hooked up on CAN. Taking measurements with a Lidar V3 module comms via I2C, then distributing that measurement on the CAN

Interrupt 1 is a 1ms timer interrupt to initiate message send on CAN

interrupt 2 is active upon receiving CAN message

I also have to poll a register via I2C on the LIDAR unit to ensure that measurement has finished before I can then use I2C to read the distance register, code snippet shown below

        status = CheckLidarStatus();

        while ((status & LIDAR_BUSY) == LIDAR_BUSY)
        {
            status = CheckLidarStatus();
        }

What I believe is the correct flow that my program should take is shown below:

flow of

My main concerns are:

  1. Does the flow seem a logical way in which to approach this?

  2. If I prioritise the timer interrupt (rather than RX int) for CAN transmission, will this affect the CAN network negatively i.e. not dealing with the received CAN messages promptly enough?

  3. If either of the interrupts are active during I2C comms, will it cause the I2C comms to "fall over"?

  4. Is it acceptable to sit in a while loop waiting for the Checklidar status to come back as not busy, or is there a better way to do this?

Best Answer

  1. Yes, it seems logical to me. Although, what's the maximum amount of time that the lidar peripheral could be busy? If that is more than 1 millisecond then you could miss a transmit opportunity. Maybe the busy case should just skip over the data read rather than looping back to poll the status.

  2. Yes, the lower priority interrupt handler will be held off while the higher priority interrupt handler runs. If the higher priority timer interrupt handler runs longer than it takes for the CAN peripheral to receive enough messages to overflow then you would lose messages. That's why it's a good rule of thumb to keep interrupt handlers short. And if all your timer interrupt does is set a flag then I doubt whether you're going to have a problem.

    Another way to consider this is what is the penalty when either interrupt handler is delayed by the other. When the CAN interrupt is delayed by the timer interrupt then you would add lag to CAN response or worst case drop a message. When the timer interrupt is delayed by the CAN interrupt then you would add jitter to the timer interrupt. Worst case would be dropping a millisecond but the CAN interrupt would have to run for more than a millisecond for that to happen. So what is less desirable for your application, a little lag or a little jitter?

  3. It's doubtful that either interrupt would break I2C communications. You're probably using an I2C controller peripheral that transmits/receives bits mostly independently from the CPU. The I2C controller will continue to clock in and out bits as necessary without affect from the interrupts. (If you were bit-banging each bit then there would be more of an impact because individual clocks could get stretched out by an unrelated interrupt. But even that is not necessarily a problem because of the synchronous nature of I2C. The slave device shouldn't care if the I2C clock pulses get stretched out.)

  4. It may be acceptable to poll the lidar status. If you don't have anything else for the CPU to do then what's the harm? But if the lidar peripheral has a "data ready" interrupt of some sort then you could enable that interrupt and wait for the interrupt rather then poll for status.