📄 rtosinit_str75x.c
字号:
__MRCC_PCLKEN |= (1 << 1); // TB clk enable
__MRCC_PSWRES &= ~(1 << 1); // release TB reset
// Initialize timer for OS, we use Timer 1
_OS_TIM_CR = 2; // Stop timer, reset mode, clear prescaler
_OS_TIM_SCR = 0; // Slave mode disabled.
_OS_TIM_PSC = _TIM_PESCALER - 1; // prescaler
_OS_TIM_ARR = _OS_TIMER_INTERVAL-1; // Setup compare register, initially use 1000 ticks per second
_OS_TIM_CR = (1 << 2); // Start timer
_OS_TIM_RSR = \
_OS_TIM_RER = (1 << 0); // Enable update interrupt
// Clear pending interrupts flags
_OS_TIM_ISR &= 0;
OS_ARM_InstallISRHandler(_OS_TIMER_ID, &_OS_ISR_Tick); // Timer/counter interrupt vector.
OS_ARM_ISRSetPrio(_OS_TIMER_ID, _OS_TIMER_PRIO); // Timer/counter interrupt priority.
OS_ARM_EnableISR(_OS_TIMER_ID); // Enable timer/counter 0 interrupt.
// optionally initialize UART for OSView
OS_COM_Init();
__EIC_ICR |= 0x01; // Enable interrupt controller
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 toggling an output or incrementing a counter)
*/
void OS_Idle(void) { // Idle loop: No task is ready to exec
while (1)
{
// enter in wait for interrupt power down mode
__MRCC_PWRCTRL &=~(3UL << 1);
__MRCC_PWRCTRL = 2UL << 1;
// You should also set this bit if the Flash is configured in non-Burst mode
// if you want to perform DMA transfers while the microcontroller is in WFI mode.
// WFI Mode with Flash in low power mode
__MRCC_PWRCTRL &=~(1UL << 4);
// Disable Flash memory
__MRCC_PWRCTRL &=~(7UL << 13);
__MRCC_PWRCTRL |= 2UL << 13;
// Low Power Mode entry sequence
WriteLPBit();
}
}
/*********************************************************************
*
* WriteLPBit()
*
* Executes the Low Power bit writing sequence.
*/
static void WriteLPBit(void)
{
volatile unsigned int Temp;
Temp = __MRCC_PWRCTRL & ~1;
__MRCC_PWRCTRL = Temp | 1;
__MRCC_PWRCTRL = Temp | 1;
__MRCC_PWRCTRL = Temp;
__MRCC_PWRCTRL = Temp | 1;
Temp = __MRCC_PWRCTRL;
}
/*********************************************************************
*
* 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_CNT; // Read current timer value
time = OS_GetTime32(); // Read current OS time
if (_OS_TIM_ISR & (1UL << 2)) { // Timer Interrupt pending ?
time++; // Adjust result, read timer again
count = _OS_TIM_CNT; // Read again
} else {
count = _OS_TIMER_INTERVAL - count;
}
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
* diagnostics.
*
* This routine is required for profiling or high resolution time
* measurement only. It does not affect operation of the 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, ReceiverStatus;
do {
UartStatus = _OS_UART_MISR; // Examine status register
if (!(UartStatus & _RX_INTR)) { // Data received?
ReceiverStatus = _OS_UART_DR;
if (!(ReceiverStatus & _UART_RX_ERROR_FLAGS)) { // Any error ?
OS_OnRx(ReceiverStatus & _UART_DATA_MASK); // Process actual byte
}
_OS_UART_ICR = UartStatus & _RX_INTR; // clear Rx interrupt
}
if (UartStatus & _TX_INTR) { // Check Tx status => Send next character
_OS_UART_ICR = UartStatus & _TX_INTR; // Clear Tx Int
if (OS_OnTx()) { // No more characters to send ?
_OS_UART_IMSCR &= ~_TX_INTR; // Disable further tx interrupts
}
}
} while (UartStatus & (_RX_INTR | _TX_INTR));
}
/*********************************************************************
*
* OS_COM_Send1()
* Never call this function directly from your application
*/
void OS_COM_Send1(OS_U8 c) {
_OS_UART_TxBUFR = c; // Send character
_OS_UART_IMSCR |= _TX_INTR; // enable Tx Empty interrupt
}
/*********************************************************************
*
* OS_COM_Init()
* Initialize UART for OSView
*/
void OS_COM_Init(void) {
int IntegerDivider,FractionalDivider;
OS_DI();
// Setup Port-Mode to alternate function, TX: push-pull, RX: open drain, CMOS input
__GPIO0_REMAP1 &= ~((1UL << 3) | (1UL << 4));
__GPIO0_PC0 &= ~(_UART_RX_PIN); // Rx set to open drain
__GPIO0_PC0 |= _UART_TX_PIN; // Tx set to push pull
__GPIO0_PC1 |= (_UART_RX_PIN | _UART_TX_PIN); // Select alternate function
__GPIO0_PC2 &= ~(_UART_RX_PIN); // Select CMOS input
__GPIO0_PC2 |= _UART_TX_PIN; // Select output
_OS_UART_CR = 0;
_OS_UART_IFLSR = 0;
_OS_UART_DMACR = 0;
/* Determine the integer part */
IntegerDivider = ((100) * (OS_PCLK_UART) / (16 * (OS_BAUDRATE)));
_OS_UART_IBRDR = IntegerDivider / 100;
/* Determine the fractional part */
FractionalDivider = IntegerDivider - (100 * (_OS_UART_IBRDR));
_OS_UART_FBRDR = ((((FractionalDivider * 64) + 50) / 100));
_OS_UART_LCR = ((0UL << 1) | // Parity disable
(1UL << 4) | // FIFOs enabled
(3UL << 5)); // 8 bit word
// Enable interrupts
_OS_UART_IMSCR = ((1UL << 4) | // Receive Interrupt
(1UL << 6) | // Receive Timeout Interrupt
(1UL << 7) | // Framing Error Interrupt
(1UL << 8) | // Parity Error Interrupt
(1UL << 10)); // Overrun Error Interrupt
// clear pending interrupts
_OS_UART_ICR = ((1UL << 4) | // Receive Interrupt
(1UL << 5) | // Transmit Interrupt
(1UL << 6) | // Receive Timeout Interrupt
(1UL << 7) | // Framing Error Interrupt
(1UL << 8) | // Parity Error Interrupt
(1UL << 10)); // Overrun Error Interrupt
/* Install OS UART interrupt handler */
OS_ARM_InstallISRHandler(_OS_UART_ID, &_OS_COM_ISR); // UART interrupt vector.
OS_ARM_ISRSetPrio(_OS_UART_ID, _OS_UART_PRIO); // UART interrupt level.
OS_ARM_EnableISR(_OS_UART_ID); // Enable OS UART interrupt
// Enable UART
_OS_UART_CR = ((1UL << 0) | // UART enabled
(1UL << 8) | // Transmit section of the UART enabled
(1UL << 9)); // Receive section of the UART enabled
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(int Index) {
#if (OS_IGNORE_UNDEFINED_INTERRUPT == 0)
_Dummy = Index;
/* You may set a breakpoint here to detect undefined interrupts */
while (_Dummy < (_INT_CHANNEL_MASK + 1)) {
}
#endif
}
/*********************************************************************
*
* OS_irq_handler
*
* Detect reason for IRQ and call corresponding 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;
int ISRIndex;
ISRIndex = __EIC_IVR; // Perform a dummy vector read to update CICR
ISRIndex = __EIC_CICR & _INT_CHANNEL_MASK; // Examine current interrupt source (channel number)
pISR = _apOS_ISRHandler[ISRIndex]; // Read interrupt vector
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(ISRIndex);
}
OS_DI(); // Disable interrupts and unlock
__EIC_IPR |= (1 << ISRIndex); // Clear current interrupt pending bit, reset EIC
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;
pOldHandler = NULL;
OS_DI();
if (ISRIndex < NUM_INT_SOURCES) {
pOldHandler = _apOS_ISRHandler[ISRIndex];
_apOS_ISRHandler[ISRIndex] = pISRHandler;
}
OS_RestoreI();
return pOldHandler;
}
/*********************************************************************
*
* OS_ARM_EnableISR
*
*/
void OS_ARM_EnableISR(int ISRIndex) {
OS_DI();
if (ISRIndex < NUM_INT_SOURCES) {
__EIC_IER |= (1 << ISRIndex);
}
OS_RestoreI();
}
/*********************************************************************
*
* OS_ARM_DisableISR
*
*/
void OS_ARM_DisableISR(int ISRIndex) {
OS_DI();
if (ISRIndex < NUM_INT_SOURCES) {
__EIC_IER &= ~(1 << ISRIndex);
}
OS_RestoreI();
}
/*********************************************************************
*
* OS_ARM_ISRSetPrio
*
*/
int OS_ARM_ISRSetPrio(int ISRIndex, int Prio) {
OS_U32* pPrio;
int OldPrio;
OS_DI();
pPrio = (OS_U32*)&__EIC_SIR0;
OldPrio = pPrio[ISRIndex];
pPrio[ISRIndex] = (OldPrio & ~_INT_PRIORITY_MASK) | (Prio & _INT_PRIORITY_MASK);
OS_RestoreI();
return OldPrio & _INT_PRIORITY_MASK;
}
/***** EOF ********************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -