diff --git a/hal/common/retarget.cpp b/hal/common/retarget.cpp index 78cab09f57..9fbc27b784 100644 --- a/hal/common/retarget.cpp +++ b/hal/common/retarget.cpp @@ -88,6 +88,10 @@ FileHandle::~FileHandle() { #if DEVICE_SERIAL extern int stdio_uart_inited; extern serial_t stdio_uart; +#if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES +static char stdio_in_prev; +static char stdio_out_prev; +#endif #endif static void init_serial() { @@ -226,9 +230,19 @@ extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsign if (fh < 3) { #if DEVICE_SERIAL if (!stdio_uart_inited) init_serial(); +#if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES + for (unsigned int i = 0; i < length; i++) { + if (buffer[i] == '\n' && stdio_out_prev != '\r') { + serial_putc(&stdio_uart, '\r'); + } + serial_putc(&stdio_uart, buffer[i]); + stdio_out_prev = buffer[i]; + } +#else for (unsigned int i = 0; i < length; i++) { serial_putc(&stdio_uart, buffer[i]); } +#endif #endif n = length; } else { @@ -254,7 +268,28 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int // only read a character at a time from stdin #if DEVICE_SERIAL if (!stdio_uart_inited) init_serial(); +#if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES + while (true) { + char c = serial_getc(&stdio_uart); + if ((c == '\r' && stdio_in_prev != '\n') || + (c == '\n' && stdio_in_prev != '\r')) { + stdio_in_prev = c; + *buffer = '\n'; + break; + } else if ((c == '\r' && stdio_in_prev == '\n') || + (c == '\n' && stdio_in_prev == '\r')) { + stdio_in_prev = c; + // onto next character + continue; + } else { + stdio_in_prev = c; + *buffer = c; + break; + } + } +#else *buffer = serial_getc(&stdio_uart); +#endif #endif n = 1; } else { diff --git a/hal/targets.json b/hal/targets.json index ce5b4af00a..7b567743a8 100644 --- a/hal/targets.json +++ b/hal/targets.json @@ -535,7 +535,14 @@ "progen": {"target": "frdm-k64f"}, "detect_code": ["0240"], "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "STORAGE"], - "features": ["IPV4"] + "features": ["IPV4"], + "config": { + "storage_driver_mode": { + "help": "Configuration parameter to select flash storage driver mode. 1 => async operation, 0 => sync operation", + "macro_name": "STORAGE_DRIVER_CONFIG_HARDWARE_MTD_ASYNC_OPS", + "value": 1 + } + } }, "MTS_GAMBIT": { "inherits": ["Target"], @@ -569,7 +576,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f030r8"}, "detect_code": ["0725"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "default_build": "small" }, "NUCLEO_F031K6": { @@ -605,7 +612,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f070rb"}, "detect_code": ["0755"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "default_build": "small" }, "NUCLEO_F072RB": { @@ -617,7 +624,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f072rb"}, "detect_code": ["0730"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "default_build": "small" }, "NUCLEO_F091RC": { @@ -629,7 +636,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f091rc"}, "detect_code": ["0750"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "default_build": "small" }, "NUCLEO_F103RB": { diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/storage_driver.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/storage_driver.c index e98f14ee40..79c757ed65 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/storage_driver.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/storage_driver.c @@ -212,10 +212,10 @@ static const ARM_STORAGE_CAPABILITIES caps = { * 1, drivers may still complete asynchronous operations synchronously as * necessary--in which case they return a positive error code to indicate * synchronous completion. */ -#ifndef YOTTA_CFG_CONFIG_HARDWARE_MTD_ASYNC_OPS +#ifndef STORAGE_DRIVER_CONFIG_HARDWARE_MTD_ASYNC_OPS .asynchronous_ops = 1, #else - .asynchronous_ops = YOTTA_CFG_CONFIG_HARDWARE_MTD_ASYNC_OPS, + .asynchronous_ops = STORAGE_DRIVER_CONFIG_HARDWARE_MTD_ASYNC_OPS, #endif /* Enable chip-erase functionality if we own all of block-1. */ diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/lp_ticker.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/lp_ticker.c new file mode 100644 index 0000000000..7c3be3588b --- /dev/null +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/lp_ticker.c @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "device.h" + +#if DEVICE_LOWPOWERTIMER + +#include "ticker_api.h" +#include "lp_ticker_api.h" +#include "rtc_api.h" +#include "rtc_api_hal.h" + +static uint8_t lp_ticker_inited = 0; +static uint8_t lp_ticker_reconf_presc = 0; + +void lp_ticker_init() { + if (lp_ticker_inited) return; + lp_ticker_inited = 1; + + rtc_init(); + rtc_set_irq_handler((uint32_t) lp_ticker_irq_handler); +} + +uint32_t lp_ticker_read() { + uint32_t sub_secs, milis; + time_t time; + + lp_ticker_init(); + + time = rtc_read(); + sub_secs = rtc_read_subseconds(); + milis = 1000 - (sub_secs * 1000 / rtc_ticker_get_synch_presc()); + + return (time * 1000000) + (milis * 1000); +} + +void lp_ticker_set_interrupt(timestamp_t timestamp) { + uint32_t sub_secs, delta, milis; + time_t secs; + struct tm *timeinfo; + + // Reconfigure RTC prescalers whenever the timestamp is below 30ms + if (!lp_ticker_reconf_presc && timestamp < 30000) { + rtc_reconfigure_prescalers(); + lp_ticker_reconf_presc = 1; + } + + milis = (timestamp % 1000000) / 1000; + + secs = rtc_read(); + delta = ((timestamp / 1000000) - secs); + + secs += delta; + sub_secs = (rtc_ticker_get_synch_presc() * (1000 - milis)) / 1000; + timeinfo = localtime(&secs); + + rtc_set_alarm(timeinfo, sub_secs); +} + +void lp_ticker_disable_interrupt() { + lp_ticker_reconf_presc = 0; + rtc_ticker_disable_irq(); +} + +void lp_ticker_clear_interrupt() { +} + +#endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c index 0cdf7cbf26..67db9a9990 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c @@ -28,6 +28,9 @@ ******************************************************************************* */ #include "rtc_api.h" +#include "rtc_api_hal.h" +#include "stm32f0xx.h" +#include "stm32f0xx_hal_rtc_ex.h" #if DEVICE_RTC @@ -39,6 +42,57 @@ static int rtc_inited = 0; static RTC_HandleTypeDef RtcHandle; +#if DEVICE_LOWPOWERTIMER +static uint32_t m_synch_prediv = RTC_SYNCH_PREDIV; +static uint32_t m_asynch_prediv = RTC_ASYNCH_PREDIV; + +static void (*irq_handler)(void); + +static void rtc_configure_time_and_date() +{ + RTC_TimeTypeDef mTime; + RTC_DateTypeDef mDate; + + mDate.WeekDay = 1; + mDate.Month = 1; + mDate.Date = 1; + mDate.Year = 1970; + if (HAL_RTC_SetDate(&RtcHandle, &mDate, RTC_FORMAT_BIN) != HAL_OK) { + error("Date set failed\n"); + } + + mTime.Hours = 0; + mTime.Minutes = 0; + mTime.Seconds = 0; + mTime.TimeFormat = RTC_HOURFORMAT12_AM; + mTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + mTime.StoreOperation = RTC_STOREOPERATION_RESET; + if (HAL_RTC_SetTime(&RtcHandle, &mTime, RTC_FORMAT_BIN) != HAL_OK) { + error("Time set failed\n"); + } +} + +void RTC_IRQHandler() +{ + HAL_RTC_AlarmIRQHandler(&RtcHandle); +} + +void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) +{ + if (irq_handler) + { + // Fire the user callback + irq_handler(); + } +} + +void rtc_set_irq_handler(uint32_t handler) +{ + irq_handler = (void (*)(void)) handler; +} + +#endif + void rtc_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct; uint32_t rtc_freq = 0; @@ -92,8 +146,14 @@ void rtc_init(void) { __HAL_RCC_RTC_ENABLE(); RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; +#if !DEVICE_LOWPOWERTIMER RtcHandle.Init.AsynchPrediv = 127; RtcHandle.Init.SynchPrediv = (rtc_freq / 128) - 1; +#else + RtcHandle.Init.AsynchPrediv = m_asynch_prediv; + RtcHandle.Init.SynchPrediv = m_synch_prediv; +#endif + RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; @@ -101,6 +161,12 @@ void rtc_init(void) { if (HAL_RTC_Init(&RtcHandle) != HAL_OK) { error("RTC error: RTC initialization failed."); } + +#if DEVICE_LOWPOWERTIMER + rtc_configure_time_and_date(); + NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC_IRQHandler); + HAL_NVIC_EnableIRQ(RTC_IRQn); +#endif } void rtc_free(void) { @@ -177,7 +243,12 @@ time_t rtc_read(void) { timeinfo.tm_wday = dateStruct.WeekDay; timeinfo.tm_mon = dateStruct.Month - 1; timeinfo.tm_mday = dateStruct.Date; +#if DEVICE_LOWPOWERTIMER + //We need to add 52 to get the 1970 year + timeinfo.tm_year = dateStruct.Year + 52; +#else timeinfo.tm_year = dateStruct.Year + 100; +#endif timeinfo.tm_hour = timeStruct.Hours; timeinfo.tm_min = timeStruct.Minutes; timeinfo.tm_sec = timeStruct.Seconds; @@ -215,4 +286,48 @@ void rtc_write(time_t t) { HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN); } +#if DEVICE_LOWPOWERTIMER +void rtc_set_alarm(struct tm *ti, uint32_t subsecs) +{ + RTC_AlarmTypeDef mAlarm; + + mAlarm.AlarmTime.Hours = ti->tm_hour; + mAlarm.AlarmTime.Minutes = ti->tm_min; + mAlarm.AlarmTime.Seconds = ti->tm_sec; + mAlarm.AlarmTime.SubSeconds = subsecs; + mAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM; + mAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; + mAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE; + mAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; + mAlarm.AlarmDateWeekDay = 1; + mAlarm.Alarm = RTC_ALARM_A; + + if (HAL_RTC_SetAlarm_IT(&RtcHandle, &mAlarm, RTC_FORMAT_BIN) != HAL_OK) { + error("Set Alarm failed\n"); + } +} + +void rtc_reconfigure_prescalers() +{ + m_synch_prediv = 0x3FF; + m_asynch_prediv = 0x1F; + rtc_init(); +} + +uint32_t rtc_ticker_get_synch_presc() +{ + return m_synch_prediv; +} + +uint32_t rtc_read_subseconds() +{ + return RTC->SSR; +} + +void rtc_ticker_disable_irq() +{ + HAL_RTC_DeactivateAlarm(&RtcHandle, RTC_ALARM_A); +} +#endif // DEVICE_LOWPOWERTIMER + #endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api_hal.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api_hal.h new file mode 100644 index 0000000000..790e6dc937 --- /dev/null +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api_hal.h @@ -0,0 +1,61 @@ +/* mbed Microcontroller Library +******************************************************************************* +* Copyright (c) 2016, STMicroelectronics +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +******************************************************************************* +*/ + +#ifndef MBED_RTC_API_HAL_H +#define MBED_RTC_API_HAL_H + +#include +#include "rtc_api.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Extend rtc_api.h + */ + +// Prescaler values for LSE clock +#define RTC_ASYNCH_PREDIV 0x7F +#define RTC_SYNCH_PREDIV 0x00FF + +void rtc_set_irq_handler(uint32_t handler); + +void rtc_ticker_disable_irq(); +uint32_t rtc_ticker_get_synch_presc(); + +void rtc_set_alarm(struct tm *ti, uint32_t subsecs); +uint32_t rtc_read_subseconds(); +void rtc_reconfigure_prescalers(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mbed_lib.json b/mbed_lib.json new file mode 100644 index 0000000000..50cd29aa75 --- /dev/null +++ b/mbed_lib.json @@ -0,0 +1,9 @@ +{ + "name": "core", + "config": { + "stdio-convert-newlines": { + "help": "Enable conversion to standard newlines on stdin/stdout", + "value": false + } + } +} diff --git a/tools/config.py b/tools/config.py index 2263dd9ab1..80cfad70ea 100644 --- a/tools/config.py +++ b/tools/config.py @@ -35,9 +35,8 @@ class ConfigParameter: def __init__(self, name, data, unit_name, unit_kind): self.name = self.get_full_name(name, unit_name, unit_kind, allow_prefix = False) self.defined_by = self.get_display_name(unit_name, unit_kind) - self.set_by = self.defined_by + self.set_value(data.get("value", None), unit_name, unit_kind) self.help_text = data.get("help", None) - self.value = data.get("value", None) self.required = data.get("required", False) self.macro_name = data.get("macro_name", "MBED_CONF_%s" % self.sanitize(self.name.upper())) self.config_errors = [] @@ -93,13 +92,14 @@ class ConfigParameter: def sanitize(name): return name.replace('.', '_').replace('-', '_') - # Sets a value for this parameter, remember the place where it was set + # Sets a value for this parameter, remember the place where it was set. + # If the value is a boolean, it is converted to 1 (for True) or to 0 (for False). # value: the value of the parameter # unit_name: the unit (target/library/application) that defines this parameter # unit_ kind: the kind of the unit ("target", "library" or "application") # label: the name of the label in the 'target_config_overrides' section (optional) def set_value(self, value, unit_name, unit_kind, label = None): - self.value = value + self.value = int(value) if isinstance(value, bool) else value self.set_by = self.get_display_name(unit_name, unit_kind, label) # Return the string representation of this configuration parameter @@ -233,7 +233,7 @@ class Config: # Remove features from the available features def add_features(self, features): for feature in features: - if (feature in self.removed_features + if (feature in self.removed_features or (self.removed_unecessary_features and feature not in self.added_features)): raise ConfigException("Configuration conflict. Feature %s both added and removed." % feature) @@ -273,7 +273,7 @@ class Config: if full_name in params: params[full_name].set_value(v, unit_name, unit_kind, label) else: - self.config_errors.append(ConfigException("Attempt to override undefined parameter '%s' in '%s'" + self.config_errors.append(ConfigException("Attempt to override undefined parameter '%s' in '%s'" % (full_name, ConfigParameter.get_display_name(unit_name, unit_kind, label)))) return params @@ -396,7 +396,7 @@ class Config: raise self.config_errors[0] return True - + # Loads configuration data from resources. Also expands resources based on defined features settings def load_resources(self, resources): # Update configuration files until added features creates no changes @@ -418,7 +418,7 @@ class Config: self.validate_config() return resources - + # Return the configuration data converted to the content of a C header file, # meant to be included to a C/C++ file. The content is returned as a string. diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 65d76a8923..b78540231e 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -210,7 +210,6 @@ LEGACY_TOOLCHAIN_NAMES = { class mbedToolchain: VERBOSE = True - ignorepatterns = [] CORTEX_SYMBOLS = { "Cortex-M0" : ["__CORTEX_M0", "ARM_MATH_CM0", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], @@ -230,48 +229,70 @@ class mbedToolchain: def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): self.target = target self.name = self.__class__.__name__ + + # compile/assemble/link/binary hooks self.hook = hooks.Hook(target, self) - self.silent = silent - self.output = "" + # Build options passed by -o flag + self.options = options if options is not None else [] + self.options.extend(BUILD_OPTIONS) + if self.options: + self.info("Build Options: %s" % (', '.join(self.options))) + + # Toolchain flags + self.flags = deepcopy(self.DEFAULT_FLAGS) + + # User-defined macros + self.macros = macros or [] + + # Macros generated from toolchain and target rules/features + self.symbols = None + + # Labels generated from toolchain and target rules/features (used for selective build) + self.labels = None + + self.has_config = False + # config_header_content will hold the content of the config header (if used) + self.config_header_content = None + + # Non-incremental compile + self.build_all = False + + # Build output dir + self.build_dir = None + self.timestamp = time() + + # Output build naming based on target+toolchain combo (mbed 2.0 builds) + self.obj_path = join("TARGET_"+target.name, "TOOLCHAIN_"+self.name) + + # Number of concurrent build jobs. 0 means auto (based on host system cores) + self.jobs = 0 + + self.CHROOT = None + + # Ignore patterns from .mbedignore files + self.ignore_patterns = [] + + # Pre-mbed 2.0 ignore dirs self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]]) + # Output notify function if notify: self.notify_fun = notify elif extra_verbose: self.notify_fun = self.print_notify_verbose else: self.notify_fun = self.print_notify - - self.options = options if options is not None else [] - - self.macros = macros or [] - self.options.extend(BUILD_OPTIONS) - if self.options: - self.info("Build Options: %s" % (', '.join(self.options))) - - self.obj_path = join("TARGET_"+target.name, "TOOLCHAIN_"+self.name) - - self.symbols = None - self.labels = None - self.has_config = False - - self.build_all = False - self.build_dir = None - self.timestamp = time() - self.jobs = 1 - - self.CHROOT = None - - self.mp_pool = None - + + # Silent builds (no output) + self.silent = silent + + # Print output buffer + self.output = "" + + # uVisor spepcific rules if 'UVISOR' in self.target.features and 'UVISOR_SUPPORTED' in self.target.extra_labels: self.target.core = re.sub(r"F$", '', self.target.core) - - self.flags = deepcopy(self.DEFAULT_FLAGS) - - # config_header_content will hold the content of the config header (if used) - self.config_header_content = None def get_output(self): return self.output @@ -325,10 +346,6 @@ class mbedToolchain: """ return self.notify_fun(event, self.silent) - def __exit__(self): - if self.mp_pool is not None: - self.mp_pool.terminate() - def goanna_parse_line(self, line): if "analyze" in self.options: return self.GOANNA_DIAGNOSTIC_PATTERN.match(line) @@ -407,7 +424,7 @@ class mbedToolchain: return False def is_ignored(self, file_path): - for pattern in self.ignorepatterns: + for pattern in self.ignore_patterns: if fnmatch.fnmatch(file_path, pattern): return True return False @@ -441,33 +458,30 @@ class mbedToolchain: lines = [l.strip() for l in lines] # Strip whitespaces lines = [l for l in lines if l != ""] # Strip empty lines lines = [l for l in lines if not re.match("^#",l)] # Strip comment lines - # Append root path to glob patterns - # and append patterns to ignorepatterns - self.ignorepatterns.extend([join(root,line.strip()) for line in lines]) + # Append root path to glob patterns and append patterns to ignore_patterns + self.ignore_patterns.extend([join(root,line.strip()) for line in lines]) for d in copy(dirs): dir_path = join(root, d) if d == '.hg': resources.repo_dirs.append(dir_path) resources.repo_files.extend(self.scan_repository(dir_path)) - + if ((d.startswith('.') or d in self.legacy_ignore_dirs) or + # Ignore targets that do not match the TARGET in extra_labels list (d.startswith('TARGET_') and d[7:] not in labels['TARGET']) or + # Ignore toolchain that do not match the current TOOLCHAIN (d.startswith('TOOLCHAIN_') and d[10:] not in labels['TOOLCHAIN']) or + # Ignore .mbedignore files + self.is_ignored(join(dir_path,"")) or + # Ignore TESTS dir (d == 'TESTS')): dirs.remove(d) - - if (d.startswith('FEATURE_')): + elif d.startswith('FEATURE_'): + # Recursively scan features but ignore them in the current scan. These are dynamically added by the config system if the conditions are matched resources.features[d[8:]] = self.scan_resources(dir_path, base_path=base_path) dirs.remove(d) - - # Remove dirs that already match the ignorepatterns - # to avoid travelling into them and to prevent them - # on appearing in include path. - if self.is_ignored(join(dir_path,"")): - dirs.remove(d) - - if exclude_paths: + elif exclude_paths: for exclude_path in exclude_paths: rel_path = relpath(dir_path, exclude_path) if not (rel_path.startswith('..')):