diff options
author | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-08-23 08:11:23 +0000 |
---|---|---|
committer | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-08-23 08:11:23 +0000 |
commit | 4ec82f62c18894d92bafc6c6f98784650106373d (patch) | |
tree | a0cec5585dff0434608241c373b9ad30af5ae869 /os | |
parent | c877f5bfcc5301b441c9b13e8c32d83e9df04f37 (diff) | |
parent | 2a494cb534dbe3535a9bf4c61dfbc8b6c9e750be (diff) | |
download | ChibiOS-4ec82f62c18894d92bafc6c6f98784650106373d.tar.gz ChibiOS-4ec82f62c18894d92bafc6c6f98784650106373d.tar.bz2 ChibiOS-4ec82f62c18894d92bafc6c6f98784650106373d.zip |
I2C. 1 - Merge code from trunk. 2 - Fix driver problems detected by the CH_DBG_SYSTEM_STATE_CHECK
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3249 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
63 files changed, 1250 insertions, 399 deletions
diff --git a/os/hal/platforms/Posix/hal_lld.c b/os/hal/platforms/Posix/hal_lld.c index 1eb0af355..8b59d992b 100644 --- a/os/hal/platforms/Posix/hal_lld.c +++ b/os/hal/platforms/Posix/hal_lld.c @@ -78,8 +78,8 @@ void ChkIntSources(void) { #if HAL_USE_SERIAL
if (sd_lld_interrupt_pending()) {
- if (chSchIsRescRequiredExI())
- chSchDoRescheduleI();
+ if (chSchIsPreemptionRequired())
+ chSchDoReschedule();
return;
}
#endif
@@ -88,8 +88,8 @@ void ChkIntSources(void) { if (timercmp(&tv, &nextcnt, >=)) {
timeradd(&nextcnt, &tick, &nextcnt);
chSysTimerHandlerI();
- if (chSchIsRescRequiredExI())
- chSchDoRescheduleI();
+ if (chSchIsPreemptionRequired())
+ chSchDoReschedule();
}
}
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index a93e2f0a1..77d4b7829 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -514,10 +514,6 @@ void i2c_lld_init(void) { * @param[in] i2cp pointer to the @p I2CDriver object */ void i2c_lld_start(I2CDriver *i2cp) { -#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS) - gptStart(i2cp->timer, i2cp->timer_cfg); -#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */ - if (i2cp->id_state == I2C_STOP) { /* If in stopped state then enables the I2C clock.*/ #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { @@ -726,7 +722,7 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, #else chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_transmit(), #1", "time to STOP is out"); if ((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ - gptStartOneShot(i2cp->timer, I2C_STOP_GPT_TIMEOUT); + gptStartOneShotI(i2cp->timer, I2C_STOP_GPT_TIMEOUT); i2cp->flags |= I2C_FLG_TIMER_ARMED; return; } @@ -784,7 +780,7 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, #else chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_receive(), #1", "time to STOP is out"); if ((i2cp->id_i2c->CR1 & I2C_CR1_STOP) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ - gptStartOneShot(i2cp->timer, I2C_STOP_GPT_TIMEOUT); + gptStartOneShotI(i2cp->timer, I2C_STOP_GPT_TIMEOUT); i2cp->flags |= I2C_FLG_TIMER_ARMED; return; } @@ -850,7 +846,7 @@ void i2c_lld_master_transceive(I2CDriver *i2cp){ #else chDbgAssert(!(i2cp->flags & I2C_FLG_TIMER_ARMED), "i2c_lld_master_transceive(), #1", "time to START is out"); if ((i2cp->id_i2c->CR1 & I2C_CR1_START) && i2cp->timer != NULL && i2cp->timer_cfg != NULL){ - gptStartOneShot(i2cp->timer, I2C_START_GPT_TIMEOUT); + gptStartOneShotI(i2cp->timer, I2C_START_GPT_TIMEOUT); i2cp->flags |= I2C_FLG_TIMER_ARMED; return; } diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox index 50ab84f38..83c33a868 100644 --- a/os/hal/platforms/STM32F1xx/platform.dox +++ b/os/hal/platforms/STM32F1xx/platform.dox @@ -19,24 +19,24 @@ */
/**
- * @defgroup STM32_DRIVERS STM32 Drivers
- * @details This section describes all the supported drivers on the STM32
+ * @defgroup STM32F1xx_DRIVERS STM32F1xx Drivers
+ * @details This section describes all the supported drivers on the STM32F1xx
* platform and the implementation details of the single drivers.
*
* @ingroup platforms
*/
/**
- * @defgroup STM32_HAL STM32 Initialization Support
- * @details The STM32 HAL support is responsible for system initialization.
+ * @defgroup STM32F1xx_HAL STM32F1xx Initialization Support
+ * @details The STM32F1xx HAL support is responsible for system initialization.
*
- * @section stm32_hal_1 Supported HW resources
+ * @section stm32f1xx_hal_1 Supported HW resources
* - PLL1.
* - PLL2 (where present).
* - RCC.
* - Flash.
* .
- * @section stm32_hal_2 STM32 HAL driver implementation features
+ * @section stm32f1xx_hal_2 STM32F1xx HAL driver implementation features
* - PLLs startup and stabilization.
* - Clock tree initialization.
* - Clock source selection.
@@ -44,19 +44,19 @@ * - SYSTICK initialization based on current clock and kernel required rate.
* - DMA support initialization.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_ADC STM32 ADC Support
- * @details The STM32 ADC driver supports the ADC peripherals using DMA
+ * @defgroup STM32F1xx_ADC STM32F1xx ADC Support
+ * @details The STM32F1xx ADC driver supports the ADC peripherals using DMA
* channels for maximum performance.
*
- * @section stm32_adc_1 Supported HW resources
+ * @section stm32f1xx_adc_1 Supported HW resources
* - ADC1.
* - DMA1.
* .
- * @section stm32_adc_2 STM32 ADC driver implementation features
+ * @section stm32f1xx_adc_2 STM32F1xx ADC driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Streaming conversion using DMA for maximum performance.
* - Programmable ADC interrupt priority level.
@@ -64,85 +64,85 @@ * - Programmable DMA interrupt priority for each DMA channel.
* - Programmable DMA error hook.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_CAN STM32 CAN Support
- * @details The STM32 CAN driver uses the CAN peripherals.
+ * @defgroup STM32F1xx_CAN STM32F1xx CAN Support
+ * @details The STM32F1xx CAN driver uses the CAN peripherals.
*
- * @section stm32_can_1 Supported HW resources
+ * @section stm32f1xx_can_1 Supported HW resources
* - bxCAN1.
* .
- * @section stm32_can_2 STM32 CAN driver implementation features
+ * @section stm32f1xx_can_2 STM32F1xx CAN driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Support for bxCAN sleep mode.
* - Programmable bxCAN interrupts priority level.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_DMA STM32 DMA Support
+ * @defgroup STM32F1xx_DMA STM32F1xx DMA Support
* @details This DMA helper driver is used by the other drivers in order to
* access the shared DMA resources in a consistent way.
*
- * @section stm32_dma_1 Supported HW resources
+ * @section stm32f1xx_dma_1 Supported HW resources
* The DMA driver can support any of the following hardware resources:
* - DMA1.
* - DMA2 (where present).
* .
- * @section stm32_dma_2 STM32 DMA driver implementation features
+ * @section stm32f1xx_dma_2 STM32F1xx DMA driver implementation features
* - Automatic DMA clock stop when not in use by other drivers.
* - Exports helper functions/macros to the other drivers that share the
* DMA resource.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_GPT STM32 GPT Support
- * @details The STM32 GPT driver uses the TIMx peripherals.
+ * @defgroup STM32F1xx_GPT STM32F1xx GPT Support
+ * @details The STM32F1xx GPT driver uses the TIMx peripherals.
*
- * @section stm32_gpt_1 Supported HW resources
+ * @section stm32f1xx_gpt_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* - TIM5.
* .
- * @section stm32_gpt_2 STM32 GPT driver implementation features
+ * @section stm32f1xx_gpt_2 STM32F1xx GPT driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable TIMx interrupts priority level.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_ICU STM32 ICU Support
- * @details The STM32 ICU driver uses the TIMx peripherals.
+ * @defgroup STM32F1xx_ICU STM32F1xx ICU Support
+ * @details The STM32F1xx ICU driver uses the TIMx peripherals.
*
- * @section stm32_icu_1 Supported HW resources
+ * @section stm32f1xx_icu_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* - TIM5.
* .
- * @section stm32_icu_2 STM32 ICU driver implementation features
+ * @section stm32f1xx_icu_2 STM32F1xx ICU driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable TIMx interrupts priority level.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_PAL STM32 PAL Support
- * @details The STM32 PAL driver uses the GPIO peripherals.
+ * @defgroup STM32F1xx_PAL STM32F1xx PAL Support
+ * @details The STM32F1xx PAL driver uses the GPIO peripherals.
*
- * @section stm32_pal_1 Supported HW resources
+ * @section stm32f1xx_pal_1 Supported HW resources
* - AFIO.
* - GPIOA.
* - GPIOB.
@@ -152,7 +152,7 @@ * - GPIOF (where present).
* - GPIOG (where present).
* .
- * @section stm32_pal_2 STM32 PAL driver implementation features
+ * @section stm32f1xx_pal_2 STM32F1xx PAL driver implementation features
* The PAL driver implementation fully supports the following hardware
* capabilities:
* - 16 bits wide ports.
@@ -161,8 +161,8 @@ * - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
- * @section stm32_pal_3 Supported PAL setup modes
- * The STM32 PAL driver supports the following I/O modes:
+ * @section stm32f1xx_pal_3 Supported PAL setup modes
+ * The STM32F1xx PAL driver supports the following I/O modes:
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
@@ -171,13 +171,13 @@ * - @p PAL_MODE_INPUT_ANALOG.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* - @p PAL_MODE_OUTPUT_OPENDRAIN.
- * - @p PAL_MODE_STM32_ALTERNATE_PUSHPULL (non standard).
- * - @p PAL_MODE_STM32_ALTERNATE_OPENDRAIN (non standard).
+ * - @p PAL_MODE_STM32F1xx_ALTERNATE_PUSHPULL (non standard).
+ * - @p PAL_MODE_STM32F1xx_ALTERNATE_OPENDRAIN (non standard).
* .
* Any attempt to setup an invalid mode is ignored.
*
- * @section stm32_pal_4 Suboptimal behavior
- * The STM32 GPIO is less than optimal in several areas, the limitations
+ * @section stm32f1xx_pal_4 Suboptimal behavior
+ * The STM32F1xx GPIO is less than optimal in several areas, the limitations
* should be taken in account while using the PAL driver:
* - Pad/port toggling operations are not atomic.
* - Pad/group mode setup is not atomic.
@@ -185,52 +185,52 @@ * resistor can change the resistor setting because the output latch is
* used for resistor selection.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_PWM STM32 PWM Support
- * @details The STM32 PWM driver uses the TIMx peripherals.
+ * @defgroup STM32F1xx_PWM STM32F1xx PWM Support
+ * @details The STM32F1xx PWM driver uses the TIMx peripherals.
*
- * @section stm32_pwm_1 Supported HW resources
+ * @section stm32f1xx_pwm_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* - TIM5.
* .
- * @section stm32_pwm_2 STM32 PWM driver implementation features
+ * @section stm32f1xx_pwm_2 STM32F1xx PWM driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Four independent PWM channels per timer.
* - Programmable TIMx interrupts priority level.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_SDC STM32 SDC Support
- * @details The STM32 SDC driver uses the SDIO peripheral.
+ * @defgroup STM32F1xx_SDC STM32F1xx SDC Support
+ * @details The STM32F1xx SDC driver uses the SDIO peripheral.
*
- * @section stm32_sdc_1 Supported HW resources
+ * @section stm32f1xx_sdc_1 Supported HW resources
* - SDIO.
* - DMA2.
* .
- * @section stm32_sdc_2 STM32 SDC driver implementation features
+ * @section stm32f1xx_sdc_2 STM32F1xx SDC driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Programmable interrupt priority.
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_SERIAL STM32 Serial Support
- * @details The STM32 Serial driver uses the USART/UART peripherals in a
+ * @defgroup STM32F1xx_SERIAL STM32F1xx Serial Support
+ * @details The STM32F1xx Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
- * @section stm32_serial_1 Supported HW resources
+ * @section stm32f1xx_serial_1 Supported HW resources
* The serial driver can support any of the following hardware resources:
* - USART1.
* - USART2.
@@ -238,29 +238,29 @@ * - UART4 (where present).
* - UART5 (where present).
* .
- * @section stm32_serial_2 STM32 Serial driver implementation features
+ * @section stm32f1xx_serial_2 STM32F1xx Serial driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each UART/USART can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Fully interrupt driven.
* - Programmable priority levels for each UART/USART.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_SPI STM32 SPI Support
- * @details The SPI driver supports the STM32 SPI peripherals using DMA
+ * @defgroup STM32F1xx_SPI STM32F1xx SPI Support
+ * @details The SPI driver supports the STM32F1xx SPI peripherals using DMA
* channels for maximum performance.
*
- * @section stm32_spi_1 Supported HW resources
+ * @section stm32f1xx_spi_1 Supported HW resources
* - SPI1.
* - SPI2.
* - SPI3 (where present).
* - DMA1.
* - DMA2 (where present).
* .
- * @section stm32_spi_2 STM32 SPI driver implementation features
+ * @section stm32f1xx_spi_2 STM32F1xx SPI driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each SPI can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
@@ -270,15 +270,15 @@ * - Programmable DMA interrupt priority for each DMA channel.
* - Programmable DMA error hook.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_UART STM32 UART Support
- * @details The UART driver supports the STM32 USART peripherals using DMA
+ * @defgroup STM32F1xx_UART STM32F1xx UART Support
+ * @details The UART driver supports the STM32F1xx USART peripherals using DMA
* channels for maximum performance.
*
- * @section stm32_uart_1 Supported HW resources
+ * @section stm32f1xx_uart_1 Supported HW resources
* The UART driver can support any of the following hardware resources:
* - USART1.
* - USART2.
@@ -287,7 +287,7 @@ * - DMA1.
* - DMA2 (where present).
* .
- * @section stm32_uart_2 STM32 UART driver implementation features
+ * @section stm32f1xx_uart_2 STM32F1xx UART driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each UART/USART can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
@@ -297,21 +297,21 @@ * - Programmable DMA interrupt priority for each DMA channel.
* - Programmable DMA error hook.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
/**
- * @defgroup STM32_USB STM32 USB Support
- * @details The USB driver supports the STM32 USB peripheral.
+ * @defgroup STM32F1xx_USB STM32F1xx USB Support
+ * @details The USB driver supports the STM32F1xx USB peripheral.
*
- * @section stm32_usb_1 Supported HW resources
+ * @section stm32f1xx_usb_1 Supported HW resources
* The USB driver can support any of the following hardware resources:
* - USB.
* .
- * @section stm32_usb_2 STM32 USB driver implementation features
+ * @section stm32f1xx_usb_2 STM32F1xx USB driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Programmable interrupt priority levels.
* - Each endpoint programmable in Control, Bulk and Interrupt modes.
* .
- * @ingroup STM32_DRIVERS
+ * @ingroup STM32F1xx_DRIVERS
*/
diff --git a/os/hal/platforms/STM32F1xx/stm32f10x.h b/os/hal/platforms/STM32F1xx/stm32f10x.h index 8773ef453..c7f447d18 100644 --- a/os/hal/platforms/STM32F1xx/stm32f10x.h +++ b/os/hal/platforms/STM32F1xx/stm32f10x.h @@ -15,15 +15,15 @@ * is using in the C source code, usually in main.c. This file contains:
* - Configuration section that allows to select:
* - The device used in the target application
- * - To use or not the peripheral’s drivers in application code(i.e.
- * code will be based on direct access to peripheral’s registers
+ * - To use or not the peripheral�s drivers in application code(i.e.
+ * code will be based on direct access to peripheral�s registers
* rather than drivers API), this option is controlled by
* "#define USE_STDPERIPH_DRIVER"
* - To change few application-specific parameters such as the HSE
* crystal frequency
* - Data structures and the address mapping for all peripherals
* - Peripheral's registers declarations and bits definition
- * - Macros to access peripheral’s registers hardware
+ * - Macros to access peripheral�s registers hardware
*
******************************************************************************
* @attention
@@ -63,6 +63,8 @@ */
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
+ /* CHIBIOS FIX */
+#include "board.h"
/* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
/* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
/* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h index 0cdfc69c9..764f58529 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.h +++ b/os/hal/platforms/STM32F2xx/hal_lld.h @@ -153,6 +153,7 @@ #define STM32_HAS_GPIOF TRUE
#define STM32_HAS_GPIOG TRUE
#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI TRUE
#define STM32_HAS_I2C1 TRUE
#define STM32_HAS_I2C2 TRUE
@@ -277,12 +278,12 @@ #define I2C3_ER_IRQHandler Vector164 /**< I2C3 Error. */
#define OTG_HS_EP1_OUT_IRQHandler Vector168 /**< USB OTG HS End Point 1 Out.*/
#define OTG_HS_EP1_IN_IRQHandler Vector16C /**< USB OTG HS End Point 1 In. */
-#define OTG_HS_WKUP_IRQHandler Vector168 /**< USB OTG HS Wakeup through
+#define OTG_HS_WKUP_IRQHandler Vector170 /**< USB OTG HS Wakeup through
EXTI line. */
-#define OTG_HS_IRQHandler Vector16C /**< USB OTG HS. */
-#define DCMI_IRQHandler Vector16C /**< DCMI. */
-#define CRYP_IRQHandler Vector16C /**< CRYP. */
-#define HASH_RNG_IRQHandler Vector16C /**< Hash and Rng. */
+#define OTG_HS_IRQHandler Vector174 /**< USB OTG HS. */
+#define DCMI_IRQHandler Vector178 /**< DCMI. */
+#define CRYP_IRQHandler Vector17C /**< CRYP. */
+#define HASH_RNG_IRQHandler Vector180 /**< Hash and Rng. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox new file mode 100644 index 000000000..7abe18e5e --- /dev/null +++ b/os/hal/platforms/STM32L1xx/platform.dox @@ -0,0 +1,254 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup STM32L1xx_DRIVERS STM32L1xx Drivers
+ * @details This section describes all the supported drivers on the STM32F1xx
+ * platform and the implementation details of the single drivers.
+ *
+ * @ingroup platforms
+ */
+
+/**
+ * @defgroup STM32L1xx_HAL STM32L1xx Initialization Support
+ * @details The STM32L1xx HAL support is responsible for system initialization.
+ *
+ * @section stm32l1xx_hal_1 Supported HW resources
+ * - PLL1.
+ * - RCC.
+ * - Flash.
+ * .
+ * @section stm32l1xx_hal_2 STM32L1xx HAL driver implementation features
+ * - PLL startup and stabilization.
+ * - Clock tree initialization.
+ * - Clock source selection.
+ * - Flash wait states initialization based on the selected clock options.
+ * - SYSTICK initialization based on current clock and kernel required rate.
+ * - DMA support initialization.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_DMA STM32L1xx DMA Support
+ * @details This DMA helper driver is used by the other drivers in order to
+ * access the shared DMA resources in a consistent way.
+ *
+ * @section stm32l1xx_dma_1 Supported HW resources
+ * The DMA driver can support any of the following hardware resources:
+ * - DMA1.
+ * .
+ * @section stm32l1xx_dma_2 STM32L1xx DMA driver implementation features
+ * - Automatic DMA clock stop when not in use by other drivers.
+ * - Exports helper functions/macros to the other drivers that share the
+ * DMA resource.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_GPT STM32L1xx GPT Support
+ * @details The STM32L1xx GPT driver uses the TIMx peripherals.
+ *
+ * @section stm32l1xx_gpt_1 Supported HW resources
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * .
+ * @section stm32l1xx_gpt_2 STM32L1xx GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_ICU STM32L1xx ICU Support
+ * @details The STM32L1xx ICU driver uses the TIMx peripherals.
+ *
+ * @section stm32l1xx_icu_1 Supported HW resources
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * .
+ * @section stm32l1xx_icu_2 STM32L1xx ICU driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_PAL STM32L1xx PAL Support
+ * @details The STM32L1xx PAL driver uses the GPIO peripherals.
+ *
+ * @section stm32l1xx_pal_1 Supported HW resources
+ * - GPIOA.
+ * - GPIOB.
+ * - GPIOC.
+ * - GPIOD.
+ * - GPIOE.
+ * - GPIOH.
+ * .
+ * @section stm32l1xx_pal_2 STM32L1xx PAL driver implementation features
+ * The PAL driver implementation fully supports the following hardware
+ * capabilities:
+ * - 16 bits wide ports.
+ * - Atomic set/reset functions.
+ * - Atomic set+reset function (atomic bus operations).
+ * - Output latched regardless of the pad setting.
+ * - Direct read of input pads regardless of the pad setting.
+ * .
+ * @section stm32l1xx_pal_3 Supported PAL setup modes
+ * The STM32L1xx PAL driver supports the following I/O modes:
+ * - @p PAL_MODE_RESET.
+ * - @p PAL_MODE_UNCONNECTED.
+ * - @p PAL_MODE_INPUT.
+ * - @p PAL_MODE_INPUT_PULLUP.
+ * - @p PAL_MODE_INPUT_PULLDOWN.
+ * - @p PAL_MODE_INPUT_ANALOG.
+ * - @p PAL_MODE_OUTPUT_PUSHPULL.
+ * - @p PAL_MODE_OUTPUT_OPENDRAIN.
+ * - @p PAL_MODE_STM32L1xx_ALTERNATE_PUSHPULL (non standard).
+ * - @p PAL_MODE_STM32L1xx_ALTERNATE_OPENDRAIN (non standard).
+ * .
+ * Any attempt to setup an invalid mode is ignored.
+ *
+ * @section stm32l1xx_pal_4 Suboptimal behavior
+ * The STM32L1xx GPIO is less than optimal in several areas, the limitations
+ * should be taken in account while using the PAL driver:
+ * - Pad/port toggling operations are not atomic.
+ * - Pad/group mode setup is not atomic.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_PWM STM32L1xx PWM Support
+ * @details The STM32L1xx PWM driver uses the TIMx peripherals.
+ *
+ * @section stm32l1xx_pwm_1 Supported HW resources
+ * - TIM1.
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * - TIM5.
+ * .
+ * @section stm32l1xx_pwm_2 STM32L1xx PWM driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Four independent PWM channels per timer.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support
+ * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a
+ * buffered, interrupt driven, implementation.
+ *
+ * @section stm32l1xx_serial_1 Supported HW resources
+ * The serial driver can support any of the following hardware resources:
+ * - USART1.
+ * - USART2.
+ * - USART3 (where present).
+ * - UART4 (where present).
+ * - UART5 (where present).
+ * .
+ * @section stm32l1xx_serial_2 STM32L1xx Serial driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each UART/USART can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Fully interrupt driven.
+ * - Programmable priority levels for each UART/USART.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_SPI STM32L1xx SPI Support
+ * @details The SPI driver supports the STM32L1xx SPI peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32l1xx_spi_1 Supported HW resources
+ * - SPI1.
+ * - SPI2.
+ * - SPI3 (where present).
+ * - DMA1.
+ * - DMA2 (where present).
+ * .
+ * @section stm32l1xx_spi_2 STM32L1xx SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each SPI can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each SPI.
+ * - DMA is used for receiving and transmitting.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_UART STM32L1xx UART Support
+ * @details The UART driver supports the STM32L1xx USART peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32l1xx_uart_1 Supported HW resources
+ * The UART driver can support any of the following hardware resources:
+ * - USART1.
+ * - USART2.
+ * - USART3 (where present).
+ * - UART4 (where present).
+ * - DMA1.
+ * - DMA2 (where present).
+ * .
+ * @section stm32l1xx_uart_2 STM32L1xx UART driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each UART/USART can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each UART/USART.
+ * - DMA is used for receiving and transmitting.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_USB STM32L1xx USB Support
+ * @details The USB driver supports the STM32L1xx USB peripheral.
+ *
+ * @section stm32l1xx_usb_1 Supported HW resources
+ * The USB driver can support any of the following hardware resources:
+ * - USB.
+ * .
+ * @section stm32l1xx_usb_2 STM32L1xx USB driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Programmable interrupt priority levels.
+ * - Each endpoint programmable in Control, Bulk and Interrupt modes.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
diff --git a/os/hal/platforms/Win32/hal_lld.c b/os/hal/platforms/Win32/hal_lld.c index 24a11f51c..5906e372c 100644 --- a/os/hal/platforms/Win32/hal_lld.c +++ b/os/hal/platforms/Win32/hal_lld.c @@ -83,8 +83,8 @@ void ChkIntSources(void) { #if HAL_USE_SERIAL
if (sd_lld_interrupt_pending()) {
- if (chSchIsRescRequiredExI())
- chSchDoRescheduleI();
+ if (chSchIsPreemptionRequired())
+ chSchDoReschedule();
return;
}
#endif
@@ -94,8 +94,8 @@ void ChkIntSources(void) { if (n.QuadPart > nextcnt.QuadPart) {
nextcnt.QuadPart += slice.QuadPart;
chSysTimerHandlerI();
- if (chSchIsRescRequiredExI())
- chSchDoRescheduleI();
+ if (chSchIsPreemptionRequired())
+ chSchDoReschedule();
}
}
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 9676a3250..974f65a08 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -103,11 +103,15 @@ void i2cObjectInit(I2CDriver *i2cp) { void i2cStart(I2CDriver *i2cp, const I2CConfig *config) {
chDbgCheck((i2cp != NULL) && (config != NULL), "i2cStart");
-
- chSysLock();
chDbgAssert((i2cp->id_state == I2C_STOP) || (i2cp->id_state == I2C_READY),
"i2cStart(), #1",
"invalid state");
+
+#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS)
+ gptStart(i2cp->timer, i2cp->timer_cfg);
+#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */
+
+ chSysLock();
i2cp->id_config = config;
i2c_lld_start(i2cp);
i2cp->id_state = I2C_READY;
@@ -124,11 +128,15 @@ void i2cStart(I2CDriver *i2cp, const I2CConfig *config) { void i2cStop(I2CDriver *i2cp) {
chDbgCheck(i2cp != NULL, "i2cStop");
-
- chSysLock();
chDbgAssert((i2cp->id_state == I2C_STOP) || (i2cp->id_state == I2C_READY),
"i2cStop(), #1",
"invalid state");
+
+#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS)
+ gptStop(i2cp->timer);
+#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */
+
+ chSysLock();
i2c_lld_stop(i2cp);
i2cp->id_state = I2C_STOP;
chSysUnlock();
diff --git a/os/kernel/include/chdebug.h b/os/kernel/include/chdebug.h index b2edf176e..f3bf6b026 100644 --- a/os/kernel/include/chdebug.h +++ b/os/kernel/include/chdebug.h @@ -29,15 +29,31 @@ #ifndef _CHDEBUG_H_
#define _CHDEBUG_H_
+#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
+ CH_DBG_ENABLE_STACK_CHECK || CH_DBG_SYSTEM_STATE_CHECK
+#define CH_DBG_ENABLED TRUE
+#else
+#define CH_DBG_ENABLED FALSE
+#endif
+
+#define __QUOTE_THIS(p) #p
+
+/*===========================================================================*/
/**
- * @brief Trace buffer entries.
+ * @name Debug related settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Trace buffer entries.
*/
#ifndef CH_TRACE_BUFFER_SIZE
#define CH_TRACE_BUFFER_SIZE 64
#endif
/**
- * @brief Fill value for thread stack area in debug mode.
+ * @brief Fill value for thread stack area in debug mode.
*/
#ifndef CH_STACK_FILL_VALUE
#define CH_STACK_FILL_VALUE 0x55
@@ -54,11 +70,33 @@ #define CH_THREAD_FILL_VALUE 0xFF
#endif
-#define __QUOTE_THIS(p) #p
+/** @} */
+
+/*===========================================================================*/
+/* System state checker related code and variables. */
+/*===========================================================================*/
+
+#if !CH_DBG_SYSTEM_STATE_CHECK
+#define dbg_check_disable()
+#define dbg_check_suspend()
+#define dbg_check_enable()
+#define dbg_check_lock()
+#define dbg_check_unlock()
+#define dbg_check_lock_from_isr()
+#define dbg_check_unlock_from_isr()
+#define dbg_check_enter_isr()
+#define dbg_check_leave_isr()
+#define chDbgCheckClassI();
+#define chDbgCheckClassS();
+#endif
+
+/*===========================================================================*/
+/* Trace related structures and macros. */
+/*===========================================================================*/
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
/**
- * @brief Trace buffer record.
+ * @brief Trace buffer record.
*/
typedef struct {
systime_t se_time; /**< @brief Time of the switch event. */
@@ -68,7 +106,7 @@ typedef struct { } ch_swc_event_t;
/**
- * @brief Trace buffer header.
+ * @brief Trace buffer header.
*/
typedef struct {
unsigned tb_size; /**< @brief Trace buffer size (entries).*/
@@ -76,9 +114,25 @@ typedef struct { /** @brief Ring buffer.*/
ch_swc_event_t tb_buffer[CH_TRACE_BUFFER_SIZE];
} ch_trace_buffer_t;
+
+#if !defined(__DOXYGEN__)
+extern ch_trace_buffer_t dbg_trace_buffer;
+#endif
+
#endif /* CH_DBG_ENABLE_TRACE */
+#if !CH_DBG_ENABLE_TRACE
+/* When the trace feature is disabled this function is replaced by an empty
+ macro.*/
+#define dbg_trace(otp)
+#endif
+
+/*===========================================================================*/
+/* Parameters checking related macros. */
+/*===========================================================================*/
+
#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
+
/**
* @brief Function parameter check.
* @details If the condition check fails then the kernel panics and halts.
@@ -102,6 +156,10 @@ typedef struct { }
#endif /* !CH_DBG_ENABLE_CHECKS */
+/*===========================================================================*/
+/* Assertions related macros. */
+/*===========================================================================*/
+
#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
/**
* @brief Condition assertion.
@@ -130,37 +188,44 @@ typedef struct { #define chDbgAssert(c, m, r) {(void)(c);}
#endif /* !CH_DBG_ENABLE_ASSERTS */
-#if !(CH_DBG_ENABLE_ASSERTS || \
- CH_DBG_ENABLE_CHECKS || \
- CH_DBG_ENABLE_STACK_CHECK)
+extern char *dbg_panic_msg;
+
+/*===========================================================================*/
+/* Panic related macros. */
+/*===========================================================================*/
+
+#if !CH_DBG_ENABLED
/* When the debug features are disabled this function is replaced by an empty
macro.*/
#define chDbgPanic(msg) {}
#endif
-#if !CH_DBG_ENABLE_TRACE
-/* When the trace feature is disabled this function is replaced by an empty
- macro.*/
-#define chDbgTrace(otp) {}
-#endif
-
-#if !defined(__DOXYGEN__)
#ifdef __cplusplus
extern "C" {
#endif
+#if CH_DBG_SYSTEM_STATE_CHECK
+ void dbg_check_disable(void);
+ void dbg_check_suspend(void);
+ void dbg_check_enable(void);
+ void dbg_check_lock(void);
+ void dbg_check_unlock(void);
+ void dbg_check_lock_from_isr(void);
+ void dbg_check_unlock_from_isr(void);
+ void dbg_check_enter_isr(void);
+ void dbg_check_leave_isr(void);
+ void chDbgCheckClassI(void);
+ void chDbgCheckClassS(void);
+#endif
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
- extern ch_trace_buffer_t dbg_trace_buffer;
void _trace_init(void);
- void chDbgTrace(Thread *otp);
+ void dbg_trace(Thread *otp);
#endif
-#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
- extern char *dbg_panic_msg;
+#if CH_DBG_ENABLED
void chDbgPanic(char *msg);
#endif
#ifdef __cplusplus
}
#endif
-#endif /* !defined(__DOXYGEN__) */
#endif /* _CHDEBUG_H_ */
diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h index cd545a05e..0e933e8ba 100644 --- a/os/kernel/include/chschd.h +++ b/os/kernel/include/chschd.h @@ -134,14 +134,14 @@ extern "C" { #if !defined(PORT_OPTIMIZED_WAKEUPS)
void chSchWakeupS(Thread *tp, msg_t msg);
#endif
-#if !defined(PORT_OPTIMIZED_DORESCHEDULEI)
- void chSchDoRescheduleI(void);
-#endif
#if !defined(PORT_OPTIMIZED_RESCHEDULES)
void chSchRescheduleS(void);
#endif
-#if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI)
- bool_t chSchIsRescRequiredExI(void);
+#if !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED)
+ bool_t chSchIsPreemptionRequired(void);
+#endif
+#if !defined(PORT_OPTIMIZED_DORESCHEDULE)
+ void chSchDoReschedule(void);
#endif
#ifdef __cplusplus
}
@@ -179,10 +179,37 @@ extern "C" { #if !defined(PORT_OPTIMIZED_DOYIELDS) || defined(__DOXYGEN__)
#define chSchDoYieldS() { \
if (chSchCanYieldS()) \
- chSchDoRescheduleI(); \
+ chSchDoReschedule(); \
}
#endif /* !defined(PORT_OPTIMIZED_DOYIELDS) */
+/**
+ * @brief Inlineable preemption code.
+ * @details This is the common preemption code, this function must be invoked
+ * exclusively from the port layer.
+ *
+ * @special
+ */
+#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
+#define chSchPreemption() { \
+ tprio_t p1 = firstprio(&rlist.r_queue); \
+ tprio_t p2 = currp->p_prio; \
+ if (rlist.r_preempt) { \
+ if (p1 > p2) \
+ chSchDoReschedule(); \
+ } \
+ else { \
+ if (p1 >= p2) \
+ chSchDoReschedule(); \
+ } \
+}
+#else /* CH_TIME_QUANTUM == 0 */
+#define chSchPreemption() { \
+ if (p1 >= p2) \
+ chSchDoReschedule(); \
+}
+#endif /* CH_TIME_QUANTUM == 0 */
+
#endif /* _CHSCHD_H_ */
/** @} */
diff --git a/os/kernel/include/chsys.h b/os/kernel/include/chsys.h index 37d4cd7ce..f807182ac 100644 --- a/os/kernel/include/chsys.h +++ b/os/kernel/include/chsys.h @@ -66,14 +66,19 @@ /**
* @brief Performs a context switch.
- * @note This function should nevel be used from user code directly.
+ * @note Not a user function, it is meant to be invoked by the scheduler
+ * itself or from within the port layer.
*
* @param[in] ntp the thread to be switched in
* @param[in] otp the thread to be switched out
*
* @special
*/
-#define chSysSwitchI(ntp, otp) port_switch(ntp, otp)
+#define chSysSwitch(ntp, otp) { \
+ dbg_trace(otp); \
+ THREAD_CONTEXT_SWITCH_HOOK(ntp, otp); \
+ port_switch(ntp, otp); \
+}
/**
* @brief Raises the system interrupt priority mask to the maximum level.
@@ -83,7 +88,10 @@ *
* @special
*/
-#define chSysDisable() port_disable()
+#define chSysDisable() { \
+ port_disable(); \
+ dbg_check_disable(); \
+}
/**
* @brief Raises the system interrupt priority mask to system level.
@@ -96,7 +104,10 @@ *
* @special
*/
-#define chSysSuspend() port_suspend()
+#define chSysSuspend() { \
+ port_suspend(); \
+ dbg_check_suspend(); \
+}
/**
* @brief Lowers the system interrupt priority mask to user level.
@@ -107,45 +118,30 @@ *
* @special
*/
-#define chSysEnable() port_enable()
+#define chSysEnable() { \
+ dbg_check_enable(); \
+ port_enable(); \
+}
/**
* @brief Enters the kernel lock mode.
- * @note The use of kernel lock mode is not recommended in the user code,
- * it is a better idea to use the semaphores or mutexes instead.
- * @see CH_USE_NESTED_LOCKS
*
* @special
*/
-#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
-#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
-#define chSysLock() { \
- if (currp->p_locks++ == 0) \
- port_lock(); \
+#define chSysLock() { \
+ port_lock(); \
+ dbg_check_lock(); \
}
-#endif /* CH_OPTIMIZE_SPEED */
-#else /* !CH_USE_NESTED_LOCKS */
-#define chSysLock() port_lock()
-#endif /* !CH_USE_NESTED_LOCKS */
/**
* @brief Leaves the kernel lock mode.
- * @note The use of kernel lock mode is not recommended in the user code,
- * it is a better idea to use the semaphores or mutexes instead.
- * @see CH_USE_NESTED_LOCKS
*
* @special
*/
-#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
-#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
-#define chSysUnlock() { \
- if (--currp->p_locks == 0) \
- port_unlock(); \
+#define chSysUnlock() { \
+ dbg_check_unlock(); \
+ port_unlock(); \
}
-#endif /* CH_OPTIMIZE_SPEED */
-#else /* !CH_USE_NESTED_LOCKS */
-#define chSysUnlock() port_unlock()
-#endif /* !CH_USE_NESTED_LOCKS */
/**
* @brief Enters the kernel lock mode from within an interrupt handler.
@@ -159,7 +155,10 @@ *
* @special
*/
-#define chSysLockFromIsr() port_lock_from_isr()
+#define chSysLockFromIsr() { \
+ port_lock_from_isr(); \
+ dbg_check_lock_from_isr(); \
+}
/**
* @brief Leaves the kernel lock mode from within an interrupt handler.
@@ -174,27 +173,42 @@ *
* @special
*/
-#define chSysUnlockFromIsr() port_unlock_from_isr()
+#define chSysUnlockFromIsr() { \
+ dbg_check_unlock_from_isr(); \
+ port_unlock_from_isr(); \
+}
/**
* @brief IRQ handler enter code.
* @note Usually IRQ handlers functions are also declared naked.
* @note On some architectures this macro can be empty.
+ *
+ * @special
*/
-#define CH_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
+#define CH_IRQ_PROLOGUE() { \
+ PORT_IRQ_PROLOGUE(); \
+ dbg_check_enter_isr(); \
+}
/**
* @brief IRQ handler exit code.
* @note Usually IRQ handlers function are also declared naked.
* @note This macro usually performs the final reschedule by using
- * @p chSchRescRequiredI() and @p chSchDoRescheduleI().
+ * @p chSchIsPreemptionRequired() and @p chSchDoReschedule().
+ *
+ * @special
*/
-#define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
+#define CH_IRQ_EPILOGUE() { \
+ dbg_check_leave_isr(); \
+ PORT_IRQ_EPILOGUE(); \
+}
/**
* @brief Standard normal IRQ handler declaration.
* @note @p id can be a function name or a vector number depending on the
* port implementation.
+ *
+ * @special
*/
#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
@@ -203,6 +217,8 @@ * @note @p id can be a function name or a vector number depending on the
* port implementation.
* @note Not all architectures support fast interrupts.
+ *
+ * @special
*/
#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
@@ -211,10 +227,6 @@ extern "C" { #endif
void chSysInit(void);
void chSysTimerHandlerI(void);
-#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED
- void chSysLock(void);
- void chSysUnlock(void);
-#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */
#ifdef __cplusplus
}
#endif
diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h index b02960bd4..a0a668df4 100644 --- a/os/kernel/include/chthreads.h +++ b/os/kernel/include/chthreads.h @@ -75,12 +75,6 @@ struct Thread { */
trefs_t p_refs;
#endif
-#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
- /**
- * @brief Number of nested locks.
- */
- cnt_t p_locks;
-#endif
#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
/**
* @brief Thread consumed time in ticks.
diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 456fc454f..d1aeb75af 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -86,6 +86,7 @@ void chCondSignal(CondVar *cp) { */
void chCondSignalI(CondVar *cp) {
+ chDbgCheckClassI();
chDbgCheck(cp != NULL, "chCondSignalI");
if (notempty(&cp->c_queue))
@@ -120,6 +121,7 @@ void chCondBroadcast(CondVar *cp) { */
void chCondBroadcastI(CondVar *cp) {
+ chDbgCheckClassI();
chDbgCheck(cp != NULL, "chCondBroadcastI");
/* Empties the condition variable queue and inserts all the Threads into the
@@ -177,6 +179,7 @@ msg_t chCondWaitS(CondVar *cp) { Mutex *mp;
msg_t msg;
+ chDbgCheckClassS();
chDbgCheck(cp != NULL, "chCondWaitS");
chDbgAssert(ctp->p_mtxlist != NULL,
"chCondWaitS(), #1",
@@ -261,6 +264,7 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { Mutex *mp;
msg_t msg;
+ chDbgCheckClassS();
chDbgCheck((cp != NULL) && (time != TIME_IMMEDIATE), "chCondWaitTimeoutS");
chDbgAssert(currp->p_mtxlist != NULL,
"chCondWaitTimeoutS(), #1",
diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 0e378cc6d..8fd081c05 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -24,18 +24,191 @@ *
* @addtogroup debug
* @details Debug APIs and services:
+ * - Runtime system state and call protocol check. The following
+ * panic messages can be generated:
+ * - SV#1, misplaced @p chSysDisable().
+ * - SV#2, misplaced @p chSysSuspend()
+ * - SV#3, misplaced @p chSysEnable().
+ * - SV#4, misplaced @p chSysLock().
+ * - SV#5, misplaced @p chSysUnlock().
+ * - SV#6, misplaced @p chSysLockFromIsr().
+ * - SV#7, misplaced @p chSysUnlockFromIsr().
+ * - SV#8, misplaced @p CH_IRQ_PROLOGUE().
+ * - SV#9, misplaced @p CH_IRQ_EPILOGUE().
+ * - SV#10, misplaced I-class function.
+ * - SV#11, misplaced S-class function.
+ * .
* - Trace buffer.
* - Parameters check.
* - Kernel assertions.
+ * - Kernel panics.
* .
- * @pre In order to use the debug APIs the @p CH_DBG_ENABLE_TRACE,
- * @p CH_DBG_ENABLE_ASSERTS, @p CH_DBG_ENABLE_CHECKS options must
- * be enabled in @p chconf.h.
+ * @note Stack checks are not implemented in this module but in the port
+ * layer in an architecture-dependent way.
* @{
*/
#include "ch.h"
+/*===========================================================================*/
+/* System state checker related code and variables. */
+/*===========================================================================*/
+
+#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__)
+
+/**
+ * @brief ISR nesting level.
+ */
+cnt_t dbg_isr_cnt;
+
+/**
+ * @brief Lock nesting level.
+ */
+cnt_t dbg_lock_cnt;
+
+/**
+ * @brief Guard code for @p chSysDisable().
+ *
+ * @notapi
+ */
+void dbg_check_disable(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#1");
+}
+
+/**
+ * @brief Guard code for @p chSysSuspend().
+ *
+ * @notapi
+ */
+void dbg_check_suspend(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#2");
+}
+
+/**
+ * @brief Guard code for @p chSysEnable().
+ *
+ * @notapi
+ */
+void dbg_check_enable(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#3");
+}
+
+/**
+ * @brief Guard code for @p chSysLock().
+ *
+ * @notapi
+ */
+void dbg_check_lock(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#4");
+ dbg_lock_cnt = 1;
+}
+
+/**
+ * @brief Guard code for @p chSysUnlock().
+ *
+ * @notapi
+ */
+void dbg_check_unlock(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0))
+ chDbgPanic("SV#5");
+ dbg_lock_cnt = 0;
+}
+
+/**
+ * @brief Guard code for @p chSysLockFromIsr().
+ *
+ * @notapi
+ */
+void dbg_check_lock_from_isr(void) {
+
+ if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#6");
+ dbg_lock_cnt = 1;
+}
+
+/**
+ * @brief Guard code for @p chSysUnlockFromIsr().
+ *
+ * @notapi
+ */
+void dbg_check_unlock_from_isr(void) {
+
+ if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt <= 0))
+ chDbgPanic("SV#7");
+ dbg_lock_cnt = 0;
+}
+
+/**
+ * @brief Guard code for @p CH_IRQ_PROLOGUE().
+ *
+ * @notapi
+ */
+void dbg_check_enter_isr(void) {
+
+ port_lock_from_isr();
+ if ((dbg_isr_cnt < 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#8");
+ dbg_isr_cnt++;
+ port_unlock_from_isr();
+}
+
+/**
+ * @brief Guard code for @p CH_IRQ_EPILOGUE().
+ *
+ * @notapi
+ */
+void dbg_check_leave_isr(void) {
+
+ port_lock_from_isr();
+ if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#9");
+ dbg_isr_cnt--;
+ port_unlock_from_isr();
+}
+
+/**
+ * @brief I-class functions context check.
+ * @details Verifies that the system is in an appropriate state for invoking
+ * an I-class API function. A panic is generated if the state is
+ * not compatible.
+ *
+ * @api
+ */
+void chDbgCheckClassI(void) {
+
+ if ((dbg_isr_cnt < 0) || (dbg_lock_cnt <= 0))
+ chDbgPanic("SV#10");
+}
+
+/**
+ * @brief S-class functions context check.
+ * @details Verifies that the system is in an appropriate state for invoking
+ * an S-class API function. A panic is generated if the state is
+ * not compatible.
+ *
+ * @api
+ */
+void chDbgCheckClassS(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0))
+ chDbgPanic("SV#11");
+}
+
+#endif /* CH_DBG_SYSTEM_STATE_CHECK */
+
+/*===========================================================================*/
+/* Trace related code and variables. */
+/*===========================================================================*/
+
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
/**
* @brief Public trace buffer.
@@ -59,7 +232,7 @@ void _trace_init(void) { *
* @notapi
*/
-void chDbgTrace(Thread *otp) {
+void dbg_trace(Thread *otp) {
dbg_trace_buffer.tb_ptr->se_time = chTimeNow();
dbg_trace_buffer.tb_ptr->se_tp = currp;
@@ -71,13 +244,15 @@ void chDbgTrace(Thread *otp) { }
#endif /* CH_DBG_ENABLE_TRACE */
-#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
- CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
+/*===========================================================================*/
+/* Panic related code and variables. */
+/*===========================================================================*/
+
+#if CH_DBG_ENABLED || defined(__DOXYGEN__)
/**
* @brief Pointer to the panic message.
* @details This pointer is meant to be accessed through the debugger, it is
- * written once and then the system is halted. This variable can be
- * set to @p NULL if the halt is caused by a stack overflow.
+ * written once and then the system is halted.
*/
char *dbg_panic_msg;
@@ -91,6 +266,6 @@ void chDbgPanic(char *msg) { dbg_panic_msg = msg;
chSysHalt();
}
-#endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */
+#endif /* CH_DBG_ENABLED */
/** @} */
diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index d74ad2dc4..7193e3a12 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -185,6 +185,7 @@ void chEvtSignalFlags(Thread *tp, eventmask_t mask) { */
void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) {
+ chDbgCheckClassI();
chDbgCheck(tp != NULL, "chEvtSignalI");
tp->p_epending |= mask;
@@ -237,6 +238,7 @@ void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) { void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) {
EventListener *elp;
+ chDbgCheckClassI();
chDbgCheck(esp != NULL, "chEvtBroadcastMaskI");
elp = esp->es_next;
diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index af6ee5ea8..bf5fdfe29 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -143,6 +143,7 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
msg_t rdymsg;
+ chDbgCheckClassS();
chDbgCheck(mbp != NULL, "chMBPostS");
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time);
@@ -172,6 +173,7 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { */
msg_t chMBPostI(Mailbox *mbp, msg_t msg) {
+ chDbgCheckClassI();
chDbgCheck(mbp != NULL, "chMBPostI");
if (chSemGetCounterI(&mbp->mb_emptysem) <= 0)
@@ -234,6 +236,7 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
msg_t rdymsg;
+ chDbgCheckClassS();
chDbgCheck(mbp != NULL, "chMBPostAheadS");
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time);
@@ -263,6 +266,7 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { */
msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) {
+ chDbgCheckClassI();
chDbgCheck(mbp != NULL, "chMBPostAheadI");
if (chSemGetCounterI(&mbp->mb_emptysem) <= 0)
@@ -325,6 +329,7 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
msg_t rdymsg;
+ chDbgCheckClassS();
chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchS");
rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, time);
@@ -354,6 +359,7 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { */
msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) {
+ chDbgCheckClassI();
chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI");
if (chSemGetCounterI(&mbp->mb_fullsem) <= 0)
diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 311d170c5..0eac9a429 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -105,6 +105,8 @@ void *chCoreAlloc(size_t size) { void *chCoreAllocI(size_t size) {
void *p;
+ chDbgCheckClassI();
+
size = MEM_ALIGN_NEXT(size);
if ((size_t)(endmem - nextmem) < size)
return NULL;
diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 38adc3d49..767bfda09 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -72,6 +72,7 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { void *chPoolAllocI(MemoryPool *mp) {
void *objp;
+ chDbgCheckClassI();
chDbgCheck(mp != NULL, "chPoolAllocI");
if ((objp = mp->mp_next) != NULL)
@@ -114,6 +115,7 @@ void *chPoolAlloc(MemoryPool *mp) { void chPoolFreeI(MemoryPool *mp, void *objp) {
struct pool_header *php = objp;
+ chDbgCheckClassI();
chDbgCheck((mp != NULL) && (objp != NULL) && MEM_IS_ALIGNED(objp),
"chPoolFreeI");
diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index df71d1cc6..7d5bbe15e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -114,6 +114,7 @@ void chMtxLock(Mutex *mp) { void chMtxLockS(Mutex *mp) {
Thread *ctp = currp;
+ chDbgCheckClassS();
chDbgCheck(mp != NULL, "chMtxLockS");
/* Ia the mutex already locked? */
@@ -157,6 +158,7 @@ void chMtxLockS(Mutex *mp) { #endif
/* Re-enqueues tp with its new priority on the ready list.*/
chSchReadyI(dequeue(tp));
+ break;
}
break;
}
@@ -224,6 +226,7 @@ bool_t chMtxTryLock(Mutex *mp) { */
bool_t chMtxTryLockS(Mutex *mp) {
+ chDbgCheckClassS();
chDbgCheck(mp != NULL, "chMtxTryLockS");
if (mp->m_owner != NULL)
@@ -308,6 +311,7 @@ Mutex *chMtxUnlockS(void) { Thread *ctp = currp;
Mutex *ump, *mp;
+ chDbgCheckClassS();
chDbgAssert(ctp->p_mtxlist != NULL,
"chMtxUnlockS(), #1",
"owned mutexes list empty");
diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 8532f8307..cf3d21732 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -108,6 +108,8 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { */
void chIQResetI(InputQueue *iqp) {
+ chDbgCheckClassI();
+
iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer;
iqp->q_counter = 0;
while (notempty(&iqp->q_waiting))
@@ -129,6 +131,8 @@ void chIQResetI(InputQueue *iqp) { */
msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
+ chDbgCheckClassI();
+
if (chIQIsFullI(iqp))
return Q_FULL;
@@ -284,6 +288,8 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { */
void chOQResetI(OutputQueue *oqp) {
+ chDbgCheckClassI();
+
oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer;
oqp->q_counter = chQSizeI(oqp);
while (notempty(&oqp->q_waiting))
@@ -349,6 +355,8 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { msg_t chOQGetI(OutputQueue *oqp) {
uint8_t b;
+ chDbgCheckClassI();
+
if (chOQIsEmptyI(oqp))
return Q_EMPTY;
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index d41649b4c..f2014b8c7 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -75,7 +75,7 @@ void _scheduler_init(void) { Thread *chSchReadyI(Thread *tp) {
Thread *cp;
- /* Integrity check.*/
+ /* Integrity checks.*/
chDbgAssert((tp->p_state != THD_STATE_READY) &&
(tp->p_state != THD_STATE_FINAL),
"chSchReadyI(), #1",
@@ -107,14 +107,15 @@ Thread *chSchReadyI(Thread *tp) { void chSchGoSleepS(tstate_t newstate) {
Thread *otp;
+ chDbgCheckClassS();
+
(otp = currp)->p_state = newstate;
#if CH_TIME_QUANTUM > 0
rlist.r_preempt = CH_TIME_QUANTUM;
#endif
setcurrp(fifo_remove(&rlist.r_queue));
currp->p_state = THD_STATE_CURRENT;
- chDbgTrace(otp);
- chSysSwitchI(currp, otp);
+ chSysSwitch(currp, otp);
}
#endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */
@@ -174,6 +175,8 @@ static void wakeup(void *p) { */
msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
+ chDbgCheckClassS();
+
if (TIME_INFINITE != time) {
VirtualTimer vt;
@@ -208,6 +211,8 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { #if !defined(PORT_OPTIMIZED_WAKEUPS) || defined(__DOXYGEN__)
void chSchWakeupS(Thread *ntp, msg_t msg) {
+ chDbgCheckClassS();
+
ntp->p_u.rdymsg = msg;
/* If the waken thread has a not-greater priority than the current
one then it is just inserted in the ready list else it made
@@ -222,37 +227,12 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #endif
setcurrp(ntp);
ntp->p_state = THD_STATE_CURRENT;
- chDbgTrace(otp);
- chSysSwitchI(ntp, otp);
+ chSysSwitch(ntp, otp);
}
}
#endif /* !defined(PORT_OPTIMIZED_WAKEUPS) */
/**
- * @brief Switches to the first thread on the runnable queue.
- * @note It is intended to be called if @p chSchRescRequiredI() evaluates
- * to @p TRUE.
- *
- * @iclass
- */
-#if !defined(PORT_OPTIMIZED_DORESCHEDULEI) || defined(__DOXYGEN__)
-void chSchDoRescheduleI(void) {
- Thread *otp;
-
-#if CH_TIME_QUANTUM > 0
- rlist.r_preempt = CH_TIME_QUANTUM;
-#endif
- otp = currp;
- /* Picks the first thread from the ready queue and makes it current.*/
- setcurrp(fifo_remove(&rlist.r_queue));
- currp->p_state = THD_STATE_CURRENT;
- chSchReadyI(otp);
- chDbgTrace(otp);
- chSysSwitchI(currp, otp);
-}
-#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */
-
-/**
* @brief Performs a reschedule if a higher priority thread is runnable.
* @details If a thread with a higher priority than the current thread is in
* the ready list then make the higher priority thread running.
@@ -262,25 +242,28 @@ void chSchDoRescheduleI(void) { #if !defined(PORT_OPTIMIZED_RESCHEDULES) || defined(__DOXYGEN__)
void chSchRescheduleS(void) {
+ chDbgCheckClassS();
+
if (chSchIsRescRequiredI())
- chSchDoRescheduleI();
+ chSchDoReschedule();
}
#endif /* !defined(PORT_OPTIMIZED_RESCHEDULES) */
/**
- * @brief Evaluates if a reschedule is required.
+ * @brief Evaluates if preemption is required.
* @details The decision is taken by comparing the relative priorities and
* depending on the state of the round robin timeout counter.
- * @note This function is meant to be used in the timer interrupt handler
- * where @p chVTDoTickI() is invoked.
+ * @note Not a user function, it is meant to be invoked by the scheduler
+ * itself or from within the port layer.
*
- * @retval TRUE if there is a thread that should go in running state.
- * @retval FALSE if a reschedule is not required.
+ * @retval TRUE if there is a thread that must go in running state
+ * immediately.
+ * @retval FALSE if preemption is not required.
*
- * @iclass
+ * @special
*/
-#if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) || defined(__DOXYGEN__)
-bool_t chSchIsRescRequiredExI(void) {
+#if !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED) || defined(__DOXYGEN__)
+bool_t chSchIsPreemptionRequired(void) {
tprio_t p1 = firstprio(&rlist.r_queue);
tprio_t p2 = currp->p_prio;
#if CH_TIME_QUANTUM > 0
@@ -295,6 +278,29 @@ bool_t chSchIsRescRequiredExI(void) { return p1 > p2;
#endif
}
-#endif /* !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) */
+#endif /* !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED) */
+
+/**
+ * @brief Switches to the first thread on the runnable queue.
+ * @note Not a user function, it is meant to be invoked by the scheduler
+ * itself or from within the port layer.
+ *
+ * @special
+ */
+#if !defined(PORT_OPTIMIZED_DORESCHEDULE) || defined(__DOXYGEN__)
+void chSchDoReschedule(void) {
+ Thread *otp;
+
+#if CH_TIME_QUANTUM > 0
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#endif
+ otp = currp;
+ /* Picks the first thread from the ready queue and makes it current.*/
+ setcurrp(fifo_remove(&rlist.r_queue));
+ currp->p_state = THD_STATE_CURRENT;
+ chSchReadyI(otp);
+ chSysSwitch(currp, otp);
+}
+#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULE) */
/** @} */
diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index c22a568ea..bf985bead 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -129,8 +129,8 @@ void chSemReset(Semaphore *sp, cnt_t n) { void chSemResetI(Semaphore *sp, cnt_t n) {
cnt_t cnt;
+ chDbgCheckClassI();
chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI");
-
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
"chSemResetI(), #1",
@@ -177,8 +177,8 @@ msg_t chSemWait(Semaphore *sp) { */
msg_t chSemWaitS(Semaphore *sp) {
+ chDbgCheckClassS();
chDbgCheck(sp != NULL, "chSemWaitS");
-
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
"chSemWaitS(), #1",
@@ -242,8 +242,8 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { */
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
+ chDbgCheckClassS();
chDbgCheck(sp != NULL, "chSemWaitTimeoutS");
-
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
"chSemWaitTimeoutS(), #1",
@@ -271,7 +271,6 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { void chSemSignal(Semaphore *sp) {
chDbgCheck(sp != NULL, "chSemSignal");
-
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
"chSemSignal(), #1",
@@ -296,8 +295,8 @@ void chSemSignal(Semaphore *sp) { */
void chSemSignalI(Semaphore *sp) {
+ chDbgCheckClassI();
chDbgCheck(sp != NULL, "chSemSignalI");
-
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
"chSemSignalI(), #1",
@@ -327,8 +326,8 @@ void chSemSignalI(Semaphore *sp) { */
void chSemAddCounterI(Semaphore *sp, cnt_t n) {
+ chDbgCheckClassI();
chDbgCheck((sp != NULL) && (n > 0), "chSemAddCounterI");
-
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
"chSemAddCounterI(), #1",
@@ -361,12 +360,10 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg;
chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait");
-
chDbgAssert(((sps->s_cnt >= 0) && isempty(&sps->s_queue)) ||
((sps->s_cnt < 0) && notempty(&sps->s_queue)),
"chSemSignalWait(), #1",
"inconsistent semaphore");
-
chDbgAssert(((spw->s_cnt >= 0) && isempty(&spw->s_queue)) ||
((spw->s_cnt < 0) && notempty(&spw->s_queue)),
"chSemSignalWait(), #2",
diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 4c8cd708d..866ee81a8 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -98,6 +98,8 @@ void chSysInit(void) { setcurrp(_thread_init(&mainthread, NORMALPRIO));
currp->p_state = THD_STATE_CURRENT;
#if CH_DBG_ENABLE_STACK_CHECK
+ /* This is a special case because the main thread Thread structure is not
+ adjacent to its stack area.*/
currp->p_stklimit = &__main_thread_stack_base__;
#endif
chSysEnable();
@@ -126,6 +128,8 @@ void chSysInit(void) { */
void chSysTimerHandlerI(void) {
+ chDbgCheckClassI();
+
#if CH_TIME_QUANTUM > 0
/* Running thread has not used up quantum yet? */
if (rlist.r_preempt > 0)
@@ -141,24 +145,4 @@ void chSysTimerHandlerI(void) { #endif
}
-#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED
-void chSysLock(void) {
-
- chDbgAssert(currp->p_locks >= 0,
- "chSysLock(), #1",
- "negative nesting counter");
- if (currp->p_locks++ == 0)
- port_lock();
-}
-
-void chSysUnlock(void) {
-
- chDbgAssert(currp->p_locks > 0,
- "chSysUnlock(), #1",
- "non-positive nesting counter");
- if (--currp->p_locks == 0)
- port_unlock();
-}
-#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */
-
/** @} */
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 182de7673..19accdb55 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -154,6 +154,8 @@ Thread *chThdCreateI(void *wsp, size_t size, /* Thread structure is layed out in the lower part of the thread workspace */
Thread *tp = wsp;
+ chDbgCheckClassI();
+
chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) &&
(prio <= HIGHPRIO) && (pf != NULL),
"chThdCreateI");
diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 4674c728e..fb8e0b0c1 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -70,6 +70,7 @@ void _vt_init(void) { void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
VirtualTimer *p;
+ chDbgCheckClassI();
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_IMMEDIATE),
"chVTSetI");
@@ -98,6 +99,7 @@ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { */
void chVTResetI(VirtualTimer *vtp) {
+ chDbgCheckClassI();
chDbgCheck(vtp != NULL, "chVTResetI");
chDbgAssert(vtp->vt_func != NULL,
"chVTResetI(), #1",
diff --git a/os/kernel/templates/chconf.h b/os/kernel/templates/chconf.h index c9c4c286a..9dd831c96 100644 --- a/os/kernel/templates/chconf.h +++ b/os/kernel/templates/chconf.h @@ -33,7 +33,10 @@ #define _CHCONF_H_
/*===========================================================================*/
-/* Kernel parameters. */
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
/*===========================================================================*/
/**
@@ -61,21 +64,6 @@ #endif
/**
- * @brief Nested locks.
- * @details If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
- * operations is allowed.<br>
- * For performance and code size reasons the recommended setting
- * is to leave this option disabled.<br>
- * You may use this option if you need to merge ChibiOS/RT with
- * external libraries that require nested lock/unlock operations.
- *
- * @note The default is @p FALSE.
- */
-#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
-#define CH_USE_NESTED_LOCKS FALSE
-#endif
-
-/**
* @brief Managed RAM size.
* @details Size of the RAM area to be managed by the OS. If set to zero
* then the whole available RAM is used. The core memory is made
@@ -107,8 +95,13 @@ #define CH_NO_IDLE_THREAD FALSE
#endif
+/** @} */
+
/*===========================================================================*/
-/* Performance options. */
+/**
+ * @name Performance options
+ * @{
+ */
/*===========================================================================*/
/**
@@ -123,8 +116,13 @@ #define CH_OPTIMIZE_SPEED TRUE
#endif
+/** @} */
+
/*===========================================================================*/
-/* Subsystem options. */
+/**
+ * @name Subsystem options
+ * @{
+ */
/*===========================================================================*/
/**
@@ -346,11 +344,27 @@ #define CH_USE_DYNAMIC TRUE
#endif
+/** @} */
+
/*===========================================================================*/
-/* Debug options. */
+/**
+ * @name Debug options
+ * @{
+ */
/*===========================================================================*/
/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
* @brief Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
* parameters are activated.
@@ -423,8 +437,13 @@ #define CH_DBG_THREADS_PROFILING TRUE
#endif
+/** @} */
+
/*===========================================================================*/
-/* Kernel hooks. */
+/**
+ * @name Kernel hooks
+ * @{
+ */
/*===========================================================================*/
/**
@@ -464,6 +483,16 @@ #endif
/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
+#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/**
* @brief Idle Loop hook.
* @details This hook is continuously invoked by the idle thread loop.
*/
@@ -495,6 +524,8 @@ }
#endif
+/** @} */
+
/*===========================================================================*/
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
diff --git a/os/kernel/templates/chcore.h b/os/kernel/templates/chcore.h index 5c8236c7b..416b3f1aa 100644 --- a/os/kernel/templates/chcore.h +++ b/os/kernel/templates/chcore.h @@ -151,7 +151,7 @@ struct context { #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (PORT_INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/GCC/ARM/chcore.h b/os/ports/GCC/ARM/chcore.h index c2d2892cd..f23048e4c 100644 --- a/os/ports/GCC/ARM/chcore.h +++ b/os/ports/GCC/ARM/chcore.h @@ -249,7 +249,7 @@ struct context { #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (PORT_INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/GCC/ARM/chcoreasm.s b/os/ports/GCC/ARM/chcoreasm.s index 41bd29a90..9b65c14b0 100644 --- a/os/ports/GCC/ARM/chcoreasm.s +++ b/os/ports/GCC/ARM/chcoreasm.s @@ -28,6 +28,9 @@ #include "chconf.h"
+#define FALSE 0
+#define TRUE 1
+
#if !defined(__DOXYGEN__)
.set MODE_USR, 0x10
@@ -143,12 +146,12 @@ _port_switch_arm: * | R0 | |
* | PC | | (user code return address)
* | PSR_USR | -+ (user code status)
- * | .... | <- mk_DoRescheduleI() stack frame, optimize it for space
+ * | .... | <- chSchDoReschedule() stack frame, optimize it for space
* | LR | -+ (system code return address)
* | R11 | |
* | R10 | |
* | R9 | |
- * | R8 | | Internal context: mk_SwitchI() frame
+ * | R8 | | Internal context: chSysSwitch() frame
* | (R7) | | (optional, see CH_CURRP_REGISTER_CACHE)
* | R6 | |
* | R5 | |
@@ -161,7 +164,7 @@ _port_switch_arm: .thumb_func
.globl _port_irq_common
_port_irq_common:
- bl chSchIsRescRequiredExI
+ bl chSchIsPreemptionRequired
mov lr, pc
bx lr
.code 32
@@ -169,7 +172,7 @@ _port_irq_common: .code 32
.globl _port_irq_common
_port_irq_common:
- bl chSchIsRescRequiredExI
+ bl chSchIsPreemptionRequired
#endif /* !THUMB_NO_INTERWORKING */
cmp r0, #0 // Simply returns if a
ldmeqfd sp!, {r0-r3, r12, lr} // reschedule is not
@@ -190,12 +193,24 @@ _port_irq_common: add r0, pc, #1
bx r0
.code 16
- bl chSchDoRescheduleI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchDoReschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
mov lr, pc
bx lr
.code 32
#else /* !THUMB_NO_INTERWORKING */
- bl chSchDoRescheduleI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchDoReschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
#endif /* !THUMB_NO_INTERWORKING */
// Re-establish the IRQ conditions again.
@@ -210,12 +225,18 @@ _port_irq_common: /*
* Threads trampoline code.
- * NOTE: The threads always start in ARM mode then switch to the thread-function mode.
+ * NOTE: The threads always start in ARM mode and then switches to the
+ * thread-function mode.
*/
.balign 16
.code 32
.globl _port_thread_start
_port_thread_start:
+#if CH_DBG_SYSTEM_STATE_CHECK
+ mov r0, #0
+ ldr r1, =dbg_lock_cnt
+ str r0, [r1]
+#endif
msr CPSR_c, #MODE_SYS
#ifndef THUMB_NO_INTERWORKING
mov r0, r5
diff --git a/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xE.ld b/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xE.ld index 7e6b8ee56..2dd7ca7a2 100644 --- a/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xE.ld +++ b/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xE.ld @@ -26,8 +26,8 @@ __process_stack_size__ = 0x0400; MEMORY
{
- flash : org = 0x08000000, len = 1m
- ram : org = 0x20000000, len = 96k
+ flash : org = 0x08000000, len = 512k
+ ram : org = 0x20000000, len = 64k
}
__ram_start__ = ORIGIN(ram);
diff --git a/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xG.ld b/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xG.ld new file mode 100644 index 000000000..a3577b314 --- /dev/null +++ b/os/ports/GCC/ARMCMx/STM32F1xx/ld/STM32F103xG.ld @@ -0,0 +1,144 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * ST32F103xG memory setup.
+ */
+__main_stack_size__ = 0x0400;
+__process_stack_size__ = 0x0400;
+
+MEMORY
+{
+ flash : org = 0x08000000, len = 1m
+ ram : org = 0x20000000, len = 96k
+}
+
+__ram_start__ = ORIGIN(ram);
+__ram_size__ = LENGTH(ram);
+__ram_end__ = __ram_start__ + __ram_size__;
+
+SECTIONS
+{
+ . = 0;
+ _text = .;
+
+ startup : ALIGN(16) SUBALIGN(16)
+ {
+ KEEP(*(vectors))
+ } > flash
+
+ constructors : ALIGN(4) SUBALIGN(4)
+ {
+ PROVIDE(__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE(__init_array_end = .);
+ } > flash
+
+ destructors : ALIGN(4) SUBALIGN(4)
+ {
+ PROVIDE(__fini_array_start = .);
+ KEEP(*(.fini_array))
+ KEEP(*(SORT(.fini_array.*)))
+ PROVIDE(__fini_array_end = .);
+ } > flash
+
+ .text : ALIGN(16) SUBALIGN(16)
+ {
+ *(.text.startup.*)
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.gcc*)
+ } > flash
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > flash
+
+ .ARM.exidx : {
+ PROVIDE(__exidx_start = .);
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ PROVIDE(__exidx_end = .);
+ } > flash
+
+ .eh_frame_hdr :
+ {
+ *(.eh_frame_hdr)
+ } > flash
+
+ .eh_frame : ONLY_IF_RO
+ {
+ *(.eh_frame)
+ } > flash
+
+ . = ALIGN(4);
+ _etext = .;
+ _textdata = _etext;
+
+ .stacks :
+ {
+ . = ALIGN(8);
+ __main_stack_base__ = .;
+ . += __main_stack_size__;
+ . = ALIGN(8);
+ __main_stack_end__ = .;
+ __process_stack_base__ = .;
+ __main_thread_stack_base__ = .;
+ . += __process_stack_size__;
+ . = ALIGN(8);
+ __process_stack_end__ = .;
+ __main_thread_stack_end__ = .;
+ } > ram
+
+ .data :
+ {
+ PROVIDE(_data = .);
+ *(.data)
+ . = ALIGN(4);
+ *(.data.*)
+ . = ALIGN(4);
+ *(.ramtext)
+ . = ALIGN(4);
+ PROVIDE(_edata = .);
+ } > ram AT > flash
+
+ .bss :
+ {
+ PROVIDE(_bss_start = .);
+ *(.bss)
+ . = ALIGN(4);
+ *(.bss.*)
+ . = ALIGN(4);
+ *(COMMON)
+ . = ALIGN(4);
+ PROVIDE(_bss_end = .);
+ } > ram
+}
+
+PROVIDE(end = .);
+_end = .;
+
+__heap_base__ = _end;
+__heap_end__ = __ram_end__;
diff --git a/os/ports/GCC/ARMCMx/STM32F1xx/vectors.c b/os/ports/GCC/ARMCMx/STM32F1xx/vectors.c index d47eeb72e..43faa0ed0 100644 --- a/os/ports/GCC/ARMCMx/STM32F1xx/vectors.c +++ b/os/ports/GCC/ARMCMx/STM32F1xx/vectors.c @@ -25,6 +25,18 @@ * @defgroup ARMCMx_STM32F1xx_VECTORS STM32F1xx Interrupt Vectors
* @ingroup ARMCMx_SPECIFIC
* @details Interrupt vectors for the STM32F1xx family.
+ * One of the following macros must be defined on the
+ * compiler command line or in a file named <tt>board.h</tt>:
+ * - @p STM32F10X_LD
+ * - @p STM32F10X_LD_VL
+ * - @p STM32F10X_MD
+ * - @p STM32F10X_MD_VL
+ * - @p STM32F10X_HD
+ * - @p STM32F10X_XL
+ * - @p STM32F10X_CL
+ * .
+ * This is required in order to include a vectors table with
+ * the correct length for the specified STM32 model.
* @{
*/
diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h index 5d47a6699..944094925 100644 --- a/os/ports/GCC/ARMCMx/chcore.h +++ b/os/ports/GCC/ARMCMx/chcore.h @@ -116,7 +116,7 @@ * separate interrupt stack and the stack space between @p intctx and
* @p extctx is known to be zero.
* @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
+ * @p chSchDoReschedule() can have a stack frame, expecially with
* compiler optimizations disabled.
*/
#ifndef PORT_INT_REQUIRED_STACK
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index 2183a9ded..453bc2c65 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -90,8 +90,8 @@ __attribute__((naked)) #endif
void _port_switch_from_isr(void) {
- if (chSchIsRescRequiredExI())
- chSchDoRescheduleI();
+ if (chSchIsPreemptionRequired())
+ chSchDoReschedule();
#if CORTEX_ALTERNATE_SWITCH
SCB_ICSR = ICSR_PENDSVSET;
port_unlock();
@@ -176,7 +176,7 @@ void _port_irq_epilogue(regarm_t lr) { */
void _port_thread_start(void) {
- port_unlock();
+ chSysUnlock();
asm volatile ("mov r0, r5 \n\t"
"blx r4 \n\t"
"bl chThdExit");
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c index 39711ce79..e8a1ff16e 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.c +++ b/os/ports/GCC/ARMCMx/chcore_v7m.c @@ -141,8 +141,10 @@ __attribute__((naked)) #endif
void _port_switch_from_isr(void) {
- if (chSchIsRescRequiredExI())
- chSchDoRescheduleI();
+ dbg_check_lock();
+ if (chSchIsPreemptionRequired())
+ chSchDoReschedule();
+ dbg_check_unlock();
#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
asm volatile ("svc #0");
#else /* CORTEX_SIMPLIFIED_PRIORITY */
@@ -183,7 +185,7 @@ void _port_switch(Thread *ntp, Thread *otp) { */
void _port_thread_start(void) {
- port_unlock();
+ chSysUnlock();
asm volatile ("mov r0, r5 \n\t"
"blx r4 \n\t"
"bl chThdExit");
diff --git a/os/ports/GCC/ARMCMx/crt0.c b/os/ports/GCC/ARMCMx/crt0.c index 6e4524fa9..e2cb2b3de 100644 --- a/os/ports/GCC/ARMCMx/crt0.c +++ b/os/ports/GCC/ARMCMx/crt0.c @@ -33,6 +33,15 @@ typedef void (*funcp_t)(void);
typedef funcp_t * funcpp_t;
+#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
+
+/*===========================================================================*/
+/**
+ * @name Startup settings
+ * @{
+ */
+/*===========================================================================*/
+
/**
* @brief Control special register initialization value.
* @details The system is setup to run in privileged mode using the PSP
@@ -84,7 +93,13 @@ typedef funcp_t * funcpp_t; #define CRT0_CALL_DESTRUCTORS TRUE
#endif
-#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Symbols from the scatter file
+ */
+/*===========================================================================*/
/**
* @brief Main stack lower boundary.
@@ -94,6 +109,7 @@ typedef funcp_t * funcpp_t; extern uint32_t __main_stack_base__;
/**
+ *
* @brief Main stack initial position.
* @details This symbol must be exported by the linker script and represents
* the main stack initial position.
@@ -168,6 +184,8 @@ extern funcp_t __fini_array_start; */
extern funcp_t __fini_array_end;
+/** @} */
+
/**
* @brief Application @p main() function.
*/
diff --git a/os/ports/GCC/ARMCMx/port.dox b/os/ports/GCC/ARMCMx/port.dox index 8f5efc9aa..13ab36d8a 100644 --- a/os/ports/GCC/ARMCMx/port.dox +++ b/os/ports/GCC/ARMCMx/port.dox @@ -126,19 +126,6 @@ * stack where all the interrupts and exceptions are processed.
* - The threads are started in thread-privileged mode.
* - Interrupt nesting and the other advanced core/NVIC features are supported.
- * - When using an STM32 one of the following macros must be defined on the
- * compiler command line or in a file named <tt>board.h</tt>:
- * - @p STM32F10X_LD
- * - @p STM32F10X_LD_VL
- * - @p STM32F10X_MD
- * - @p STM32F10X_MD_VL
- * - @p STM32F10X_HD
- * - @p STM32F10X_XL
- * - @p STM32F10X_CL
- * .
- * This is required in order to include a vectors table with the correct
- * length for the STM32 model, see the file
- * <tt>./os/ports/GCC/ARMCMx/STM32/vectors.c</tt>.
* - The Cortex-Mx port is perfectly generic, support for more devices can be
* easily added by adding a subdirectory under <tt>./os/ports/GCC/ARMCMx</tt>
* and giving it the name of the new device, then copy the files from another
@@ -211,25 +198,27 @@ * @section ARMCMx_STARTUP_1 Startup Process
* The startup process, as implemented, is the following:
* -# Interrupts are masked globally.
- * -# The two stacks are initialized by assigning them the sizes defined in the
- * linker script (usually named @p ch.ld). Stack areas are allocated from
- * the highest RAM location downward.
+ * -# The two stacks are initialized by assigning them the sizes defined in
+ * the linker script (also known as scatter file).
* -# The CPU state is switched to Privileged and the PSP stack is used.
* -# An early initialization routine @p __early_init() is invoked, if the
* symbol is not defined then an empty default routine is executed
* (weak symbol).
* -# DATA and BSS segments are initialized.
+ * -# Constructors are invoked.
* -# The @p main() function is invoked with no parameters.
- * -# Should the @p main() function return a branch is performed to the weak
- * symbol _main_exit_handler. The default code is an endless empty loop.
+ * -# Destructors are invoked.
+ * -# A branch is performed to the weak symbol @p _default_exit(). The
+ * default code is an endless empty loop.
* .
* @section ARMCMx_STARTUP_2 Expected linker symbols
* The startup code starts at the symbol @p ResetHandler and expects the
* following symbols to be defined in the linker script:
* - @p __ram_end__ End of RAM.
- * - @p __main_stack_size__ Exception stack size.
- * - @p __process_stack_size__ Process stack size. This is the stack area used
- * by the @p main() function.
+ * - @p __main_stack_base__ Main stack lower boundary.
+ * - @p __main_stack_end__ Main stack initial position.
+ * - @p __process_stack_base__ Process stack lower boundary.
+ * - @p __process_stack_end__ Process stack initial position.
* - @p _textdata Address of the data segment source read only data.
* - @p _data Start of the data segment.
* - @p _edata End of the data segment end location.
diff --git a/os/ports/GCC/AVR/chcore.c b/os/ports/GCC/AVR/chcore.c index 7cb0dda07..58663cd9c 100644 --- a/os/ports/GCC/AVR/chcore.c +++ b/os/ports/GCC/AVR/chcore.c @@ -123,7 +123,7 @@ void port_halt(void) { */
void _port_thread_start(void) {
- asm volatile ("sei");
+ chSysUnlock();
asm volatile ("movw r24, r4");
asm volatile ("movw r30, r2");
asm volatile ("icall");
diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h index 2d33b205d..744502825 100644 --- a/os/ports/GCC/AVR/chcore.h +++ b/os/ports/GCC/AVR/chcore.h @@ -142,15 +142,15 @@ struct context { * @details This code usually setup the context switching frame represented
* by an @p intctx structure.
*/
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.sp = (struct intctx*)((uint8_t *)workspace + wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.sp->r2 = (int)pf; \
- tp->p_ctx.sp->r3 = (int)pf >> 8; \
- tp->p_ctx.sp->r4 = (int)arg; \
- tp->p_ctx.sp->r5 = (int)arg >> 8; \
- tp->p_ctx.sp->pcl = (int)_port_thread_start >> 8; \
- tp->p_ctx.sp->pch = (int)_port_thread_start; \
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.sp = (struct intctx*)((uint8_t *)workspace + wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.sp->r2 = (int)pf; \
+ tp->p_ctx.sp->r3 = (int)pf >> 8; \
+ tp->p_ctx.sp->r4 = (int)arg; \
+ tp->p_ctx.sp->r5 = (int)arg >> 8; \
+ tp->p_ctx.sp->pcl = (int)_port_thread_start >> 8; \
+ tp->p_ctx.sp->pch = (int)_port_thread_start; \
}
/**
@@ -185,9 +185,9 @@ struct context { /**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
- (sizeof(struct intctx) - 1) + \
- (sizeof(struct extctx) - 1) + \
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ (sizeof(struct intctx) - 1) + \
+ (sizeof(struct extctx) - 1) + \
(n) + (PORT_INT_REQUIRED_STACK))
/**
@@ -204,9 +204,9 @@ struct context { * @note This code tricks the compiler to save all the specified registers
* by "touching" them.
*/
-#define PORT_IRQ_PROLOGUE() { \
- asm ("" : : : "r18", "r19", "r20", "r21", "r22", "r23", "r24", \
- "r25", "r26", "r27", "r30", "r31"); \
+#define PORT_IRQ_PROLOGUE() { \
+ asm ("" : : : "r18", "r19", "r20", "r21", "r22", "r23", "r24", \
+ "r25", "r26", "r27", "r30", "r31"); \
}
/**
@@ -214,9 +214,11 @@ struct context { * @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() { \
- if (chSchIsRescRequiredExI()) \
- chSchDoRescheduleI(); \
+#define PORT_IRQ_EPILOGUE() { \
+ dbg_check_lock(); \
+ if (chSchIsPreemptionRequired()) \
+ chSchDoReschedule(); \
+ dbg_check_unlock(); \
}
/**
diff --git a/os/ports/GCC/MSP430/chcore.c b/os/ports/GCC/MSP430/chcore.c index d9192177d..ef8ae4967 100644 --- a/os/ports/GCC/MSP430/chcore.c +++ b/os/ports/GCC/MSP430/chcore.c @@ -93,8 +93,8 @@ void port_halt(void) { */
void _port_thread_start(void) {
- asm volatile ("eint \n\t" \
- "mov r11, r15 \n\t" \
+ chSysUnlock();
+ asm volatile ("mov r11, r15 \n\t" \
"call r10 \n\t" \
"call #chThdExit");
}
diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h index 3e3d5b5d1..3fb0f3591 100644 --- a/os/ports/GCC/MSP430/chcore.h +++ b/os/ports/GCC/MSP430/chcore.h @@ -119,13 +119,13 @@ struct context { * @details This code usually setup the context switching frame represented
* by an @p intctx structure.
*/
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.sp = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.sp->r10 = pf; \
- tp->p_ctx.sp->r11 = arg; \
- tp->p_ctx.sp->pc = _port_thread_start; \
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.sp = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.sp->r10 = pf; \
+ tp->p_ctx.sp->r11 = arg; \
+ tp->p_ctx.sp->pc = _port_thread_start; \
}
/**
@@ -159,10 +159,10 @@ struct context { /**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
- sizeof(struct intctx) + \
- sizeof(struct extctx) + \
- (n) + (PORT_INT_REQUIRED_STACK))
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
@@ -183,9 +183,11 @@ struct context { * @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() { \
- if (chSchIsRescRequiredExI()) \
- chSchDoRescheduleI(); \
+#define PORT_IRQ_EPILOGUE() { \
+ dbg_check_lock(); \
+ if (chSchIsPreemptionRequired()) \
+ chSchDoReschedule(); \
+ dbg_check_unlock(); \
}
/**
@@ -220,7 +222,11 @@ struct context { /**
* @brief Kernel-lock action from an interrupt handler.
* @details This function is invoked before invoking I-class APIs from
- * interrupt handlers. The implementation is architecture dependent,
+ * interrupt handlers. The implementation is architecture dependen#define PORT_IRQ_EPILOGUE() { \
+ if (chSchIsPreemptionRequired()) \
+ chSchDoReschedule(); \
+}
+ * t,
* in its simplest form it is void.
* @note This function is empty in this port.
*/
@@ -270,8 +276,8 @@ struct context { */
#if ENABLE_WFI_IDLE != 0
#ifndef port_wait_for_interrupt
-#define port_wait_for_interrupt() { \
- asm volatile ("nop" : : : "memory"); \
+#define port_wait_for_interrupt() { \
+ asm volatile ("nop" : : : "memory"); \
}
#endif
#else
diff --git a/os/ports/GCC/PPC/SPC56x/ivor.s b/os/ports/GCC/PPC/SPC56x/ivor.s index 7f470d26a..f572db1b5 100644 --- a/os/ports/GCC/PPC/SPC56x/ivor.s +++ b/os/ports/GCC/PPC/SPC56x/ivor.s @@ -25,8 +25,13 @@ * @addtogroup PPC_CORE
* @{
*/
-/** @cond never */
+#include "chconf.h"
+
+#define FALSE 0
+#define TRUE 1
+
+#if !defined(__DOXYGEN__)
/*
* INTC registers address.
*/
@@ -71,12 +76,15 @@ IVOR10: lis %r3, 0x0800 /* DIS bit mask. */
mtspr 336, %r3 /* TSR register. */
- /* System tick handler invokation.*/
+ /* System tick handler invocation.*/
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
bl chSysTimerHandlerI
- bl chSchIsRescRequiredExI
+ bl chSchIsPreemptionRequired
cmpli cr0, %r3, 0
beq cr0, .ctxrestore
- bl chSchDoRescheduleI
+ bl chSchDoReschedule
b .ctxrestore
/*
@@ -138,13 +146,19 @@ IVOR4: stw %r3, 0(%r3) /* Writing any value should do. */
/* Verifies if a reschedule is required.*/
- bl chSchIsRescRequiredExI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchIsPreemptionRequired
cmpli cr0, %r3, 0
beq cr0, .ctxrestore
- bl chSchDoRescheduleI
+ bl chSchDoReschedule
/* Context restore.*/
.ctxrestore:
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
lwz %r3, 36(%sp) /* Restores GPR3...GPR12. */
lwz %r4, 40(%sp)
lwz %r5, 44(%sp)
@@ -171,5 +185,6 @@ IVOR4: addi %sp, %sp, 80 /* Back to the previous frame. */
rfi
-/** @endcond */
+#endif /* !defined(__DOXYGEN__) */
+
/** @} */
diff --git a/os/ports/GCC/PPC/chcore.c b/os/ports/GCC/PPC/chcore.c index c68d5e07c..7fb5dd578 100644 --- a/os/ports/GCC/PPC/chcore.c +++ b/os/ports/GCC/PPC/chcore.c @@ -81,7 +81,8 @@ void port_switch(Thread *ntp, Thread *otp) { * invoked.
*/
void _port_thread_start(void) {
- asm ("wrteei 1");
+
+ chSysUnlock();
asm ("mr %r3, %r31"); /* Thread parameter. */
asm ("mtctr %r30");
asm ("bctrl"); /* Invoke thread function. */
diff --git a/os/ports/GCC/PPC/chcore.h b/os/ports/GCC/PPC/chcore.h index 6504532ac..01b31bbb7 100644 --- a/os/ports/GCC/PPC/chcore.h +++ b/os/ports/GCC/PPC/chcore.h @@ -221,10 +221,10 @@ struct context { /**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
- sizeof(struct intctx) + \
- sizeof(struct extctx) + \
- (n) + (PORT_INT_REQUIRED_STACK))
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
@@ -307,8 +307,8 @@ struct context { */
#if ENABLE_WFI_IDLE != 0
#ifndef port_wait_for_interrupt
-#define port_wait_for_interrupt() { \
- asm volatile ("wait" : : : "memory"); \
+#define port_wait_for_interrupt() { \
+ asm volatile ("wait" : : : "memory"); \
}
#endif
#else
diff --git a/os/ports/GCC/SIMIA32/chcore.h b/os/ports/GCC/SIMIA32/chcore.h index 3d5c62b23..2a9d3d452 100644 --- a/os/ports/GCC/SIMIA32/chcore.h +++ b/os/ports/GCC/SIMIA32/chcore.h @@ -144,7 +144,7 @@ struct context { sizeof(void *) * 4 + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (PORT_INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* Macro used to allocate a thread working area aligned as both position and
diff --git a/os/ports/IAR/ARMCMx/STM32/cmparams.h b/os/ports/IAR/ARMCMx/STM32F1xx/cmparams.h index 3e18146c0..8f9795822 100644 --- a/os/ports/IAR/ARMCMx/STM32/cmparams.h +++ b/os/ports/IAR/ARMCMx/STM32F1xx/cmparams.h @@ -19,13 +19,13 @@ */
/**
- * @file IAR/ARMCMx/STM32/cmparams.h
- * @brief ARM Cortex-M3 parameters for the STM32.
+ * @file IAR/ARMCMx/STM32F1xx/cmparams.h
+ * @brief ARM Cortex-M3 parameters for the STM32F1xx.
*
- * @defgroup IAR_ARMCMx_STM32 STM32 Specific Parameters
+ * @defgroup IAR_ARMCMx_STM32F1xx STM32F1xx Specific Parameters
* @ingroup IAR_ARMCMx_SPECIFIC
* @details This file contains the Cortex-M3 specific parameters for the
- * STM32 platform.
+ * STM32F1xx platform.
* @{
*/
diff --git a/os/ports/IAR/ARMCMx/STM32/vectors.s b/os/ports/IAR/ARMCMx/STM32F1xx/vectors.s index 85c889267..85c889267 100644 --- a/os/ports/IAR/ARMCMx/STM32/vectors.s +++ b/os/ports/IAR/ARMCMx/STM32F1xx/vectors.s diff --git a/os/ports/IAR/ARMCMx/chcore.h b/os/ports/IAR/ARMCMx/chcore.h index 5eff85f51..c3e91cc02 100644 --- a/os/ports/IAR/ARMCMx/chcore.h +++ b/os/ports/IAR/ARMCMx/chcore.h @@ -116,7 +116,7 @@ * separate interrupt stack and the stack space between @p intctx and
* @p extctx is known to be zero.
* @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
+ * @p chSchDoReschedule() can have a stack frame, expecially with
* compiler optimizations disabled.
*/
#ifndef PORT_INT_REQUIRED_STACK
diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.h b/os/ports/IAR/ARMCMx/chcore_v6m.h index a25fde1ef..0480451c0 100644 --- a/os/ports/IAR/ARMCMx/chcore_v6m.h +++ b/os/ports/IAR/ARMCMx/chcore_v6m.h @@ -240,7 +240,7 @@ struct intctx { #define port_switch(ntp, otp) _port_switch(ntp, otp)
#else
#define port_switch(ntp, otp) { \
- if ((void *)(__get_SP() - sizeof(struct intctx)) < (void *)(otp + 1)) \
+ if ((stkalign_t *)(__get_SP() - sizeof(struct intctx)) < otp->p_stklimit) \
chDbgPanic("stack overflow"); \
_port_switch(ntp, otp); \
}
diff --git a/os/ports/IAR/ARMCMx/chcore_v7m.h b/os/ports/IAR/ARMCMx/chcore_v7m.h index 059f29711..086a99d39 100644 --- a/os/ports/IAR/ARMCMx/chcore_v7m.h +++ b/os/ports/IAR/ARMCMx/chcore_v7m.h @@ -306,7 +306,7 @@ struct intctx { #define port_switch(ntp, otp) _port_switch(ntp, otp)
#else
#define port_switch(ntp, otp) { \
- if ((void *)(__get_SP() - sizeof(struct intctx)) < (void *)(otp + 1)) \
+ if ((stkalign_t *)(__get_SP() - sizeof(struct intctx)) < otp->p_stklimit) \
chDbgPanic("stack overflow"); \
_port_switch(ntp, otp); \
}
diff --git a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s index a05ce3aa1..56e62d16f 100644 --- a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s +++ b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s @@ -37,8 +37,12 @@ SCB_ICSR SET 0xE000ED04 SECTION .text:CODE:NOROOT(2)
EXTERN chThdExit
- EXTERN chSchIsRescRequiredExI
- EXTERN chSchDoRescheduleI
+ EXTERN chSchIsPreemptionRequired
+ EXTERN chSchDoReschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ EXTERN dbg_check_unlock
+ EXTERN dbg_check_lock
+#endif
THUMB
@@ -70,6 +74,9 @@ _port_switch: */
PUBLIC _port_thread_start
_port_thread_start:
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
cpsie i
mov r0, r5
blx r4
@@ -110,11 +117,17 @@ PendSVVector: */
PUBLIC _port_switch_from_isr
_port_switch_from_isr:
- bl chSchIsRescRequiredExI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchIsPreemptionRequired
cmp r0, #0
beq noresch
- bl chSchDoRescheduleI
+ bl chSchDoReschedule
noresch:
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
ldr r2, =SCB_ICSR
movs r3, #128
#if CORTEX_ALTERNATE_SWITCH
diff --git a/os/ports/IAR/ARMCMx/chcoreasm_v7m.s b/os/ports/IAR/ARMCMx/chcoreasm_v7m.s index 8367fcdb0..4c40babc5 100644 --- a/os/ports/IAR/ARMCMx/chcoreasm_v7m.s +++ b/os/ports/IAR/ARMCMx/chcoreasm_v7m.s @@ -39,8 +39,12 @@ ICSR_PENDSVSET SET 0x10000000 SECTION .text:CODE:NOROOT(2)
EXTERN chThdExit
- EXTERN chSchIsRescRequiredExI
- EXTERN chSchDoRescheduleI
+ EXTERN chSchIsPreemptionRequired
+ EXTERN chSchDoReschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ EXTERN dbg_check_unlock
+ EXTERN dbg_check_lock
+#endif
THUMB
@@ -60,6 +64,9 @@ _port_switch: */
PUBLIC _port_thread_start
_port_thread_start:
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
#if CORTEX_SIMPLIFIED_PRIORITY
cpsie i
#else
@@ -76,10 +83,16 @@ _port_thread_start: */
PUBLIC _port_switch_from_isr
_port_switch_from_isr:
- bl chSchIsRescRequiredExI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchIsPreemptionRequired
cbz r0, .L2
- bl chSchDoRescheduleI
+ bl chSchDoReschedule
.L2:
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
#if CORTEX_SIMPLIFIED_PRIORITY
mov r3, #LWRD SCB_ICSR
movt r3, #HWRD SCB_ICSR
diff --git a/os/ports/RC/STM8/chcore.c b/os/ports/RC/STM8/chcore.c index d7034e38a..a45f4c27f 100644 --- a/os/ports/RC/STM8/chcore.c +++ b/os/ports/RC/STM8/chcore.c @@ -54,8 +54,8 @@ void _port_switch(Thread *otp) { */
void _port_thread_start(void) {
+ chSysUnlock();
#pragma ASM
- RIM
POPW X
#pragma ENDASM
}
diff --git a/os/ports/RC/STM8/chcore.h b/os/ports/RC/STM8/chcore.h index 07b7fa0b6..c8c2ebb16 100644 --- a/os/ports/RC/STM8/chcore.h +++ b/os/ports/RC/STM8/chcore.h @@ -206,8 +206,10 @@ struct stm8_startctx { * enabled to invoke system APIs.
*/
#define PORT_IRQ_EPILOGUE() { \
- if (chSchIsRescRequiredExI()) \
- chSchDoRescheduleI(); \
+ dbg_check_lock(); \
+ if (chSchIsPreemptionRequired()) \
+ chSchDoReschedule(); \
+ dbg_check_unlock(); \
}
/**
diff --git a/os/ports/RVCT/ARMCMx/STM32/cmparams.h b/os/ports/RVCT/ARMCMx/STM32F1xx/cmparams.h index 73a3f2357..2bd7715a4 100644 --- a/os/ports/RVCT/ARMCMx/STM32/cmparams.h +++ b/os/ports/RVCT/ARMCMx/STM32F1xx/cmparams.h @@ -19,13 +19,13 @@ */
/**
- * @file RVCT/ARMCMx/STM32/cmparams.h
- * @brief ARM Cortex-M3 parameters for the STM32.
+ * @file RVCT/ARMCMx/STM32F1xx/cmparams.h
+ * @brief ARM Cortex-M3 parameters for the STM32F1xx.
*
- * @defgroup RVCT_ARMCMx_STM32 STM32 Specific Parameters
+ * @defgroup RVCT_ARMCMx_STM32F1xx STM32F1xx Specific Parameters
* @ingroup RVCT_ARMCMx_SPECIFIC
* @details This file contains the Cortex-M3 specific parameters for the
- * STM32 platform.
+ * STM32F1xx platform.
* @{
*/
diff --git a/os/ports/RVCT/ARMCMx/STM32/vectors.s b/os/ports/RVCT/ARMCMx/STM32F1xx/vectors.s index 330f34bf8..330f34bf8 100644 --- a/os/ports/RVCT/ARMCMx/STM32/vectors.s +++ b/os/ports/RVCT/ARMCMx/STM32F1xx/vectors.s diff --git a/os/ports/RVCT/ARMCMx/chcore.h b/os/ports/RVCT/ARMCMx/chcore.h index 42b397e93..7c4e82613 100644 --- a/os/ports/RVCT/ARMCMx/chcore.h +++ b/os/ports/RVCT/ARMCMx/chcore.h @@ -116,7 +116,7 @@ * separate interrupt stack and the stack space between @p intctx and
* @p extctx is known to be zero.
* @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
+ * @p chSchDoReschedule() can have a stack frame, expecially with
* compiler optimizations disabled.
*/
#ifndef PORT_INT_REQUIRED_STACK
@@ -227,6 +227,7 @@ struct intctx { /**
* @brief Platform dependent part of the @p Thread structure.
+
* @details In this port the structure just holds a pointer to the @p intctx
* structure representing the stack pointer at context switch time.
*/
diff --git a/os/ports/RVCT/ARMCMx/chcore_v6m.h b/os/ports/RVCT/ARMCMx/chcore_v6m.h index 7241d462f..bdeec1674 100644 --- a/os/ports/RVCT/ARMCMx/chcore_v6m.h +++ b/os/ports/RVCT/ARMCMx/chcore_v6m.h @@ -240,8 +240,8 @@ struct intctx { #define port_switch(ntp, otp) _port_switch(ntp, otp)
#else
#define port_switch(ntp, otp) { \
- struct intctx *r13 = (struct intctx *)__current_sp(); \
- if ((void *)(r13 - 1) < (void *)(otp + 1)) \
+ uint8_t *r13 = (uint8_t *)__current_sp(); \
+ if ((stkalign_t *)(r13 - sizeof(struct intctx)) < otp->p_stklimit) \
chDbgPanic("stack overflow"); \
_port_switch(ntp, otp); \
}
diff --git a/os/ports/RVCT/ARMCMx/chcore_v7m.h b/os/ports/RVCT/ARMCMx/chcore_v7m.h index fdf855f77..17447476f 100644 --- a/os/ports/RVCT/ARMCMx/chcore_v7m.h +++ b/os/ports/RVCT/ARMCMx/chcore_v7m.h @@ -314,8 +314,8 @@ struct intctx { #define port_switch(ntp, otp) _port_switch(ntp, otp)
#else
#define port_switch(ntp, otp) { \
- struct intctx *r13 = (struct intctx *)__current_sp(); \
- if ((void *)(r13 - 1) < (void *)(otp + 1)) \
+ uint8_t *r13 = (uint8_t *)__current_sp(); \
+ if ((stkalign_t *)(r13 - sizeof(struct intctx)) < otp->p_stklimit) \
chDbgPanic("stack overflow"); \
_port_switch(ntp, otp); \
}
diff --git a/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s b/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s index 579680421..83878805e 100644 --- a/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s +++ b/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s @@ -34,8 +34,12 @@ SCB_ICSR EQU 0xE000ED04 AREA |.text|, CODE, READONLY
IMPORT chThdExit
- IMPORT chSchIsRescRequiredExI
- IMPORT chSchDoRescheduleI
+ IMPORT chSchIsPreemptionRequired
+ IMPORT chSchDoReschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ IMPORT dbg_check_unlock
+ IMPORT dbg_check_lock
+#endif
/*
* Performs a context switch between two threads.
@@ -66,6 +70,9 @@ _port_switch PROC */
EXPORT _port_thread_start
_port_thread_start PROC
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
cpsie i
mov r0, r5
blx r4
@@ -109,11 +116,17 @@ PendSVVector PROC */
EXPORT _port_switch_from_isr
_port_switch_from_isr PROC
- bl chSchIsRescRequiredExI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchIsPreemptionRequired
cmp r0, #0
- beq noresch
- bl chSchDoRescheduleI
-noresch
+ beq noreschedule
+ bl chSchDoReschedule
+noreschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
ldr r2, =SCB_ICSR
movs r3, #128
#if CORTEX_ALTERNATE_SWITCH
diff --git a/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s b/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s index f6acf2968..6be194737 100644 --- a/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s +++ b/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s @@ -36,8 +36,12 @@ ICSR_PENDSVSET EQU 0x10000000 AREA |.text|, CODE, READONLY
IMPORT chThdExit
- IMPORT chSchIsRescRequiredExI
- IMPORT chSchDoRescheduleI
+ IMPORT chSchIsPreemptionRequired
+ IMPORT chSchDoReschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ IMPORT dbg_check_unlock
+ IMPORT dbg_check_lock
+#endif
/*
* Performs a context switch between two threads.
@@ -56,6 +60,9 @@ _port_switch PROC */
EXPORT _port_thread_start
_port_thread_start PROC
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
#if CORTEX_SIMPLIFIED_PRIORITY
cpsie i
#else
@@ -73,10 +80,16 @@ _port_thread_start PROC */
EXPORT _port_switch_from_isr
_port_switch_from_isr PROC
- bl chSchIsRescRequiredExI
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_lock
+#endif
+ bl chSchIsPreemptionRequired
cbz r0, noreschedule
- bl chSchDoRescheduleI
+ bl chSchDoReschedule
noreschedule
+#if CH_DBG_SYSTEM_STATE_CHECK
+ bl dbg_check_unlock
+#endif
#if CORTEX_SIMPLIFIED_PRIORITY
mov r3, #SCB_ICSR :AND: 0xFFFF
movt r3, #SCB_ICSR :SHR: 16
diff --git a/os/ports/cosmic/STM8/chcore.c b/os/ports/cosmic/STM8/chcore.c index c5f1de2d6..3c1807330 100644 --- a/os/ports/cosmic/STM8/chcore.c +++ b/os/ports/cosmic/STM8/chcore.c @@ -50,8 +50,8 @@ void _port_switch(Thread *otp) { */
void _port_thread_start(void) {
- _asm(" rim \n"
- " popw x \n");
+ chSysUnlock();
+ _asm(" popw x \n");
}
/**
diff --git a/os/ports/cosmic/STM8/chcore.h b/os/ports/cosmic/STM8/chcore.h index 93a4c24f0..9073592aa 100644 --- a/os/ports/cosmic/STM8/chcore.h +++ b/os/ports/cosmic/STM8/chcore.h @@ -203,8 +203,10 @@ struct stm8_startctx { * enabled to invoke system APIs.
*/
#define PORT_IRQ_EPILOGUE() { \
- if (chSchIsRescRequiredExI()) \
- chSchDoRescheduleI(); \
+ dbg_check_lock(); \
+ if (chSchIsPreemptionRequired()) \
+ chSchDoReschedule(); \
+ dbg_check_unlock(); \
}
/**
|