Deferred Work
"Keep your ISRs short" is the most repeated piece of firmware advice and the least actionable, because it never says short compared to what. The useful form is a consequence of how the NVIC works rather than a style preference: every microsecond a handler runs is a microsecond added to the worst-case latency of every interrupt at the same or a less urgent priority. A 200 µs handler is not "a bit slow". It is a 200 µs latency tax levied on most of the system, paid every time that handler runs, and it does not appear in any register you can read.
ISR-Safe APIs
Every kernel object in the previous six pages — the ready lists, the delayed list, each queue's two event lists, each mutex's holder field — is an ordinary linked list in RAM, and the kernel keeps it consistent by the only means a single-core Cortex-M offers: it masks interrupts around the update. That is the entire content of taskENTER_CRITICAL(). So a kernel API is not "thread-safe code" in the hosted sense; it is code that assumes nothing else on this core is running while it edits the list.
Writing Interrupt Handlers in C
An interrupt handler is the only function in your program that nothing calls. You write it, you never reference it, and yet it runs — sometimes millions of times a second, at a moment you did not choose, on top of whatever the main program happened to be doing. That inversion is the whole difficulty. Every rule below follows from it: you cannot pass arguments to something nobody calls, you cannot return a value to nobody, and you cannot assume anything about the state of the code you interrupted.