advanced interrupts in FreqMeasureMulti library

Status
Not open for further replies.

humanoid2050

New member
I have been trying to understand the intricacies of interrupts on the Teensy 3.2. Along the way, I started examining the FreqMeasureMulti library included with Teensyduino. https://github.com/PaulStoffregen/FreqMeasureMulti

I mostly understand the code, but it doesn't do a lot of things that I would have expected. For starters, there are no calls to cli/sei. How is this possible? Is the assumption that there are no other interrupts being called so it's not necessary? This is especially notable in the read function.

Code:
uint32_t FreqMeasureMulti::read(void)
{
	uint32_t head = buffer_head;
	uint32_t tail = buffer_tail;
	if (head == tail) return 0xFFFFFFFF;
	tail = tail + 1;
	if (tail >= FREQMEASUREMULTI_BUFFER_LEN) tail = 0;
	uint32_t value = buffer_value[tail].count;
	last_read_level = buffer_value[tail].level;
	buffer_tail = tail;
	return value;
}

The buffer_tail variable is used in the ISR, but its read and write back is not protected. Is this acceptable because the variable is a uint8_t and therefore it should be atomic?

Additionally, how are there no volatile variables? There are a few uses of volatile, such as line 207 of FreqMeasureMulti.cpp

Code:
    volatile uint32_t *csc = &FTM0_C0SC + channel * 2;
    uint32_t capture = csc[1];

My understanding is that declaring the csc variable as volatile forces the compiler to not optimize away the subsequent reads. However, the 4byte copy to the variable capture seems to have no protection against a subsequent interrupt messing with the copy operation. Is it just assumed that it happens so fast after the interrupt that there will be no problem?

I also have a couple general code questions related to this library.

The read function (reproduced above) increments tail before accessing the buffer_value array. Doesn't this result in buffer_value[0] being skipped the first time through the code, requiring at least two interrupts be logged before one can be read?

I also have some questions about the data logging.

Code:
	if (period != 0) {
		uint32_t i = buffer_head + 1;
		if (i >= FREQMEASUREMULTI_BUFFER_LEN) i = 0;
		if (i != buffer_tail) {
			buffer_value[i].level = level;
			buffer_value[i].count = period;
			buffer_head = i;
		}
	}

Doesn't this result in data recording halting whenever the buffer fills? The buffer is allocated with 24 elements by default. If that is the case, then doesn't it mean that if I read from the FreqMeasureMulti object at say 10Hz, each read represents data which is 2.4 seconds old?
 
Status
Not open for further replies.
Back
Top