mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2024-12-14 01:25:56 +02:00
523 lines
13 KiB
C
523 lines
13 KiB
C
|
/*--------------------------------------------------------------------
|
||
|
* TITLE: Test Plasma Real Time Operating System
|
||
|
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
|
||
|
* DATE CREATED: 1/1/06
|
||
|
* FILENAME: rtos_test.c
|
||
|
* PROJECT: Plasma CPU core
|
||
|
* COPYRIGHT: Software placed into the public domain by the author.
|
||
|
* Software 'as is' without warranty. Author liable for nothing.
|
||
|
* DESCRIPTION:
|
||
|
* Test Plasma Real Time Operating System
|
||
|
*--------------------------------------------------------------------*/
|
||
|
#include "plasma.h"
|
||
|
#include "rtos.h"
|
||
|
#include "tcpip.h"
|
||
|
|
||
|
/* Including mmu.h will cause all OS calls to use SYSCALL */
|
||
|
//#include "mmu.h"
|
||
|
|
||
|
//#define DLL_SETUP
|
||
|
//#define DLL_CALL
|
||
|
//#include "dll.h"
|
||
|
|
||
|
#define SEMAPHORE_COUNT 50
|
||
|
#define TIMER_COUNT 10
|
||
|
|
||
|
extern void TestMathFull(void);
|
||
|
|
||
|
typedef struct {
|
||
|
OS_Thread_t *MyThread[TIMER_COUNT];
|
||
|
OS_Semaphore_t *MySemaphore[SEMAPHORE_COUNT];
|
||
|
OS_Mutex_t *MyMutex;
|
||
|
OS_Timer_t *MyTimer[TIMER_COUNT];
|
||
|
OS_MQueue_t *MyQueue[TIMER_COUNT];
|
||
|
int TimerDone;
|
||
|
} TestInfo_t;
|
||
|
|
||
|
int Global;
|
||
|
|
||
|
//******************************************************************
|
||
|
static void TestCLib(void)
|
||
|
{
|
||
|
char s1[80], s2[80], *ptr;
|
||
|
int rc, v1, v2, v3;
|
||
|
|
||
|
printf("TestCLib\n");
|
||
|
strcpy(s1, "Hello ");
|
||
|
memset(s2, 0, sizeof(s2));
|
||
|
strncpy(s2, "World wide", 5);
|
||
|
strcat(s1, s2);
|
||
|
strncat(s1, "!\nthing", 14);
|
||
|
printf("%s", s1);
|
||
|
rc = strcmp(s1, "Hello World!\n");
|
||
|
assert(rc == 0);
|
||
|
rc = strcmp(s1, "Hello WOrld!\n");
|
||
|
assert(rc > 0);
|
||
|
rc = strcmp(s1, "Hello world!\n");
|
||
|
assert(rc < 0);
|
||
|
rc = strncmp(s1, "Hellx", 4);
|
||
|
assert(rc == 0);
|
||
|
ptr = strstr(s1, "orl");
|
||
|
assert(ptr[0] = 'o');
|
||
|
rc = strlen(s1);
|
||
|
assert(rc == 13);
|
||
|
memcpy(s2, s1, rc+1);
|
||
|
rc = memcmp(s1, s2, 8);
|
||
|
assert(rc == 0);
|
||
|
s2[5] = 'z';
|
||
|
rc = memcmp(s1, s2, 8);
|
||
|
assert(rc != 0);
|
||
|
memset(s2, 0, 5);
|
||
|
memset(s2, 'a', 3);
|
||
|
rc = abs(-5);
|
||
|
itoa(1234, s1, 10);
|
||
|
itoa(0, s1, 10);
|
||
|
itoa(-1234, s1, 10);
|
||
|
itoa(0xabcd, s1, 16);
|
||
|
itoa(0x12ab, s1, 16);
|
||
|
sprintf(s1, "test c%c d%d 0x%x s%s End\n", 'C', 1234, 0xabcd, "String");
|
||
|
printf("%s", s1);
|
||
|
sprintf(s1, "test c%c d%6d 0x%6x s%8s End\n", 'C', 1234, 0xabcd, "String");
|
||
|
printf("%s", s1);
|
||
|
sscanf("1234 -1234 0xabcd text h", "%d %d %x %s", &v1, &v2, &v3, s1);
|
||
|
assert(v1 == 1234 && v2 == -1234 && v3 == 0xabcd);
|
||
|
assert(strcmp(s1, "text") == 0);
|
||
|
//UartScanf("%d %d", &v1, &v2);
|
||
|
//printf("v1 = %d v2 = %d\n", v1, v2);
|
||
|
printf("Done.\n");
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
static void TestHeap(void)
|
||
|
{
|
||
|
uint8 *ptrs[256], size[256], *ptr;
|
||
|
int i, j, k, value;
|
||
|
|
||
|
printf("TestHeap\n");
|
||
|
memset(ptrs, 0, sizeof(ptrs));
|
||
|
for(i = 0; i < 1000; ++i)
|
||
|
{
|
||
|
j = rand() & 255;
|
||
|
if(ptrs[j])
|
||
|
{
|
||
|
ptr = ptrs[j];
|
||
|
value = size[j];
|
||
|
for(k = 0; k < value; ++k)
|
||
|
{
|
||
|
if(ptr[k] != value)
|
||
|
printf("Error\n");
|
||
|
}
|
||
|
OS_HeapFree(ptrs[j]);
|
||
|
}
|
||
|
size[j] = (uint8)(rand() & 255);
|
||
|
ptrs[j] = OS_HeapMalloc(NULL, size[j]);
|
||
|
if(ptrs[j] == NULL)
|
||
|
printf("malloc NULL\n");
|
||
|
else
|
||
|
memset(ptrs[j], size[j], size[j]);
|
||
|
}
|
||
|
for(i = 0; i < 256; ++i)
|
||
|
{
|
||
|
if(ptrs[i])
|
||
|
OS_HeapFree(ptrs[i]);
|
||
|
}
|
||
|
printf("Done.\n");
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
static void MyThreadMain(void *arg)
|
||
|
{
|
||
|
OS_Thread_t *thread;
|
||
|
int priority;
|
||
|
|
||
|
thread = OS_ThreadSelf();
|
||
|
priority = OS_ThreadPriorityGet(thread);
|
||
|
OS_ThreadSleep(10);
|
||
|
printf("Arg=%d thread=0x%x info=0x%x priority=%d\n",
|
||
|
(uint32)arg, thread, OS_ThreadInfoGet(thread, 0), priority);
|
||
|
OS_ThreadExit();
|
||
|
}
|
||
|
|
||
|
static void TestThread(void)
|
||
|
{
|
||
|
OS_Thread_t *thread;
|
||
|
int i, priority;
|
||
|
|
||
|
printf("TestThread\n");
|
||
|
for(i = 0; i < 32; ++i)
|
||
|
{
|
||
|
priority = 50 + i;
|
||
|
thread = OS_ThreadCreate("MyThread", MyThreadMain, (uint32*)i, priority, 0);
|
||
|
OS_ThreadInfoSet(thread, 0, (void*)(0xabcd + i));
|
||
|
//printf("Created thread 0x%x\n", thread);
|
||
|
}
|
||
|
|
||
|
thread = OS_ThreadSelf();
|
||
|
priority = OS_ThreadPriorityGet(thread);
|
||
|
printf("Priority = %d\n", priority);
|
||
|
OS_ThreadPrioritySet(thread, 200);
|
||
|
printf("Priority = %d\n", OS_ThreadPriorityGet(thread));
|
||
|
OS_ThreadPrioritySet(thread, priority);
|
||
|
|
||
|
printf("Thread time = %d\n", OS_ThreadTime());
|
||
|
OS_ThreadSleep(100);
|
||
|
printf("Thread time = %d\n", OS_ThreadTime());
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
static void TestSemThread(void *arg)
|
||
|
{
|
||
|
int i;
|
||
|
TestInfo_t *info = (TestInfo_t*)arg;
|
||
|
|
||
|
for(i = 0; i < SEMAPHORE_COUNT/2; ++i)
|
||
|
{
|
||
|
printf("s");
|
||
|
OS_SemaphorePend(info->MySemaphore[i], OS_WAIT_FOREVER);
|
||
|
OS_SemaphorePost(info->MySemaphore[i + SEMAPHORE_COUNT/2]);
|
||
|
}
|
||
|
OS_ThreadExit();
|
||
|
}
|
||
|
|
||
|
static void TestSemaphore(void)
|
||
|
{
|
||
|
int i, rc;
|
||
|
TestInfo_t info;
|
||
|
printf("TestSemaphore\n");
|
||
|
for(i = 0; i < SEMAPHORE_COUNT; ++i)
|
||
|
{
|
||
|
info.MySemaphore[i] = OS_SemaphoreCreate("MySem", 0);
|
||
|
//printf("sem[%d]=0x%x\n", i, MySemaphore[i]);
|
||
|
}
|
||
|
|
||
|
OS_ThreadCreate("TestSem", TestSemThread, &info, 50, 0);
|
||
|
|
||
|
for(i = 0; i < SEMAPHORE_COUNT/2; ++i)
|
||
|
{
|
||
|
printf("S");
|
||
|
OS_SemaphorePost(info.MySemaphore[i]);
|
||
|
rc = OS_SemaphorePend(info.MySemaphore[i + SEMAPHORE_COUNT/2], 500);
|
||
|
assert(rc == 0);
|
||
|
}
|
||
|
|
||
|
printf(":");
|
||
|
rc = OS_SemaphorePend(info.MySemaphore[0], 10);
|
||
|
assert(rc != 0);
|
||
|
printf(":");
|
||
|
OS_SemaphorePend(info.MySemaphore[0], 100);
|
||
|
printf(":");
|
||
|
|
||
|
for(i = 0; i < SEMAPHORE_COUNT; ++i)
|
||
|
OS_SemaphoreDelete(info.MySemaphore[i]);
|
||
|
|
||
|
printf("\nDone.\n");
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
static void TestMutexThread(void *arg)
|
||
|
{
|
||
|
TestInfo_t *info = (TestInfo_t*)arg;
|
||
|
|
||
|
printf("Waiting for mutex\n");
|
||
|
OS_MutexPend(info->MyMutex);
|
||
|
printf("Have Mutex1\n");
|
||
|
OS_MutexPend(info->MyMutex);
|
||
|
printf("Have Mutex2\n");
|
||
|
OS_MutexPend(info->MyMutex);
|
||
|
printf("Have Mutex3\n");
|
||
|
|
||
|
OS_ThreadSleep(100);
|
||
|
|
||
|
OS_MutexPost(info->MyMutex);
|
||
|
OS_MutexPost(info->MyMutex);
|
||
|
OS_MutexPost(info->MyMutex);
|
||
|
|
||
|
OS_ThreadExit();
|
||
|
}
|
||
|
|
||
|
static void TestMutex(void)
|
||
|
{
|
||
|
TestInfo_t info;
|
||
|
printf("TestMutex\n");
|
||
|
info.MyMutex = OS_MutexCreate("MyMutex");
|
||
|
OS_MutexPend(info.MyMutex);
|
||
|
OS_MutexPend(info.MyMutex);
|
||
|
OS_MutexPend(info.MyMutex);
|
||
|
|
||
|
OS_ThreadSleep(100);
|
||
|
|
||
|
OS_ThreadCreate("TestMutex", TestMutexThread, &info, 50, 0);
|
||
|
|
||
|
OS_ThreadSleep(50);
|
||
|
OS_MutexPost(info.MyMutex);
|
||
|
OS_MutexPost(info.MyMutex);
|
||
|
OS_MutexPost(info.MyMutex);
|
||
|
|
||
|
printf("Try get mutex\n");
|
||
|
OS_MutexPend(info.MyMutex);
|
||
|
printf("Gotit\n");
|
||
|
|
||
|
OS_MutexDelete(info.MyMutex);
|
||
|
printf("Done.\n");
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
static void TestMQueue(void)
|
||
|
{
|
||
|
OS_MQueue_t *mqueue;
|
||
|
char data[16];
|
||
|
int i, rc;
|
||
|
|
||
|
printf("TestMQueue\n");
|
||
|
mqueue = OS_MQueueCreate("MyMQueue", 10, 16);
|
||
|
strcpy(data, "Test0");
|
||
|
for(i = 0; i < 16; ++i)
|
||
|
{
|
||
|
data[4] = (char)('0' + i);
|
||
|
OS_MQueueSend(mqueue, data);
|
||
|
}
|
||
|
for(i = 0; i < 16; ++i)
|
||
|
{
|
||
|
memset(data, 0, sizeof(data));
|
||
|
rc = OS_MQueueGet(mqueue, data, 20);
|
||
|
if(rc == 0)
|
||
|
printf("message=(%s)\n", data);
|
||
|
else
|
||
|
printf("timeout\n");
|
||
|
}
|
||
|
|
||
|
OS_MQueueDelete(mqueue);
|
||
|
printf("Done.\n");
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
static void TestTimerThread(void *arg)
|
||
|
{
|
||
|
int index;
|
||
|
uint32 data[4];
|
||
|
OS_Timer_t *timer;
|
||
|
TestInfo_t *info = (TestInfo_t*)arg;
|
||
|
|
||
|
//printf("TestTimerThread\n");
|
||
|
|
||
|
OS_ThreadSleep(1);
|
||
|
index = (int)OS_ThreadInfoGet(OS_ThreadSelf(), 0);
|
||
|
//printf("index=%d\n", index);
|
||
|
OS_MQueueGet(info->MyQueue[index], data, 1000);
|
||
|
timer = (OS_Timer_t*)data[1];
|
||
|
printf("%d ", data[2]);
|
||
|
OS_MQueueGet(info->MyQueue[index], data, 1000);
|
||
|
printf("%d ", data[2]);
|
||
|
++info->TimerDone;
|
||
|
OS_ThreadExit();
|
||
|
}
|
||
|
|
||
|
static void TestTimer(void)
|
||
|
{
|
||
|
int i;
|
||
|
TestInfo_t info;
|
||
|
|
||
|
printf("TestTimer\n");
|
||
|
info.TimerDone = 0;
|
||
|
for(i = 0; i < TIMER_COUNT; ++i)
|
||
|
{
|
||
|
info.MyQueue[i] = OS_MQueueCreate("MyQueue", 10, 16);
|
||
|
info.MyTimer[i] = OS_TimerCreate("MyTimer", info.MyQueue[i], i);
|
||
|
info.MyThread[i] = OS_ThreadCreate("TimerTest", TestTimerThread, &info, 50, 0);
|
||
|
OS_ThreadInfoSet(info.MyThread[i], 0, (void*)i);
|
||
|
OS_TimerStart(info.MyTimer[i], 10+i*2, 220+i);
|
||
|
}
|
||
|
|
||
|
while(info.TimerDone < TIMER_COUNT)
|
||
|
OS_ThreadSleep(10);
|
||
|
|
||
|
for(i = 0; i < TIMER_COUNT; ++i)
|
||
|
{
|
||
|
OS_MQueueDelete(info.MyQueue[i]);
|
||
|
OS_TimerDelete(info.MyTimer[i]);
|
||
|
}
|
||
|
|
||
|
printf("Done.\n");
|
||
|
}
|
||
|
|
||
|
//******************************************************************
|
||
|
#if 1
|
||
|
void TestMath(void)
|
||
|
{
|
||
|
int i;
|
||
|
float a, b, sum, diff, mult, div;
|
||
|
uint32 compare;
|
||
|
|
||
|
//Check add subtract multiply and divide
|
||
|
for(i = -4; i < 4; ++i)
|
||
|
{
|
||
|
a = (float)(i * 10 + (float)63.2);
|
||
|
b = (float)(-i * 5 + (float)3.5);
|
||
|
sum = a + b;
|
||
|
diff = a - b;
|
||
|
mult = a * b;
|
||
|
div = a / b;
|
||
|
printf("a=%dE-3 b=%dE-3 sum=%dE-3 diff=%dE-3 mult=%dE-3 div=%dE-3\n",
|
||
|
(int)(a*(float)1000), (int)(b*(float)1000),
|
||
|
(int)(sum*(float)1000), (int)(diff*(float)1000),
|
||
|
(int)(mult*(float)1000), (int)(div*(float)1000));
|
||
|
}
|
||
|
|
||
|
//Comparisons
|
||
|
b = (float)2.0;
|
||
|
compare = 0;
|
||
|
for(i = 1; i < 4; ++i)
|
||
|
{
|
||
|
a = (float)i;
|
||
|
compare = (compare << 1) | (a == b);
|
||
|
compare = (compare << 1) | (a != b);
|
||
|
compare = (compare << 1) | (a < b);
|
||
|
compare = (compare << 1) | (a <= b);
|
||
|
compare = (compare << 1) | (a > b);
|
||
|
compare = (compare << 1) | (a >= b);
|
||
|
}
|
||
|
printf("Compare = %8x %s\n", compare,
|
||
|
compare==0x1c953 ? "OK" : "ERROR");
|
||
|
|
||
|
//Cosine
|
||
|
for(a = (float)0.0; a <= (float)(3.1415); a += (float)(3.1415/16.0))
|
||
|
{
|
||
|
b = FP_Cos(a);
|
||
|
printf("cos(%4dE-3) = %4dE-3\n",
|
||
|
(int)(a*(float)1000.0), (int)(b*(float)1000.0));
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
//******************************************************************
|
||
|
#ifndef WIN32
|
||
|
static void MySyscall(void *arg)
|
||
|
{
|
||
|
uint32 *stack = arg;
|
||
|
stack[STACK_EPC] += 4; //skip over SYSCALL
|
||
|
printf("Inside MySyscall %d\n", stack[28/4]);
|
||
|
}
|
||
|
|
||
|
void TestSyscall(void)
|
||
|
{
|
||
|
OS_InterruptRegister((uint32)(1<<31), MySyscall);
|
||
|
OS_Syscall(57);
|
||
|
OS_ThreadSleep(1);
|
||
|
printf("Done\n");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef __MMU_ENUM_H__
|
||
|
void TestProcess(void)
|
||
|
{
|
||
|
OS_Process_t *process;
|
||
|
process = (OS_Process_t*)OS_HeapMalloc(NULL, sizeof(OS_Process_t));
|
||
|
process->name = "test";
|
||
|
process->funcPtr = MainThread;
|
||
|
process->arg = NULL;
|
||
|
process->priority = 200;
|
||
|
process->stackSize = 1024*32;
|
||
|
process->heapSize = 1024*128;
|
||
|
process->processId = 1;
|
||
|
process->semaphoreDone = OS_SemaphoreCreate("processDone", 0);
|
||
|
printf("Creating process\n");
|
||
|
OS_MMUProcessCreate(process);
|
||
|
OS_SemaphorePend(process->semaphoreDone, OS_WAIT_FOREVER);
|
||
|
printf("Process done\n");
|
||
|
OS_MMUProcessDelete(process);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//******************************************************************
|
||
|
void MMUTest(void);
|
||
|
void HtmlThread(void *arg);
|
||
|
void ConsoleInit(void);
|
||
|
void exit(int);
|
||
|
uint8 macAddress[] = {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4};
|
||
|
|
||
|
|
||
|
void MainThread(void *Arg)
|
||
|
{
|
||
|
int ch, i, display=1;
|
||
|
(void)Arg;
|
||
|
#ifdef __MMU_ENUM_H__
|
||
|
OS_MMUInit();
|
||
|
#endif
|
||
|
|
||
|
#ifdef INCLUDE_ETH
|
||
|
EthernetInit(macAddress);
|
||
|
IPInit(EthernetTransmit, macAddress, "plasma");
|
||
|
HtmlInit(1);
|
||
|
#endif
|
||
|
|
||
|
#ifdef INCLUDE_HTML
|
||
|
IPInit(NULL, macAddress, "plasma");
|
||
|
HtmlInit(1);
|
||
|
#endif
|
||
|
|
||
|
#ifdef INCLUDE_CONSOLE
|
||
|
ConsoleInit();
|
||
|
#endif
|
||
|
|
||
|
for(;;)
|
||
|
{
|
||
|
if(display)
|
||
|
{
|
||
|
printf("\n");
|
||
|
printf("1 CLib\n");
|
||
|
printf("2 Heap\n");
|
||
|
printf("3 Thread\n");
|
||
|
printf("4 Semaphore\n");
|
||
|
printf("5 Mutex\n");
|
||
|
printf("6 MQueue\n");
|
||
|
printf("7 Timer\n");
|
||
|
printf("8 Math\n");
|
||
|
printf("9 Syscall\n");
|
||
|
#ifdef __MMU_ENUM_H__
|
||
|
printf("p MMU Process\n");
|
||
|
#endif
|
||
|
}
|
||
|
printf("> ");
|
||
|
display = 1;
|
||
|
ch = UartRead();
|
||
|
printf("%c\n", ch);
|
||
|
switch(ch)
|
||
|
{
|
||
|
#ifdef WIN32
|
||
|
case '0': exit(0);
|
||
|
#endif
|
||
|
case '1': TestCLib(); break;
|
||
|
case '2': TestHeap(); break;
|
||
|
case '3': TestThread(); break;
|
||
|
case '4': TestSemaphore(); break;
|
||
|
case '5': TestMutex(); break;
|
||
|
case '6': TestMQueue(); break;
|
||
|
case '7': TestTimer(); break;
|
||
|
case '8': TestMath(); break;
|
||
|
#ifndef WIN32
|
||
|
case '9': TestSyscall(); break;
|
||
|
#endif
|
||
|
#ifdef __MMU_ENUM_H__
|
||
|
case 'p': TestProcess(); break;
|
||
|
#endif
|
||
|
#ifdef WIN32
|
||
|
case 'm': TestMathFull(); break;
|
||
|
#endif
|
||
|
case 'g': printf("Global=%d\n", ++Global); break;
|
||
|
default:
|
||
|
printf("E");
|
||
|
display = 0;
|
||
|
for(i = 0; i < 30; ++i)
|
||
|
{
|
||
|
while(kbhit())
|
||
|
ch = UartRead();
|
||
|
OS_ThreadSleep(1);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|