diff --git a/include/rtdef.h b/include/rtdef.h index 027440fc48787eb680c2dc062e2c4a93115a14c0..24d4bc8f02983a827337bee80becb540b0728e01 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -528,7 +528,7 @@ enum rt_device_class_type RT_Device_Class_Block, /* block device */ RT_Device_Class_NetIf, /* net interface */ RT_Device_Class_MTD, /* memory device */ - RT_Device_Class_CAN, /* CAN device */ + RT_Device_Class_CAN, /* CAN device */ RT_Device_Class_RTC, /* RTC device */ RT_Device_Class_Unknown /* unknown device */ }; @@ -566,9 +566,9 @@ enum rt_device_class_type #define RT_DEVICE_CTRL_BLK_GETGEOME 0x10 /* get geometry information */ #define RT_DEVICE_CTRL_NETIF_GETMAC 0x10 /* get mac address */ #define RT_DEVICE_CTRL_MTD_FORMAT 0x10 /* format a MTD device */ -#define RT_DEVICE_CTRL_RTC_GET_TIME 0x10 /* get time */ +#define RT_DEVICE_CTRL_RTC_GET_TIME 0x10 /* get time */ #define RT_DEVICE_CTRL_RTC_SET_TIME 0x11 /* set time */ - + typedef struct rt_device* rt_device_t; /* * Device related structure diff --git a/libcpu/arm/stm32/context_rvds.S b/libcpu/arm/stm32/context_rvds.S index 6904f5856373adb95ebf8b6120905fa4d1bd82cd..23e1a701422c357cf3add85d9fe6814b944bdb5b 100644 --- a/libcpu/arm/stm32/context_rvds.S +++ b/libcpu/arm/stm32/context_rvds.S @@ -55,24 +55,29 @@ rt_hw_interrupt_enable PROC ; * r0 --> from ; * r1 --> to ; */ +rt_hw_context_switch_interrupt + EXPORT rt_hw_context_switch_interrupt rt_hw_context_switch PROC EXPORT rt_hw_context_switch ; set rt_thread_switch_interrput_flag to 1 LDR r2, =rt_thread_switch_interrput_flag LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch MOV r3, #1 STR r3, [r2] LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread STR r0, [r2] + +_reswitch LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread STR r1, [r2] - LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) LDR r1, =NVIC_PENDSVSET STR r1, [r0] - ; CPSIE I ; enable interrupts at processor level BX LR ENDP @@ -143,55 +148,11 @@ rt_hw_context_switch_to PROC ; never reach here! ENDP -;/* -; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to) -; * { -; * if (rt_thread_switch_interrput_flag == 1) -; * { -; * rt_interrupt_to_thread = to; -; * } -; * else -; * { -; * rt_thread_switch_interrput_flag = 1; -; * rt_interrupt_from_thread = from; -; * rt_interrupt_to_thread = to; -; * } -; * } -; */ -rt_hw_context_switch_interrupt PROC - EXPORT rt_hw_context_switch_interrupt - LDR r2, =rt_thread_switch_interrput_flag - LDR r3, [r2] - CMP r3, #1 - BEQ _reswitch - MOV r3, #1 ; set rt_thread_switch_interrput_flag to 1 - STR r3, [r2] - LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread - STR r0, [r2] -_reswitch - LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread - STR r1, [r2] - BX lr - ENDP - -rt_hw_interrupt_thread_switch PROC +; compatible with old version +rt_hw_interrupt_thread_switch PROC EXPORT rt_hw_interrupt_thread_switch - LDR r0, =rt_thread_switch_interrput_flag - LDR r1, [r0] - CBZ r1, _no_switch - - ; clear rt_thread_switch_interrput_flag to 0 - ; MOV r1, #0x00 - ; STR r1, [r0] - - ; trigger context switch - LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) - LDR r1, =NVIC_PENDSVSET - STR r1, [r0] - -_no_switch BX lr - + NOP ENDP - END \ No newline at end of file + END diff --git a/libcpu/arm/stm32/interrupt.c b/libcpu/arm/stm32/interrupt.c index a57656c7fb7054132729043f97ab42d7d52db8bd..3f6165a255036aad8597d5f8dc4395c5a9cf132e 100644 --- a/libcpu/arm/stm32/interrupt.c +++ b/libcpu/arm/stm32/interrupt.c @@ -14,10 +14,6 @@ #include -#define MAX_HANDLERS 32 - -extern rt_uint32_t rt_interrupt_nest; - /* exception and interrupt handler table */ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrput_flag; diff --git a/libcpu/arm/stm32/start_rvds.s b/libcpu/arm/stm32/start_rvds.s index 9360522086a6c52841d7b353a5b6026ab9ece695..b212037fca375f70fe45b3422a581390bb64b087 100644 --- a/libcpu/arm/stm32/start_rvds.s +++ b/libcpu/arm/stm32/start_rvds.s @@ -1,9 +1,10 @@ -;******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -;* File Name : stm32f10x_vector.s +;******************** (C) COPYRIGHT 2009 STMicroelectronics ******************** +;* File Name : startup_stm32f10x_hd.s ;* Author : MCD Application Team -;* Version : V1.1.2 -;* Date : 09/22/2008 -;* Description : STM32F10x vector table for RVMDK toolchain. +;* Version : V3.1.0 +;* Date : 06/19/2009 +;* Description : STM32F10x High Density Devices vector table for RVMDK +;* toolchain. ;* This module performs: ;* - Set the initial SP ;* - Set the initial PC == Reset_Handler @@ -26,246 +27,329 @@ ; Amount of memory (in bytes) allocated for Stack ; Tailor this value to your application needs -;// Stack Configuration -;// Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -;// -Stack_Size EQU 0x00000200 +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size +Stack_Size EQU 0x00000200 -__initial_sp -; If you need to use external SRAM mounted on STM3210E-EVAL board as data memory -; and internal SRAM for Stack, uncomment the following line and comment the line above -;__initial_sp EQU 0x20000000 + Stack_Size ; "Use MicroLIB" must be checked in - ; the Project->Options->Target window + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp EQU 0x20000400 ; stack used for SystemInit_ExtMemCtl + ; always internal RAM used -; Amount of memory (in bytes) allocated for Heap -; Tailor this value to your application needs -;// Heap Configuration -;// Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -;// +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; -Heap_Size EQU 0x00000000 +Heap_Size EQU 0x00000000 - AREA HEAP, NOINIT, READWRITE, ALIGN=3 + AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base -Heap_Mem SPACE Heap_Size +Heap_Mem SPACE Heap_Size __heap_limit - THUMB PRESERVE8 + THUMB - ; Import exceptions handlers - IMPORT NMIException IMPORT rt_hw_hard_fault - IMPORT MemManageException - IMPORT BusFaultException - IMPORT UsageFaultException - IMPORT SVCHandler - IMPORT DebugMonitor IMPORT rt_hw_pend_sv - IMPORT SysTickHandler - IMPORT WWDG_IRQHandler - IMPORT PVD_IRQHandler - IMPORT TAMPER_IRQHandler - IMPORT RTC_IRQHandler - IMPORT FLASH_IRQHandler - IMPORT RCC_IRQHandler - IMPORT EXTI0_IRQHandler - IMPORT EXTI1_IRQHandler - IMPORT EXTI2_IRQHandler - IMPORT EXTI3_IRQHandler - IMPORT EXTI4_IRQHandler - IMPORT DMA1_Channel1_IRQHandler - IMPORT DMA1_Channel2_IRQHandler - IMPORT DMA1_Channel3_IRQHandler - IMPORT DMA1_Channel4_IRQHandler - IMPORT DMA1_Channel5_IRQHandler - IMPORT DMA1_Channel6_IRQHandler - IMPORT DMA1_Channel7_IRQHandler - IMPORT ADC1_2_IRQHandler - IMPORT USB_HP_CAN1_TX_IRQHandler - IMPORT USB_LP_CAN1_RX0_IRQHandler - IMPORT CAN1_RX1_IRQHandler - IMPORT CAN1_SCE_IRQHandler - IMPORT EXTI9_5_IRQHandler - IMPORT TIM1_BRK_IRQHandler - IMPORT TIM1_UP_IRQHandler - IMPORT TIM1_TRG_COM_IRQHandler - IMPORT TIM1_CC_IRQHandler - IMPORT TIM2_IRQHandler - IMPORT TIM3_IRQHandler - IMPORT TIM4_IRQHandler - IMPORT I2C1_EV_IRQHandler - IMPORT I2C1_ER_IRQHandler - IMPORT I2C2_EV_IRQHandler - IMPORT I2C2_ER_IRQHandler - IMPORT SPI1_IRQHandler - IMPORT SPI2_IRQHandler - IMPORT USART1_IRQHandler - IMPORT USART2_IRQHandler - IMPORT USART3_IRQHandler - IMPORT EXTI15_10_IRQHandler - IMPORT RTCAlarm_IRQHandler - IMPORT USBWakeUp_IRQHandler - ; HD - IMPORT TIM8_BRK_IRQHandler - IMPORT TIM8_UP_IRQHandler - IMPORT TIM8_TRG_COM_IRQHandler - IMPORT TIM8_CC_IRQHandler - IMPORT ADC3_IRQHandler - IMPORT FSMC_IRQHandler - IMPORT SDIO_IRQHandler - IMPORT TIM5_IRQHandler - IMPORT SPI3_IRQHandler - IMPORT UART4_IRQHandler - IMPORT UART5_IRQHandler - IMPORT TIM6_IRQHandler - IMPORT TIM7_IRQHandler - IMPORT DMA2_Channel1_IRQHandler - IMPORT DMA2_Channel2_IRQHandler - IMPORT DMA2_Channel3_IRQHandler - IMPORT DMA2_Channel4_5_IRQHandler - ; CL (DMA2_Channel4 DMA2_Channel5 is alone) - IMPORT DMA2_Channel5_IRQHandler ; DMA2 Channel5 - IMPORT ETH_IRQHandler ; Ethernet - IMPORT ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line - IMPORT CAN2_TX_IRQHandler ; CAN2 TX - IMPORT CAN2_RX0_IRQHandler ; CAN2 RX0 - IMPORT CAN2_RX1_IRQHandler ; CAN2 RX1 - IMPORT CAN2_SCE_IRQHandler ; CAN2 SCE - IMPORT OTG_FS_IRQHandler ; USB OTG FS + IMPORT rt_hw_timer_handler -;******************************************************************************* -; Fill-up the Vector Table entries with the exceptions ISR address -;******************************************************************************* - AREA RESET, DATA, READONLY - EXPORT __Vectors - -__Vectors DCD __initial_sp ; Top of Stack - DCD Reset_Handler - DCD NMIException - DCD rt_hw_hard_fault - DCD MemManageException - DCD BusFaultException - DCD UsageFaultException - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD SVCHandler - DCD DebugMonitor - DCD 0 ; Reserved - DCD rt_hw_pend_sv - DCD SysTickHandler - DCD WWDG_IRQHandler - DCD PVD_IRQHandler - DCD TAMPER_IRQHandler - DCD RTC_IRQHandler - DCD FLASH_IRQHandler - DCD RCC_IRQHandler - DCD EXTI0_IRQHandler - DCD EXTI1_IRQHandler - DCD EXTI2_IRQHandler - DCD EXTI3_IRQHandler - DCD EXTI4_IRQHandler - DCD DMA1_Channel1_IRQHandler - DCD DMA1_Channel2_IRQHandler - DCD DMA1_Channel3_IRQHandler - DCD DMA1_Channel4_IRQHandler - DCD DMA1_Channel5_IRQHandler - DCD DMA1_Channel6_IRQHandler - DCD DMA1_Channel7_IRQHandler - DCD ADC1_2_IRQHandler - DCD USB_HP_CAN1_TX_IRQHandler - DCD USB_LP_CAN1_RX0_IRQHandler - DCD CAN1_RX1_IRQHandler - DCD CAN1_SCE_IRQHandler - DCD EXTI9_5_IRQHandler - DCD TIM1_BRK_IRQHandler - DCD TIM1_UP_IRQHandler - DCD TIM1_TRG_COM_IRQHandler - DCD TIM1_CC_IRQHandler - DCD TIM2_IRQHandler - DCD TIM3_IRQHandler - DCD TIM4_IRQHandler - DCD I2C1_EV_IRQHandler - DCD I2C1_ER_IRQHandler - DCD I2C2_EV_IRQHandler - DCD I2C2_ER_IRQHandler - DCD SPI1_IRQHandler - DCD SPI2_IRQHandler - DCD USART1_IRQHandler - DCD USART2_IRQHandler - DCD USART3_IRQHandler - DCD EXTI15_10_IRQHandler - DCD RTCAlarm_IRQHandler - DCD USBWakeUp_IRQHandler - ; HD - DCD TIM8_BRK_IRQHandler - DCD TIM8_UP_IRQHandler - DCD TIM8_TRG_COM_IRQHandler - DCD TIM8_CC_IRQHandler - DCD ADC3_IRQHandler - DCD FSMC_IRQHandler - DCD SDIO_IRQHandler - DCD TIM5_IRQHandler - DCD SPI3_IRQHandler - DCD UART4_IRQHandler - DCD UART5_IRQHandler - DCD TIM6_IRQHandler - DCD TIM7_IRQHandler - DCD DMA2_Channel1_IRQHandler - DCD DMA2_Channel2_IRQHandler - DCD DMA2_Channel3_IRQHandler - DCD DMA2_Channel4_5_IRQHandler - ; CL (DMA2_Channel4 DMA2_Channel5 is alone) - DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5 - DCD ETH_IRQHandler ; Ethernet - DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line - DCD CAN2_TX_IRQHandler ; CAN2 TX - DCD CAN2_RX0_IRQHandler ; CAN2 RX0 - DCD CAN2_RX1_IRQHandler ; CAN2 RX1 - DCD CAN2_SCE_IRQHandler ; CAN2 SCE - DCD OTG_FS_IRQHandler ; USB OTG FS - - - AREA |.text|, CODE, READONLY +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD rt_hw_hard_fault ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD rt_hw_pend_sv ; PendSV Handler + DCD rt_hw_timer_handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window Watchdog + DCD PVD_IRQHandler ; PVD through EXTI Line detect + DCD TAMPER_IRQHandler ; Tamper + DCD RTC_IRQHandler ; RTC + DCD FLASH_IRQHandler ; Flash + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line 0 + DCD EXTI1_IRQHandler ; EXTI Line 1 + DCD EXTI2_IRQHandler ; EXTI Line 2 + DCD EXTI3_IRQHandler ; EXTI Line 3 + DCD EXTI4_IRQHandler ; EXTI Line 4 + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 + DCD ADC1_2_IRQHandler ; ADC1 & ADC2 + DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX + DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; CAN1 SCE + DCD EXTI9_5_IRQHandler ; EXTI Line 9..5 + DCD TIM1_BRK_IRQHandler ; TIM1 Break + DCD TIM1_UP_IRQHandler ; TIM1 Update + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; EXTI Line 15..10 + DCD RTCAlarm_IRQHandler ; RTC Alarm through EXTI Line + DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend + DCD TIM8_BRK_IRQHandler ; TIM8 Break + DCD TIM8_UP_IRQHandler ; TIM8 Update + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare + DCD ADC3_IRQHandler ; ADC3 + DCD FSMC_IRQHandler ; FSMC + DCD SDIO_IRQHandler ; SDIO + DCD TIM5_IRQHandler ; TIM5 + DCD SPI3_IRQHandler ; SPI3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD TIM6_IRQHandler ; TIM6 + DCD TIM7_IRQHandler ; TIM7 + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1 + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2 + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3 + DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5 +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY ; Reset handler routine -Reset_Handler PROC - EXPORT Reset_Handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + + LDR R1, = __initial_sp ; restore original stack pointer + MSR MSP, R1 + + LDR R0, =__main + BX R0 + ENDP - IMPORT __main - LDR R0, =__main - BX R0 - ENDP +; Dummy Exception Handlers (infinite loops which can be modified) - ALIGN +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_IRQHandler [WEAK] + EXPORT TAMPER_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC1_2_IRQHandler [WEAK] + EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK] + EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTCAlarm_IRQHandler [WEAK] + EXPORT USBWakeUp_IRQHandler [WEAK] + EXPORT TIM8_BRK_IRQHandler [WEAK] + EXPORT TIM8_UP_IRQHandler [WEAK] + EXPORT TIM8_TRG_COM_IRQHandler [WEAK] + EXPORT TIM8_CC_IRQHandler [WEAK] + EXPORT ADC3_IRQHandler [WEAK] + EXPORT FSMC_IRQHandler [WEAK] + EXPORT SDIO_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_5_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_IRQHandler +TAMPER_IRQHandler +RTC_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC1_2_IRQHandler +USB_HP_CAN1_TX_IRQHandler +USB_LP_CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTCAlarm_IRQHandler +USBWakeUp_IRQHandler +TIM8_BRK_IRQHandler +TIM8_UP_IRQHandler +TIM8_TRG_COM_IRQHandler +TIM8_CC_IRQHandler +ADC3_IRQHandler +FSMC_IRQHandler +SDIO_IRQHandler +TIM5_IRQHandler +SPI3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_5_IRQHandler + B . + + ENDP + + ALIGN ;******************************************************************************* ; User Stack and Heap initialization ;******************************************************************************* - IF :DEF:__MICROLIB - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - ELSE - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap __user_initial_stackheap - LDR R0, = Heap_Mem - LDR R1, = (Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ALIGN + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF - ENDIF + END - END +;******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE***** -;******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE***** diff --git a/src/ipc.c b/src/ipc.c index 8b54cabbdb9f4d8637c94c13369f0f731c9e5558..255bee12e769d9b1016b3ac7d84df21e11c84e85 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -1340,6 +1340,7 @@ rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32_t* value, rt_int32_t timeout) /* parameter check */ RT_ASSERT(mb != RT_NULL); + tick_delta = 0; #ifdef RT_USING_HOOK if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mb->parent.parent)); #endif @@ -1788,6 +1789,7 @@ rt_err_t rt_mq_recv (rt_mq_t mq, void* buffer, rt_size_t size, rt_int32_t timeou if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mq->parent.parent)); #endif + tick_delta = 0; /* disable interrupt */ temp = rt_hw_interrupt_disable(); diff --git a/src/object.c b/src/object.c index 0655382350d4e21d53c5d09531a7423339d2d90d..a19f0d4c46e4de6dc7121f83e6ef17d71dbfcfcb 100644 --- a/src/object.c +++ b/src/object.c @@ -121,7 +121,7 @@ void rt_system_object_init(void) rt_object_container[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread); rt_object_container[RT_Object_Class_Thread].type = RT_Object_Class_Thread; -#ifdef RT_USING_MODULE +#ifdef RT_USING_MODULE /* init object container - module */ rt_list_init(&(rt_object_container[RT_Object_Class_Module].object_list)); rt_object_container[RT_Object_Class_Module].object_size = sizeof(struct rt_module); diff --git a/src/scheduler.c b/src/scheduler.c index 5a8aba3e4c534ce8ad11b2b48ff36e16494cad63..4714d3ea7377e808da7dab6d479a4b6222f267f3 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1,417 +1,417 @@ -/* - * File : scheduler.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2006-03-17 Bernard the first version - * 2006-04-28 Bernard fix the scheduler algorthm - * 2006-04-30 Bernard add SCHEDULER_DEBUG - * 2006-05-27 Bernard fix the scheduler algorthm for same priority thread - * schedule - * 2006-06-04 Bernard rewrite the scheduler algorithm - * 2006-08-03 Bernard add hook support - * 2006-09-05 Bernard add 32 priority level support - * 2006-09-24 Bernard add rt_system_scheduler_start function - * 2009-09-16 Bernard fix _rt_scheduler_stack_check - */ - -#include -#include - -#include "kservice.h" - -/* #define SCHEDULER_DEBUG */ - -static rt_int16_t rt_scheduler_lock_nest; -extern rt_uint32_t rt_interrupt_nest; - -rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; -struct rt_thread* rt_current_thread; - -rt_uint8_t rt_current_priority; - -#if RT_THREAD_PRIORITY_MAX > 32 -/* maximun priority level, 256 */ -rt_uint32_t rt_thread_ready_priority_group; -rt_uint8_t rt_thread_ready_table[32]; -#else -/* maximun priority level, 32 */ -rt_uint32_t rt_thread_ready_priority_group; -#endif - -#ifdef RT_USING_HEAP -rt_list_t rt_thread_defunct; -#endif - -const rt_uint8_t rt_lowest_bitmap[] = -{ - /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -#ifdef RT_USING_HOOK -static void (*rt_scheduler_hook)(struct rt_thread* from, struct rt_thread* to); - -/** - * @addtogroup Hook - */ -/*@{*/ - -/** - * This function will set a hook function, which will be invoked when thread - * switch happens. - * - * @param hook the hook function - */ -void rt_scheduler_sethook(void (*hook)(struct rt_thread* from, struct rt_thread* to)) -{ - rt_scheduler_hook = hook; -} - -/*@}*/ -#endif - -#ifdef RT_USING_OVERFLOW_CHECK -static void _rt_scheduler_stack_check(struct rt_thread* thread) -{ - RT_ASSERT(thread != RT_NULL); - - if ( (rt_uint32_t)thread->sp <= (rt_uint32_t)thread->stack_addr || - (rt_uint32_t)thread->sp > - (rt_uint32_t)thread->stack_addr + (rt_uint32_t)thread->stack_size ) - { - rt_uint32_t level; - - rt_kprintf("thread:%s stack overflow\n", thread->name); - level = rt_hw_interrupt_disable(); - while (level); - } - else if ((rt_uint32_t)thread->sp <= ((rt_uint32_t)thread->stack_addr + 32)) - { - rt_kprintf("warning: %s stack is close to end of stack address.\n", - thread->name); - } -} -#endif - -/** - * @ingroup SystemInit - * This function will init the system scheduler - * - */ -void rt_system_scheduler_init(void) -{ - register rt_base_t offset; - - rt_scheduler_lock_nest = 0; - - for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++) - { - rt_list_init(&rt_thread_priority_table[offset]); - } - - rt_current_priority = RT_THREAD_PRIORITY_MAX - 1; - rt_current_thread = RT_NULL; - - /* init ready priority group */ - rt_thread_ready_priority_group = 0; - -#if RT_THREAD_PRIORITY_MAX > 32 - /* init ready table */ - rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table)); -#endif - -#ifdef RT_USING_HEAP - /* init thread defunct */ - rt_list_init(&rt_thread_defunct); -#endif -} - -/** - * This function will startup scheduler. It will select one thread - * with the highest priority level, then switch to it. - */ -void rt_system_scheduler_start() -{ - register rt_uint8_t number; - register rt_uint8_t highest_ready_priority; - - struct rt_thread *to_thread; - - /* find out the highest priority task */ - if (rt_thread_ready_priority_group & 0xff) - { - number = rt_lowest_bitmap[rt_thread_ready_priority_group & 0xff]; - } - else if (rt_thread_ready_priority_group & 0xff00) - { - number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 8) & 0xff] + 8; - } - else if (rt_thread_ready_priority_group & 0xff0000) - { - number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 16) & 0xff] + 16; - } - else - { - number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 24) & 0xff] + 24; - } - -#if RT_THREAD_PRIORITY_MAX > 32 - highest_ready_priority = (number << 3) + rt_lowest_bitmap[rt_thread_ready_table[number]]; -#else - highest_ready_priority = number; -#endif - - /* get switch to thread */ - to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, - struct rt_thread, tlist); - - rt_current_thread = to_thread; - - /* switch to new thread */ - rt_hw_context_switch_to((rt_uint32_t)&to_thread->sp); - - /* never come back */ -} - -/** - * @addtogroup Thread - */ -/*@{*/ - -/** - * This function will perform one schedule. It will select one thread - * with the highest priority level, then switch to it. - */ -void rt_schedule() -{ - register rt_uint8_t number; - register rt_base_t level; - register rt_uint8_t highest_ready_priority; - - struct rt_thread *to_thread; - struct rt_thread *from_thread; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - - /* check the scheduler is enabled or not */ - if (rt_scheduler_lock_nest == 0) - { - /* find out the highest priority task */ - if (rt_thread_ready_priority_group & 0xff) - { - number = rt_lowest_bitmap[rt_thread_ready_priority_group & 0xff]; - } - else if (rt_thread_ready_priority_group & 0xff00) - { - number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 8) & 0xff] + 8; - } - else if (rt_thread_ready_priority_group & 0xff0000) - { - number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 16) & 0xff] + 16; - } - else - { - number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 24) & 0xff] + 24; - } - -#if RT_THREAD_PRIORITY_MAX > 32 - highest_ready_priority = (number << 3) + rt_lowest_bitmap[rt_thread_ready_table[number]]; -#else - highest_ready_priority = number; -#endif - /* get switch to thread */ - to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, - struct rt_thread, tlist); - - /* if the destination thread is not the same as current thread */ - if (to_thread != rt_current_thread) - { - rt_current_priority = highest_ready_priority; - from_thread = rt_current_thread; - rt_current_thread = to_thread; - -#ifdef RT_USING_HOOK - if (rt_scheduler_hook != RT_NULL) rt_scheduler_hook(from_thread, to_thread); -#endif - - /* switch to new thread */ -#ifdef SCHEDULER_DEBUG - rt_kprintf("[%d]switch to priority#%d thread:%s\n", rt_interrupt_nest, - highest_ready_priority, to_thread->name); -#endif -#ifdef RT_USING_OVERFLOW_CHECK - _rt_scheduler_stack_check(to_thread); -#endif - - if (rt_interrupt_nest == 0) - { - rt_hw_context_switch((rt_uint32_t)&from_thread->sp, (rt_uint32_t)&to_thread->sp); - } - else - { -#ifdef SCHEDULER_DEBUG - rt_kprintf("switch in interrupt\n"); -#endif - rt_hw_context_switch_interrupt((rt_uint32_t)&from_thread->sp, - (rt_uint32_t)&to_thread->sp); - } - } - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); -} - -/** - * This function will insert a thread to system ready queue. The state of - * thread will be set as READY and remove from suspend queue. - * - * @param thread the thread to be inserted - * @note Please do not invoke this function in user application. - */ -void rt_schedule_insert_thread(struct rt_thread* thread) -{ - register rt_base_t temp; - - RT_ASSERT(thread != RT_NULL); - - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); - - /* change stat */ - thread->stat = RT_THREAD_READY; - - /* insert thread to ready list */ - rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]), - &(thread->tlist)); - - /* set priority mask */ -#ifdef SCHEDULER_DEBUG -#if RT_THREAD_PRIORITY_MAX == 32 - rt_kprintf("insert thread, the priority: %d\n", thread->current_priority); -#else - rt_kprintf("insert thread, the priority: %d 0x%x %d\n", thread->number, thread->number_mask, thread->high_mask); -#endif -#endif - -#if RT_THREAD_PRIORITY_MAX > 32 - rt_thread_ready_table[thread->number] |= thread->high_mask; -#endif - rt_thread_ready_priority_group |= thread->number_mask; - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); -} - -/** - * This function will remove a thread from system ready queue. - * - * @param thread the thread to be removed - * - * @note Please do not invoke this function in user application. - */ -void rt_schedule_remove_thread(struct rt_thread* thread) -{ - register rt_base_t temp; - - RT_ASSERT(thread != RT_NULL); - - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); - -#ifdef SCHEDULER_DEBUG -#if RT_THREAD_PRIORITY_MAX == 32 - rt_kprintf("remove thread, the priority: %d\n", thread->current_priority); -#else - rt_kprintf("remove thread, the priority: %d 0x%x %d\n", thread->number, - thread->number_mask, thread->high_mask); -#endif -#endif - - /* remove thread from ready list */ - rt_list_remove(&(thread->tlist)); - if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority]))) - { -#if RT_THREAD_PRIORITY_MAX > 32 - rt_thread_ready_table[thread->number] &= ~thread->high_mask; - if (rt_thread_ready_table[thread->number] == 0) - { - rt_thread_ready_priority_group &= ~thread->number_mask; - } -#else - rt_thread_ready_priority_group &= ~thread->number_mask; -#endif - } - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); -} - -/** - * This function will lock the thread scheduler. - */ -void rt_enter_critical() -{ - register rt_base_t level; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - - if (rt_scheduler_lock_nest < 255u) - rt_scheduler_lock_nest++; - - /* enable interrupt */ - rt_hw_interrupt_enable(level); -} - -/** - * This function will unlock the thread scheduler. - */ -void rt_exit_critical() -{ - register rt_base_t level; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - - rt_scheduler_lock_nest --; - - if (rt_scheduler_lock_nest <= 0) - { - rt_scheduler_lock_nest = 0; - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - rt_schedule(); - } - else - { - /* enable interrupt */ - rt_hw_interrupt_enable(level); - } -} - -/*@}*/ - +/* + * File : scheduler.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-03-17 Bernard the first version + * 2006-04-28 Bernard fix the scheduler algorthm + * 2006-04-30 Bernard add SCHEDULER_DEBUG + * 2006-05-27 Bernard fix the scheduler algorthm for same priority thread + * schedule + * 2006-06-04 Bernard rewrite the scheduler algorithm + * 2006-08-03 Bernard add hook support + * 2006-09-05 Bernard add 32 priority level support + * 2006-09-24 Bernard add rt_system_scheduler_start function + * 2009-09-16 Bernard fix _rt_scheduler_stack_check + */ + +#include +#include + +#include "kservice.h" + +/* #define SCHEDULER_DEBUG */ + +static rt_int16_t rt_scheduler_lock_nest; +extern rt_uint32_t rt_interrupt_nest; + +rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; +struct rt_thread* rt_current_thread; + +rt_uint8_t rt_current_priority; + +#if RT_THREAD_PRIORITY_MAX > 32 +/* maximun priority level, 256 */ +rt_uint32_t rt_thread_ready_priority_group; +rt_uint8_t rt_thread_ready_table[32]; +#else +/* maximun priority level, 32 */ +rt_uint32_t rt_thread_ready_priority_group; +#endif + +#ifdef RT_USING_HEAP +rt_list_t rt_thread_defunct; +#endif + +const rt_uint8_t rt_lowest_bitmap[] = +{ + /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +#ifdef RT_USING_HOOK +static void (*rt_scheduler_hook)(struct rt_thread* from, struct rt_thread* to); + +/** + * @addtogroup Hook + */ +/*@{*/ + +/** + * This function will set a hook function, which will be invoked when thread + * switch happens. + * + * @param hook the hook function + */ +void rt_scheduler_sethook(void (*hook)(struct rt_thread* from, struct rt_thread* to)) +{ + rt_scheduler_hook = hook; +} + +/*@}*/ +#endif + +#ifdef RT_USING_OVERFLOW_CHECK +static void _rt_scheduler_stack_check(struct rt_thread* thread) +{ + RT_ASSERT(thread != RT_NULL); + + if ( (rt_uint32_t)thread->sp <= (rt_uint32_t)thread->stack_addr || + (rt_uint32_t)thread->sp > + (rt_uint32_t)thread->stack_addr + (rt_uint32_t)thread->stack_size ) + { + rt_uint32_t level; + + rt_kprintf("thread:%s stack overflow\n", thread->name); + level = rt_hw_interrupt_disable(); + while (level); + } + else if ((rt_uint32_t)thread->sp <= ((rt_uint32_t)thread->stack_addr + 32)) + { + rt_kprintf("warning: %s stack is close to end of stack address.\n", + thread->name); + } +} +#endif + +/** + * @ingroup SystemInit + * This function will init the system scheduler + * + */ +void rt_system_scheduler_init(void) +{ + register rt_base_t offset; + + rt_scheduler_lock_nest = 0; + + for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++) + { + rt_list_init(&rt_thread_priority_table[offset]); + } + + rt_current_priority = RT_THREAD_PRIORITY_MAX - 1; + rt_current_thread = RT_NULL; + + /* init ready priority group */ + rt_thread_ready_priority_group = 0; + +#if RT_THREAD_PRIORITY_MAX > 32 + /* init ready table */ + rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table)); +#endif + +#ifdef RT_USING_HEAP + /* init thread defunct */ + rt_list_init(&rt_thread_defunct); +#endif +} + +/** + * This function will startup scheduler. It will select one thread + * with the highest priority level, then switch to it. + */ +void rt_system_scheduler_start() +{ + register rt_uint8_t number; + register rt_uint8_t highest_ready_priority; + + struct rt_thread *to_thread; + + /* find out the highest priority task */ + if (rt_thread_ready_priority_group & 0xff) + { + number = rt_lowest_bitmap[rt_thread_ready_priority_group & 0xff]; + } + else if (rt_thread_ready_priority_group & 0xff00) + { + number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 8) & 0xff] + 8; + } + else if (rt_thread_ready_priority_group & 0xff0000) + { + number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 16) & 0xff] + 16; + } + else + { + number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 24) & 0xff] + 24; + } + +#if RT_THREAD_PRIORITY_MAX > 32 + highest_ready_priority = (number << 3) + rt_lowest_bitmap[rt_thread_ready_table[number]]; +#else + highest_ready_priority = number; +#endif + + /* get switch to thread */ + to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, + struct rt_thread, tlist); + + rt_current_thread = to_thread; + + /* switch to new thread */ + rt_hw_context_switch_to((rt_uint32_t)&to_thread->sp); + + /* never come back */ +} + +/** + * @addtogroup Thread + */ +/*@{*/ + +/** + * This function will perform one schedule. It will select one thread + * with the highest priority level, then switch to it. + */ +void rt_schedule() +{ + register rt_uint8_t number; + register rt_base_t level; + register rt_uint8_t highest_ready_priority; + + struct rt_thread *to_thread; + struct rt_thread *from_thread; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + /* check the scheduler is enabled or not */ + if (rt_scheduler_lock_nest == 0) + { + /* find out the highest priority task */ + if (rt_thread_ready_priority_group & 0xff) + { + number = rt_lowest_bitmap[rt_thread_ready_priority_group & 0xff]; + } + else if (rt_thread_ready_priority_group & 0xff00) + { + number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 8) & 0xff] + 8; + } + else if (rt_thread_ready_priority_group & 0xff0000) + { + number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 16) & 0xff] + 16; + } + else + { + number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 24) & 0xff] + 24; + } + +#if RT_THREAD_PRIORITY_MAX > 32 + highest_ready_priority = (number << 3) + rt_lowest_bitmap[rt_thread_ready_table[number]]; +#else + highest_ready_priority = number; +#endif + /* get switch to thread */ + to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, + struct rt_thread, tlist); + + /* if the destination thread is not the same as current thread */ + if (to_thread != rt_current_thread) + { + rt_current_priority = highest_ready_priority; + from_thread = rt_current_thread; + rt_current_thread = to_thread; + +#ifdef RT_USING_HOOK + if (rt_scheduler_hook != RT_NULL) rt_scheduler_hook(from_thread, to_thread); +#endif + + /* switch to new thread */ +#ifdef SCHEDULER_DEBUG + rt_kprintf("[%d]switch to priority#%d thread:%s\n", rt_interrupt_nest, + highest_ready_priority, to_thread->name); +#endif +#ifdef RT_USING_OVERFLOW_CHECK + _rt_scheduler_stack_check(to_thread); +#endif + + if (rt_interrupt_nest == 0) + { + rt_hw_context_switch((rt_uint32_t)&from_thread->sp, (rt_uint32_t)&to_thread->sp); + } + else + { +#ifdef SCHEDULER_DEBUG + rt_kprintf("switch in interrupt\n"); +#endif + rt_hw_context_switch_interrupt((rt_uint32_t)&from_thread->sp, + (rt_uint32_t)&to_thread->sp); + } + } + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); +} + +/** + * This function will insert a thread to system ready queue. The state of + * thread will be set as READY and remove from suspend queue. + * + * @param thread the thread to be inserted + * @note Please do not invoke this function in user application. + */ +void rt_schedule_insert_thread(struct rt_thread* thread) +{ + register rt_base_t temp; + + RT_ASSERT(thread != RT_NULL); + + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + + /* change stat */ + thread->stat = RT_THREAD_READY; + + /* insert thread to ready list */ + rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]), + &(thread->tlist)); + + /* set priority mask */ +#ifdef SCHEDULER_DEBUG +#if RT_THREAD_PRIORITY_MAX == 32 + rt_kprintf("insert thread, the priority: %d\n", thread->current_priority); +#else + rt_kprintf("insert thread, the priority: %d 0x%x %d\n", thread->number, thread->number_mask, thread->high_mask); +#endif +#endif + +#if RT_THREAD_PRIORITY_MAX > 32 + rt_thread_ready_table[thread->number] |= thread->high_mask; +#endif + rt_thread_ready_priority_group |= thread->number_mask; + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); +} + +/** + * This function will remove a thread from system ready queue. + * + * @param thread the thread to be removed + * + * @note Please do not invoke this function in user application. + */ +void rt_schedule_remove_thread(struct rt_thread* thread) +{ + register rt_base_t temp; + + RT_ASSERT(thread != RT_NULL); + + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + +#ifdef SCHEDULER_DEBUG +#if RT_THREAD_PRIORITY_MAX == 32 + rt_kprintf("remove thread, the priority: %d\n", thread->current_priority); +#else + rt_kprintf("remove thread, the priority: %d 0x%x %d\n", thread->number, + thread->number_mask, thread->high_mask); +#endif +#endif + + /* remove thread from ready list */ + rt_list_remove(&(thread->tlist)); + if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority]))) + { +#if RT_THREAD_PRIORITY_MAX > 32 + rt_thread_ready_table[thread->number] &= ~thread->high_mask; + if (rt_thread_ready_table[thread->number] == 0) + { + rt_thread_ready_priority_group &= ~thread->number_mask; + } +#else + rt_thread_ready_priority_group &= ~thread->number_mask; +#endif + } + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); +} + +/** + * This function will lock the thread scheduler. + */ +void rt_enter_critical() +{ + register rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + if (rt_scheduler_lock_nest < 255u) + rt_scheduler_lock_nest++; + + /* enable interrupt */ + rt_hw_interrupt_enable(level); +} + +/** + * This function will unlock the thread scheduler. + */ +void rt_exit_critical() +{ + register rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + rt_scheduler_lock_nest --; + + if (rt_scheduler_lock_nest <= 0) + { + rt_scheduler_lock_nest = 0; + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + rt_schedule(); + } + else + { + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } +} + +/*@}*/ + diff --git a/src/thread.c b/src/thread.c index b8ab0fb641534306b59602f7fb9bd1bb31785f05..53f6cbf6b06a411d3641c7ef8375b6c5eb1d37e9 100644 --- a/src/thread.c +++ b/src/thread.c @@ -60,7 +60,7 @@ static rt_err_t _rt_thread_init(struct rt_thread* thread, (void *) ((char *)thread->stack_addr + thread->stack_size - 4), (void*)rt_thread_exit); - /* priority init */ + /* priority init */ RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX); thread->init_priority = priority; thread->current_priority = priority; @@ -74,13 +74,13 @@ static rt_err_t _rt_thread_init(struct rt_thread* thread, thread->stat = RT_THREAD_INIT; thread->flags = 0; -#ifdef RT_USING_MODULE - /* init module parent */ - thread->module_parent = RT_NULL; +#ifdef RT_USING_MODULE + /* init module parent */ + thread->module_parent = RT_NULL; #endif - /* init user data */ - thread->user_data = 0; + /* init user data */ + thread->user_data = 0; /* init thread timer */ rt_timer_init(&(thread->thread_timer),