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

📄 rtosinit_lpc2xxx.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 2 页
字号:
}

/*********************************************************************
*
*       OS_InitHW()
*
*       Initialize the hardware (timer) required for the OS to run.
*       May be modified, if an other timer should be used
*       Also enables memory accelerator module
*/

void OS_InitHW(void) {
  OS_DI();
  _Init_VIC();                               // Initialize VIC, clear and disable all interrupts
  // Initialize timer for OS
  __PCONP     |= (1 << _TIMER_PCONP_BIT);    // Enable Clock for OS timer
  _OS_TIM_TCR &= ~(1 << 0);                  // Disable timer
  _OS_TIM_IR   = (1 << _OS_TIM_IR_BIT);      // Clear OS timer interrupt flag
  _OS_TIM_PR   = 0;                          // Count on every pclk
  _OS_TIM_MR0  = _OS_TIMER_INTERVAL - 1;     // Initialize match register 1
  _OS_TIM_MCR  = (1 << 0)                    // Interrupt on match channel 0
                |(1 << 1);                   // Counter reset on match channel 0
  _OS_TIM_TC   = 0;                          // Clear counter
  _OS_TIM_TCR |= (1 << 0);                   // Enable timer
  // Setup interrupt controller
  OS_ARM_InstallISRHandler(_OS_TIMER_INT_INDEX, &_OS_ISR_Tick); // Timer/counter interrupt vector.
  OS_ARM_AssignISRSource(_OS_TIMER_INT_INDEX, _OS_TIMER_INT_SOURCE);
  OS_ARM_EnableISR(_OS_TIMER_INT_INDEX);                        // Enable timer/counter 0 interrupt.
  OS_ARM_EnableISRSource(_OS_TIMER_INT_SOURCE);                 // Enable timer/counter 0 interrupt.
  // optionally initialize UART for OSView
  OS_COM_Init();
  OS_RestoreI();
}

/*********************************************************************
*
*       Idle loop  (OS_Idle)
*
*       Please note:
*       This is basically the "core" of the idle loop.
*       This core loop can be changed, but:
*       The idle loop does not have a stack of its own, therefore no
*       functionality should be implemented that relies on the stack
*       to be preserved. However, a simple program loop can be programmed
*       (like toggeling an output or incrementing a counter)
*/
void OS_Idle(void) {     // Idle loop: No task is ready to exec
  while (1) {
    // Enter in Idle mode
    __PCON = __PCON_IDL;
  }
}

/*********************************************************************
*
*       Get time [cycles]
*
*       This routine is required for task-info via OSView or high
*       resolution time maesurement functions.
*       It returns the system time in timer clock cycles.
*/
OS_U32 OS_GetTime_Cycles(void) {
  OS_U32 time;
  OS_I16 count;

  count = _OS_TIM_TC;                               // Read current timer value
  time  = OS_GetTime32();                           // Read current OS time
  if ((_OS_TIM_IR & (1 << _OS_TIM_IR_BIT)) != 0) {  // Timer Interrupt pending ?
    time++;                                         // Adjust result, read timer again
    count = _OS_TIM_TC;                             // Read again
  }
  return (_OS_TIMER_INTERVAL) * time + count;
}

/*********************************************************************
*
*       OS_ConvertCycles2us
*
*       Convert Cycles into micro seconds.
*
*       If your clock frequency is not a multiple of 1 MHz,
*       you may have to modify this routine in order to get proper
*       diagonstics.
*
*       This routine is required for profiling or high resolution time
*       measurement only. It does not affect operation of the OS.
*/
OS_U32 OS_ConvertCycles2us(OS_U32 Cycles) {
  return Cycles/(OS_PCLK_TIMER/1000000);
}

/*********************************************************************
*
*       Communication for OSView via UART (optional)
*
**********************************************************************
*/

#if OS_UART_USED

/*********************************************************************
*
*       OS_COM_ISR_Usart() OS USART interrupt handler
*       handles both, Rx and Tx interrupt
*/
static void _OS_COM_ISR(void) {
  int UartStatus;

  UartStatus = _OS_UART_IIR;                                            // Examine interrupt identification register
  do {
    if ((UartStatus & _UART_INT_MASK) == _UART_ERROR_INT_STATUS) {      // Error pending ?
      _Dummy = _OS_UART_RBR;                                            // Discard data
      _Dummy = _OS_UART_LSR;                                            // reset error
    } else if ((UartStatus & _UART_INT_MASK) == _UART_RX_INT_STATUS) {  // Data received?
      OS_OnRx(_OS_UART_RBR);                                            // Process actual byte
    } else if ((UartStatus & _UART_INT_MASK) == _UART_TX_INT_STATUS) {  // Tx interrupt pending?
     OS_OnTx();
    }
    UartStatus = _OS_UART_IIR;                                          // Re-read interrupt identification register
  } while ((UartStatus & (1 << _INT_PENDING_BIT)) == 0);                // Handle all interrupts
}

/*********************************************************************
*
*       OS_COM_Send1()
*       Never call this function directly from your application
*/
void OS_COM_Send1(OS_U8 c) {
  _OS_UART_THR = c;                                 // Send character
}

/*********************************************************************
*
*       OS_COM_Init()
*       Initialize UART for OSView
*/
#define _BAUDDIVIDE ((OS_PCLK_UART+OS_BAUDRATE*8L)/(OS_BAUDRATE*16L))

void OS_COM_Init(void) {
  OS_DI();
  // Setup Port-Mode to alternate function
  __PINSEL0    |= _PINSEL_UART_MODE;       // Set UART-port to alternate function
  __PCONP      |= (1 << _UART_PCONP_BIT);  // Enable UART unit
  _OS_UART_IER  = 0x00;                    // Initially disable all interrupts
  _OS_UART_LCR  = 0x80;                    // Set DLAB to initialize Baudrate generator
  _OS_UART_DLL  = (_BAUDDIVIDE & 0xFF);
  _OS_UART_DLM  = ((_BAUDDIVIDE >> 8) & 0xFF);
  _OS_UART_LCR &= ~0x80;                   // reset DLAB to lock baudrate generator access
  _OS_UART_LCR  = 0x03                     // 8 data bits
                 |(0 << 2)                 // 1 stop bit
                 |(0 << 3)                 // NO parity
                 |(0 << 4)                 // Parity setting (bit 5:4) does not care
                 |(0 << 6)                 // Disable Break transmission
                 |(0 << 7);                // Clear DLAB
  _OS_UART_FCR  = 0;                       // Disable FIFO
  /*  Install OS UART interrupt handler */
  OS_ARM_InstallISRHandler(_OS_UART_INT_INDEX, &_OS_COM_ISR);  // OS UART interrupt vector.
  OS_ARM_AssignISRSource(_OS_UART_INT_INDEX, _OS_UART_INT_SOURCE);
  OS_ARM_EnableISR(_OS_UART_INT_INDEX);                        // Enable UART interrupt vector.
  OS_ARM_EnableISRSource(_OS_UART_INT_SOURCE);                 // Enable UART interrupt source.
  _OS_UART_IER |= (1 << _RX_FULL_INT_ENABLE_BIT);              // Enable Rx interrupts
  _OS_UART_IER |= (1 << _RX_ERROR_INT_ENABLE_BIT);             // Enable Rx error interrupts
  _OS_UART_IER |= (1 << _TX_EMPTY_INT_ENABLE_BIT);             // Enable Tx interrupts
  OS_RestoreI();
}

#else  /* selected UART not supported, using dummies */

void OS_COM_Init(void) {}
void OS_COM_Send1(OS_U8 c) {
  OS_USEPARA(c);           // avoid compiler warning
  OS_COM_ClearTxActive();  // let the OS know that Tx is not busy
}

#endif /*  OS_UART_USED  */

/****** Final check of configuration ********************************/
#ifndef OS_UART_USED
  #error "OS_UART_USED has to be defined"
#endif

/*********************************************************************
*
*       OS interrupt handler and ISR specific functions
*
**********************************************************************
*/

/*********************************************************************
*
*       _OS_ISR_Undefined
*
*       Is called when an uninstalled interrupt was detected
*       As interrupt pending condition of peripherals has to be reset,
*       program will not continue when interrupt is ignored.
*/
static void _OS_ISR_Undefined(void) {
  #if (OS_IGNORE_UNDEFINED_INTERRUPT == 0)
    _Dummy = 1;
    /* You may set a breakpoint here to detect undefined interrupts */
    while (_Dummy > 0) {
    }
  #endif
}

/*********************************************************************
*
*       OS_irq_handler
*
*       Detect reason for IRQ and call correspondig service routine.
*       OS_irq_handler is called from OS_IRQ_SERVICE function
*       found in RTOSVect.asm
*/
OS_INTERWORK void OS_irq_handler(void) {
  OS_ISR_HANDLER* pISR;
  pISR = (OS_ISR_HANDLER*) __VIC_VECTORADDR;  // Get current interrupt handler
  OS_EnterNestableInterrupt();                // Now interrupts may be reenabled. If nesting should be allowed
  if (pISR != NULL) {
    pISR();                                   // Call installed interrupt service routine
  } else {
    _OS_ISR_Undefined();
  }
  OS_DI();                                    // Disable interrupts and unlock
  __VIC_VECTORADDR = 0;                       // Clear current interrupt pending condition, reset VIC
  OS_LeaveNestableInterrupt();                // Replace by OS_LeaveInterrupt(), when nesting was disabled
}

/*********************************************************************
*
*       OS_ARM_InstallISRHandler
*
*/
OS_ISR_HANDLER* OS_ARM_InstallISRHandler (int ISRIndex, OS_ISR_HANDLER* pISRHandler) {
  OS_ISR_HANDLER*  pOldHandler;
  OS_ISR_HANDLER** papISR;

  pOldHandler = NULL;
  OS_DI();
  papISR = (OS_ISR_HANDLER**) &__VIC_VECT_BASE;
  if (ISRIndex < _NUM_INT_VECTORS) {
    pOldHandler          = *(papISR + ISRIndex);
    *(papISR + ISRIndex) = pISRHandler;
  }
  OS_RestoreI();
  return pOldHandler;
}

/*********************************************************************
*
*       OS_ARM_AssignISRSource
*
*/
void OS_ARM_AssignISRSource(int ISRIndex, int Source) {
  OS_U32* pCntlRegister;
  OS_U32 ControlReg;
  pCntlRegister = (OS_U32*) &__VIC_VECTCNTL_BASE;
  if (ISRIndex < _NUM_INT_VECTORS) {
    OS_DI();
    ControlReg  = *(pCntlRegister + ISRIndex) & ~_INT_SOURCE_MASK;
    *(pCntlRegister + ISRIndex) = (ControlReg | (Source & _INT_SOURCE_MASK));
    OS_RestoreI();
  }
}

/*********************************************************************
*
*       OS_ARM_EnableISR
*
*/
void OS_ARM_EnableISR(int ISRIndex) {
  OS_U32* pCntlRegister;

  pCntlRegister = (OS_U32*) &__VIC_VECTCNTL_BASE;
  if (ISRIndex < _NUM_INT_VECTORS) {
    OS_DI();
    *(pCntlRegister + ISRIndex) |= (1 << 5);
    OS_RestoreI();
  }
}

/*********************************************************************
*
*       OS_ARM_DisableISR
*
*/
void OS_ARM_DisableISR(int ISRIndex) {
  OS_U32* pCntlRegister;

  pCntlRegister = (OS_U32*) &__VIC_VECTCNTL_BASE;
  if (ISRIndex < _NUM_INT_VECTORS) {
    OS_DI();
    *(pCntlRegister + ISRIndex) &= ~(1 << 5);
    OS_RestoreI();
  }
}

/*********************************************************************
*
*       OS_ARM_EnableISRSource
*
*/
void OS_ARM_EnableISRSource(int SourceIndex) {
  if (SourceIndex < _NUM_INT_SOURCES) {
    OS_DI();
    __VIC_INTENABLE |= (1 << SourceIndex);
    OS_RestoreI();
  }
}

/*********************************************************************
*
*       OS_ARM_DisableISRSource
*
*/
void OS_ARM_DisableISRSource(int SourceIndex) {
  if (SourceIndex < _NUM_INT_SOURCES) {
    OS_DI();
    __VIC_INTENABLECLEAR = (1 << SourceIndex);
    OS_RestoreI();
  }
}

/*********************************************************************
*
*       OS_ARM_ISRSetPrio
*/
int OS_ARM_ISRSetPrio(int ISRIndex, int Prio) {
  // Not supported for CPU with VIC
  return 0;
}

/*****  EOF  ********************************************************/

⌨️ 快捷键说明

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