Turning off interrupts on core 1

Derf Jagged
Posts: 16
Joined: Wed Jul 08, 2020 8:33 pm

Re: Turning off interrupts on core 1

Postby Derf Jagged » Mon Jul 27, 2020 1:38 pm

mad_b747 wrote:
Mon Jun 08, 2020 5:29 am
Well, after some hours during last days studying, setting up esp-idf and using code from Mr. Weber Github repo, It seems that it works.
It starts core 0 normally, and set a task to run only on core 1, it ius running an endless testing loop that does a frequency sweep on a GPIO out, I wired it up to a buzzer and the audio is crystal clear - no cracks/interruptions, code seems to be running without any interrupts, task switches, delays or breaks. I´ve done tests as this in the past, and putting a while in between a sequence of for loops was generating a small 'crack' in the audio output to an output port by that time. The slightest discontinuity in the cadency of output of the square wave generated is audible.
Of course in order to trully confirm I must get an oscilloscope however I am far from the place wher I could do such confirmation. I however plan to make tick counts readings - I am printing out on a terminal on a core 0 task along with this core 1 uninterrupted loop, no watchdog breaks also.
Hope this confirms, I plan to use core 1 "bare metal" routines but still have RTOS utilities on core 0...
Hello! Would you mind sharing your code or what functions exactly you used? I've been having the same issue as you with background interrupts and watchdog messing up my high speed signals.

mad_b747
Posts: 12
Joined: Sun Apr 12, 2020 1:26 pm

Re: Turning off interrupts on core 1

Postby mad_b747 » Mon Jul 27, 2020 2:17 pm

Hello.
I based my tests on this https://github.com/MacLeod-D/ESp32-Fast-external-IRQs
I needed to install and configure Espressif IDE for that.
Followed the online instructions. Maybe a bit of trial and error.

Basically the code is the same. You will of course replace most or all of the inner code of the core1 task with your own needs.

mad_b747
Posts: 12
Joined: Sun Apr 12, 2020 1:26 pm

Re: Turning off interrupts on core 1

Postby mad_b747 » Mon Jul 27, 2020 2:50 pm

Below excerpt from my test, stripped out my particular code, in essence the core working is below.
There may be unuised variables or other minor issues, but the idea is to provide the essence of what I made based on McLeod's Github code.

Code: Select all

#pragma GCC optimize ("O3")
extern "C" void app_main(void);

TaskHandle_t xHandle1;
TaskHandle_t xHandle2;
TaskHandle_t TaskA;

volatile int Irqs = 0;
volatile int Irqs2 = 0;
volatile int IrqsPerSecond = 0;
volatile int IrqsPerSecond2 = 0;
int IrqErrors = 0;
volatile uint32_t maxDiff, minDiff = 99999;

const int MOTOR_STEP 18 //pin number - choose your own

inline uint32_t IRAM_ATTR clocks()
{
	uint32_t ccount;
	asm volatile ( "rsr %0, ccount" : "=a" (ccount) );
	return ccount;
}

inline int64_t micros()
{
  return esp_timer_get_time();
}

void IRAM_ATTR delayMicroseconds(int64_t us)
{
	if (us)
	{
		int64_t m = micros() + us;
		while (micros() < m)
		{
			asm(" nop");
		}
	}
}

//This task runs on core 1 No taskswitch No other interrupts
// spit out a 1KHz square wave

void IRAM_ATTR Core1(void* p)
{
	portDISABLE_INTERRUPTS();  // Need it ??
	
	while (1)
	{
		GPIO_Set(MOTOR_STEP);
		delayMicroseconds(500);
		GPIO_Clear(MOTOR_STEP);
		delayMicroseconds(500);
	}
}

void StartCore1( void )
{
	BaseType_t res = xTaskCreatePinnedToCore(
		Core1,				// Function that implements the task.
		"Core1",			// Text name for the task.
		STACK_SIZE,			// Stack size in bytes, not words.
		(void*) 1,			// Parameter passed into the task.
		tskIDLE_PRIORITY+2,
		&TaskA,
		1);					// Core 1
	if (res == pdPASS)
		printf("Task Core 1 created OK!\n");
	else
		printf("Task Core 1 FAILED!\n");
	vTaskDelay(1000);
}

void RTOS_1(void *p)
{
	vTaskDelay(3500);
	while (1)
	{
		vTaskDelay(1000);
	}
}

void app_main(void)
{
	vTaskDelay(3000);
	gpio_set_direction(GPIO_NUM_19, GPIO_MODE_OUTPUT);
	// ------------------- Create RTOS-Tasks ---------------------//
	printf("\nCreating monitoring task...\n");
	xTaskCreatePinnedToCore(
		  RTOS_1,				// Function that implements the task.
		  "RTOS-1",				// Text name for the task.
		  STACK_SIZE,			// Stack size in bytes, not words.
		  (void*) 1,			// Parameter passed into the task.
		  tskIDLE_PRIORITY+2,
		  &xHandle1,			// Variable to hold the task's data structure.
		  0);
	printf("Creating worker tasks on core 1...\n\n\n");
	StartCore1();				// Start the one and only task in core 1
}

Peluko
Posts: 1
Joined: Mon Aug 14, 2023 10:31 am

Re: Turning off interrupts on core 1

Postby Peluko » Mon Aug 14, 2023 10:49 am

apuder wrote:
Thu Jun 04, 2020 1:27 am
unfortunately not. I did a kludgy solution whereby I communicate to the second core via a global shared volatile variable that it should temporarily turn on interrupts. I then do the NVS operations and tell the other core that it can turn interrupts off again. I would prefer a cleaner solution but don't have cycles to look into that.

AP
Hello. I've found a solution to this problem an want to share here just for the record. I can keep a tight bit banger loop on core 1 and use core 0 for NVS without re-enabling interrupts on core 1.
I traced the problem to 'spi_flah_os_func_app.c', function 'spi1_start()'. It calls a function called 'cache_disable()' to make sure the other core doesn't want to fetch instructions or ro data from flash while the flash is being used. It tries to put the other core on a busy loop until the flash operation has ended.
But at least with an esp32s3 and a board with SPI RAM you can configure the options CONFIG_SPIRAM_FETCH_INSTRUCTIONS and CONFIG_SPIRAM_RODATA, explained here https://docs.espressif.com/projects/esp ... structions
With this options enabled, the instructions and ro data are fetched from PSRAM and do not interfere with flash, so the system doesn't try to stop the other core.

Regards.

Who is online

Users browsing this forum: Esp_Noobe_Sag and 88 guests