Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: порт х86
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Drozd2
Использую порт MSVC-MingW. Пытаюсь приподнять точность таймера с помощью функции rdtsc вместо Sleep. Текст оригинальный, только закомментированы Sleep в бесконечном цикле и добавлен вызов wait_ms.

CODE
void wait_ms(unsigned long ms)
{
unsigned long long t2 = _rdtsc() + (unsigned long long)ms * 3000000;
while (_rdtsc() < t2);
}


/*-----------------------------------------------------------*/

static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
{
TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps;

/* Set the timer resolution to the maximum possible. */
if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
{
xMinimumWindowsBlockTime = ( TickType_t ) xTimeCaps.wPeriodMin;
timeBeginPeriod( xTimeCaps.wPeriodMin );

/* Register an exit handler so the timeBeginPeriod() function can be
matched with a timeEndPeriod() when the application exits. */
SetConsoleCtrlHandler( prvEndProcess, TRUE );
}
else
{
xMinimumWindowsBlockTime = ( TickType_t ) 20;
}

/* Just to prevent compiler warnings. */
( void ) lpParameter;
//Sleep(1);

for( ;; )
{
/* Wait until the timer expires and we can access the simulated interrupt
variables. *NOTE* this is not a 'real time' way of generating tick
events as the next wake time should be relative to the previous wake
time, not the time that Sleep() is called. It is done this way to
prevent overruns in this very non real time simulated/emulated
environment. */
/*if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
{
Sleep( xMinimumWindowsBlockTime );
}
else
{
Sleep( portTICK_PERIOD_MS );
}*/
wait_ms(portTICK_PERIOD_MS);

configASSERT( xPortRunning );

WaitForSingleObject( pvInterruptEventMutex, INFINITE );

/* The timer has expired, generate the simulated tick event. */
ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );

/* The interrupt is now pending - notify the simulated interrupt
handler thread. */
if( ulCriticalNesting == 0 )
{
SetEvent( pvInterruptEvent );
}

/* Give back the mutex so the simulated interrupt handler unblocks
and can access the interrupt handler variables. */
ReleaseMutex( pvInterruptEventMutex );
}

#ifdef __GNUC__
/* Should never reach here - MingW complains if you leave this line out,
MSVC complains if you put it in. */
return 0;
#endif
}


Программа зависает намертво. Причем если в wait_ms добавить Sleep, то начинает работать. Или хотя бы закомментированный Sleep перед for(;;) раскомментировать, то один раз выводится Task 1 is running. И тоже зависает. Как починить?
Drozd2
Изучение матчасти помогло. Так работает:

Код
void wait_ms(unsigned long ms)
{
    unsigned long long t2 = _rdtsc() + (unsigned long long)ms * 3000000;
    while (_rdtsc() < t2)
        Sleep(0);
}


Только ускорения не вышло.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.