return sp;
}
-/* Return true if the CPU is in an interrupt context
- (PS.UM == 0)
-*/
-static inline bool cpu_in_interrupt_context(void)
-{
- uint32_t ps;
- RSR(PS, ps);
- return (ps & PS_UM) == 0;
-}
-
/* Functions to set page attributes for Region Protection option in the CPU.
* See Xtensa ISA Reference manual for explanation of arguments (section 4.6.3.2).
*/
*/
void vPortSetStackWatchpoint( void* pxStackStart );
+/*
+ * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
+ * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
+ */
+BaseType_t xPortInIsrContext();
+
/*
* The structures and methods of manipulating the MPU are contained within the
* port layer.
/*-----------------------------------------------------------*/
unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting
-unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level
+unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit
/*-----------------------------------------------------------*/
#endif
+/*
+ * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
+ * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
+ */
+BaseType_t xPortInIsrContext()
+{
+ unsigned int irqStatus;
+ BaseType_t ret;
+ irqStatus=portENTER_CRITICAL_NESTED();
+ ret=(port_interruptNesting[xPortGetCoreID()] != 0);
+ portEXIT_CRITICAL_NESTED(irqStatus);
+ return ret;
+}
+
+
void vPortAssertIfInISR()
{
- configASSERT(port_interruptNesting[xPortGetCoreID()]==0)
+ configASSERT(xPortInIsrContext());
}
/*
--- /dev/null
+/*
+ See if xPortInIsrContext works
+*/
+
+#include <esp_types.h>
+#include <stdio.h>
+#include "rom/ets_sys.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "freertos/queue.h"
+#include "freertos/xtensa_api.h"
+#include "unity.h"
+#include "esp_intr_alloc.h"
+#include "xtensa/hal.h"
+
+static volatile int in_int_context, int_handled;
+
+
+static void testint(void *arg) {
+ xthal_set_ccompare(1, xthal_get_ccount()+8000000000);
+ ets_printf("INT!\n");
+ if (xPortInIsrContext()) in_int_context++;
+ int_handled++;
+}
+
+
+static void testthread(void *arg) {
+ intr_handle_t handle;
+ in_int_context=0;
+ int_handled=0;
+ TEST_ASSERT(!xPortInIsrContext());
+ xthal_set_ccompare(2, xthal_get_ccount()+8000000);
+ esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, &testint, NULL, &handle);
+ vTaskDelay(100 / portTICK_PERIOD_MS);
+ TEST_ASSERT(int_handled);
+ TEST_ASSERT(in_int_context);
+ esp_intr_free(handle);
+ vTaskDelete(NULL);
+}
+
+
+TEST_CASE("xPortInIsrContext test", "[freertos]")
+{
+ xTaskCreatePinnedToCore(testthread, "tst" , 4096, NULL, 3, NULL, 0);
+ vTaskDelay(150 / portTICK_PERIOD_MS);
+ xTaskCreatePinnedToCore(testthread, "tst" , 4096, NULL, 3, NULL, 1);
+ vTaskDelay(150 / portTICK_PERIOD_MS);
+}
+
#include "freertos/semphr.h"
#include "freertos/portmacro.h"
#include "freertos/task.h"
+#include "freertos/portable.h"
/* Notes on our newlib lock implementation:
*
}
BaseType_t success;
- if (cpu_in_interrupt_context()) {
+ if (xPortInIsrContext()) {
/* In ISR Context */
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
abort(); /* recursive mutexes make no sense in ISR context */
return;
}
- if (cpu_in_interrupt_context()) {
+ if (xPortInIsrContext()) {
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
abort(); /* indicates logic bug, it shouldn't be possible to lock recursively in ISR */
}