C++ code inside ISR

mistert69

New member
I was wondering if there are any problems using std:vector inside an interrupt.
I need to give a device every 10mS some serial data and the data comes from the teensy SD card.
First I tested the code in Visual studio on a PC which could not make the timing of 10mS put for the rest it is working.
I used 2 threads one for the main program that reads (packets) from the SD and stores the packets in a vector.
The other thread just takes a packets from the vector and send its over the serial port to the device. The synchronositation is garded by a mutex.

But porting it to a teensy gives some problem. Here I also have a main (loop()) that reads from the SD card and fills the vector.
The other 'thread' is a IntervalTimer with a very low prio of 200 so interrupt from the serialport and SD card should still work (?)
Since I could not find an mutex for teensy i made it myself by just briefly blocking interrupts:
#ifdef COMPILE_FOR_TEENSY

void MutexHAL::lock()
{
noInterrupts();
}

void MutexHAL::checklock()
{

}

void MutexHAL::unlock()
{
interrupts();
}
#endif

and I know I do a litlle bit to much in an interrupt but this is the code :
if (packetBuffer.getNumPackets() > 0)
{
Packet packet = packetBuffer.getPacketAndRemove();
serial.SendPacket(&packet);
if (packet.getType() == STATUS)
{
Packet receivePacket;
serial.ReceiveAckPacketifAvailable(&receivePacket);
}
}
else
{
std::cout << "No packets in buffer" << std::endl;
}
}
If i prefill the packetBuffer (vector of packets) with some packets it works. But when it fills the packetBuffer in the main loop and empty it in the ISR it just stops working. like the whole ISR is crashing..
 
like the whole ISR is crashing..

Is this inside your interrupt? What does it actually do?

Code:
serial.SendPacket(&packet);

Use of the serial ports from interrupts can be risky. Usually it works if not also accessed from main program or any other interrupts running at different priority. Also (sometimes) can lock up if your interrupt runs at a higher priority than the serial interrupt but appears to usually be successful when your requests can be satisfied from the buffers. Or if you've disabled interrupts (eg, your mutex) and you ask the serial code to transmit, can usually be sucessful when the outgoing bytes fit into the buffer, but without interrupts enabled it will of course lock up if it has to wait on the hardware.
 
That mutex implementation looks very iffy. If a thread locks multiple mutexes (including using one mutex recursively), interrupts will be re-enabled the first time unlock() is called.

Usually it's not allowed for an ISR to try to claim a mutex at all, since they do not have an associated thread context for ownership. If the thread library has been implemented correctly, this also means ISRs can't use malloc/free because they should be protected by internal mutexes.
 
Is this inside your interrupt? What does it actually do?

Code:
serial.SendPacket(&packet);

Use of the serial ports from interrupts can be risky. Usually it works if not also accessed from main program or any other interrupts running at different priority. Also (sometimes) can lock up if your interrupt runs at a higher priority than the serial interrupt but appears to usually be successful when your requests can be satisfied from the buffers. Or if you've disabled interrupts (eg, your mutex) and you ask the serial code to transmit, can usually be sucessful when the outgoing bytes fit into the buffer, but without interrupts enabled it will of course lock up if it has to wait on the hardware.
it indeed uses the serial port (1) to transmit a packet. Packet size can be 10 but also more then 200 bytes. I also think its the serial port that gives me the problem here or the Mutex, I disable the interrupts only briefly in the part that I need to update the packetBuffer.
 
Back
Top