It's easy to do it for a single value (that's what ldrex/strex are for) but significantly harder to atomically update multiple values.
Perfect, thank you.
It's easy to do it for a single value (that's what ldrex/strex are for) but significantly harder to atomically update multiple values.
I think, not really.would any of these help?
That allows for an interrupt on an active edge on the RX pin. If you want an interrupt on receipt of a byte, you would use RIE.But I found something interesting in the processor reference manual in "49.6.1.7 LPUART Status Register (STAT)", the field labeled RXEDGIF. Am I reading that correctly? is that an interrupt on the start of recieving a character?
The code tree there is a file cores/teesy4/util/atomic.h. I think this is not used in the T4 code, but it is an interesting bit of history.Some few things and places across the CORES code disables interrupts. Interrupts are not LOST - only queued until re-enabled with the encompassed 'delay' during that 'brief' time.
Aha! Yes indeed that is it.That allows for an interrupt on an active edge on the RX pin. If you want an interrupt on receipt of a byte, you would use RIE.
Is it not the case that the following will always need to be considered when assessing interrupt jitter:That time delay is the problem. It also accounts for the jitter in interrupt latency that we discussed in another thread. And that is s severe limitation. You simply can't do hard real-time like that. We really aught to hunt all of these down, or all of those that might show up routinely as in serial, and fix them, and add conspicuous warnings to the documentation of all the others.
When we design a real time system, what interrupts may occur and when is part of the design.Is it not the case that the following
CTRL[RIE] (page 2928) enables interrrupts from STAT[RDRF] (register full, page 2924, last line) and STAT[RDRF] is set either on a byte or when the FIFO crosses WATER[RXWATER].
Why isn't it used?
#define CTRL_ENABLE (LPUART_CTRL_TE | LPUART_CTRL_RE | LPUART_CTRL_RIE | LPUART_CTRL_ILIE)
#define CTRL_TX_ACTIVE (CTRL_ENABLE | LPUART_CTRL_TIE)
#define CTRL_TX_COMPLETING (CTRL_ENABLE | LPUART_CTRL_TCIE)
#define CTRL_TX_INACTIVE CTRL_ENABLE
uint32_t micros(void)
{
uint32_t smc, scc;
do {
__LDREXW(&systick_safe_read);
smc = systick_millis_count;
scc = systick_cycle_count;
} while ( __STREXW(1, &systick_safe_read));
uint32_t cyccnt = ARM_DWT_CYCCNT;
asm volatile("" : : : "memory");
uint32_t ccdelta = cyccnt - scc;
uint32_t frac = ((uint64_t)ccdelta * scale_cpu_cycles_to_microseconds) >> 32;
if (frac > 1000) frac = 1000;
uint32_t usec = 1000*smc + frac;
return usec;
}
Looks to me like it is used, via macro CTRL_ENABLE
may of the UART protections can manipulate both HEAD and TAIL values as well as sometimes storing a value at the new indicated location.
I am also very confused because here this started out as a discussion of using USB serial and is now discussing the details of the hardware UART serial driver... not to mention the original issue even earlier was how to wait for a flexPWM interrupt.
What's the practical issue here that can be physically demonstrated? Seems like a bunch of conjecture and hand-waving.
I think there's another point missing here, which strikes to the heart of the issue:1) fact: a higher priority interrupt (lower interrupt number on the Teensy) will always block a lower priority interrupt, and therefore, delay the execution/completion of the lower priority interrupt
2) fact: a higher priority interrupt will always suspend a lower priority interrupt, and therefore, delay the execution/completion of the lower priority interrupt
__disable_irq(). An immediate consequence of that is that a lower-priority ISR can block a higher-priority one__disable_irq(). It would be a bonus if the interrupt-disabling process could be shown to stop working [reliably] if it leaves interrupts enabled.__disable_irq() in the Teensy 4 cores, so fixing them all would definitely be a slog, but not an impossible goal.The load and store exclusive instructions only work for normal memory. They don't work for addresses which are hardware registers or memory mapped peripherals, or in ARM-speak strongly ordered memory.
As a general point, I think perhaps @DrM has unreasonably high expectations of the Teensyduino ecosystem.
Super cool and really goog point, though what it might be used for in out case does not immediately come to mind.The address used does not need to match the preceding ldrex* instruction.
The exclusive load and store are used to protect a single fixed address in normal memory, which is then used to protect whatever you want to protect.
Think of it as functioning like a semaphore or mutex. In fact that is what it is. Except that instead of threads, we are only dealing with the isr and loop, or other isrs.