diff --git a/src/Platforms/Iar/UtestPlatform.cpp b/src/Platforms/Iar/UtestPlatform.cpp index 13c32b5e5..6bdc4351e 100644 --- a/src/Platforms/Iar/UtestPlatform.cpp +++ b/src/Platforms/Iar/UtestPlatform.cpp @@ -43,159 +43,177 @@ #undef strndup #include "CppUTest/PlatformSpecificFunctions.h" +#define DEMCR_TRCENA 0x01000000 +#define DEMCR (*(volatile uint32_t *)0xE000EDFC) +#define DWT_CTRL (*(volatile uint32_t *)0xE0001000) +#define CYCCNTENA (1<<0) +#define DWT_CYCCNT ((volatile uint32_t *)0xE0001004) + +static int initialized = 0; +static uint32_t overflow_cnt = 0; +static uint32_t start; +extern uint32_t SystemCoreClock; + static jmp_buf test_exit_jmp_buf[10]; static int jmp_buf_index = 0; TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment() { - return TestOutput::eclipse; + return TestOutput::eclipse; } static void DummyPlatformSpecificRunTestInASeperateProcess(UtestShell* shell, TestPlugin*, TestResult* result) { - result->addFailure(TestFailure(shell, "-p doesn't work on this platform, as it is lacking fork.\b")); + result->addFailure(TestFailure(shell, "-p doesn't work on this platform, as it is lacking fork.\b")); } static int DummyPlatformSpecificFork(void) { - return 0; + return 0; } static int DummyPlatformSpecificWaitPid(int, int*, int) { - return 0; + return 0; } void (*PlatformSpecificRunTestInASeperateProcess)(UtestShell* shell, TestPlugin* plugin, TestResult* result) = - DummyPlatformSpecificRunTestInASeperateProcess; + DummyPlatformSpecificRunTestInASeperateProcess; int (*PlatformSpecificFork)(void) = DummyPlatformSpecificFork; int (*PlatformSpecificWaitPid)(int, int*, int) = DummyPlatformSpecificWaitPid; extern "C" { -static int PlatformSpecificSetJmpImplementation(void (*function) (void* data), void* data) -{ + static int PlatformSpecificSetJmpImplementation(void (*function) (void* data), void* data) + { if (0 == setjmp(test_exit_jmp_buf[jmp_buf_index])) { - jmp_buf_index++; - function(data); - jmp_buf_index--; - return 1; + jmp_buf_index++; + function(data); + jmp_buf_index--; + return 1; } return 0; -} + } -static void PlatformSpecificLongJmpImplementation() -{ + static void PlatformSpecificLongJmpImplementation() + { jmp_buf_index--; longjmp(test_exit_jmp_buf[jmp_buf_index], 1); -} + } -static void PlatformSpecificRestoreJumpBufferImplementation() -{ + static void PlatformSpecificRestoreJumpBufferImplementation() + { jmp_buf_index--; -} - -void (*PlatformSpecificLongJmp)() = PlatformSpecificLongJmpImplementation; -int (*PlatformSpecificSetJmp)(void (*)(void*), void*) = PlatformSpecificSetJmpImplementation; -void (*PlatformSpecificRestoreJumpBuffer)() = PlatformSpecificRestoreJumpBufferImplementation; - -///////////// Time in millis - -static long TimeInMillisImplementation() -{ - clock_t t = clock(); - - t = t * 10; - - return t; -} - -///////////// Time in String + } + + void (*PlatformSpecificLongJmp)() = PlatformSpecificLongJmpImplementation; + int (*PlatformSpecificSetJmp)(void (*)(void*), void*) = PlatformSpecificSetJmpImplementation; + void (*PlatformSpecificRestoreJumpBuffer)() = PlatformSpecificRestoreJumpBufferImplementation; + + long TimeInMillisImplementation() + { + if (initialized == 0) { + DEMCR |= DEMCR_TRCENA; + *DWT_CYCCNT = 0; + DWT_CTRL |= CYCCNTENA; + start = *DWT_CYCCNT; + initialized = 1; + } + double ticks; + if (*DWT_CYCCNT < start) { + // overflow + overflow_cnt++; + ticks = UINT32_MAX*overflow_cnt + *DWT_CYCCNT; + } else { + ticks = UINT32_MAX*overflow_cnt + *DWT_CYCCNT - start; + } + return long(ticks/SystemCoreClock * 1000); // ms + } -static const char* TimeStringImplementation() -{ + static const char* TimeStringImplementation() + { time_t tm = time(NULL); char* pTimeStr = ctime(&tm); char* newlineChar = strchr(pTimeStr, '\n'); // Find the terminating newline character. if(newlineChar != NULL) *newlineChar = '\0'; //If newline is found replace it with the string terminator. return (pTimeStr); -} + } -long (*GetPlatformSpecificTimeInMillis)() = TimeInMillisImplementation; -const char* (*GetPlatformSpecificTimeString)() = TimeStringImplementation; + long (*GetPlatformSpecificTimeInMillis)() = TimeInMillisImplementation; + const char* (*GetPlatformSpecificTimeString)() = TimeStringImplementation; -int (*PlatformSpecificVSNprintf)(char *str, size_t size, const char* format, va_list args) = vsnprintf; + int (*PlatformSpecificVSNprintf)(char *str, size_t size, const char* format, va_list args) = vsnprintf; -static PlatformSpecificFile PlatformSpecificFOpenImplementation(const char* filename, const char* flag) -{ + static PlatformSpecificFile PlatformSpecificFOpenImplementation(const char* filename, const char* flag) + { (void)filename; (void)flag; return 0; -} + } -static void PlatformSpecificFPutsImplementation(const char* str, PlatformSpecificFile file) -{ + static void PlatformSpecificFPutsImplementation(const char* str, PlatformSpecificFile file) + { (void)str; (void)file; -} + } -static void PlatformSpecificFCloseImplementation(PlatformSpecificFile file) -{ + static void PlatformSpecificFCloseImplementation(PlatformSpecificFile file) + { (void)file; -} + } -static void PlatformSpecificFlushImplementation() -{ -} + static void PlatformSpecificFlushImplementation() + { + } -PlatformSpecificFile (*PlatformSpecificFOpen)(const char*, const char*) = PlatformSpecificFOpenImplementation; -void (*PlatformSpecificFPuts)(const char*, PlatformSpecificFile) = PlatformSpecificFPutsImplementation; -void (*PlatformSpecificFClose)(PlatformSpecificFile) = PlatformSpecificFCloseImplementation; + PlatformSpecificFile (*PlatformSpecificFOpen)(const char*, const char*) = PlatformSpecificFOpenImplementation; + void (*PlatformSpecificFPuts)(const char*, PlatformSpecificFile) = PlatformSpecificFPutsImplementation; + void (*PlatformSpecificFClose)(PlatformSpecificFile) = PlatformSpecificFCloseImplementation; -int (*PlatformSpecificPutchar)(int) = putchar; -void (*PlatformSpecificFlush)() = PlatformSpecificFlushImplementation; + int (*PlatformSpecificPutchar)(int) = putchar; + void (*PlatformSpecificFlush)() = PlatformSpecificFlushImplementation; -void* (*PlatformSpecificMalloc)(size_t size) = malloc; -void* (*PlatformSpecificRealloc)(void*, size_t) = realloc; -void (*PlatformSpecificFree)(void* memory) = free; -void* (*PlatformSpecificMemCpy)(void*, const void*, size_t) = memcpy; -void* (*PlatformSpecificMemset)(void*, int, size_t) = memset; + void* (*PlatformSpecificMalloc)(size_t size) = malloc; + void* (*PlatformSpecificRealloc)(void*, size_t) = realloc; + void (*PlatformSpecificFree)(void* memory) = free; + void* (*PlatformSpecificMemCpy)(void*, const void*, size_t) = memcpy; + void* (*PlatformSpecificMemset)(void*, int, size_t) = memset; -static int IsNanImplementation(double d) -{ + static int IsNanImplementation(double d) + { return isnan(d); -} + } -static int IsInfImplementation(double d) -{ + static int IsInfImplementation(double d) + { return isinf(d); -} + } -double (*PlatformSpecificFabs)(double) = fabs; -int (*PlatformSpecificIsNan)(double) = IsNanImplementation; -int (*PlatformSpecificIsInf)(double) = IsInfImplementation; -int (*PlatformSpecificAtExit)(void(*func)(void)) = atexit; /// this was undefined before + double (*PlatformSpecificFabs)(double) = fabs; + int (*PlatformSpecificIsNan)(double) = IsNanImplementation; + int (*PlatformSpecificIsInf)(double) = IsInfImplementation; + int (*PlatformSpecificAtExit)(void(*func)(void)) = atexit; /// this was undefined before -static PlatformSpecificMutex DummyMutexCreate(void) -{ + static PlatformSpecificMutex DummyMutexCreate(void) + { return 0; -} + } -static void DummyMutexLock(PlatformSpecificMutex) -{ -} + static void DummyMutexLock(PlatformSpecificMutex) + { + } -static void DummyMutexUnlock(PlatformSpecificMutex) -{ -} + static void DummyMutexUnlock(PlatformSpecificMutex) + { + } -static void DummyMutexDestroy(PlatformSpecificMutex) -{ -} + static void DummyMutexDestroy(PlatformSpecificMutex) + { + } -PlatformSpecificMutex (*PlatformSpecificMutexCreate)(void) = DummyMutexCreate; -void (*PlatformSpecificMutexLock)(PlatformSpecificMutex) = DummyMutexLock; -void (*PlatformSpecificMutexUnlock)(PlatformSpecificMutex) = DummyMutexUnlock; -void (*PlatformSpecificMutexDestroy)(PlatformSpecificMutex) = DummyMutexDestroy; + PlatformSpecificMutex (*PlatformSpecificMutexCreate)(void) = DummyMutexCreate; + void (*PlatformSpecificMutexLock)(PlatformSpecificMutex) = DummyMutexLock; + void (*PlatformSpecificMutexUnlock)(PlatformSpecificMutex) = DummyMutexUnlock; + void (*PlatformSpecificMutexDestroy)(PlatformSpecificMutex) = DummyMutexDestroy; }