rsta2 / circle

A C++ bare metal environment for Raspberry Pi with USB (32 and 64 bit)

Home Page:https://circle-rpi.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CTimer delays busy-spin the processor

Blackaddr opened this issue · comments

When using the CTimer delay functions, the processor sits in a busy loop tying up the processor core.

E.g.

// do nothing

It would be nice if we had the option to Yield() instead. Busy-waiting improves the precising timing of the delay (I assume this was the intent), but is not great for multi-threaded applications. I found this while porting other baremetal libraries to Circle that expect a delay() call to be yielding.

void CTimer::SimpleusDelay (unsigned nMicroSeconds, bool yield = false);  // same optional param for all delays needed

void CTimer::SimpleusDelay (unsigned nMicroSeconds, bool yield )
{
	if (nMicroSeconds > 0)
	{
		unsigned nTicks = nMicroSeconds * (CLOCKHZ / 1000000) + 1;

#ifndef USE_PHYSICAL_COUNTER
		PeripheralEntry ();

		unsigned nStartTicks = read32 (ARM_SYSTIMER_CLO);
		while (read32 (ARM_SYSTIMER_CLO) - nStartTicks < nTicks)
		{
			// do nothing, 
			if (yield && CScheduler::Get()) { CScheduler::Get()->Yield(); }  // add optional yield
		}

		PeripheralExit ();
#else
		unsigned nStartTicks = GetClockTicks ();
		while (GetClockTicks () - nStartTicks < nTicks)
		{
			// do nothing
			if (yield && CScheduler::Get()) { CScheduler::Get()->Yield(); }  // add optional yield
		}
#endif
	}
}

The CScheduler::Sleep(), CScheduler::MsSleep() and CScheduler::usSleep() methods put the current task to sleep for the given amount of time and let other tasks run. See this.

@rsta2 Great! I was not aware of these functions, thank you for bringing them to my attention and for your help.