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

📄 rtos.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
📖 第 1 页 / 共 3 页
字号:
   uint32 message[8];   OS_Timer_t *timer;   (void)arg;   timeNow = OS_ThreadTime();   for(;;)   {      //Determine how long to sleep      OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);      if(TimerHead)         ticks = TimerHead->ticksTimeout - timeNow;      else         ticks = OS_WAIT_FOREVER;      OS_SemaphorePost(SemaphoreLock);      OS_SemaphorePend(SemaphoreTimer, ticks);      //Send messages for all timed out timers      timeNow = OS_ThreadTime();      for(;;)      {         timer = NULL;         OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);         if(TimerHead)         {            diff = timeNow - TimerHead->ticksTimeout;            if(diff >= 0)               timer = TimerHead;         }         OS_SemaphorePost(SemaphoreLock);         if(timer == NULL)            break;         if(timer->ticksRestart)            OS_TimerStart(timer, timer->ticksRestart, timer->ticksRestart);         else            OS_TimerStop(timer);         //Send message         message[0] = MESSAGE_TYPE_TIMER;         message[1] = (uint32)timer;         message[2] = (uint32)timer->info;         OS_MQueueSend(timer->mqueue, message);      }   }}/******************************************/OS_Timer_t *OS_TimerCreate(const char *name, OS_MQueue_t *mQueue, uint32 info){   OS_Timer_t *timer;   int startThread=0;   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);   if(SemaphoreTimer == NULL)   {      SemaphoreTimer = OS_SemaphoreCreate("Timer", 0);      startThread = 1;   }   OS_SemaphorePost(SemaphoreLock);   if(startThread)      OS_ThreadCreate("Timer", OS_TimerThread, NULL, 250, 2000);   timer = (OS_Timer_t*)OS_HeapMalloc(HEAP_SYSTEM, sizeof(OS_Timer_t));   if(timer == NULL)      return NULL;   timer->name = name;   timer->mqueue = mQueue;   timer->next = NULL;   timer->prev = NULL;   timer->info = info;   timer->active = 0;   return timer;}/******************************************/void OS_TimerDelete(OS_Timer_t *timer){   OS_TimerStop(timer);   OS_HeapFree(timer);}/******************************************///Must not be called from an ISRvoid OS_TimerStart(OS_Timer_t *timer, uint32 ticks, uint32 ticksRestart){   OS_Timer_t *node, *prev;   int diff, check=0;   assert(timer);   assert(InterruptInside == 0);   ticks += OS_ThreadTime();   if(timer->active)      OS_TimerStop(timer);   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);   if(timer->active)   {      //Prevent race condition      OS_SemaphorePost(SemaphoreLock);      return;   }   timer->ticksTimeout = ticks;   timer->ticksRestart = ticksRestart;   timer->active = 1;   prev = NULL;   for(node = TimerHead; node; node = node->next)   {      diff = ticks - node->ticksTimeout;      if(diff <= 0)         break;      prev = node;   }   timer->next = node;   timer->prev = prev;   if(node)      node->prev = timer;   if(prev == NULL)   {      TimerHead = timer;      check = 1;   }   else      prev->next = timer;   OS_SemaphorePost(SemaphoreLock);   if(check)      OS_SemaphorePost(SemaphoreTimer);}/******************************************///Must not be called from an ISRvoid OS_TimerStop(OS_Timer_t *timer){   assert(timer);   assert(InterruptInside == 0);   OS_SemaphorePend(SemaphoreLock, OS_WAIT_FOREVER);   if(timer->active)   {      timer->active = 0;      if(timer->prev == NULL)         TimerHead = timer->next;      else         timer->prev->next = timer->next;      if(timer->next)         timer->next->prev = timer->prev;   }   OS_SemaphorePost(SemaphoreLock);}/***************** ISR ********************//******************************************/void OS_InterruptServiceRoutine(uint32 status, uint32 *stack){   int i;   uint32 state;   if(status == 0 && Isr[31])      Isr[31](stack);                   //SYSCALL or BREAK   InterruptInside = 1;   i = 0;   do   {         if(status & 1)      {         if(Isr[i])            Isr[i](stack);         else            OS_InterruptMaskClear(1 << i);      }      status >>= 1;      ++i;   } while(status);   InterruptInside = 0;   state = OS_SpinLock();   if(ThreadNeedReschedule)      OS_ThreadReschedule(ThreadNeedReschedule & 1);   OS_SpinUnlock(state);}/******************************************/void OS_InterruptRegister(uint32 mask, OS_FuncPtr_t funcPtr){   int i;   for(i = 0; i < 32; ++i)   {      if(mask & (1 << i))         Isr[i] = funcPtr;   }}/******************************************///Plasma hardware dependentuint32 OS_InterruptStatus(void){   return MemoryRead(IRQ_STATUS);}/******************************************///Plasma hardware dependentuint32 OS_InterruptMaskSet(uint32 mask){   uint32 state;   state = OS_CriticalBegin();   mask |= MemoryRead(IRQ_MASK);   MemoryWrite(IRQ_MASK, mask);   OS_CriticalEnd(state);   return mask;}/******************************************///Plasma hardware dependentuint32 OS_InterruptMaskClear(uint32 mask){   uint32 state;   state = OS_CriticalBegin();   mask = MemoryRead(IRQ_MASK) & ~mask;   MemoryWrite(IRQ_MASK, mask);   OS_CriticalEnd(state);   return mask;}/**************** Init ********************//******************************************/static volatile uint32 IdleCount;static void OS_IdleThread(void *arg){   (void)arg;   //Don't block in the idle thread!   for(;;)   {      ++IdleCount;   }}/******************************************/#ifndef DISABLE_IRQ_SIMstatic void OS_IdleSimulateIsr(void *arg){   uint32 count=0, value;   (void)arg;   for(;;)   {      MemoryRead(IRQ_MASK + 4);       //calls Sleep(10)#if WIN32      while(OS_InterruptMaskSet(0) & IRQ_UART_WRITE_AVAILABLE)         OS_InterruptServiceRoutine(IRQ_UART_WRITE_AVAILABLE, 0);#endif      value = OS_InterruptMaskSet(0) & 0xf;      if(value)         OS_InterruptServiceRoutine(value, 0);      ++count;   }}#endif //DISABLE_IRQ_SIM/******************************************///Plasma hardware dependentstatic void OS_ThreadTickToggle(void *arg){   uint32 status, mask, state;   //Toggle looking for IRQ_COUNTER18 or IRQ_COUNTER18_NOT   state = OS_SpinLock();   status = MemoryRead(IRQ_STATUS) & (IRQ_COUNTER18 | IRQ_COUNTER18_NOT);   mask = MemoryRead(IRQ_MASK) | IRQ_COUNTER18 | IRQ_COUNTER18_NOT;   mask &= ~status;   MemoryWrite(IRQ_MASK, mask);   OS_ThreadTick(arg);   OS_SpinUnlock(state);}/******************************************/void OS_Init(uint32 *heapStorage, uint32 bytes){   int i;   OS_AsmInterruptInit();               //Patch interrupt vector   OS_InterruptMaskClear(0xffffffff);   //Disable interrupts   HeapArray[0] = OS_HeapCreate("Default", heapStorage, bytes);   HeapArray[1] = HeapArray[0];   SemaphoreSleep = OS_SemaphoreCreate("Sleep", 0);   SemaphoreLock = OS_SemaphoreCreate("Lock", 1);   for(i = 0; i < OS_CPU_COUNT; ++i)      OS_ThreadCreate("Idle", OS_IdleThread, NULL, 0, 256);#ifndef DISABLE_IRQ_SIM   if((OS_InterruptStatus() & (IRQ_COUNTER18 | IRQ_COUNTER18_NOT)) == 0)   {      //Detected that running in simulator so create SimIsr thread      UartPrintfCritical("SimIsr\n");      OS_ThreadCreate("SimIsr", OS_IdleSimulateIsr, NULL, 1, 0);   }#endif //DISABLE_IRQ_SIM   //Plasma hardware dependent   OS_InterruptRegister(IRQ_COUNTER18 | IRQ_COUNTER18_NOT, OS_ThreadTickToggle);   OS_InterruptMaskSet(IRQ_COUNTER18 | IRQ_COUNTER18_NOT);}/******************************************/void OS_Start(void){   ThreadSwapEnabled = 1;   (void)OS_SpinLock();   OS_ThreadReschedule(1);}/******************************************///Place breakpoint herevoid OS_Assert(void){}#if OS_CPU_COUNT > 1static uint8 SpinLockArray[OS_CPU_COUNT];/******************************************/uint32 OS_CpuIndex(void){   return 0; //0 to OS_CPU_COUNT-1}/******************************************///Symmetric Multiprocessing Spin Lock Mutexuint32 OS_SpinLock(void){   uint32 state, cpuIndex, i, j, ok, delay;   cpuIndex = OS_CpuIndex();   delay = cpuIndex + 8;   state = OS_AsmInterruptEnable(0);   do   {      ok = 1;      if(++SpinLockArray[cpuIndex] == 1)      {         for(i = 0; i < OS_CPU_COUNT; ++i)         {            if(i != cpuIndex && SpinLockArray[i])               ok = 0;         }         if(ok == 0)         {            SpinLockArray[cpuIndex] = 0;            for(j = 0; j < delay; ++j)  //wait a bit               ++i;            if(delay < 128)               delay <<= 1;         }      }   } while(ok == 0);   return state;}/******************************************/void OS_SpinUnlock(uint32 state){   uint32 cpuIndex;   cpuIndex = OS_CpuIndex();   if(--SpinLockArray[cpuIndex] == 0)      OS_AsmInterruptEnable(state);   assert(SpinLockArray[cpuIndex] < 10);}/******************************************///Must be called with interrupts disabled and spin lockeduint32 OS_SpinCountGet(void){   uint32 cpuIndex, count;   cpuIndex = OS_CpuIndex();   count = SpinLockArray[cpuIndex];   return count;}/******************************************///Must be called with interrupts disabled and spin lockedvoid OS_SpinCountSet(uint32 count){   uint32 cpuIndex;   cpuIndex = OS_CpuIndex();   SpinLockArray[cpuIndex] = (uint8)count;   assert(count);}/******************************************/void OS_CpuInterrupt(uint32 cpuIndex, uint32 bitfield){   //Request other CPU to reschedule threads   (void)cpuIndex;   (void)bitfield;}/******************************************/void OS_CpuInterruptServiceRoutine(void *arg){   uint32 state;   (void)arg;   state = OS_SpinLock();   OS_ThreadReschedule(0);   OS_SpinUnlock(state);}#endif/************** WIN32 Support *************/#ifdef WIN32//Support RTOS inside Windowsextern int kbhit();extern int getch(void);extern int putch(int);extern void __stdcall Sleep(unsigned long value);static uint32 Memory[8];uint32 MemoryRead(uint32 address){   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS   switch(address)   {   case UART_READ:       if(kbhit())         Memory[0] = getch();                //UART_READ      Memory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit      return Memory[0];   case IRQ_MASK:       return Memory[1];                      //IRQ_MASK   case IRQ_MASK + 4:      Sleep(10);      return 0;   case IRQ_STATUS:       if(kbhit())         Memory[2] |= IRQ_UART_READ_AVAILABLE;      return Memory[2];   }   return 0;}void MemoryWrite(uint32 address, uint32 value){   switch(address)   {   case UART_WRITE:       putch(value);       break;   case IRQ_MASK:         Memory[1] = value;       break;   case IRQ_STATUS:       Memory[2] = value;       break;   }}uint32 OS_AsmInterruptEnable(uint32 enableInterrupt){   return enableInterrupt;}void OS_AsmInterruptInit(void){}#endif  //WIN32/**************** Example *****************/#ifndef NO_MAINstatic uint8 HeapSpace[1024*512];int main(void){   UartPrintfCritical("Starting RTOS\n");   OS_Init((uint32*)HeapSpace, sizeof(HeapSpace));   UartInit();   OS_ThreadCreate("Main", MainThread, NULL, 100, 64000);   OS_Start();   return 0;}#endif

⌨️ 快捷键说明

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