⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtos.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
📖 第 1 页 / 共 3 页
字号:
   {      threadNext = threadBest;   }   else if(roundRobin)   {      //Find the next ready thread      for(threadAlt = threadCurrent->next; threadAlt; threadAlt = threadAlt->next)      {         if(threadAlt->state == THREAD_READY &&            (threadAlt->cpuLock == -1 || threadAlt->cpuLock == (int)cpuIndex))            break;      }      if(threadAlt && threadAlt->priority == threadCurrent->priority)         threadNext = threadAlt;      else if(threadBest && threadBest->priority >= threadCurrent->priority)         threadNext = threadBest;   }   if(threadNext != threadCurrent)   {      //Swap threads      ThreadCurrent[cpuIndex] = threadNext;      assert(threadNext);      if(threadCurrent)      {         assert(threadCurrent->magic[0] == THREAD_MAGIC); //check stack overflow         threadCurrent->state = THREAD_READY;         threadCurrent->spinLocks = OS_SpinCountGet();         threadCurrent->cpuIndex = -1;         rc = setjmp(threadCurrent->env);   //ANSI C call to save registers         if(rc)         {            //Returned from longjmp()            return;         }      }      //Restore spin lock count      cpuIndex = OS_CpuIndex();             //removed warning      threadNext = ThreadCurrent[cpuIndex]; //removed warning      threadNext->state = THREAD_RUNNING;      OS_SpinCountSet(threadNext->spinLocks);      threadNext->cpuIndex = (int)cpuIndex;      OS_ThreadRescheduleCheck();      longjmp(threadNext->env, 1);          //ANSI C call to restore registers   }   OS_ThreadRescheduleCheck();}/******************************************/void OS_ThreadCpuLock(OS_Thread_t *Thread, int CpuIndex){   Thread->cpuLock = CpuIndex;   if(Thread == OS_ThreadSelf() && CpuIndex != (int)OS_CpuIndex())      OS_ThreadSleep(1);}#endif //#if OS_CPU_COUNT <= 1/******************************************/static void OS_ThreadInit(void *arg){   uint32 cpuIndex = OS_CpuIndex();   (void)arg;   OS_CriticalEnd(1);   ThreadCurrent[cpuIndex]->funcPtr(ThreadCurrent[cpuIndex]->arg);   OS_ThreadExit();}/******************************************///Stops warning "argument X might be clobbered by `longjmp'"static void OS_ThreadRegsInit(jmp_buf env){   setjmp(env); //ANSI C call to save registers}/******************************************/OS_Thread_t *OS_ThreadCreate(const char *name,                             OS_FuncPtr_t funcPtr,                              void *arg,                              uint32 priority,                              uint32 stackSize){   OS_Thread_t *thread;   uint8 *stack;   jmp_buf2 *env;   uint32 state;   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);   if(NeedToFree)      OS_HeapFree(NeedToFree);   NeedToFree = NULL;   OS_SemaphorePost(SemaphoreLock);   if(stackSize == 0)      stackSize = STACK_SIZE_DEFAULT;   if(stackSize < STACK_SIZE_MINIMUM)      stackSize = STACK_SIZE_MINIMUM;   thread = (OS_Thread_t*)OS_HeapMalloc(NULL, sizeof(OS_Thread_t) + stackSize);   assert(thread);   if(thread == NULL)      return NULL;   memset(thread, 0, sizeof(OS_Thread_t));   stack = (uint8*)(thread + 1);   memset(stack, 0xcd, stackSize);   thread->name = name;   thread->state = THREAD_READY;   thread->cpuLock = -1;   thread->funcPtr = funcPtr;   thread->arg = arg;   thread->priority = priority;   thread->info = NULL;   thread->semaphorePending = NULL;   thread->returnCode = 0;   thread->spinLocks = 1;   if(OS_ThreadSelf())   {      thread->processId = OS_ThreadSelf()->processId;      thread->heap = OS_ThreadSelf()->heap;   }   else   {      thread->processId = 0;      thread->heap = NULL;   }   thread->next = NULL;   thread->prev = NULL;   thread->nextTimeout = NULL;   thread->prevTimeout = NULL;   thread->magic[0] = THREAD_MAGIC;   OS_ThreadRegsInit(thread->env);   env = (jmp_buf2*)thread->env;   env->sp = (uint32)stack + stackSize - 24; //minimum stack frame size   env->pc = (uint32)OS_ThreadInit;   state = OS_CriticalBegin();   OS_ThreadPriorityInsert(&ThreadHead, thread);   OS_ThreadReschedule(0);   OS_CriticalEnd(state);   return thread;}/******************************************/void OS_ThreadExit(void){   uint32 state, cpuIndex = OS_CpuIndex();   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);   if(NeedToFree)      OS_HeapFree(NeedToFree);   NeedToFree = NULL;   OS_SemaphorePost(SemaphoreLock);   state = OS_CriticalBegin();   OS_ThreadPriorityRemove(&ThreadHead, ThreadCurrent[cpuIndex]);   NeedToFree = ThreadCurrent[cpuIndex];   OS_ThreadReschedule(0);   OS_CriticalEnd(state);}/******************************************/OS_Thread_t *OS_ThreadSelf(void){   return ThreadCurrent[OS_CpuIndex()];}/******************************************/void OS_ThreadSleep(int ticks){   OS_SemaphorePend(SemaphoreSleep, ticks);}/******************************************/uint32 OS_ThreadTime(void){   return ThreadTime;}/******************************************/void OS_ThreadInfoSet(OS_Thread_t *thread, void *Info){   thread->info = Info;}/******************************************/void *OS_ThreadInfoGet(OS_Thread_t *thread){   return thread->info;}/******************************************/uint32 OS_ThreadPriorityGet(OS_Thread_t *thread){   return thread->priority;}/******************************************/void OS_ThreadPrioritySet(OS_Thread_t *thread, uint32 priority){   uint32 state;   state = OS_CriticalBegin();   thread->priority = priority;   if(thread->state != THREAD_PEND)   {      OS_ThreadPriorityRemove(&ThreadHead, thread);      OS_ThreadPriorityInsert(&ThreadHead, thread);      OS_ThreadReschedule(0);   }   OS_CriticalEnd(state);}/******************************************/void OS_ThreadProcessId(OS_Thread_t *thread, uint32 processId, OS_Heap_t *heap){   thread->processId = processId;   thread->heap = heap;}/******************************************///Must be called with interrupts disabledvoid OS_ThreadTick(void *Arg){   OS_Thread_t *thread;   OS_Semaphore_t *semaphore;   int diff;   (void)Arg;   ++ThreadTime;   while(TimeoutHead)   {      thread = TimeoutHead;      diff = ThreadTime - thread->ticksTimeout;      if(diff < 0)         break;      OS_ThreadTimeoutRemove(thread);      semaphore = thread->semaphorePending;      ++semaphore->count;      thread->semaphorePending = NULL;      thread->returnCode = -1;      OS_ThreadPriorityRemove(&semaphore->threadHead, thread);      OS_ThreadPriorityInsert(&ThreadHead, thread);   }   OS_ThreadReschedule(1);}/***************** Semaphore **************//******************************************/OS_Semaphore_t *OS_SemaphoreCreate(const char *name, uint32 count){   OS_Semaphore_t *semaphore;   static int semCount = 0;   if(semCount < SEM_RESERVED_COUNT)      semaphore = &SemaphoreReserved[semCount++];  //Heap not ready yet   else      semaphore = (OS_Semaphore_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_Semaphore_t));   assert(semaphore);   if(semaphore == NULL)      return NULL;   semaphore->name = name;   semaphore->threadHead = NULL;   semaphore->count = count;   return semaphore;}/******************************************/void OS_SemaphoreDelete(OS_Semaphore_t *semaphore){   while(semaphore->threadHead)      OS_SemaphorePost(semaphore);   OS_HeapFree(semaphore);}/******************************************/int OS_SemaphorePend(OS_Semaphore_t *semaphore, int ticks){   uint32 state, cpuIndex;   OS_Thread_t *thread;   int returnCode=0;   assert(semaphore);   assert(InterruptInside == 0);   state = OS_CriticalBegin();   if(--semaphore->count < 0)   {      if(ticks == 0)      {         ++semaphore->count;         OS_CriticalEnd(state);         return -1;      }      cpuIndex = OS_CpuIndex();      thread = ThreadCurrent[cpuIndex];      assert(thread);      thread->semaphorePending = semaphore;      thread->ticksTimeout = ticks + OS_ThreadTime();      OS_ThreadPriorityRemove(&ThreadHead, thread);      OS_ThreadPriorityInsert(&semaphore->threadHead, thread);      if(ticks != OS_WAIT_FOREVER)         OS_ThreadTimeoutInsert(thread);      assert(ThreadHead);      OS_ThreadReschedule(0);      returnCode = thread->returnCode;   }   OS_CriticalEnd(state);   return returnCode;}/******************************************/void OS_SemaphorePost(OS_Semaphore_t *semaphore){   uint32 state;   OS_Thread_t *thread;   assert(semaphore);   state = OS_CriticalBegin();   if(++semaphore->count <= 0)   {      thread = semaphore->threadHead;      OS_ThreadTimeoutRemove(thread);      OS_ThreadPriorityRemove(&semaphore->threadHead, thread);      OS_ThreadPriorityInsert(&ThreadHead, thread);      thread->semaphorePending = NULL;      thread->returnCode = 0;      OS_ThreadReschedule(0);   }   OS_CriticalEnd(state);}/***************** Mutex ******************//******************************************/OS_Mutex_t *OS_MutexCreate(const char *name){   OS_Mutex_t *mutex;   mutex = (OS_Mutex_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_Mutex_t));   if(mutex == NULL)      return NULL;   mutex->semaphore = OS_SemaphoreCreate(name, 1);   if(mutex->semaphore == NULL)      return NULL;   mutex->thread = NULL;   mutex->count = 0;   return mutex;}/******************************************/void OS_MutexDelete(OS_Mutex_t *mutex){   OS_SemaphoreDelete(mutex->semaphore);   OS_HeapFree(mutex);}/******************************************/void OS_MutexPend(OS_Mutex_t *mutex){   OS_Thread_t *thread;   assert(mutex);   thread = OS_ThreadSelf();   if(thread == mutex->thread)   {      ++mutex->count;      return;   }   OS_SemaphorePend(mutex->semaphore, OS_WAIT_FOREVER);   mutex->thread = thread;   mutex->count = 1;}/******************************************/void OS_MutexPost(OS_Mutex_t *mutex){   assert(mutex);   assert(mutex->thread == OS_ThreadSelf());   assert(mutex->count > 0);   if(--mutex->count <= 0)   {      mutex->thread = NULL;      OS_SemaphorePost(mutex->semaphore);   }}/***************** MQueue *****************//******************************************/OS_MQueue_t *OS_MQueueCreate(const char *name,                             int messageCount,                             int messageBytes){   OS_MQueue_t *queue;   int size;   size = messageBytes / sizeof(uint32);   queue = (OS_MQueue_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_MQueue_t) +       messageCount * size * 4);   if(queue == NULL)      return queue;   queue->name = name;   queue->semaphore = OS_SemaphoreCreate(name, 0);   if(queue->semaphore == NULL)      return NULL;   queue->count = messageCount;   queue->size = size;   queue->used = 0;   queue->read = 0;   queue->write = 0;   return queue;}/******************************************/void OS_MQueueDelete(OS_MQueue_t *mQueue){   OS_SemaphoreDelete(mQueue->semaphore);   OS_HeapFree(mQueue);}/******************************************/int OS_MQueueSend(OS_MQueue_t *mQueue, void *message){   uint32 state, *dst, *src;   int i;   assert(mQueue);   src = (uint32*)message;   state = OS_CriticalBegin();   if(++mQueue->used > mQueue->count)   {      --mQueue->used;      OS_CriticalEnd(state);      return -1;   }   dst = (uint32*)(mQueue + 1) + mQueue->write * mQueue->size;   for(i = 0; i < mQueue->size; ++i)      dst[i] = src[i];   if(++mQueue->write >= mQueue->count)      mQueue->write = 0;   OS_CriticalEnd(state);   OS_SemaphorePost(mQueue->semaphore);   return 0;}/******************************************/int OS_MQueueGet(OS_MQueue_t *mQueue, void *message, int ticks){   uint32 state, *dst, *src;   int i, rc;   assert(mQueue);   dst = (uint32*)message;   rc = OS_SemaphorePend(mQueue->semaphore, ticks);   if(rc)      return rc;   state = OS_CriticalBegin();   --mQueue->used;   src = (uint32*)(mQueue + 1) + mQueue->read * mQueue->size;   for(i = 0; i < mQueue->size; ++i)      dst[i] = src[i];   if(++mQueue->read >= mQueue->count)      mQueue->read = 0;   OS_CriticalEnd(state);   return 0;}/***************** Timer ******************//******************************************/static void OS_TimerThread(void *arg){   uint32 timeNow;   int diff, ticks;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -