📄 rtosinit_lpc2xxx.c
字号:
}
/*********************************************************************
*
* 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 + -