OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [rtos.c] - Diff between revs 395 and 396

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 395 Rev 396
Line 127... Line 127...
static int ThreadNeedReschedule[OS_CPU_COUNT];
static int ThreadNeedReschedule[OS_CPU_COUNT];
static OS_Thread_t *ThreadCurrent[OS_CPU_COUNT];  //Currently running thread(s)
static OS_Thread_t *ThreadCurrent[OS_CPU_COUNT];  //Currently running thread(s)
static OS_Thread_t *ThreadHead;   //Linked list of threads sorted by priority
static OS_Thread_t *ThreadHead;   //Linked list of threads sorted by priority
static OS_Thread_t *TimeoutHead;  //Linked list of threads sorted by timeout
static OS_Thread_t *TimeoutHead;  //Linked list of threads sorted by timeout
static int ThreadSwapEnabled;
static int ThreadSwapEnabled;
static uint32 ThreadTime;
static uint32 ThreadTime;         //Number of ~10ms ticks since reboot
static void *NeedToFree;
static void *NeedToFree;          //Closed but not yet freed thread
static OS_Semaphore_t SemaphoreReserved[SEM_RESERVED_COUNT];
static OS_Semaphore_t SemaphoreReserved[SEM_RESERVED_COUNT];
static OS_Semaphore_t *SemaphoreSleep;
static OS_Semaphore_t *SemaphoreSleep;
static OS_Semaphore_t *SemaphoreRelease;
static OS_Semaphore_t *SemaphoreRelease;
static OS_Semaphore_t *SemaphoreLock;
static OS_Semaphore_t *SemaphoreLock;
static OS_Semaphore_t *SemaphoreTimer;
static OS_Semaphore_t *SemaphoreTimer;
Line 166... Line 166...
   OS_SemaphoreDelete(heap->semaphore);
   OS_SemaphoreDelete(heap->semaphore);
}
}
 
 
 
 
/******************************************/
/******************************************/
//Modified from K&R
//Modified from Kernighan & Ritchie "The C Programming Language"
void *OS_HeapMalloc(OS_Heap_t *heap, int bytes)
void *OS_HeapMalloc(OS_Heap_t *heap, int bytes)
{
{
   HeapNode_t *node, *prevp;
   HeapNode_t *node, *prevp;
   int nunits;
   int nunits;
 
 
Line 393... Line 393...
 
 
   //Determine which thread should run
   //Determine which thread should run
   threadNext = ThreadHead;
   threadNext = ThreadHead;
   while(threadNext && threadNext->cpuLock != -1 &&
   while(threadNext && threadNext->cpuLock != -1 &&
         threadNext->cpuLock != cpuIndex)
         threadNext->cpuLock != cpuIndex)
      threadNext = threadNext->next;
      threadNext = threadNext->next;         //Skip CPU locked threads
   if(threadNext == NULL)
   if(threadNext == NULL)
      return;
      return;
   threadCurrent = ThreadCurrent[cpuIndex];
   threadCurrent = ThreadCurrent[cpuIndex];
 
 
   if(threadCurrent == NULL ||
   if(threadCurrent == NULL ||
Line 514... Line 514...
   OS_ThreadRegsInit(thread->env);
   OS_ThreadRegsInit(thread->env);
   env = (jmp_buf2*)thread->env;
   env = (jmp_buf2*)thread->env;
   env->sp = (uint32)stack + stackSize - 24; //minimum stack frame size
   env->sp = (uint32)stack + stackSize - 24; //minimum stack frame size
   env->pc = (uint32)OS_ThreadInit;
   env->pc = (uint32)OS_ThreadInit;
 
 
 
   //Add thread to linked list of ready to run threads
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();
   OS_ThreadPriorityInsert(&ThreadHead, thread);
   OS_ThreadPriorityInsert(&ThreadHead, thread);
   OS_ThreadReschedule(0);
   OS_ThreadReschedule(0);                   //run highest priority thread
   OS_CriticalEnd(state);
   OS_CriticalEnd(state);
   return thread;
   return thread;
}
}
 
 
 
 
Line 529... Line 530...
{
{
   uint32 state, cpuIndex = OS_CpuIndex();
   uint32 state, cpuIndex = OS_CpuIndex();
 
 
   for(;;)
   for(;;)
   {
   {
 
      //Free the memory for closed but not yet freed threads
      OS_SemaphorePend(SemaphoreRelease, OS_WAIT_FOREVER);
      OS_SemaphorePend(SemaphoreRelease, OS_WAIT_FOREVER);
      if(NeedToFree)
      if(NeedToFree)
         OS_HeapFree(NeedToFree);
         OS_HeapFree(NeedToFree);
      NeedToFree = NULL;
      NeedToFree = NULL;
      OS_SemaphorePost(SemaphoreRelease);
      OS_SemaphorePost(SemaphoreRelease);
Line 550... Line 552...
   }
   }
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Return currently running thread
OS_Thread_t *OS_ThreadSelf(void)
OS_Thread_t *OS_ThreadSelf(void)
{
{
   return ThreadCurrent[OS_CpuIndex()];
   return ThreadCurrent[OS_CpuIndex()];
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Sleep for ~10 msecs ticks
void OS_ThreadSleep(int ticks)
void OS_ThreadSleep(int ticks)
{
{
   OS_SemaphorePend(SemaphoreSleep, ticks);
   OS_SemaphorePend(SemaphoreSleep, ticks);
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Return the number of ~10 msecs ticks since reboot
uint32 OS_ThreadTime(void)
uint32 OS_ThreadTime(void)
{
{
   return ThreadTime;
   return ThreadTime;
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Save thread unique values
void OS_ThreadInfoSet(OS_Thread_t *thread, uint32 index, void *Info)
void OS_ThreadInfoSet(OS_Thread_t *thread, uint32 index, void *Info)
{
{
   if(index < INFO_COUNT)
   if(index < INFO_COUNT)
      thread->info[index] = Info;
      thread->info[index] = Info;
}
}
Line 619... Line 625...
   thread->heap = heap;
   thread->heap = heap;
}
}
 
 
 
 
/******************************************/
/******************************************/
//Must be called with interrupts disabled
//Must be called with interrupts disabled every ~10 msecs
 
//Will wake up threads that have timed out waiting on a semaphore
void OS_ThreadTick(void *Arg)
void OS_ThreadTick(void *Arg)
{
{
   OS_Thread_t *thread;
   OS_Thread_t *thread;
   OS_Semaphore_t *semaphore;
   OS_Semaphore_t *semaphore;
   int diff;
   int diff;
   (void)Arg;
   (void)Arg;
 
 
   ++ThreadTime;
   ++ThreadTime;         //Number of ~10 msec ticks since reboot
   while(TimeoutHead)
   while(TimeoutHead)
   {
   {
      thread = TimeoutHead;
      thread = TimeoutHead;
      diff = ThreadTime - thread->ticksTimeout;
      diff = ThreadTime - thread->ticksTimeout;
      if(diff < 0)
      if(diff < 0)
         break;
         break;
 
 
 
      //The thread has timed out waiting for a semaphore
      OS_ThreadTimeoutRemove(thread);
      OS_ThreadTimeoutRemove(thread);
      semaphore = thread->semaphorePending;
      semaphore = thread->semaphorePending;
      ++semaphore->count;
      ++semaphore->count;
      thread->semaphorePending = NULL;
      thread->semaphorePending = NULL;
      thread->returnCode = -1;
      thread->returnCode = -1;
      OS_ThreadPriorityRemove(&semaphore->threadHead, thread);
      OS_ThreadPriorityRemove(&semaphore->threadHead, thread);
      OS_ThreadPriorityInsert(&ThreadHead, thread);
      OS_ThreadPriorityInsert(&ThreadHead, thread);
   }
   }
   OS_ThreadReschedule(1);
   OS_ThreadReschedule(1);    //Run highest priority thread
}
}
 
 
 
 
 
 
/***************** Semaphore **************/
/***************** Semaphore **************/
/******************************************/
/******************************************/
 
//Create a counting semaphore
OS_Semaphore_t *OS_SemaphoreCreate(const char *name, uint32 count)
OS_Semaphore_t *OS_SemaphoreCreate(const char *name, uint32 count)
{
{
   OS_Semaphore_t *semaphore;
   OS_Semaphore_t *semaphore;
   static int semCount = 0;
   static int semCount = 0;
 
 
Line 679... Line 689...
   OS_HeapFree(semaphore);
   OS_HeapFree(semaphore);
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Sleep the number of ticks (~10ms) until the semaphore is acquired
int OS_SemaphorePend(OS_Semaphore_t *semaphore, int ticks)
int OS_SemaphorePend(OS_Semaphore_t *semaphore, int ticks)
{
{
   uint32 state, cpuIndex;
   uint32 state, cpuIndex;
   OS_Thread_t *thread;
   OS_Thread_t *thread;
   int returnCode=0;
   int returnCode=0;
 
 
   assert(semaphore);
   assert(semaphore);
   assert(InterruptInside[OS_CpuIndex()] == 0);
   assert(InterruptInside[OS_CpuIndex()] == 0);
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();    //Disable interrupts
   if(--semaphore->count < 0)
   if(--semaphore->count < 0)
   {
   {
 
      //Semaphore not available
      if(ticks == 0)
      if(ticks == 0)
      {
      {
         ++semaphore->count;
         ++semaphore->count;
         OS_CriticalEnd(state);
         OS_CriticalEnd(state);
         return -1;
         return -1;
      }
      }
 
 
 
      //Need to sleep until the semaphore is available
      cpuIndex = OS_CpuIndex();
      cpuIndex = OS_CpuIndex();
      thread = ThreadCurrent[cpuIndex];
      thread = ThreadCurrent[cpuIndex];
      assert(thread);
      assert(thread);
      thread->semaphorePending = semaphore;
      thread->semaphorePending = semaphore;
      thread->ticksTimeout = ticks + OS_ThreadTime();
      thread->ticksTimeout = ticks + OS_ThreadTime();
 
 
      //FYI: The current thread isn't in the ThreadHead linked list
      //FYI: The current thread isn't in the ThreadHead linked list
 
      //Place the thread into a sorted linked list of pending threads
      OS_ThreadPriorityInsert(&semaphore->threadHead, thread);
      OS_ThreadPriorityInsert(&semaphore->threadHead, thread);
      thread->state = THREAD_PEND;
      thread->state = THREAD_PEND;
      if(ticks != OS_WAIT_FOREVER)
      if(ticks != OS_WAIT_FOREVER)
         OS_ThreadTimeoutInsert(thread);
         OS_ThreadTimeoutInsert(thread); //Check every ~10ms for timeouts
      assert(ThreadHead);
      assert(ThreadHead);
      OS_ThreadReschedule(0);
      OS_ThreadReschedule(0);           //Run highest priority thread
      returnCode = thread->returnCode;
      returnCode = thread->returnCode;  //Will be -1 if timed out
   }
   }
   OS_CriticalEnd(state);
   OS_CriticalEnd(state);               //Re-enable interrupts
   return returnCode;
   return returnCode;
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Release a semaphore and possibly wake up a blocked thread
void OS_SemaphorePost(OS_Semaphore_t *semaphore)
void OS_SemaphorePost(OS_Semaphore_t *semaphore)
{
{
   uint32 state;
   uint32 state;
   OS_Thread_t *thread;
   OS_Thread_t *thread;
 
 
   assert(semaphore);
   assert(semaphore);
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();
   if(++semaphore->count <= 0)
   if(++semaphore->count <= 0)
   {
   {
 
      //Wake up a thread that was waiting for this semaphore
      thread = semaphore->threadHead;
      thread = semaphore->threadHead;
      OS_ThreadTimeoutRemove(thread);
      OS_ThreadTimeoutRemove(thread);
      OS_ThreadPriorityRemove(&semaphore->threadHead, thread);
      OS_ThreadPriorityRemove(&semaphore->threadHead, thread);
      OS_ThreadPriorityInsert(&ThreadHead, thread);
      OS_ThreadPriorityInsert(&ThreadHead, thread);
      thread->semaphorePending = NULL;
      thread->semaphorePending = NULL;
Line 740... Line 758...
 
 
 
 
 
 
/***************** Mutex ******************/
/***************** Mutex ******************/
/******************************************/
/******************************************/
 
//Create a mutex (a thread aware semaphore)
OS_Mutex_t *OS_MutexCreate(const char *name)
OS_Mutex_t *OS_MutexCreate(const char *name)
{
{
   OS_Mutex_t *mutex;
   OS_Mutex_t *mutex;
 
 
   mutex = (OS_Mutex_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_Mutex_t));
   mutex = (OS_Mutex_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_Mutex_t));
Line 799... Line 818...
 
 
 
 
 
 
/***************** MQueue *****************/
/***************** MQueue *****************/
/******************************************/
/******************************************/
 
//Create a message queue
OS_MQueue_t *OS_MQueueCreate(const char *name,
OS_MQueue_t *OS_MQueueCreate(const char *name,
                             int messageCount,
                             int messageCount,
                             int messageBytes)
                             int messageBytes)
{
{
   OS_MQueue_t *queue;
   OS_MQueue_t *queue;
   int size;
   int size;
 
 
 
   assert((messageBytes & 3) == 0);
   size = messageBytes / sizeof(uint32);
   size = messageBytes / sizeof(uint32);
   queue = (OS_MQueue_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_MQueue_t) +
   queue = (OS_MQueue_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_MQueue_t) +
      messageCount * size * 4);
      messageCount * size * 4);
   if(queue == NULL)
   if(queue == NULL)
      return queue;
      return queue;
Line 833... Line 854...
   OS_HeapFree(mQueue);
   OS_HeapFree(mQueue);
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Send a message that is messageBytes long (defined during create)
int OS_MQueueSend(OS_MQueue_t *mQueue, void *message)
int OS_MQueueSend(OS_MQueue_t *mQueue, void *message)
{
{
   uint32 state, *dst, *src;
   uint32 state, *dst, *src;
   int i;
   int i;
 
 
   assert(mQueue);
   assert(mQueue);
   src = (uint32*)message;
   src = (uint32*)message;
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();           //Disable interrupts
   if(++mQueue->used > mQueue->count)
   if(++mQueue->used > mQueue->count)
   {
   {
 
      //The message queue is full so discard the message
      --mQueue->used;
      --mQueue->used;
      OS_CriticalEnd(state);
      OS_CriticalEnd(state);
      return -1;
      return -1;
   }
   }
   dst = (uint32*)(mQueue + 1) + mQueue->write * mQueue->size;
   dst = (uint32*)(mQueue + 1) + mQueue->write * mQueue->size;
   for(i = 0; i < mQueue->size; ++i)
   for(i = 0; i < mQueue->size; ++i)     //Copy the message into the queue
      dst[i] = src[i];
      dst[i] = src[i];
   if(++mQueue->write >= mQueue->count)
   if(++mQueue->write >= mQueue->count)
      mQueue->write = 0;
      mQueue->write = 0;
   OS_CriticalEnd(state);
   OS_CriticalEnd(state);                //Re-enable interrupts
   OS_SemaphorePost(mQueue->semaphore);
   OS_SemaphorePost(mQueue->semaphore);  //Wakeup the receiving thread
   return 0;
   return 0;
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Receive a message that is messageBytes long (defined during create)
 
//Wait at most ~10 msec ticks
int OS_MQueueGet(OS_MQueue_t *mQueue, void *message, int ticks)
int OS_MQueueGet(OS_MQueue_t *mQueue, void *message, int ticks)
{
{
   uint32 state, *dst, *src;
   uint32 state, *dst, *src;
   int i, rc;
   int i, rc;
 
 
   assert(mQueue);
   assert(mQueue);
   dst = (uint32*)message;
   rc = OS_SemaphorePend(mQueue->semaphore, ticks); //Wait for message
   rc = OS_SemaphorePend(mQueue->semaphore, ticks);
 
   if(rc)
   if(rc)
      return rc;
      return rc;                         //Request timed out so rc = -1
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();           //Disable interrupts
   --mQueue->used;
   --mQueue->used;
 
   dst = (uint32*)message;
   src = (uint32*)(mQueue + 1) + mQueue->read * mQueue->size;
   src = (uint32*)(mQueue + 1) + mQueue->read * mQueue->size;
   for(i = 0; i < mQueue->size; ++i)
   for(i = 0; i < mQueue->size; ++i)     //Copy message from the queue
      dst[i] = src[i];
      dst[i] = src[i];
   if(++mQueue->read >= mQueue->count)
   if(++mQueue->read >= mQueue->count)
      mQueue->read = 0;
      mQueue->read = 0;
   OS_CriticalEnd(state);
   OS_CriticalEnd(state);                //Re-enable interrupts
   return 0;
   return 0;
}
}
 
 
 
 
 
 
Line 888... Line 913...
/******************************************/
/******************************************/
typedef void (*JobFunc_t)();
typedef void (*JobFunc_t)();
static OS_MQueue_t *jobQueue;
static OS_MQueue_t *jobQueue;
static OS_Thread_t *jobThread;
static OS_Thread_t *jobThread;
 
 
 
//This thread waits for jobs that request a function to be called
static void JobThread(void *arg)
static void JobThread(void *arg)
{
{
   uint32 message[4];
   uint32 message[4];
   JobFunc_t funcPtr;
   JobFunc_t funcPtr;
   (void)arg;
   (void)arg;
Line 903... Line 929...
   }
   }
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Call a function using the job thread so the caller won't be blocked
void OS_Job(void (*funcPtr)(), void *arg0, void *arg1, void *arg2)
void OS_Job(void (*funcPtr)(), void *arg0, void *arg1, void *arg2)
{
{
   uint32 message[4];
   uint32 message[4];
   int rc;
   int rc;
 
 
Line 926... Line 953...
}
}
 
 
 
 
/***************** Timer ******************/
/***************** Timer ******************/
/******************************************/
/******************************************/
 
//This thread polls the list of timers to see if any have timed out
static void OS_TimerThread(void *arg)
static void OS_TimerThread(void *arg)
{
{
   uint32 timeNow;
   uint32 timeNow;
   int diff, ticks;
   int diff, ticks;
   uint32 message[8];
   uint32 message[8];
   OS_Timer_t *timer;
   OS_Timer_t *timer;
   (void)arg;
   (void)arg;
 
 
   timeNow = OS_ThreadTime();
   timeNow = OS_ThreadTime();  //Number of ~10 msec ticks since reboot
   for(;;)
   for(;;)
   {
   {
      //Determine how long to sleep
      //Determine how long to sleep
      OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);
      OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);
      if(TimerHead)
      if(TimerHead)
Line 982... Line 1010...
   }
   }
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Create a timer that will send a message upon timeout
OS_Timer_t *OS_TimerCreate(const char *name, OS_MQueue_t *mQueue, uint32 info)
OS_Timer_t *OS_TimerCreate(const char *name, OS_MQueue_t *mQueue, uint32 info)
{
{
   OS_Timer_t *timer;
   OS_Timer_t *timer;
 
 
   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);
   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);
Line 1025... Line 1054...
}
}
 
 
 
 
/******************************************/
/******************************************/
//Must not be called from an ISR
//Must not be called from an ISR
 
//In ~10 msec ticks send a message (or callback)
void OS_TimerStart(OS_Timer_t *timer, uint32 ticks, uint32 ticksRestart)
void OS_TimerStart(OS_Timer_t *timer, uint32 ticks, uint32 ticksRestart)
{
{
   OS_Timer_t *node, *prev;
   OS_Timer_t *node, *prev;
   int diff, check=0;
   int diff, check=0;
 
 
Line 1066... Line 1096...
   }
   }
   else
   else
      prev->next = timer;
      prev->next = timer;
   OS_SemaphorePost(SemaphoreLock);
   OS_SemaphorePost(SemaphoreLock);
   if(check)
   if(check)
      OS_SemaphorePost(SemaphoreTimer);
      OS_SemaphorePost(SemaphoreTimer);  //Wakeup OS_TimerThread
}
}
 
 
 
 
/******************************************/
/******************************************/
//Must not be called from an ISR
//Must not be called from an ISR
Line 1173... Line 1203...
}
}
 
 
 
 
/**************** Init ********************/
/**************** Init ********************/
/******************************************/
/******************************************/
 
//If there aren't any other ready to run threads then spin here
static volatile uint32 IdleCount;
static volatile uint32 IdleCount;
static void OS_IdleThread(void *arg)
static void OS_IdleThread(void *arg)
{
{
   (void)arg;
   (void)arg;
 
 
Line 1188... Line 1219...
}
}
 
 
 
 
/******************************************/
/******************************************/
#ifndef DISABLE_IRQ_SIM
#ifndef DISABLE_IRQ_SIM
 
//Simulate the hardware interrupts
static void OS_IdleSimulateIsr(void *arg)
static void OS_IdleSimulateIsr(void *arg)
{
{
   uint32 count=0, value;
   uint32 count=0, value;
   (void)arg;
   (void)arg;
 
 
Line 1211... Line 1243...
#endif //DISABLE_IRQ_SIM
#endif //DISABLE_IRQ_SIM
 
 
 
 
/******************************************/
/******************************************/
//Plasma hardware dependent
//Plasma hardware dependent
 
//ISR called every ~10 msecs when bit 18 of the counter register toggles
static void OS_ThreadTickToggle(void *arg)
static void OS_ThreadTickToggle(void *arg)
{
{
   uint32 status, mask, state;
   uint32 status, mask, state;
 
 
   //Toggle looking for IRQ_COUNTER18 or IRQ_COUNTER18_NOT
   //Toggle looking for IRQ_COUNTER18 or IRQ_COUNTER18_NOT
Line 1227... Line 1260...
   OS_SpinUnlock(state);
   OS_SpinUnlock(state);
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Initialize the OS by setting up the system heap and the tick interrupt
void OS_Init(uint32 *heapStorage, uint32 bytes)
void OS_Init(uint32 *heapStorage, uint32 bytes)
{
{
   int i;
   int i;
   if((int)OS_Init > 0x10000000)        //Running from DDR?
   if((int)OS_Init > 0x10000000)        //Running from DDR?
      OS_AsmInterruptInit();            //Patch interrupt vector
      OS_AsmInterruptInit();            //Patch interrupt vector
Line 1248... Line 1282...
      //Detected that running in simulator so create SimIsr thread
      //Detected that running in simulator so create SimIsr thread
      UartPrintfCritical("SimIsr\n");
      UartPrintfCritical("SimIsr\n");
      OS_ThreadCreate("SimIsr", OS_IdleSimulateIsr, NULL, 1, 0);
      OS_ThreadCreate("SimIsr", OS_IdleSimulateIsr, NULL, 1, 0);
   }
   }
#endif //DISABLE_IRQ_SIM
#endif //DISABLE_IRQ_SIM
   //Plasma hardware dependent
   //Plasma hardware dependent (register for OS tick interrupt every ~10 msecs)
   OS_InterruptRegister(IRQ_COUNTER18 | IRQ_COUNTER18_NOT, OS_ThreadTickToggle);
   OS_InterruptRegister(IRQ_COUNTER18 | IRQ_COUNTER18_NOT, OS_ThreadTickToggle);
   OS_InterruptMaskSet(IRQ_COUNTER18 | IRQ_COUNTER18_NOT);
   OS_InterruptMaskSet(IRQ_COUNTER18 | IRQ_COUNTER18_NOT);
}
}
 
 
 
 
/******************************************/
/******************************************/
 
//Start thread swapping
void OS_Start(void)
void OS_Start(void)
{
{
   ThreadSwapEnabled = 1;
   ThreadSwapEnabled = 1;
   (void)OS_SpinLock();
   (void)OS_SpinLock();
   OS_ThreadReschedule(1);
   OS_ThreadReschedule(1);
Line 1288... Line 1323...
   uint32 state, cpuIndex, i, j, ok, delay;
   uint32 state, cpuIndex, i, j, ok, delay;
 
 
   cpuIndex = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
   delay = cpuIndex + 8;
   delay = cpuIndex + 8;
   state = OS_AsmInterruptEnable(0);
   state = OS_AsmInterruptEnable(0);
 
   //Spin until only this CPU has the spin lock
   do
   do
   {
   {
      ok = 1;
      ok = 1;
      if(++SpinLockArray[cpuIndex] == 1)
      if(++SpinLockArray[cpuIndex] == 1)
      {
      {
         for(i = 0; i < OS_CPU_COUNT; ++i)
         for(i = 0; i < OS_CPU_COUNT; ++i)
         {
         {
            if(i != cpuIndex && SpinLockArray[i])
            if(i != cpuIndex && SpinLockArray[i])
               ok = 0;
               ok = 0;   //Another CPU has the spin lock
         }
         }
         if(ok == 0)
         if(ok == 0)
         {
         {
            SpinLockArray[cpuIndex] = 0;
            SpinLockArray[cpuIndex] = 0;
            for(j = 0; j < delay; ++j)  //wait a bit
            for(j = 0; j < delay; ++j)  //wait a bit
Line 1338... Line 1374...
#define UartScanf UartScanf2
#define UartScanf UartScanf2
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <termios.h>
#include <termios.h>
#include <unistd.h>
#include <unistd.h>
 
//Support RTOS inside Linux
void Sleep(unsigned int value)
void Sleep(unsigned int value)
{
{
   usleep(value * 1000);
   usleep(value * 1000);
}
}
 
 
Line 1389... Line 1426...
extern void __stdcall Sleep(unsigned long value);
extern void __stdcall Sleep(unsigned long value);
#endif
#endif
 
 
static uint32 Memory[8];
static uint32 Memory[8];
 
 
 
//Simulates device register memory reads
uint32 MemoryRead(uint32 address)
uint32 MemoryRead(uint32 address)
{
{
   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS
   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS
   switch(address)
   switch(address)
   {
   {
Line 1412... Line 1450...
      return Memory[2];
      return Memory[2];
   }
   }
   return 0;
   return 0;
}
}
 
 
 
//Simulates device register memory writes
void MemoryWrite(uint32 address, uint32 value)
void MemoryWrite(uint32 address, uint32 value)
{
{
   switch(address)
   switch(address)
   {
   {
   case UART_WRITE:
   case UART_WRITE:
Line 1442... Line 1481...
 
 
 
 
/**************** Example *****************/
/**************** Example *****************/
#ifndef NO_MAIN
#ifndef NO_MAIN
#ifdef WIN32
#ifdef WIN32
static uint8 HeapSpace[1024*512];
static uint8 HeapSpace[1024*512];  //For simulation on a PC
#endif
#endif
 
 
int main(int programEnd, char *argv[])
int main(int programEnd, char *argv[])
{
{
   (void)programEnd;  //Pointer to end of used memory
   (void)programEnd;  //Pointer to end of used memory
   (void)argv;
   (void)argv;
 
 
   UartPrintfCritical("Starting RTOS\n");
   UartPrintfCritical("Starting RTOS\n");
#ifdef WIN32
#ifdef WIN32
   OS_Init((uint32*)HeapSpace, sizeof(HeapSpace));
   OS_Init((uint32*)HeapSpace, sizeof(HeapSpace));  //For PC simulation
#else
#else
   //Remaining space after program in 1MB external RAM
   //Create heap in remaining space after program in 1MB external RAM
   OS_Init((uint32*)programEnd,
   OS_Init((uint32*)programEnd,
           RAM_EXTERNAL_BASE + RAM_EXTERNAL_SIZE - programEnd);
           RAM_EXTERNAL_BASE + RAM_EXTERNAL_SIZE - programEnd);
#endif
#endif
   UartInit();
   UartInit();
   OS_ThreadCreate("Main", MainThread, NULL, 100, 4000);
   OS_ThreadCreate("Main", MainThread, NULL, 100, 4000);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.