📄 rtosinit.c
字号:
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (C) 2008 SEGGER Microcontroller GmbH & CO. KG *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* embOS * Real time operating system for microcontrollers *
* *
* *
* Please note: *
* *
* Knowledge of this file may under no circumstances *
* be used to write a similar product or a real-time *
* operating system for in-house use. *
* *
* Thank you for your fairness ! *
* *
**********************************************************************
* *
* embOS version: 3.60c *
* *
**********************************************************************
----------------------------------------------------------------------
File : RTOSInit.c
Purpose : RTOSInit for STM32F103 (MB525 & MB672). Initializes and
handles the hardware for the OS as far as required by the OS.
-------- END-OF-HEADER ---------------------------------------------
*/
#include "RTOS.H"
/*********************************************************************
*
* Configuration
*
*********************************************************************/
/*********************************************************************
*
* Clock frequency settings
*/
#ifndef OS_FSYS /* CPU main clock frequency */
#define OS_FSYS 72000000uL
#endif
#ifndef OS_PCLK_TIMER /* Peripheral clock for timer */
#define OS_PCLK_TIMER OS_FSYS /* May vary from CPU clock */
#endif /* depending on CPU */
#ifndef OS_PCLK_UART /* Peripheral clock for UART */
#define OS_PCLK_UART OS_FSYS /* May vary from CPU clock */
#endif /* depending on CPU */
#ifndef OS_TICK_FREQ
#define OS_TICK_FREQ (1000)
#endif
#ifndef OS_USE_VARINTTABLE /* The interrupt vector table */
#define OS_USE_VARINTTABLE (0) /* may be located in RAM */
#endif
/*********************************************************************
*
* UART settings for OSView
* If you do not want (or can not due to hardware limitations)
* to dedicate a UART to OSView, please define it to be -1
* Currently the standard code enables UART 0 per default
*/
#ifndef OS_UART
#define OS_UART (0)
#endif
#ifndef OS_BAUDRATE
#define OS_BAUDRATE (115200)
#endif
/****** End of configuration settings *******************************/
#define OS_UART_USED ((OS_UART == 0) || (OS_UART == 1))
/*********************************************************************
*
* Local defines (sfrs used in RTOSInit.c)
*
**********************************************************************
*/
#define _SYS_HANDLER_STATE (*(volatile OS_U32*)(0xE000ED24))
#define _SYS_TICK_ACT_BIT (11)
#define _SYS_INT_CTRL_STATE (*(volatile OS_U32*)(0xE000ED04))
#define _SYS_PENDSTSET 26
#define _SYSCTRL_BASE_ADDR (0x400FE000)
#define _SYSCTRL_RCGC1 (*(volatile OS_U32*)(_SYSCTRL_BASE_ADDR + 0x104))
#define _SYSCTRL_RCGC2 (*(volatile OS_U32*)(_SYSCTRL_BASE_ADDR + 0x108))
#define _SYSCTRL_RCC (*(volatile OS_U32*)(_SYSCTRL_BASE_ADDR + 0x60)) // Run-mode clock config register
#define _SYSCTRL_MISC (*(volatile OS_U32*)(_SYSCTRL_BASE_ADDR + 0x58)) // Interrupt status register
#define _SYSCTRL_RIS (*(volatile OS_U32*)(_SYSCTRL_BASE_ADDR + 0x50)) // Raw interrupt status register
#define _SYSCTRL_RCC_BYPASS (0x00000800) // PLL bypass
#define _SYSCTRL_RCC_USE_SYSDIV (0x00400000) // Use sytem clock divider
#define _SYSCTRL_RCC_IOSCDIS (0x00000002) // Internal oscillator disable
#define _SYSCTRL_RCC_MOSCDIS (0x00000001) // Main oscillator disable
#define _SYSCTRL_RCC_XTAL_MASK (0x000003C0) // Crystal attached to main osc
#define _SYSCTRL_RCC_OSCSRC_MASK (0x00000030) // Oscillator input select
#define _SYSCTRL_RCC_PWRDN (0x00002000) // PLL power down
#define _SYSCTRL_RCC_OE (0x00001000) // PLL output enable
#define _SYSCTRL_INT_PLL_LOCK (0x00000040) // PLL lock interrupt
#define _SYSCTRL_RCC_SYSDIV_MASK (0x07800000) // System clock divider
#define _SYSPRI1_ADDR (0xE000ED18)
#define _SYSHND_CTRL_ADDR (0xE000ED24) // System Handler Control and State
#define _SYSHND_CTRL (*(volatile OS_U32*) (_SYSHND_CTRL_ADDR))
#define _NVIC_SYS_HND_CTRL_MEM (0x00010000) // Mem manage fault enable
#define _NVIC_SYS_HND_CTRL_BUS (0x00020000) // Bus fault enable
#define _NVIC_SYS_HND_CTRL_USAGE (0x00040000) // Usage fault enable
#define _NVIC_BASE_ADDR (0xE000E000)
#define _NVIC_PRIOBASE_ADDR (0xE000E400)
#define _NVIC_ENABLE_ADDR (0xE000E100)
#define _NVIC_DISABLE_ADDR (0xE000E180)
#define _NVIC_VTOREG_ADDR (0xE000ED08)
#define _NUM_INTERRUPTS (16+43)
/*********************************************************************
*
* The following can be used as as arguments for the PLL activation
* if required in __low_level_init()
*
**********************************************************************
*/
#define _SYSCTRL_SYSDIV_1 (0x07800000) // Processor clock is osc/pll /1
#define _SYSCTRL_SYSDIV_4 (0x01C00000) // Processor clock is osc/pll /4
#define _SYSCTRL_SYSDIV_10 (0x04C00000) // Processor clock is osc/pll /10
#define _SYSCTRL_USE_PLL (0x00000000) // System clock is the PLL clock
#define _SYSCTRL_USE_OSC (0x00003800) // System clock is the osc clock
#define _SYSCTRL_XTAL_6MHZ (0x000002C0) // External crystal is 6MHz
#define _SYSCTRL_XTAL_8MHZ (0x00000380) // External crystal is 8MHz
#define _SYSCTRL_OSC_MAIN (0x00000000) // Oscillator source is main osc
#define _SYS_TICK_BASE_ADDR (0xE000E010)
#define _SYS_TICK_CONTROL *(volatile OS_U32*)(_SYS_TICK_BASE_ADDR + 0x00)
#define _SYS_TICK_RELOAD *(volatile OS_U32*)(_SYS_TICK_BASE_ADDR + 0x04)
#define _SYS_TICK_VALUE *(volatile OS_U32*)(_SYS_TICK_BASE_ADDR + 0x08)
#define _SYS_TICK_CALIBRATION *(volatile OS_U32*)(_SYS_TICK_BASE_ADDR + 0x0C)
#define _SYS_TICK_ENABLE_BIT (0)
#define _SYS_TICK_INT_ENABLE_BIT (1)
#define _SYS_TICK_CLK_SOURCE_BIT (2)
#define OS_TIMER_RELOAD (OS_PCLK_TIMER / OS_TICK_FREQ - 1)
#if (OS_TIMER_RELOAD >= 0x100000000)
#error "Systick can not be used, please check configuration"
#endif
/***** Interrupt ID numbers ****************************************/
#define _ISR_ID_NMI (2) // NMI fault
#define _ISR_ID_HARD (3) // Hard fault
#define _ISR_ID_MPU (4) // MPU fault
#define _ISR_ID_BUS (5) // Bus fault
#define _ISR_ID_USAGE (6) // Usage fault
#define _ISR_ID_SVCALL (11) // SVCall
#define _ISR_ID_DEBUG (12) // Debug monitor
#define _ISR_ID_PENDSV (14) // PendSV
#define _ISR_ID_SYSTICK (15) // System Tick
#define _ISR_ID_USART1 (53) // USART1
#define _ISR_ID_USART2 (54) // USART2
#define _OS_ISR_ID_TICK _ISR_ID_SYSTICK // We use Sys-Timer
#define _OS_ISR_TICK_PRIO (0xFF) // Lowest priority
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* OS_Systick
*
* Function description
* This is the code that gets called when the processor receives a
* _SysTick exception. SysTick is used as OS timer tick.
*
* NOTES:
* (1) It has to be inserted in the interrupt vector table, if RAM
* vectors are not used. Therefore is is declared public
*/
void OS_Systick(void) {
OS_EnterNestableInterrupt();
OS_HandleTick();
OS_LeaveNestableInterrupt();
}
/*********************************************************************
*
* OS_InitHW()
*
* Initialize the hardware (timer) required for the OS to run.
* May be modified, if an other timer should be used
*/
#define PERIPH_BASE ((OS_U32)0x40000000)
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define RCC_CR *(volatile OS_U32*)(RCC_BASE + 0x00)
#define RCC_CFGR *(volatile OS_U32*)(RCC_BASE + 0x04)
#define RCC_CIR *(volatile OS_U32*)(RCC_BASE + 0x08)
#define RCC_APB2RSTR *(volatile OS_U32*)(RCC_BASE + 0x0C)
#define RCC_APB1RSTR *(volatile OS_U32*)(RCC_BASE + 0x10)
#define RCC_AHBENR *(volatile OS_U32*)(RCC_BASE + 0x14)
#define RCC_APB2ENR *(volatile OS_U32*)(RCC_BASE + 0x18)
#define RCC_APB1ENR *(volatile OS_U32*)(RCC_BASE + 0x1C)
#define RCC_BDCR *(volatile OS_U32*)(RCC_BASE + 0x20)
#define RCC_CSR *(volatile OS_U32*)(RCC_BASE + 0x24)
#define FLASH_ACR *(volatile OS_U32*)(FLASH_BASE + 0x00)
#define CR_PLLON_BB *(volatile OS_U32*)(0x42420060)
#define CR_HSEBYP_Reset ((OS_U32)0xFFFBFFFF)
#define CR_HSEBYP_Set ((OS_U32)0x00040000)
#define CR_HSEON_Reset ((OS_U32)0xFFFEFFFF)
#define CR_HSEON_Set ((OS_U32)0x00010000)
#define CR_HSITRIM_Mask ((OS_U32)0xFFFFFF07)
#define FLASH_Latency_2 ((OS_U32)0x00000002)
#define ACR_LATENCY_Mask ((OS_U32)0x00000038)
#define ACR_PRFTBE_Mask ((OS_U32)0xFFFFFFEF)
#define FLASH_BASE ((OS_U32)0x40022000)
#define FLASH_PrefetchBuffer_Enable ((OS_U32)0x00000010)
#define CFGR_HPRE_Reset_Mask ((OS_U32)0xFFFFFF0F)
#define RCC_SYSCLK_Div1 ((OS_U32)0x00000000)
#define CFGR_PPRE2_Reset_Mask ((OS_U32)0xFFFFC7FF)
#define RCC_HCLK_Div1 ((OS_U32)0x00000000)
#define RCC_HCLK_Div2 ((OS_U32)0x00000400)
#define CFGR_PPRE1_Reset_Mask ((OS_U32)0xFFFFF8FF)
#define CFGR_PLL_Mask ((OS_U32)0xFFC0FFFF)
#define PERIPH_BB_BASE ((OS_U32)0x42000000)
#define PLLON_BitNumber 0x18
#define CFGR_SW_Mask ((OS_U32)0xFFFFFFFC)
#define RCC_SYSCLKSource_PLLCLK ((OS_U32)0x00000002)
#define CFGR_SWS_Mask ((OS_U32)0x0000000C)
#define RCC_PLLSource_HSE_Div1 ((OS_U32)0x00010000)
#define RCC_PLLMul_9 ((OS_U32)0x001C0000)
void OS_InitHW(void) {
OS_U32 tmpreg;
RCC_APB2RSTR = 0x00000000; // Disable APB2 Peripheral Reset
RCC_APB1RSTR = 0x00000000; // Disable APB1 Peripheral Reset
RCC_AHBENR = 0x00000014; // FLITF and SRAM Clock ON
RCC_APB2ENR = 0x00000000; // Disable APB2 Peripheral Clock
RCC_APB1ENR = 0x00000000; // Disable APB1 Peripheral Clock
RCC_CR |= (OS_U32)0x00000001; // Set HSION bit
RCC_CFGR &= 0xF8FF0000; // Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], ADCPRE[1:0] and MCO[2:0] bits
RCC_CR &= 0xFEF6FFFF; // Reset HSEON, CSSON and PLLON bits
RCC_CR &= 0xFFFBFFFF; // Reset HSEBYP bit
RCC_CFGR &= 0xFF80FFFF; // Reset PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE bits
RCC_CIR = 0x00000000; // Disable all interrupts
RCC_CR &= CR_HSEON_Reset; // Reset HSEON bit
RCC_CR &= CR_HSEBYP_Reset; // Reset HSEBYP bit
RCC_CR |= CR_HSEON_Set; // Configure HSE (RCC_HSE_OFF is already covered by the code section above
while (RCC_CR & (1 << 17)); // Wait till HSE is ready
FLASH_ACR &= ACR_LATENCY_Mask; // Flash 2 wait state and Prefetch enable
FLASH_ACR |= FLASH_Latency_2;
FLASH_ACR &= ACR_PRFTBE_Mask; // Enable or disable the Prefetch Buffer
FLASH_ACR |= FLASH_PrefetchBuffer_Enable;
RCC_CFGR &= CFGR_HPRE_Reset_Mask; // HCLK = SYSCLK
RCC_CFGR |= RCC_SYSCLK_Div1;
RCC_CFGR &= CFGR_PPRE2_Reset_Mask; // PCLK2 = HCLK
RCC_CFGR = (RCC_HCLK_Div1 << 3);
RCC_CFGR &= CFGR_PPRE1_Reset_Mask; // PCLK1 = HCLK/2
RCC_CFGR = RCC_HCLK_Div2;
tmpreg = RCC_CFGR; // PLLCLK = 8MHz * 9 = 72 MHz */
tmpreg &= CFGR_PLL_Mask; // Clear PLLSRC, PLLXTPRE and PLLMUL[21:18] bits
tmpreg |= RCC_PLLSource_HSE_Div1 | RCC_PLLMul_9;// Set the PLL configuration bits
RCC_CFGR = tmpreg; // Store the new value
CR_PLLON_BB = (OS_U32)0x01; // Enable PLL
while (RCC_CR & (1 << 25)); // Wait till PLL is ready
tmpreg = RCC_CFGR; // Select PLL as system clock source
tmpreg &= CFGR_SW_Mask; // Clear SW[1:0] bits
tmpreg |= RCC_SYSCLKSource_PLLCLK; // Set SW[1:0] bits according to RCC_SYSCLKSource value
RCC_CFGR = tmpreg; // Store the new value
while ((RCC_CFGR & CFGR_SWS_Mask) != 0x08); // Wait till PLL is used as system clock source
OS_DI();
//
// Initialize OS timer, clock soure = core clock
//
_SYS_TICK_RELOAD = OS_TIMER_RELOAD;
_SYS_TICK_CONTROL = (1 << _SYS_TICK_ENABLE_BIT) | (1 << _SYS_TICK_CLK_SOURCE_BIT);
//
// Install Systick Timer Handler and enable timer interrupt
//
OS_ARM_InstallISRHandler(_OS_ISR_ID_TICK, (OS_ISR_HANDLER*)OS_Systick);
OS_ARM_ISRSetPrio(_OS_ISR_ID_TICK, _OS_ISR_TICK_PRIO);
OS_ARM_EnableISR(_OS_ISR_ID_TICK);
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 execute
while (1) {
}
}
/*********************************************************************
*
* Get time [cycles]
*
* This routine is required for high
* resolution time maesurement functions.
* It returns the system time in timer clock cycles.
*/
OS_U32 OS_GetTime_Cycles(void) {
unsigned int t_cnt;
OS_U32 time;
time = OS_Time;
t_cnt = (OS_PCLK_TIMER/1000) - _SYS_TICK_VALUE;
if (_SYS_INT_CTRL_STATE & (1 << _SYS_PENDSTSET)) { /* Missed a counter interrupt? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -