diff --git a/.shippable.yml b/.shippable.yml index ff6883c339f5a..22bf2ce298b1f 100644 --- a/.shippable.yml +++ b/.shippable.yml @@ -27,6 +27,7 @@ build: ci: - export CCACHE_DIR=${SHIPPABLE_BUILD_DIR}/ccache/.ccache - export COMMIT_RANGE=${SHIPPABLE_COMMIT_RANGE} + - echo ${SHIPPABLE_COMMIT_RANGE} - source zephyr-env.sh - ccache -s --max-size=2000M - make host-tools diff --git a/arch/arm/core/isr_wrapper.S b/arch/arm/core/isr_wrapper.S index 28b3f6ead94ff..04bee7060fd30 100644 --- a/arch/arm/core/isr_wrapper.S +++ b/arch/arm/core/isr_wrapper.S @@ -43,6 +43,10 @@ SECTION_FUNC(TEXT, _isr_wrapper) push {lr} /* lr is now the first item on the stack */ +#ifdef CONFIG_EXECUTION_BENCHMARKING + bl read_systick_start_of_isr +#endif + #ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT bl _sys_k_event_logger_interrupt #endif @@ -105,6 +109,20 @@ _idle_state_cleared: * in thumb mode */ ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */ +#ifdef CONFIG_EXECUTION_BENCHMARKING +#if defined(CONFIG_ARMV6_M) + push {r3} +#endif + push {lr} + bl read_systick_end_of_isr +#if defined(CONFIG_ARMV6_M) + pop {r3} + mov lr,r3 + pop {r3} +#else + pop {lr} +#endif +#endif blx r3 /* call ISR */ #if defined(CONFIG_ARMV6_M) diff --git a/arch/arm/core/swap.S b/arch/arm/core/swap.S index e24a53d6b576d..b0ff7634b78e9 100644 --- a/arch/arm/core/swap.S +++ b/arch/arm/core/swap.S @@ -177,6 +177,23 @@ _thread_irq_disabled: msr PSP, ip +#ifdef CONFIG_EXECUTION_BENCHMARKING +#if defined(CONFIG_ARMV6_M) + push {r3} +#endif + push {lr} + + bl read_systick_end_of_swap + +#if defined(CONFIG_ARMV6_M) + pop {r3} + mov lr,r3 + pop {r3} +#else + pop {lr} +#endif +#endif + /* exc return */ bx lr @@ -292,6 +309,20 @@ _oops: SECTION_FUNC(TEXT, __swap) +#ifdef CONFIG_EXECUTION_BENCHMARKING +#if defined(CONFIG_ARMV6_M) + push {r3} +#endif + push {lr} + bl read_systick_start_of_swap +#if defined(CONFIG_ARMV6_M) + pop {r3} + mov lr,r3 + pop {r3} +#else + pop {lr} +#endif +#endif ldr r1, =_kernel ldr r2, [r1, #_kernel_offset_to_current] str r0, [r2, #_thread_offset_to_basepri] diff --git a/arch/arm/soc/arm/mps2/soc_devices.h b/arch/arm/soc/arm/mps2/soc_devices.h index 5afa2b6171a43..e87e0698986a9 100644 --- a/arch/arm/soc/arm/mps2/soc_devices.h +++ b/arch/arm/soc/arm/mps2/soc_devices.h @@ -58,6 +58,13 @@ #define CMSDK_APB_DUALTIMER_IRQ IRQ_DUAL_TIMER #endif /* CONFIG_COUNTER */ +#if defined(CONFIG_I2C_SBCON) +#define I2C_SBCON_0_BASE_ADDR I2C_TOUCH_BASE_ADDR +#define I2C_SBCON_1_BASE_ADDR I2C_AUDIO_CONF_BASE_ADDR +#define I2C_SBCON_2_BASE_ADDR I2C_SHIELD0_BASE_ADDR +#define I2C_SBCON_3_BASE_ADDR I2C_SHIELD1_BASE_ADDR +#endif + #ifndef _ASMLANGUAGE #include "soc_registers.h" diff --git a/arch/arm/soc/arm/mps2/soc_memory_map.h b/arch/arm/soc/arm/mps2/soc_memory_map.h index 4fd95234dad49..a80ea8c19c6bd 100644 --- a/arch/arm/soc/arm/mps2/soc_memory_map.h +++ b/arch/arm/soc/arm/mps2/soc_memory_map.h @@ -35,6 +35,10 @@ #define UART_4_BASE_ADDR (MPS2_APB_BASE_ADDR + 0x9000) /* MPS2 peripherals in FPGA APB subsystem */ -#define FPGAIO_BASE_ADDR (MPS2_FPGA_APB_BASE_ADDR + 0x8000) +#define I2C_TOUCH_BASE_ADDR (MPS2_FPGA_APB_BASE_ADDR + 0x2000) +#define I2C_AUDIO_CONF_BASE_ADDR (MPS2_FPGA_APB_BASE_ADDR + 0x3000) +#define FPGAIO_BASE_ADDR (MPS2_FPGA_APB_BASE_ADDR + 0x8000) +#define I2C_SHIELD0_BASE_ADDR (MPS2_FPGA_APB_BASE_ADDR + 0x9000) +#define I2C_SHIELD1_BASE_ADDR (MPS2_FPGA_APB_BASE_ADDR + 0xa000) #endif /* _SOC_MEMORY_MAP_H_ */ diff --git a/arch/arm/soc/atmel_sam/Kconfig b/arch/arm/soc/atmel_sam/Kconfig index 759f70525c702..1988dd2005ab0 100644 --- a/arch/arm/soc/atmel_sam/Kconfig +++ b/arch/arm/soc/atmel_sam/Kconfig @@ -4,10 +4,5 @@ # SPDX-License-Identifier: Apache-2.0 # -config SOC_ATMEL_SAM3 - bool - depends on ARM - default n - # Select SoC Part No. and configuration options source "arch/arm/soc/atmel_sam/*/Kconfig.soc" diff --git a/arch/arm/soc/atmel_sam/Kconfig.defconfig b/arch/arm/soc/atmel_sam/Kconfig.defconfig index 1f5550b230c4d..bdddffc438751 100644 --- a/arch/arm/soc/atmel_sam/Kconfig.defconfig +++ b/arch/arm/soc/atmel_sam/Kconfig.defconfig @@ -16,7 +16,7 @@ config SOC_FAMILY default atmel_sam config WATCHDOG - def_bool y if !SOC_ATMEL_SAM3X8E + def_bool y endif #SOC_FAMILY_SAM diff --git a/arch/arm/soc/atmel_sam/sam3x/Kconfig.defconfig.series b/arch/arm/soc/atmel_sam/sam3x/Kconfig.defconfig.series index 30159e2ebf0d6..8ed2fecfcf417 100644 --- a/arch/arm/soc/atmel_sam/sam3x/Kconfig.defconfig.series +++ b/arch/arm/soc/atmel_sam/sam3x/Kconfig.defconfig.series @@ -6,7 +6,7 @@ # SPDX-License-Identifier: Apache-2.0 # -if SOC_SERIES_SAM3X || SOC_ATMEL_SAM3X8E +if SOC_SERIES_SAM3X config SOC_SERIES string @@ -14,7 +14,7 @@ config SOC_SERIES config SOC_PART_NUMBER string - default sam3x8e if SOC_PART_NUMBER_SAM3X8E || SOC_ATMEL_SAM3X8E + default sam3x8e if SOC_PART_NUMBER_SAM3X8E config NUM_IRQ_PRIO_BITS int @@ -42,66 +42,19 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC # to provide one continuous 96K block. # config SRAM_SIZE - default 96 if SOC_PART_NUMBER_SAM3X8E || SOC_ATMEL_SAM3X8E + default 96 if SOC_PART_NUMBER_SAM3X8E config SRAM_BASE_ADDRESS - default 0x20000000 if !SOC_PART_NUMBER_SAM3X8E && !SOC_ATMEL_SAM3X8E - default 0x20070000 if SOC_PART_NUMBER_SAM3X8E || SOC_ATMEL_SAM3X8E + default 0x20000000 if !SOC_PART_NUMBER_SAM3X8E + default 0x20070000 if SOC_PART_NUMBER_SAM3X8E # # Atmel SAM3X family has flash starting @ 0x00080000. # config FLASH_SIZE - default 512 if SOC_PART_NUMBER_SAM3X8E || SOC_ATMEL_SAM3X8E + default 512 if SOC_PART_NUMBER_SAM3X8E config FLASH_BASE_ADDRESS default 0x00080000 -if UART_ATMEL_SAM3 - -config UART_ATMEL_SAM3_BAUD_RATE - default 115200 - -config UART_ATMEL_SAM3_CLK_FREQ - default 84000000 - -endif # UART_ATMEL_SAM3 - -if GPIO - -config GPIO_ATMEL_SAM3 - def_bool y - -config GPIO_ATMEL_SAM3_PORTA - default y - -config GPIO_ATMEL_SAM3_PORTB - default y - -config GPIO_ATMEL_SAM3_PORTC - default y - -config GPIO_ATMEL_SAM3_PORTD - default y - -endif # GPIO - -if I2C - -config I2C_ATMEL_SAM3 - def_bool y - -config I2C_0 - default y -config I2C_0_IRQ_PRI - default 0 - -config I2C_1 - default y - -config I2C_1_IRQ_PRI - default 0 - -endif # I2C - endif # SOC_SERIES_SAM3X diff --git a/arch/arm/soc/atmel_sam/sam3x/Kconfig.series b/arch/arm/soc/atmel_sam/sam3x/Kconfig.series index 59bb0f4ea8672..9d77cb7a8e814 100644 --- a/arch/arm/soc/atmel_sam/sam3x/Kconfig.series +++ b/arch/arm/soc/atmel_sam/sam3x/Kconfig.series @@ -16,13 +16,3 @@ config SOC_SERIES_SAM3X help Enable support for Atmel SAM3X Cortex-M3 microcontrollers. Part No.: SAM3X8E - -config SOC_ATMEL_SAM3X8E - bool "Atmel SAM3X8E Processor" - select SOC_PART_NUMBER_SAM3X8E - select CPU_CORTEX_M - select CPU_CORTEX_M3 - select SOC_FAMILY_SAM - select SYS_POWER_LOW_POWER_STATE_SUPPORTED - select CPU_HAS_SYSTICK - select SOC_ATMEL_SAM3 diff --git a/arch/arm/soc/atmel_sam/sam3x/Kconfig.soc b/arch/arm/soc/atmel_sam/sam3x/Kconfig.soc index 06bf046725faa..1277d9e53b9c5 100644 --- a/arch/arm/soc/atmel_sam/sam3x/Kconfig.soc +++ b/arch/arm/soc/atmel_sam/sam3x/Kconfig.soc @@ -15,7 +15,7 @@ choice bool "SAM3X8E" endchoice -if SOC_SERIES_SAM3X || SOC_ATMEL_SAM3X8E +if SOC_SERIES_SAM3X config SOC_ATMEL_SAM3X_EXT_SLCK bool "Atmel SAM3 to use external crystal oscillator for slow clock" @@ -75,7 +75,7 @@ config SOC_ATMEL_SAM3X_PLLA_DIVA config SOC_ATMEL_SAM3X_WAIT_MODE bool "Atmel SAM3 goes to Wait mode instead of Sleep mode" - depends on SOC_ATMEL_SAM3_EXT_MAINCK + depends on SOC_ATMEL_SAM3X_EXT_MAINCK default y if DEBUG help For JTAG debugging CPU clock (HCLK) should not stop. In order diff --git a/arch/arm/soc/atmel_sam/sam3x/soc.c b/arch/arm/soc/atmel_sam/sam3x/soc.c index 1e8b01fb400e3..98215571a1b52 100644 --- a/arch/arm/soc/atmel_sam/sam3x/soc.c +++ b/arch/arm/soc/atmel_sam/sam3x/soc.c @@ -50,7 +50,7 @@ static ALWAYS_INLINE void clock_init(void) /* Wait for oscillator to be stablized */ while (!(__SUPC->sr & SUPC_SR_OSCSEL)) ; -#endif /* CONFIG_SOC_ATMEL_SAM3_EXT_SLCK */ +#endif /* CONFIG_SOC_ATMEL_SAM3X_EXT_SLCK */ #ifdef CONFIG_SOC_ATMEL_SAM3X_EXT_MAINCK /* Start the external main oscillator */ @@ -88,7 +88,7 @@ static ALWAYS_INLINE void clock_init(void) /* Wait for main fast RC oscillator to be stablized */ while (!(__PMC->sr & PMC_INT_MOSCRCS)) ; -#endif /* CONFIG_SOC_ATMEL_SAM3_EXT_MAINCK */ +#endif /* CONFIG_SOC_ATMEL_SAM3X_EXT_MAINCK */ /* Use PLLA as master clock. * According to datasheet, PMC_MCKR must not be programmed in diff --git a/arch/x86/core/intstub.S b/arch/x86/core/intstub.S index 55bede1f743f9..9c6edbfa28b9a 100644 --- a/arch/x86/core/intstub.S +++ b/arch/x86/core/intstub.S @@ -78,6 +78,15 @@ */ SECTION_FUNC(TEXT, _interrupt_enter) +#ifdef CONFIG_EXECUTION_BENCHMARKING + pushl %eax + pushl %edx + rdtsc + mov %eax, __start_intr_tsc + mov %edx, __start_intr_tsc+4 + pop %edx + pop %eax +#endif /* * The gen_idt tool creates an interrupt-gate descriptor for * all connections. The processor will automatically clear the IF @@ -246,6 +255,19 @@ alreadyOnIntStack: */ push %eax #endif +#ifdef CONFIG_EXECUTION_BENCHMARKING + /* Save the eax and edx registers before reading the time stamp + * once done pop the values + */ + pushl %eax + pushl %edx + rdtsc + mov %eax,__end_intr_tsc + mov %edx,__end_intr_tsc+4 + pop %edx + pop %eax +#endif + #ifdef CONFIG_NESTED_INTERRUPTS sti /* re-enable interrupts */ #endif diff --git a/arch/x86/core/swap.S b/arch/x86/core/swap.S index 6c931637382cf..8687ebec49a6c 100644 --- a/arch/x86/core/swap.S +++ b/arch/x86/core/swap.S @@ -77,7 +77,28 @@ * */ +.macro read_tsc var_name + push %eax + push %edx + rdtsc + mov %eax,\var_name + mov %edx,\var_name+4 + pop %edx + pop %eax +.endm SECTION_FUNC(TEXT, __swap) +#ifdef CONFIG_EXECUTION_BENCHMARKING + /* Save the eax and edx registers before reading the time stamp + * once done pop the values. + */ + push %eax + push %edx + rdtsc + mov %eax,__start_swap_tsc + mov %edx,__start_swap_tsc+4 + pop %edx + pop %eax +#endif #ifdef CONFIG_X86_IAMCU /* save EFLAGS on stack right before return address, just as SYSV would * have done @@ -335,5 +356,16 @@ skipIntLatencyStop: */ popl %edx movl %edx, (%esp) +#endif + +#ifdef CONFIG_EXECUTION_BENCHMARKING + /* Save the eax and edx registers before reading the time stamp + * once done pop the values. + */ + cmp $0x1,__read_swap_end_tsc_value + jne time_read_not_needed + movw $0x2,__read_swap_end_tsc_value + read_tsc __common_var_swap_end_tsc +time_read_not_needed: #endif ret diff --git a/boards/arm/arduino_due/Kconfig.board b/boards/arm/arduino_due/Kconfig.board index 552742e6fb6bf..5818773a88228 100644 --- a/boards/arm/arduino_due/Kconfig.board +++ b/boards/arm/arduino_due/Kconfig.board @@ -1,4 +1,9 @@ +# Kconfig - Arduino Due Board configuration +# +# Copyright (c) 2017 Justin Watson +# SPDX-License-Identifier: Apache-2.0 +# config BOARD_ARDUINO_DUE bool "Arduino Due Board" - depends on SOC_ATMEL_SAM3X8E + depends on SOC_PART_NUMBER_SAM3X8E diff --git a/boards/arm/arduino_due/Kconfig.defconfig b/boards/arm/arduino_due/Kconfig.defconfig index 952d4e0d3e2c6..b5d1d0ebcacd2 100644 --- a/boards/arm/arduino_due/Kconfig.defconfig +++ b/boards/arm/arduino_due/Kconfig.defconfig @@ -1,14 +1,59 @@ +# Kconfig - Arduino Due Board configuration +# +# Copyright (c) 2017 Justin Watson +# SPDX-License-Identifier: Apache-2.0 +# if BOARD_ARDUINO_DUE config BOARD default arduino_due +if UART_ATMEL_SAM3 + +config UART_ATMEL_SAM3_BAUD_RATE + default 115200 + +config UART_ATMEL_SAM3_CLK_FREQ + default 84000000 + +endif # UART_ATMEL_SAM3 + +if GPIO + +config GPIO_ATMEL_SAM3 + def_bool y + +config GPIO_ATMEL_SAM3_PORTA + default y + +config GPIO_ATMEL_SAM3_PORTB + default y + +config GPIO_ATMEL_SAM3_PORTC + default y + +config GPIO_ATMEL_SAM3_PORTD + default y + +endif # GPIO + if I2C config I2C_ATMEL_SAM3 + def_bool y + +config I2C_0 + default y +config I2C_0_IRQ_PRI + default 0 + +config I2C_1 default y +config I2C_1_IRQ_PRI + default 0 + endif # I2C endif # BOARD_ARDUINO_DUE diff --git a/boards/arm/arduino_due/arduino_due_defconfig b/boards/arm/arduino_due/arduino_due_defconfig index 625064ef5be85..73b61fd8844a3 100644 --- a/boards/arm/arduino_due/arduino_due_defconfig +++ b/boards/arm/arduino_due/arduino_due_defconfig @@ -1,10 +1,13 @@ CONFIG_ARM=y -CONFIG_SOC_ATMEL_SAM3X8E=y +CONFIG_SOC_FAMILY_SAM=y +CONFIG_SOC_SERIES_SAM3X=y +CONFIG_SOC_PART_NUMBER_SAM3X8E=y CONFIG_BOARD_ARDUINO_DUE=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_ATMEL_SAM3=y -CONFIG_SOC_ATMEL_SAM3_EXT_MAINCK=y +CONFIG_SOC_ATMEL_SAM3X_EXT_MAINCK=y CONFIG_PINMUX=y +CONFIG_WATCHDOG=n diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig b/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig index 63e0d7409836d..2863475c4324b 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig @@ -55,4 +55,3 @@ CONFIG_I2C_STM32LX=y #configure HTS221 sensor CONFIG_HTS221_I2C_MASTER_DEV_NAME="I2C_2" CONFIG_HTS221_TRIGGER_NONE=y -CONFIG_HTS221_I2C_ADDR=0x5F diff --git a/boards/arm/mps2_an385/Kconfig.defconfig b/boards/arm/mps2_an385/Kconfig.defconfig index 1ada42a138931..f8cf08b0d396d 100644 --- a/boards/arm/mps2_an385/Kconfig.defconfig +++ b/boards/arm/mps2_an385/Kconfig.defconfig @@ -105,4 +105,35 @@ endif # TIMER_DTMR_CMSDK_APB endif # COUNTER +if I2C + +config I2C_SBCON + def_bool y + +config I2C_SBCON_0 + def_bool y + +config I2C_SBCON_0_NAME + default I2C_TOUCH + +config I2C_SBCON_1 + def_bool y + +config I2C_SBCON_1_NAME + default I2C_AUDIO_CONF + +config I2C_SBCON_2 + def_bool y + +config I2C_SBCON_2_NAME + default I2C_SHIELD0 + +config I2C_SBCON_3 + def_bool y + +config I2C_SBCON_3_NAME + default I2C_SHIELD1 + +endif # I2C + endif diff --git a/boards/arm/mps2_an385/mps2_an385_defconfig b/boards/arm/mps2_an385/mps2_an385_defconfig index 2a1485df4a8d3..427e50246df48 100644 --- a/boards/arm/mps2_an385/mps2_an385_defconfig +++ b/boards/arm/mps2_an385/mps2_an385_defconfig @@ -28,3 +28,5 @@ CONFIG_UART_CONSOLE_ON_DEV_NAME="UART_0" # Watchdog CONFIG_WATCHDOG=y + +CONFIG_I2C=y \ No newline at end of file diff --git a/boards/arm/stm3210c_eval/support/openocd.cfg b/boards/arm/stm3210c_eval/support/openocd.cfg index bcf95398b28e2..afa40b0c66725 100644 --- a/boards/arm/stm3210c_eval/support/openocd.cfg +++ b/boards/arm/stm3210c_eval/support/openocd.cfg @@ -1,4 +1,4 @@ -source [find board/st3210c_eval.cfg] +source [find board/stm3210c_eval.cfg] $_TARGETNAME configure -event gdb-attach { echo "Debugger attaching: halting execution" diff --git a/drivers/gpio/Kconfig.atmel_sam3 b/drivers/gpio/Kconfig.atmel_sam3 index 8413a8b606ce0..584b6aef0c171 100644 --- a/drivers/gpio/Kconfig.atmel_sam3 +++ b/drivers/gpio/Kconfig.atmel_sam3 @@ -8,7 +8,7 @@ menuconfig GPIO_ATMEL_SAM3 bool "Atmel SAM3 PIO Controllers" - depends on GPIO && SOC_ATMEL_SAM3 + depends on GPIO && SOC_SERIES_SAM3X default n help Enable config options to support the PIO controllers diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index f8f869395aabd..9b4993892f9ed 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -45,12 +45,11 @@ config I2C_QMSI provided by the QMSI BSP. config I2C_ATMEL_SAM3 - bool "Atmel SAM3 I2C Driver" - depends on SOC_ATMEL_SAM3 + bool "Atmel SAM3X I2C Driver" + depends on SOC_SERIES_SAM3X default n help Enable I2C support on the Atmel SAM3 family processor. - Says y to enable additional options to enable support for individual controllers. @@ -111,6 +110,8 @@ config I2C_BITBANG help Enable library used for software driven (bit banging) I2C support +source "drivers/i2c/Kconfig.sbcon" + source "drivers/i2c/Kconfig.gpio" config I2C_INIT_PRIORITY diff --git a/drivers/i2c/Kconfig.sbcon b/drivers/i2c/Kconfig.sbcon new file mode 100644 index 0000000000000..10241711604f2 --- /dev/null +++ b/drivers/i2c/Kconfig.sbcon @@ -0,0 +1,51 @@ +# +# Copyright (c) 2016 Linaro Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig I2C_SBCON + bool "I2C driver for ARM's SBCon two-wire serial bus interface" + depends on I2C + select I2C_BITBANG + default n + +if I2C_SBCON + +config I2C_SBCON_0 + bool "Enable SBCon device 0" + default n + +config I2C_SBCON_0_NAME + depends on I2C_SBCON_0 + string "SBCon device 0 Device Name" + default "SBCON_0" + +config I2C_SBCON_1 + bool "Enable SBCon device 1" + default n + +config I2C_SBCON_1_NAME + depends on I2C_SBCON_1 + string "SBCon device 1 Device Name" + default "SBCON_1" + +config I2C_SBCON_2 + bool "Enable SBCon device 2" + default n + +config I2C_SBCON_2_NAME + depends on I2C_SBCON_2 + string "SBCon device 2 Device Name" + default "SBCON_2" + +config I2C_SBCON_3 + bool "Enable SBCon device 3" + default n + +config I2C_SBCON_3_NAME + depends on I2C_SBCON_3 + string "SBCon device 0 Device Name" + default "SBCON_3" + +endif diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index b3db3e81d31cb..c998d3cfd9386 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_I2C_MCUX) += i2c_mcux.o obj-$(CONFIG_I2C_NRF5) += i2c_nrf5.o obj-$(CONFIG_I2C_QMSI) += i2c_qmsi.o obj-$(CONFIG_I2C_QMSI_SS) += i2c_qmsi_ss.o +obj-$(CONFIG_I2C_SBCON) += i2c_sbcon.o obj-$(CONFIG_I2C_STM32LX) += i2c_stm32lx.o obj-$(CONFIG_TWIHS_SAM) += twihs_sam.o diff --git a/drivers/i2c/i2c_sbcon.c b/drivers/i2c/i2c_sbcon.c new file mode 100644 index 0000000000000..ed256cebe96b2 --- /dev/null +++ b/drivers/i2c/i2c_sbcon.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 Linaro Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Driver for ARM's SBCon 2-wire serial bus interface + * + * SBCon is a simple device which allows directly setting and getting the + * hardware state of two-bit serial interfaces like I2C. + */ + +#include +#include +#include +#include +#include + +/* SBCon hardware registers layout */ +struct sbcon { + union { + volatile u32_t SB_CONTROLS; /* Write to set pins high */ + volatile u32_t SB_CONTROL; /* Read for state of pins */ + }; + volatile u32_t SB_CONTROLC; /* Write to set pins low */ +}; + +/* Bits values for SCL and SDA lines in struct sbcon registers */ +#define SCL BIT(0) +#define SDA BIT(1) + +/* Driver config */ +struct i2c_sbcon_config { + struct sbcon *sbcon; /* Address of hardware registers */ +}; + +/* Driver instance data */ +struct i2c_sbcon_context { + struct i2c_bitbang bitbang; /* Bit-bang library data */ +}; + +static void i2c_sbcon_set_scl(void *io_context, int state) +{ + struct sbcon *sbcon = io_context; + + if (state) { + sbcon->SB_CONTROLS = SCL; + } else { + sbcon->SB_CONTROLC = SCL; + } +} + +static void i2c_sbcon_set_sda(void *io_context, int state) +{ + struct sbcon *sbcon = io_context; + + if (state) { + sbcon->SB_CONTROLS = SDA; + } else { + sbcon->SB_CONTROLC = SDA; + } +} + +static int i2c_sbcon_get_sda(void *io_context) +{ + struct sbcon *sbcon = io_context; + + return sbcon->SB_CONTROL & SDA; +} + +static const struct i2c_bitbang_io io_fns = { + .set_scl = &i2c_sbcon_set_scl, + .set_sda = &i2c_sbcon_set_sda, + .get_sda = &i2c_sbcon_get_sda, +}; + +static int i2c_sbcon_configure(struct device *dev, u32_t dev_config) +{ + struct i2c_sbcon_context *context = dev->driver_data; + + return i2c_bitbang_configure(&context->bitbang, dev_config); +} + +static int i2c_sbcon_transfer(struct device *dev, struct i2c_msg *msgs, + u8_t num_msgs, u16_t slave_address) +{ + struct i2c_sbcon_context *context = dev->driver_data; + + return i2c_bitbang_transfer(&context->bitbang, msgs, num_msgs, + slave_address); +} + +static struct i2c_driver_api api = { + .configure = i2c_sbcon_configure, + .transfer = i2c_sbcon_transfer, +}; + +static int i2c_sbcon_init(struct device *dev) +{ + struct i2c_sbcon_context *context = dev->driver_data; + const struct i2c_sbcon_config *config = dev->config->config_info; + + i2c_bitbang_init(&context->bitbang, &io_fns, config->sbcon); + + dev->driver_api = &api; + + return 0; +} + +#define DEFINE_I2C_SBCON(_num) \ + \ +static struct i2c_sbcon_context i2c_sbcon_dev_data_##_num; \ + \ +static const struct i2c_sbcon_config i2c_sbcon_dev_cfg_##_num = { \ + .sbcon = (void *)I2C_SBCON_##_num##_BASE_ADDR, \ +}; \ + \ +DEVICE_INIT(i2c_sbcon_##_num, CONFIG_I2C_SBCON_##_num##_NAME, \ + i2c_sbcon_init, \ + &i2c_sbcon_dev_data_##_num, \ + &i2c_sbcon_dev_cfg_##_num, \ + PRE_KERNEL_2, CONFIG_I2C_INIT_PRIORITY) + +#ifdef CONFIG_I2C_SBCON_0 +DEFINE_I2C_SBCON(0); +#endif + +#ifdef CONFIG_I2C_SBCON_1 +DEFINE_I2C_SBCON(1); +#endif + +#ifdef CONFIG_I2C_SBCON_2 +DEFINE_I2C_SBCON(2); +#endif + +#ifdef CONFIG_I2C_SBCON_3 +DEFINE_I2C_SBCON(3); +#endif diff --git a/drivers/ipm/ipm_quark_se.h b/drivers/ipm/ipm_quark_se.h index e6480a3efc769..05ecf822b612e 100644 --- a/drivers/ipm/ipm_quark_se.h +++ b/drivers/ipm/ipm_quark_se.h @@ -20,20 +20,20 @@ extern "C" { #endif -#define QUARK_SE_IPM_OUTBOUND 0 +#define QUARK_SE_IPM_OUTBOUND 0 #define QUARK_SE_IPM_INBOUND 1 #if defined(CONFIG_SOC_QUARK_SE_C1000) /* First byte of the QUARK_SE_IPM_MASK register is for the Lakemont */ #define QUARK_SE_IPM_MASK_START_BIT 0 -#define QUARK_SE_IPM_INTERRUPT 21 +#define QUARK_SE_IPM_INTERRUPT 21 #define QUARK_SE_IPM_ARC_LMT_DIR QUARK_SE_IPM_INBOUND #define QUARK_SE_IPM_LMT_ARC_DIR QUARK_SE_IPM_OUTBOUND #elif defined(CONFIG_SOC_QUARK_SE_C1000_SS) /* Second byte is for ARC */ #define QUARK_SE_IPM_MASK_START_BIT 8 -#define QUARK_SE_IPM_INTERRUPT 57 +#define QUARK_SE_IPM_INTERRUPT 57 #define QUARK_SE_IPM_ARC_LMT_DIR QUARK_SE_IPM_OUTBOUND #define QUARK_SE_IPM_LMT_ARC_DIR QUARK_SE_IPM_INBOUND diff --git a/drivers/pinmux/dev/Kconfig b/drivers/pinmux/dev/Kconfig index 418b5eaa3cc45..87a93cb9db9f4 100644 --- a/drivers/pinmux/dev/Kconfig +++ b/drivers/pinmux/dev/Kconfig @@ -24,7 +24,7 @@ config PINMUX_DEV_NAME config PINMUX_DEV_ATMEL_SAM3X bool "Enable pinmux dev driver for Atmel SAM3X boards" - depends on PINMUX_DEV && SOC_ATMEL_SAM3X8E + depends on PINMUX_DEV && SOC_SERIES_SAM3X help Enables the pinmux dev driver for boards based on the Atmel SAM3X family of microcontrollers. diff --git a/drivers/serial/Kconfig.atmel_sam3 b/drivers/serial/Kconfig.atmel_sam3 index ef678fd30e298..d87e92da9314b 100644 --- a/drivers/serial/Kconfig.atmel_sam3 +++ b/drivers/serial/Kconfig.atmel_sam3 @@ -2,7 +2,7 @@ menuconfig UART_ATMEL_SAM3 bool "Atmel SAM3 family processor UART driver" default n select SERIAL_HAS_DRIVER - depends on SOC_ATMEL_SAM3 + depends on SOC_SERIES_SAM3X help This option enables the UART driver for Atmel SAM3 family processors. Note that there is only one diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index 12656724225f8..fe98e17f7e8ff 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -211,6 +211,11 @@ void _timer_int_handler(void *unused) { ARG_UNUSED(unused); +#ifdef CONFIG_EXECUTION_BENCHMARKING + extern void read_systick_start_of_tick_handler(void); + read_systick_start_of_tick_handler(); +#endif + #ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT extern void _sys_k_event_logger_interrupt(void); _sys_k_event_logger_interrupt(); @@ -337,6 +342,11 @@ void _timer_int_handler(void *unused) #endif /* CONFIG_SYS_POWER_MANAGEMENT */ +#ifdef CONFIG_EXECUTION_BENCHMARKING + extern void read_systick_end_of_tick_handler(void); + read_systick_end_of_tick_handler(); +#endif + extern void _ExcExit(void); _ExcExit(); } diff --git a/drivers/timer/loapic_timer.c b/drivers/timer/loapic_timer.c index 2f7d100b27870..15c008d8c5a41 100644 --- a/drivers/timer/loapic_timer.c +++ b/drivers/timer/loapic_timer.c @@ -252,6 +252,16 @@ static inline void program_max_cycles(void) void _timer_int_handler(void *unused /* parameter is not used */ ) { +#ifdef CONFIG_EXECUTION_BENCHMARKING + __asm__ __volatile__ ( + "pushl %eax\n\t" + "pushl %edx\n\t" + "rdtsc\n\t" + "mov %eax, __start_tick_tsc\n\t" + "mov %edx, __start_tick_tsc+4\n\t" + "pop %edx\n\t" + "pop %eax\n\t"); +#endif ARG_UNUSED(unused); #if defined(CONFIG_TICKLESS_KERNEL) @@ -324,7 +334,16 @@ void _timer_int_handler(void *unused /* parameter is not used */ _sys_clock_tick_announce(); #endif /*CONFIG_TICKLESS_IDLE*/ #endif - +#ifdef CONFIG_EXECUTION_BENCHMARKING + __asm__ __volatile__ ( + "pushl %eax\n\t" + "pushl %edx\n\t" + "rdtsc\n\t" + "mov %eax, __end_tick_tsc\n\t" + "mov %edx, __end_tick_tsc+4\n\t" + "pop %edx\n\t" + "pop %eax\n\t"); +#endif /* CONFIG_EXECUTION_BENCHMARKING */ } #ifdef CONFIG_TICKLESS_KERNEL diff --git a/include/arch/x86/arch.h b/include/arch/x86/arch.h index 24bd9929dd57c..c088bd6966b37 100644 --- a/include/arch/x86/arch.h +++ b/include/arch/x86/arch.h @@ -440,7 +440,7 @@ extern void _arch_irq_disable(unsigned int irq); * by _Swap() it will either inherit an FPU that is guaranteed to be in a "sane" * state (if the most recent user of the FPU was cooperatively swapped out) * or the thread's own floating point context will be loaded (if the most - * recent user of the FPU was pre-empted, or if this thread is the first user + * recent user of the FPU was preempted, or if this thread is the first user * of the FPU). Thereafter, the kernel will protect the thread's FP context * so that it is not altered during a preemptive context switch. * diff --git a/include/bluetooth/bluetooth.h b/include/bluetooth/bluetooth.h index e24e352a19f53..73d1242b7d095 100644 --- a/include/bluetooth/bluetooth.h +++ b/include/bluetooth/bluetooth.h @@ -118,7 +118,7 @@ struct bt_le_adv_param { /** Maximum Advertising Interval (N * 0.625) */ u16_t interval_max; - /** Optional pre-defined (random) own address. Currently + /** Optional predefined (random) own address. Currently * the only permitted use of this is for NRPA with * non-connectable advertising. */ @@ -179,7 +179,7 @@ int bt_le_adv_stop(void); * @param addr Advertiser LE address and type. * @param rssi Strength of advertiser signal. * @param adv_type Type of advertising response from advertiser. - * @param data Buffer containig advertiser data. + * @param data Buffer containing advertiser data. */ typedef void bt_le_scan_cb_t(const bt_addr_le_t *addr, s8_t rssi, u8_t adv_type, struct net_buf_simple *buf); diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index 28dc5a42cd192..bd836a6d286cb 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -196,7 +196,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, /** @brief Automatically connect to remote device if it's in range. * * This function enables/disables automatic connection initiation. - * Everytime the device looses the connection with peer, this connection + * Every time the device looses the connection with peer, this connection * will be re-established if connectable advertisement from peer is received. * * @param addr Remote Bluetooth address. @@ -219,7 +219,7 @@ int bt_le_set_auto_conn(bt_addr_le_t *addr, * In case of high duty cycle this will result in a callback with * connected() with a new connection or with an error. * - * The advertising may be cancelled with bt_conn_disconnect(). + * The advertising may be canceled with bt_conn_disconnect(). * * Returns a new reference that the the caller is responsible for managing. * @@ -282,7 +282,7 @@ u8_t bt_conn_enc_key_size(struct bt_conn *conn); * * This structure is used for tracking the state of a connection. * It is registered with the help of the bt_conn_cb_register() API. - * It's premissible to register multiple instances of this @ref bt_conn_cb + * It's permissible to register multiple instances of this @ref bt_conn_cb * type, in case different modules of an application are interested in * tracking the connection state. If a callback is not of interest for * an instance, it may be set to NULL and will as a consequence not be diff --git a/include/bluetooth/gatt.h b/include/bluetooth/gatt.h index 28228768d49c6..eb5002fb0276a 100644 --- a/include/bluetooth/gatt.h +++ b/include/bluetooth/gatt.h @@ -343,7 +343,7 @@ ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, /** @brief Read Service Attribute helper. * * Read service attribute value storing the result into buffer after - * enconding it. + * encoding it. * NOTE: Only use this with attributes which user_data is a bt_uuid. * * @param conn Connection object. @@ -408,7 +408,7 @@ ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, /** @brief Read Include Attribute helper. * * Read include service attribute value storing the result into buffer after - * enconding it. + * encoding it. * NOTE: Only use this with attributes which user_data is a bt_gatt_include. * * @param conn Connection object. @@ -442,7 +442,7 @@ ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, /** @brief Read Characteristic Attribute helper. * * Read characteristic attribute value storing the result into buffer after - * enconding it. + * encoding it. * NOTE: Only use this with attributes which user_data is a bt_gatt_chrc. * * @param conn Connection object. @@ -497,7 +497,7 @@ struct _bt_gatt_ccc { /** @brief Read Client Characteristic Configuration Attribute helper. * * Read CCC attribute value storing the result into buffer after - * enconding it. + * encoding it. * NOTE: Only use this with attributes which user_data is a _bt_gatt_ccc. * * @param conn Connection object. @@ -943,7 +943,7 @@ int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params); /** @brief Write Attribute Value by handle without response * * This procedure write the attribute value without requiring an - * acknowledgement that the write was successfully performed + * acknowledgment that the write was successfully performed * * @param conn Connection object. * @param handle Attribute handle. diff --git a/include/bluetooth/hci.h b/include/bluetooth/hci.h index 14d1125b38ccd..924dce13b09ff 100644 --- a/include/bluetooth/hci.h +++ b/include/bluetooth/hci.h @@ -491,8 +491,12 @@ struct bt_hci_write_local_name { #define BT_BREDR_SCAN_INQUIRY 0x01 #define BT_BREDR_SCAN_PAGE 0x02 +#define BT_HCI_CTL_TO_HOST_FLOW_DISABLE 0x00 #define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01 #define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031) +struct bt_hci_cp_set_ctl_to_host_flow { + u8_t flow_enable; +} __packed; #define BT_HCI_OP_HOST_BUFFER_SIZE BT_OP(BT_OGF_BASEBAND, 0x0033) struct bt_hci_cp_host_buffer_size { diff --git a/include/bluetooth/sdp.h b/include/bluetooth/sdp.h index 35372f88010ef..0d71f4bce92c7 100644 --- a/include/bluetooth/sdp.h +++ b/include/bluetooth/sdp.h @@ -472,7 +472,7 @@ struct bt_sdp_client_result { }; /** @brief Helper enum to be used as return value of bt_sdp_discover_func_t. - * The value informs the caller to perform futher pending actions or stop them. + * The value informs the caller to perform further pending actions or stop them. */ enum { BT_SDP_DISCOVER_UUID_STOP = 0, @@ -483,7 +483,7 @@ enum { * * @brief Callback type reporting to user that there is a resolved result * on remote for given UUID and the result record buffer can be used by user - * for futher inspection. + * for further inspection. * * A function of this type is given by the user to the bt_sdp_discover_params * object. It'll be called on each valid record discovery completion for given diff --git a/include/display/grove_lcd.h b/include/display/grove_lcd.h index 5d888afe88761..8bc945876082c 100644 --- a/include/display/grove_lcd.h +++ b/include/display/grove_lcd.h @@ -50,7 +50,7 @@ void glcd_clear(struct device *port); * @brief Function to change the display state. * @details This function provides the user the ability to change the state * of the display as per needed. Controlling things like powering on or off - * the screen, the option to display the cusror or not, and the ability to + * the screen, the option to display the cursor or not, and the ability to * blink the cursor. * * @param port Pointer to device structure for driver instance. @@ -129,9 +129,9 @@ u8_t glcd_function_get(struct device *port); #define GROVE_RGB_GREEN 2 #define GROVE_RGB_BLUE 3 /** - * @brief Set LCD background to a predfined color + * @brief Set LCD background to a predefined color * @param port Pointer to device structure for driver instance. - * @param color One of the pre-defined color options + * @param color One of the predefined color options */ void glcd_color_select(struct device *port, u8_t color); diff --git a/include/drivers/usb/usb_dc.h b/include/drivers/usb/usb_dc.h index 0ae236e08940c..f248e48234359 100644 --- a/include/drivers/usb/usb_dc.h +++ b/include/drivers/usb/usb_dc.h @@ -277,7 +277,7 @@ int usb_dc_ep_read(const u8_t ep, u8_t *const data, * @brief set callback function for the specified endpoint * * Function to set callback function for notification of data received and - * available to application or trasmit done on the selected endpoint, + * available to application or transmit done on the selected endpoint, * NULL if callback not required by application code. * * @param[in] ep Endpoint address corresponding to the one @@ -291,7 +291,7 @@ int usb_dc_ep_set_callback(const u8_t ep, const usb_dc_ep_callback cb); /** * @brief read data from the specified endpoint * - * This is similar to usb_dc_ep_read, the difference being that, it doesnt + * This is similar to usb_dc_ep_read, the difference being that, it doesn't * clear the endpoint NAKs so that the consumer is not bogged down by further * upcalls till he is done with the processing of the data. The caller should * reactivate ep by invoking usb_dc_ep_read_continue() do so. @@ -316,7 +316,7 @@ int usb_dc_ep_read_wait(u8_t ep, u8_t *data, u32_t max_data_len, * Clear the endpoint NAK and enable the endpoint to accept more data * from the host. Usually called after usb_dc_ep_read_wait() when the consumer * is fine to accept more data. Thus these calls together acts as flow control - * meachanism. + * mechanism. * * @param[in] ep Endpoint address corresponding to the one * listed in the device configuration table diff --git a/include/kernel.h b/include/kernel.h index 826052ea23b75..eb864e7601923 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1139,7 +1139,7 @@ extern s64_t k_uptime_get(void); /** * @brief Enable clock always on in tickless kernel * - * This routine enables keepng the clock running when + * This routine enables keeping the clock running when * there are no timer events programmed in tickless kernel * scheduling. This is necessary if the clock is used to track * passage of time. @@ -1159,7 +1159,7 @@ static inline int k_enable_sys_clock_always_on(void) /** * @brief Disable clock always on in tickless kernel * - * This routine disables keepng the clock running when + * This routine disables keeping the clock running when * there are no timer events programmed in tickless kernel * scheduling. To save power, this routine should be called * immediately when clock is not used to track time. diff --git a/include/logging/kernel_event_logger.h b/include/logging/kernel_event_logger.h index 3b1b803e10910..7d7908b509fb9 100644 --- a/include/logging/kernel_event_logger.h +++ b/include/logging/kernel_event_logger.h @@ -18,7 +18,7 @@ extern "C" { #endif -/* pre-defined event types */ +/* predefined event types */ #define KERNEL_EVENT_LOGGER_CONTEXT_SWITCH_EVENT_ID 0x0001 #define KERNEL_EVENT_LOGGER_INTERRUPT_EVENT_ID 0x0002 diff --git a/include/logging/sys_log.h b/include/logging/sys_log.h index ef4d06a62e9d3..f17332b1c2de8 100644 --- a/include/logging/sys_log.h +++ b/include/logging/sys_log.h @@ -156,7 +156,7 @@ void syslog_hook_install(void (*hook)(const char *, ...)); * * @details available if SYS_LOG_LEVEL is SYS_LOG_LEVEL_WARNING or higher. * It's meant to register messages related to unusual situations that are - * not necesarily errors. + * not necessarily errors. * * @param ... A string optionally containing printk valid conversion specifier, * followed by as many values as specifiers. diff --git a/include/misc/byteorder.h b/include/misc/byteorder.h index fc5654b7f0c7c..bcd160671c309 100644 --- a/include/misc/byteorder.h +++ b/include/misc/byteorder.h @@ -109,7 +109,7 @@ #endif /** - * @brief Put a 16-bit intger as big-endian to arbitrary location. + * @brief Put a 16-bit integer as big-endian to arbitrary location. * * Put a 16-bit integer, originally in host endianness, to a * potentially unaligned memory location in big-endian format. @@ -124,7 +124,7 @@ static inline void sys_put_be16(u16_t val, u8_t dst[2]) } /** - * @brief Put a 32-bit intger as big-endian to arbitrary location. + * @brief Put a 32-bit integer as big-endian to arbitrary location. * * Put a 32-bit integer, originally in host endianness, to a * potentially unaligned memory location in big-endian format. @@ -139,7 +139,7 @@ static inline void sys_put_be32(u32_t val, u8_t dst[4]) } /** - * @brief Put a 16-bit intger as little-endian to arbitrary location. + * @brief Put a 16-bit integer as little-endian to arbitrary location. * * Put a 16-bit integer, originally in host endianness, to a * potentially unaligned memory location in little-endian format. @@ -154,7 +154,7 @@ static inline void sys_put_le16(u16_t val, u8_t dst[2]) } /** - * @brief Put a 32-bit intger as little-endian to arbitrary location. + * @brief Put a 32-bit integer as little-endian to arbitrary location. * * Put a 32-bit integer, originally in host endianness, to a * potentially unaligned memory location in little-endian format. @@ -184,7 +184,7 @@ static inline void sys_put_le64(u64_t val, u8_t dst[8]) } /** - * @brief Get a 16-bit intger stored in big-endian format. + * @brief Get a 16-bit integer stored in big-endian format. * * Get a 16-bit integer, stored in big-endian format in a potentially * unaligned memory location, and convert it to the host endianness. @@ -199,7 +199,7 @@ static inline u16_t sys_get_be16(const u8_t src[2]) } /** - * @brief Get a 32-bit intger stored in big-endian format. + * @brief Get a 32-bit integer stored in big-endian format. * * Get a 32-bit integer, stored in big-endian format in a potentially * unaligned memory location, and convert it to the host endianness. @@ -214,7 +214,7 @@ static inline u32_t sys_get_be32(const u8_t src[4]) } /** - * @brief Get a 16-bit intger stored in little-endian format. + * @brief Get a 16-bit integer stored in little-endian format. * * Get a 16-bit integer, stored in little-endian format in a potentially * unaligned memory location, and convert it to the host endianness. @@ -229,7 +229,7 @@ static inline u16_t sys_get_le16(const u8_t src[2]) } /** - * @brief Get a 32-bit intger stored in little-endian format. + * @brief Get a 32-bit integer stored in little-endian format. * * Get a 32-bit integer, stored in little-endian format in a potentially * unaligned memory location, and convert it to the host endianness. diff --git a/include/misc/dlist.h b/include/misc/dlist.h index 72275238e3625..cb211488a3d94 100644 --- a/include/misc/dlist.h +++ b/include/misc/dlist.h @@ -132,7 +132,7 @@ typedef struct _dnode sys_dnode_t; /** * @brief Provide the primitive to iterate on a list under a container - * Note: the loop is unsafe and thus __cn should not be dettached + * Note: the loop is unsafe and thus __cn should not be detached * * User _MUST_ add the loop statement curly braces enclosing its own code: * @@ -150,7 +150,7 @@ typedef struct _dnode sys_dnode_t; /** * @brief Provide the primitive to safely iterate on a list under a container - * Note: __cn can be dettached, it will not break the loop. + * Note: __cn can be detached, it will not break the loop. * * User _MUST_ add the loop statement curly braces enclosing its own code: * diff --git a/include/misc/slist.h b/include/misc/slist.h index a3da0bfbbbc09..4afb8d729e530 100644 --- a/include/misc/slist.h +++ b/include/misc/slist.h @@ -138,7 +138,7 @@ typedef struct _slist sys_slist_t; /** * @brief Provide the primitive to iterate on a list under a container - * Note: the loop is unsafe and thus __cn should not be dettached + * Note: the loop is unsafe and thus __cn should not be detached * * User _MUST_ add the loop statement curly braces enclosing its own code: * @@ -156,7 +156,7 @@ typedef struct _slist sys_slist_t; /** * @brief Provide the primitive to safely iterate on a list under a container - * Note: __cn can be dettached, it will not break the loop. + * Note: __cn can be detached, it will not break the loop. * * User _MUST_ add the loop statement curly braces enclosing its own code: * diff --git a/include/net/buf.h b/include/net/buf.h index e09f29672a4be..7b2f03fe035f0 100644 --- a/include/net/buf.h +++ b/include/net/buf.h @@ -226,7 +226,7 @@ void net_buf_simple_push_u8(struct net_buf_simple *buf, u8_t val); /** * @brief Remove data from the beginning of the buffer. * - * Removes data from the beginnig of the buffer by modifying the data + * Removes data from the beginning of the buffer by modifying the data * pointer and buffer length. * * @param buf Buffer to update. @@ -826,7 +826,7 @@ static inline void *net_buf_user_data(struct net_buf *buf) * @def net_buf_pull * @brief Remove data from the beginning of the buffer. * - * Removes data from the beginnig of the buffer by modifying the data + * Removes data from the beginning of the buffer by modifying the data * pointer and buffer length. * * @param buf Buffer to update. diff --git a/include/net/ieee802154_radio.h b/include/net/ieee802154_radio.h index c2344dae3c611..a08c20776f674 100644 --- a/include/net/ieee802154_radio.h +++ b/include/net/ieee802154_radio.h @@ -74,7 +74,7 @@ extern int ieee802154_radio_send(struct net_if *iface, * @brief Radio driver ACK handling function that hw drivers should use * * @details ACK handling requires fast handling and thus such function - * helps to hook direcly the hw drivers to the radio driver. + * helps to hook directly the hw drivers to the radio driver. * * @param iface A valid pointer on a network interface that received the packet * @param pkt A valid pointer on a packet to check diff --git a/include/net/net_context.h b/include/net/net_context.h index 326cc76427102..e0d1c7cdf6ecd 100644 --- a/include/net/net_context.h +++ b/include/net/net_context.h @@ -691,7 +691,7 @@ int net_context_sendto(struct net_pkt *pkt, * called. The callback is called even if timeout was set to K_FOREVER, * the callback is called before this function will return in this case. * The callback is not called if the timeout expires. The timeout functionality - * can be compiled out if synchronous behaviour is not needed. The sync call + * can be compiled out if synchronous behavior is not needed. The sync call * logic requires some memory that can be saved if only async way of call is * used. If CONFIG_NET_CONTEXT_SYNC_RECV is not set, then the timeout parameter * value is ignored. diff --git a/include/net/net_mgmt.h b/include/net/net_mgmt.h index 6fefabe2f47c1..7be0679b476d7 100644 --- a/include/net/net_mgmt.h +++ b/include/net/net_mgmt.h @@ -199,7 +199,7 @@ void net_mgmt_event_notify(u32_t mgmt_event, struct net_if *iface); * has bit NET_MGMT_IFACE_BIT set relevantly, depending on events * the caller wants to listen to. * @param timeout a delay in milliseconds. K_FOREVER can be used to wait - * undefinitely. + * indefinitely. * * @return 0 on success, a negative error code otherwise. -ETIMEDOUT will * be specifically returned if the timeout kick-in instead of an @@ -220,7 +220,7 @@ int net_mgmt_event_wait(u32_t mgmt_event_mask, * the mask generated the event. Can be NULL if the caller is not * interested in that information. * @param timeout a delay in milliseconds. K_FOREVER can be used to wait - * undefinitely. + * indefinitely. * * @return 0 on success, a negative error code otherwise. -ETIMEDOUT will * be specifically returned if the timeout kick-in instead of an diff --git a/include/net/net_offload.h b/include/net/net_offload.h index 6e7e11bf8577b..aed1530acfb3f 100644 --- a/include/net/net_offload.h +++ b/include/net/net_offload.h @@ -369,7 +369,7 @@ static inline int net_offload_sendto(struct net_if *iface, * called. The callback is called even if timeout was set to K_FOREVER, * the callback is called before this function will return in this case. * The callback is not called if the timeout expires. The timeout functionality - * can be compiled out if synchronous behaviour is not needed. The sync call + * can be compiled out if synchronous behavior is not needed. The sync call * logic requires some memory that can be saved if only async way of call is * used. If CONFIG_NET_CONTEXT_SYNC_RECV is not set, then the timeout parameter * value is ignored. diff --git a/include/net/net_pkt.h b/include/net/net_pkt.h index e9797b25ff82e..da04c50b0a9e8 100644 --- a/include/net/net_pkt.h +++ b/include/net/net_pkt.h @@ -775,7 +775,7 @@ struct net_buf *net_pkt_frag_del(struct net_pkt *pkt, void net_pkt_frag_add(struct net_pkt *pkt, struct net_buf *frag); /** - * @brief Insert a fragment to a packet at the beginning of its framgment list + * @brief Insert a fragment to a packet at the beginning of its fragment list * * @param pkt pkt Network packet where to insert the fragment * @param frag Fragment to insert @@ -989,7 +989,7 @@ static inline bool net_pkt_append_le32(struct net_pkt *pkt, u32_t data) * @brief Get data from buffer * * @details Get N number of bytes starting from fragment's offset. If the total - * length of data is placed in multiple framgents, this function will read from + * length of data is placed in multiple fragments, this function will read from * all fragments until it reaches N number of bytes. Caller has to take care of * endianness if needed. * @@ -1011,7 +1011,7 @@ struct net_buf *net_frag_read(struct net_buf *frag, u16_t offset, * @brief Skip N number of bytes while reading buffer * * @details Skip N number of bytes starting from fragment's offset. If the total - * length of data is placed in multiple framgents, this function will skip from + * length of data is placed in multiple fragments, this function will skip from * all fragments until it reaches N number of bytes. This function is useful * when unwanted data (e.g. reserved or not supported data in message) is part * of fragment and want to skip it. @@ -1280,7 +1280,7 @@ int net_pkt_split(struct net_pkt *pkt, struct net_buf *orig_frag, struct net_buf **fragB, s32_t timeout); /** - * @brief Get information about pre-defined RX, TX and DATA pools. + * @brief Get information about predefined RX, TX and DATA pools. * * @param rx Pointer to RX pool is returned. * @param tx Pointer to TX pool is returned. diff --git a/include/net/zoap.h b/include/net/zoap.h index ca75f45f0045f..cabc96706e627 100644 --- a/include/net/zoap.h +++ b/include/net/zoap.h @@ -443,7 +443,7 @@ void zoap_pending_clear(struct zoap_pending *pending); * @brief Cancels awaiting for this reply, so it becomes available * again. * - * @param reply The reply to be cancelled + * @param reply The reply to be canceled */ void zoap_reply_clear(struct zoap_reply *reply); @@ -511,7 +511,7 @@ int zoap_packet_set_used(struct zoap_packet *zpkt, u16_t len); /** * @brief Adds an option to the packet. * - * Note: ptions must be added in numeric order of their codes. + * Note: options must be added in numeric order of their codes. * * @param zpkt Packet to be updated * @param code Option code to add to the packet, see #zoap_option_num diff --git a/include/usb/usb_device.h b/include/usb/usb_device.h index e05d6a8d32fe3..b80013c35cd98 100644 --- a/include/usb/usb_device.h +++ b/include/usb/usb_device.h @@ -263,7 +263,7 @@ int usb_ep_clear_stall(u8_t ep); /** * @brief read data from the specified endpoint * - * This is similar to usb_ep_read, the difference being that, it doesnt + * This is similar to usb_ep_read, the difference being that, it doesn't * clear the endpoint NAKs so that the consumer is not bogged down by further * upcalls till he is done with the processing of the data. The caller should * reactivate ep by invoking usb_ep_read_continue() do so. @@ -288,7 +288,7 @@ int usb_ep_read_wait(u8_t ep, u8_t *data, u32_t max_data_len, * Clear the endpoint NAK and enable the endpoint to accept more data * from the host. Usually called after usb_ep_read_wait() when the consumer * is fine to accept more data. Thus these calls together acts as flow control - * meachanism. + * mechanism. * * @param[in] ep Endpoint address corresponding to the one * listed in the device configuration table diff --git a/include/usb/usbstruct.h b/include/usb/usbstruct.h index de1fdb83fdefd..a60f44d14d1ef 100644 --- a/include/usb/usbstruct.h +++ b/include/usb/usbstruct.h @@ -28,9 +28,9 @@ /** * @file - * @brief standard USB packet stuctures and defines + * @brief standard USB packet structures and defines * - * This file contains stuctures and defines of the standard USB packets + * This file contains structures and defines of the standard USB packets */ #ifndef _USBSTRUCT_H_ diff --git a/kernel/Kconfig b/kernel/Kconfig index 03e586bbc46c9..ec0bc471fec43 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -204,6 +204,16 @@ config INT_LATENCY_BENCHMARK The metrics are displayed (and a new sampling interval is started) each time int_latency_show() is called thereafter. +config EXECUTION_BENCHMARKING + bool + prompt "Timing metrics " + default n + help + This option enables the tracking of various times inside the kernel + the exact set of metrics being tracked is board-dependent. + All timing measurements are enabled for X86 and ARM based architectures. + In other architectures only a subset are enabled. + config THREAD_MONITOR bool prompt "Thread monitoring [EXPERIMENTAL]" diff --git a/kernel/init.c b/kernel/init.c index 4037db246c3cb..63d27af1a0d57 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -56,6 +56,14 @@ u64_t __noinit __main_tsc; /* timestamp when main task starts */ u64_t __noinit __idle_tsc; /* timestamp when CPU goes idle */ #endif +#ifdef CONFIG_EXECUTION_BENCHMARKING +u64_t __noinit __start_swap_tsc; +u64_t __noinit __end_swap_tsc; +u64_t __noinit __start_intr_tsc; +u64_t __noinit __end_intr_tsc; +u64_t __noinit __start_tick_tsc; +u64_t __noinit __end_tick_tsc; +#endif /* init/main and idle threads */ #define IDLE_STACK_SIZE CONFIG_IDLE_STACK_SIZE diff --git a/lib/json/json.h b/lib/json/json.h index 30edd5b618d0d..09026237395e9 100644 --- a/lib/json/json.h +++ b/lib/json/json.h @@ -67,6 +67,37 @@ struct json_obj_descr { typedef int (*json_append_bytes_t)(const u8_t *bytes, size_t len, void *data); + +/** + * @brief Helper macro to declare a descriptor for supported primitive + * values. + * + * @param struct_ Struct packing the values + * + * @param field_name_ Field name in the struct + * + * @param type_ Token type for JSON value corresponding to a primitive + * type. Must be one of: JSON_TOK_STRING for strings, JSON_TOK_NUMBER + * for numbers, JSON_TOK_TRUE (or JSON_TOK_FALSE) for booleans. + * + * Here's an example of use: + * + * struct foo { + * int some_int; + * }; + * + * struct json_obj_descr foo[] = { + * JSON_OBJ_DESCR_PRIM(struct foo, some_int, JSON_TOK_NUMBER), + * }; + */ +#define JSON_OBJ_DESCR_PRIM(struct_, field_name_, type_) \ + { \ + .field_name = (#field_name_), \ + .field_name_len = sizeof(#field_name_) - 1, \ + .offset = offsetof(struct_, field_name_), \ + .type = type_, \ + } + /** * @brief Helper macro to declare a descriptor for an object value * @@ -148,14 +179,8 @@ typedef int (*json_append_bytes_t)(const u8_t *bytes, size_t len, * * struct s { int foo; char *bar; } * struct json_obj_descr descr[] = { - * { .field_name = "foo", - * .field_name_len = 3, - * .offset = offsetof(struct s, foo), - * .type = JSON_TOK_NUMBER }, - * { .field_name = "bar", - * .field_name_len = 3, - * .offset = offsetof(struct s, bar), - * .type = JSON_TOK_STRING } + * JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER), + * JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING), * }; * * Since this parser is designed for machine-to-machine communications, some diff --git a/samples/bluetooth/hci_uart/96b_nitrogen.overlay b/samples/bluetooth/hci_uart/96b_nitrogen.overlay new file mode 100644 index 0000000000000..4113eafe1d36c --- /dev/null +++ b/samples/bluetooth/hci_uart/96b_nitrogen.overlay @@ -0,0 +1,5 @@ +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <1000000>; + status = "ok"; +}; diff --git a/samples/bluetooth/hci_uart/nrf51_blenano.overlay b/samples/bluetooth/hci_uart/nrf51_blenano.overlay new file mode 100644 index 0000000000000..4113eafe1d36c --- /dev/null +++ b/samples/bluetooth/hci_uart/nrf51_blenano.overlay @@ -0,0 +1,5 @@ +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <1000000>; + status = "ok"; +}; diff --git a/samples/bluetooth/hci_uart/nrf51_pca10028.overlay b/samples/bluetooth/hci_uart/nrf51_pca10028.overlay new file mode 100644 index 0000000000000..4113eafe1d36c --- /dev/null +++ b/samples/bluetooth/hci_uart/nrf51_pca10028.overlay @@ -0,0 +1,5 @@ +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <1000000>; + status = "ok"; +}; diff --git a/samples/bluetooth/hci_uart/nrf52840_pca10056.overlay b/samples/bluetooth/hci_uart/nrf52840_pca10056.overlay new file mode 100644 index 0000000000000..4113eafe1d36c --- /dev/null +++ b/samples/bluetooth/hci_uart/nrf52840_pca10056.overlay @@ -0,0 +1,5 @@ +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <1000000>; + status = "ok"; +}; diff --git a/samples/bluetooth/hci_uart/nrf52_blenano2.overlay b/samples/bluetooth/hci_uart/nrf52_blenano2.overlay new file mode 100644 index 0000000000000..4113eafe1d36c --- /dev/null +++ b/samples/bluetooth/hci_uart/nrf52_blenano2.overlay @@ -0,0 +1,5 @@ +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <1000000>; + status = "ok"; +}; diff --git a/samples/bluetooth/hci_uart/nrf52_pca10040.overlay b/samples/bluetooth/hci_uart/nrf52_pca10040.overlay new file mode 100644 index 0000000000000..4113eafe1d36c --- /dev/null +++ b/samples/bluetooth/hci_uart/nrf52_pca10040.overlay @@ -0,0 +1,5 @@ +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <1000000>; + status = "ok"; +}; diff --git a/samples/drivers/gpio/src/main.c b/samples/drivers/gpio/src/main.c index 8a19726bb1fb9..07ce642339d32 100644 --- a/samples/drivers/gpio/src/main.c +++ b/samples/drivers/gpio/src/main.c @@ -114,7 +114,7 @@ #define GPIO_OUT_PIN 16 #define GPIO_INT_PIN 19 #define GPIO_NAME "GPIO_" -#elif defined(CONFIG_SOC_ATMEL_SAM3) +#elif defined(CONFIG_SOC_PART_NUMBER_SAM3X8E) #define GPIO_OUT_PIN 25 #define GPIO_INT_PIN 27 #define GPIO_NAME "GPIO_" diff --git a/samples/drivers/lcd_hd44780/src/main.c b/samples/drivers/lcd_hd44780/src/main.c index 1ed57a7a5d10f..4b015bea08f51 100644 --- a/samples/drivers/lcd_hd44780/src/main.c +++ b/samples/drivers/lcd_hd44780/src/main.c @@ -71,13 +71,13 @@ #include -#if defined(CONFIG_GPIO_ATMEL_SAM3) +#if defined(CONFIG_SOC_PART_NUMBER_SAM3X8E) #define GPIO_DRV_NAME CONFIG_GPIO_ATMEL_SAM3_PORTC_DEV_NAME #else #error "Unsupported GPIO driver" #endif -#if defined(CONFIG_SOC_ATMEL_SAM3) +#if defined(CONFIG_SOC_PART_NUMBER_SAM3X8E) /* Define GPIO OUT to LCD */ #define GPIO_PIN_PC12_D0 12 /* PC12 - pin 51 */ #define GPIO_PIN_PC13_D1 13 /* PC13 - pin 50 */ diff --git a/samples/drivers/lcd_hd44780/testcase.ini b/samples/drivers/lcd_hd44780/testcase.ini index c0d4933d98dc5..2d8e8587b8ecf 100644 --- a/samples/drivers/lcd_hd44780/testcase.ini +++ b/samples/drivers/lcd_hd44780/testcase.ini @@ -1,5 +1,5 @@ [test] tags = samples build_only = true -filter = CONFIG_SOC_ATMEL_SAM3 +filter = CONFIG_SOC_SERIES_SAM3X diff --git a/samples/sensor/hts221/Makefile b/samples/sensor/hts221/Makefile new file mode 100644 index 0000000000000..63cb452ce0e06 --- /dev/null +++ b/samples/sensor/hts221/Makefile @@ -0,0 +1,4 @@ +BOARD ?= disco_l475_iot1 +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.inc diff --git a/samples/sensor/hts221/README.rst b/samples/sensor/hts221/README.rst new file mode 100644 index 0000000000000..bdd91fbc51dcd --- /dev/null +++ b/samples/sensor/hts221/README.rst @@ -0,0 +1,47 @@ +.. _hts221: + +HTS221: Temperature and Humidity Monitor +######################################## + +Overview +******** +This sample periodically reads temperature and humidity from the HTS221 +Temperature & Humidity Sensor and displays it on the console + + +Requirements +************ + +This sample uses the HTS221 sensor controlled using the I2C interface. + +References +********** + + - HTS211: http://www.st.com/en/mems-and-sensors/hts221.html + +Building and Running +******************** + + This project outputs sensor data to the console. It requires an HTS221 + sensor, which is present on the disco_l475_iot1 board. + + .. code-block:: console + + $ cd samples/sensors/hts221 + $ make BOARD=disco_l475_iot1 + +Sample Output +============= + + .. code-block:: console + + Temperature:25.3 C + Relative Humidity:40% + Temperature:25.3 C + Relative Humidity:40% + Temperature:25.3 C + Relative Humidity:40% + Temperature:25.3 C + Relative Humidity:40% + + diff --git a/samples/sensor/hts221/prj.conf b/samples/sensor/hts221/prj.conf new file mode 100644 index 0000000000000..6031b70dff747 --- /dev/null +++ b/samples/sensor/hts221/prj.conf @@ -0,0 +1,4 @@ +CONFIG_STDOUT_CONSOLE=y +CONFIG_I2C=y +CONFIG_SENSOR=y +CONFIG_HTS221=y diff --git a/samples/sensor/hts221/src/Makefile b/samples/sensor/hts221/src/Makefile new file mode 100644 index 0000000000000..b666967fd5706 --- /dev/null +++ b/samples/sensor/hts221/src/Makefile @@ -0,0 +1 @@ +obj-y += main.o diff --git a/samples/sensor/hts221/src/main.c b/samples/sensor/hts221/src/main.c new file mode 100644 index 0000000000000..2a5f856ad9dee --- /dev/null +++ b/samples/sensor/hts221/src/main.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +void main(void) +{ + struct sensor_value temp, hum; + struct device *dev = device_get_binding("HTS221"); + + if (dev == NULL) { + printf("Could not get HTS221 device\n"); + return; + } + + while (1) { + if (sensor_sample_fetch(dev) < 0) { + printf("Sensor sample update error\n"); + return; + } + + if (sensor_channel_get(dev, SENSOR_CHAN_TEMP, &temp) < 0) { + printf("Cannot read HTS221 temperature channel\n"); + return; + } + + if (sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &hum) < 0) { + printf("Cannot read HTS221 humidity channel\n"); + return; + } + + /* display temperature */ + printf("Temperature:%.1f C\n", sensor_value_to_double(&temp)); + + /* display humidity (converted from millipercent) */ + printf("Relative Humidity:%.0f%%\n", + sensor_value_to_double(&hum) / 1000); + + k_sleep(2000); + } +} diff --git a/samples/sensor/hts221/testcase.ini b/samples/sensor/hts221/testcase.ini new file mode 100644 index 0000000000000..7260b929f7194 --- /dev/null +++ b/samples/sensor/hts221/testcase.ini @@ -0,0 +1,4 @@ +[test] +build_only = true +tags = samples sensor +platform_whitelist = disco_l475_iot1 diff --git a/scripts/ci/build-docs.sh b/scripts/ci/build-docs.sh index 12bf5d662fbab..f6b587a6129fd 100755 --- a/scripts/ci/build-docs.sh +++ b/scripts/ci/build-docs.sh @@ -5,10 +5,10 @@ echo "- Install dependencies" sudo apt-get install doxygen make sudo pip install breathe sphinx awscli sphinx_rtd_theme -cd ${TESTING_REPO_STATE} +cd ${MAIN_REPO_STATE} source zephyr-env.sh -cp -a /build/IN/docs-theme-repo/gitRepo doc/themes/zephyr-docs-theme +cp -a /build/IN/docs_theme_repo/gitRepo doc/themes/zephyr-docs-theme ls -la doc/themes echo "- Building docs..." diff --git a/scripts/ci/check-compliance.py b/scripts/ci/check-compliance.py index 11fd2d1d65d59..779f006afc557 100755 --- a/scripts/ci/check-compliance.py +++ b/scripts/ci/check-compliance.py @@ -19,7 +19,7 @@ def run_gitlint(tc): msg = proc.stdout.read() if msg != "": - failure = ET.SubElement(tc, 'failure', type="failure", message="commit message error") + failure = ET.SubElement(tc, 'failure', type="failure", message="commit message error on range: %s" %commit_range) failure.text = (str(msg)) return 1 diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 44fa3ad278f55..d0c7a09e44f02 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -30,6 +30,15 @@ endchoice comment "BLE Controller configuration" +config BLUETOOTH_CONTROLLER_TO_HOST_FC + bool "Controller to Host Flow Control" + depends on BLUETOOTH_CONN + default n + default y if BLUETOOTH_HCI_RAW + select POLL + help + Enable Controller to Host flow control. + config BLUETOOTH_CONTROLLER_DUP_FILTER_LEN prompt "Number of addresses in the scan duplicate filter" int diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 4709057d9218d..fa3fa5f2d8a48 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,18 @@ static s32_t dup_count; static u32_t dup_curr; #endif +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) +s32_t hci_hbuf_total; +u32_t hci_hbuf_sent; +u32_t hci_hbuf_acked; +atomic_t hci_state_mask; +static struct k_poll_signal *hbuf_signal; +#endif + +#if defined(CONFIG_BLUETOOTH_CONN) +static u32_t conn_count; +#endif + #define DEFAULT_EVENT_MASK 0x1fffffffffff #define DEFAULT_LE_EVENT_MASK 0x1f @@ -159,8 +172,6 @@ static void reset(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_evt_cc_status *ccst; - ll_reset(); - #if CONFIG_BLUETOOTH_CONTROLLER_DUP_FILTER_LEN > 0 dup_count = -1; #endif @@ -168,9 +179,112 @@ static void reset(struct net_buf *buf, struct net_buf **evt) event_mask = DEFAULT_EVENT_MASK; le_event_mask = DEFAULT_LE_EVENT_MASK; + if (buf) { + ll_reset(); + ccst = cmd_complete(evt, sizeof(*ccst)); + ccst->status = 0x00; + } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + hci_hbuf_total = 0; + hci_hbuf_sent = 0; + hci_hbuf_acked = 0; + conn_count = 0; + atomic_set_bit(&hci_state_mask, HCI_STATE_BIT_RESET); + k_poll_signal(hbuf_signal, 0x0); +#endif +} + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) +static void set_ctl_to_host_flow(struct net_buf *buf, struct net_buf **evt) +{ + struct bt_hci_cp_set_ctl_to_host_flow *cmd = (void *)buf->data; + struct bt_hci_evt_cc_status *ccst; + ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = 0x00; + + /* require host buffer size before enabling flow control, and + * disallow if any connections are up + */ + if (!hci_hbuf_total || conn_count) { + ccst->status = BT_HCI_ERR_CMD_DISALLOWED; + return; + } else { + ccst->status = 0x00; + } + + switch (cmd->flow_enable) { + case BT_HCI_CTL_TO_HOST_FLOW_DISABLE: + if (hci_hbuf_total < 0) { + /* already disabled */ + return; + } + break; + case BT_HCI_CTL_TO_HOST_FLOW_ENABLE: + if (hci_hbuf_total > 0) { + /* already enabled */ + return; + } + break; + default: + ccst->status = BT_HCI_ERR_INVALID_PARAM; + return; + } + + hci_hbuf_sent = 0; + hci_hbuf_acked = 0; + hci_hbuf_total = -hci_hbuf_total; +} + +static void host_buffer_size(struct net_buf *buf, struct net_buf **evt) +{ + struct bt_hci_cp_host_buffer_size *cmd = (void *)buf->data; + struct bt_hci_evt_cc_status *ccst; + + ccst = cmd_complete(evt, sizeof(*ccst)); + + if (hci_hbuf_total) { + ccst->status = BT_HCI_ERR_CMD_DISALLOWED; + return; + } + /* fragmentation from controller to host not supported, require + * ACL MTU to be at least the LL MTU + */ + if (cmd->acl_mtu < RADIO_LL_LENGTH_OCTETS_RX_MAX) { + ccst->status = BT_HCI_ERR_INVALID_PARAM; + return; + } + + hci_hbuf_total = -cmd->acl_pkts; +} + +static void host_num_completed_packets(struct net_buf *buf, + struct net_buf **evt) +{ + struct bt_hci_cp_host_num_completed_packets *cmd = (void *)buf->data; + struct bt_hci_evt_cc_status *ccst; + u32_t count = 0; + int i; + + /* special case, no event returned except for error conditions */ + if (hci_hbuf_total <= 0) { + ccst = cmd_complete(evt, sizeof(*ccst)); + ccst->status = BT_HCI_ERR_CMD_DISALLOWED; + return; + } else if (!conn_count) { + ccst = cmd_complete(evt, sizeof(*ccst)); + ccst->status = BT_HCI_ERR_INVALID_PARAM; + return; + } + + /* leave *evt == NULL so no event is generated */ + for (i = 0; i < cmd->num_handles; i++) { + count += cmd->h[i].count; + } + + hci_hbuf_acked += count; + k_poll_signal(hbuf_signal, 0x0); } +#endif static int ctrl_bb_cmd_handle(u8_t ocf, struct net_buf *cmd, struct net_buf **evt) @@ -184,6 +298,19 @@ static int ctrl_bb_cmd_handle(u8_t ocf, struct net_buf *cmd, reset(cmd, evt); break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + case BT_OCF(BT_HCI_OP_SET_CTL_TO_HOST_FLOW): + set_ctl_to_host_flow(cmd, evt); + break; + + case BT_OCF(BT_HCI_OP_HOST_BUFFER_SIZE): + host_buffer_size(cmd, evt); + break; + + case BT_OCF(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS): + host_num_completed_packets(cmd, evt); + break; +#endif default: return -EINVAL; } @@ -1082,6 +1209,7 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b, } +#if defined(CONFIG_BLUETOOTH_CONN) static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { @@ -1106,6 +1234,8 @@ static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle, sep->latency = sys_cpu_to_le16(radio_cc->latency); sep->supv_timeout = sys_cpu_to_le16(radio_cc->timeout); sep->clock_accuracy = radio_cc->mca; + + conn_count++; } static void disconn_complete(struct pdu_data *pdu_data, u16_t handle, @@ -1123,6 +1253,8 @@ static void disconn_complete(struct pdu_data *pdu_data, u16_t handle, ep->status = 0x00; ep->handle = sys_cpu_to_le16(handle); ep->reason = *((u8_t *)pdu_data); + + conn_count--; } static void le_conn_update_complete(struct pdu_data *pdu_data, u16_t handle, @@ -1163,6 +1295,7 @@ static void enc_refresh_complete(struct pdu_data *pdu_data, u16_t handle, ep->status = 0x00; ep->handle = sys_cpu_to_le16(handle); } +#endif #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) static void auth_payload_timeout_exp(struct pdu_data *pdu_data, u16_t handle, @@ -1212,6 +1345,7 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, le_advertising_report(pdu_data, b, buf); break; +#if defined(CONFIG_BLUETOOTH_CONN) case NODE_RX_TYPE_CONNECTION: le_conn_complete(pdu_data, handle, buf); break; @@ -1227,6 +1361,7 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, case NODE_RX_TYPE_ENC_REFRESH: enc_refresh_complete(pdu_data, handle, buf); break; +#endif #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) case NODE_RX_TYPE_APTO: @@ -1460,6 +1595,7 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx, } } +#if defined(CONFIG_BLUETOOTH_CONN) void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) { struct bt_hci_acl_hdr *acl; @@ -1484,6 +1620,13 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) acl->len = sys_cpu_to_le16(pdu_data->len); data = (void *)net_buf_add(buf, pdu_data->len); memcpy(data, &pdu_data->payload.lldata[0], pdu_data->len); +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + if (hci_hbuf_total > 0) { + LL_ASSERT((hci_hbuf_sent - hci_hbuf_acked) < + hci_hbuf_total); + hci_hbuf_sent++; + } +#endif break; default: @@ -1492,6 +1635,7 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) } } +#endif void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) { @@ -1534,3 +1678,54 @@ bool hci_evt_is_discardable(struct radio_pdu_node_rx *node_rx) return false; } } + +s8_t hci_get_class(struct radio_pdu_node_rx *node_rx) +{ + struct pdu_data *pdu_data; + + pdu_data = (struct pdu_data *)node_rx->pdu_data; + + if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU) { + + switch (node_rx->hdr.type) { + case NODE_RX_TYPE_REPORT: +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_INDICATION) + case NODE_RX_TYPE_ADV_INDICATION: +#endif +#if defined(CONFIG_BLUETOOTH_CONTROLLER_PROFILE_ISR) + case NODE_RX_TYPE_PROFILE: +#endif + return HCI_CLASS_EVT_DISCARDABLE; + case NODE_RX_TYPE_CONNECTION: + return HCI_CLASS_EVT_REQUIRED; + case NODE_RX_TYPE_TERMINATE: + case NODE_RX_TYPE_CONN_UPDATE: + case NODE_RX_TYPE_ENC_REFRESH: +#if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI) + case NODE_RX_TYPE_RSSI: +#endif +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) + case NODE_RX_TYPE_APTO: +#endif +#if defined(CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2) + case NODE_RX_TYPE_CHAN_SEL_ALGO: +#endif + return HCI_CLASS_EVT_CONNECTION; + default: + return -1; + } + + } else if (pdu_data->ll_id == PDU_DATA_LLID_CTRL) { + return HCI_CLASS_EVT_CONNECTION; + } else { + return HCI_CLASS_ACL_DATA; + } +} + +void hci_init(struct k_poll_signal *signal_host_buf) +{ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + hbuf_signal = signal_host_buf; +#endif + reset(NULL, NULL); +} diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index 19c6476bbb900..58224cabb14e7 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,9 @@ #include "hal/debug.h" +#define NODE_RX(_node) CONTAINER_OF(_node, struct radio_pdu_node_rx, \ + hdr.onion.node) + static K_SEM_DEFINE(sem_prio_recv, 0, UINT_MAX); static K_FIFO_DEFINE(recv_fifo); @@ -51,23 +55,30 @@ static u32_t prio_ts; static u32_t rx_ts; #endif +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) +static struct k_poll_signal hbuf_signal = K_POLL_SIGNAL_INITIALIZER(); +static sys_slist_t hbuf_pend; +static s32_t hbuf_count; +#endif + static void prio_recv_thread(void *p1, void *p2, void *p3) { while (1) { struct radio_pdu_node_rx *node_rx; - struct net_buf *buf; u8_t num_cmplt; u16_t handle; while ((num_cmplt = radio_rx_get(&node_rx, &handle))) { +#if defined(CONFIG_BLUETOOTH_CONN) + struct net_buf *buf; buf = bt_buf_get_rx(K_FOREVER); bt_buf_set_type(buf, BT_BUF_EVT); hci_num_cmplt_encode(buf, handle, num_cmplt); BT_DBG("Num Complete: 0x%04x:%u", handle, num_cmplt); bt_recv_prio(buf); - k_yield(); +#endif } if (node_rx) { @@ -95,44 +106,209 @@ static void prio_recv_thread(void *p1, void *p2, void *p3) } } -static void recv_thread(void *p1, void *p2, void *p3) +static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx, + s8_t class) { - while (1) { - struct radio_pdu_node_rx *node_rx; - struct pdu_data *pdu_data; - struct net_buf *buf; + struct net_buf *buf = NULL; + + /* Check if we need to generate an HCI event or ACL data */ + switch (class) { + case HCI_CLASS_EVT_DISCARDABLE: + case HCI_CLASS_EVT_REQUIRED: + case HCI_CLASS_EVT_CONNECTION: + if (class == HCI_CLASS_EVT_DISCARDABLE) { + buf = bt_buf_get_rx(K_NO_WAIT); + } else { + buf = bt_buf_get_rx(K_FOREVER); + } + if (buf) { + bt_buf_set_type(buf, BT_BUF_EVT); + hci_evt_encode(node_rx, buf); + } + break; +#if defined(CONFIG_BLUETOOTH_CONN) + case HCI_CLASS_ACL_DATA: + /* generate ACL data */ + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_ACL_IN); + hci_acl_encode(node_rx, buf); + break; +#endif + default: + LL_ASSERT(0); + break; + } - BT_DBG("RX node get"); - node_rx = k_fifo_get(&recv_fifo, K_FOREVER); - BT_DBG("RX node dequeued"); - - pdu_data = (void *)node_rx->pdu_data; - /* Check if we need to generate an HCI event or ACL - * data - */ - if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU || - pdu_data->ll_id == PDU_DATA_LLID_CTRL) { - /* generate a (non-priority) HCI event */ - if (hci_evt_is_discardable(node_rx)) { - buf = bt_buf_get_rx(K_NO_WAIT); - } else { - buf = bt_buf_get_rx(K_FOREVER); + radio_rx_fc_set(node_rx->hdr.handle, 0); + node_rx->hdr.onion.next = 0; + radio_rx_mem_release(&node_rx); + + return buf; +} + +static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx) +{ + s8_t class = hci_get_class(node_rx); + struct net_buf *buf = NULL; + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + if (hbuf_count != -1) { + bool pend = !sys_slist_is_empty(&hbuf_pend); + + /* controller to host flow control enabled */ + switch (class) { + case HCI_CLASS_EVT_DISCARDABLE: + case HCI_CLASS_EVT_REQUIRED: + break; + case HCI_CLASS_EVT_CONNECTION: + /* for conn-related events, only pend is relevant */ + hbuf_count = 1; + /* fallthrough */ + case HCI_CLASS_ACL_DATA: + if (pend || !hbuf_count) { + sys_slist_append(&hbuf_pend, + &node_rx->hdr.onion.node); + return NULL; + } + break; + default: + LL_ASSERT(0); + break; + } + } +#endif + + /* process regular node from radio */ + buf = encode_node(node_rx, class); + + return buf; +} + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) +static inline struct net_buf *process_hbuf(void) +{ + /* shadow total count in case of preemption */ + s32_t hbuf_total = hci_hbuf_total; + struct net_buf *buf = NULL; + int reset; + + reset = atomic_test_and_clear_bit(&hci_state_mask, HCI_STATE_BIT_RESET); + if (reset) { + /* flush queue, no need to free, the LL has already done it */ + sys_slist_init(&hbuf_pend); + } + + if (hbuf_total > 0) { + struct radio_pdu_node_rx *node_rx = NULL; + s8_t class, next_class = -1; + sys_snode_t *node = NULL; + + /* available host buffers */ + hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked); + + /* host acked ACL packets, try to dequeue from hbuf */ + node = sys_slist_peek_head(&hbuf_pend); + if (node) { + node_rx = NODE_RX(node); + class = hci_get_class(node_rx); + switch (class) { + case HCI_CLASS_EVT_CONNECTION: + node = sys_slist_get(&hbuf_pend); + break; + case HCI_CLASS_ACL_DATA: + if (hbuf_count) { + node = sys_slist_get(&hbuf_pend); + hbuf_count--; + } else { + /* no buffers, HCI will signal */ + node = NULL; + } + break; + case HCI_CLASS_EVT_DISCARDABLE: + case HCI_CLASS_EVT_REQUIRED: + default: + LL_ASSERT(0); + break; } - if (buf) { - bt_buf_set_type(buf, BT_BUF_EVT); - hci_evt_encode(node_rx, buf); + if (node) { + struct radio_pdu_node_rx *next; + bool empty = true; + + node_rx = NODE_RX(node); + node = sys_slist_peek_head(&hbuf_pend); + if (node) { + next = NODE_RX(node); + next_class = hci_get_class(next); + } + empty = sys_slist_is_empty(&hbuf_pend); + + buf = encode_node(node_rx, class); + if (!empty && (class == HCI_CLASS_EVT_CONNECTION || + (class == HCI_CLASS_ACL_DATA && + hbuf_count))) { + /* more to process, schedule an + * iteration + */ + + k_poll_signal(&hbuf_signal, 0x0); + } } - } else { - /* generate ACL data */ - buf = bt_buf_get_rx(K_FOREVER); - bt_buf_set_type(buf, BT_BUF_ACL_IN); - hci_acl_encode(node_rx, buf); } + } else { + hbuf_count = -1; + } + + return buf; +} +#endif - radio_rx_fc_set(node_rx->hdr.handle, 0); - node_rx->hdr.onion.next = 0; - radio_rx_mem_release(&node_rx); +static void recv_thread(void *p1, void *p2, void *p3) +{ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + /* @todo: check if the events structure really needs to be static */ + static struct k_poll_event events[2] = { + K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SIGNAL, + K_POLL_MODE_NOTIFY_ONLY, + &hbuf_signal, 0), + K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, + K_POLL_MODE_NOTIFY_ONLY, + &recv_fifo, 0), + }; +#endif + + while (1) { + struct radio_pdu_node_rx *node_rx = NULL; + struct net_buf *buf = NULL; + + BT_DBG("blocking"); +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + int err; + + err = k_poll(events, 2, K_FOREVER); + LL_ASSERT(err == 0); + if (events[0].state == K_POLL_STATE_SIGNALED) { + events[0].signal->signaled = 0; + } else if (events[1].state == + K_POLL_STATE_FIFO_DATA_AVAILABLE) { + node_rx = k_fifo_get(events[1].fifo, 0); + } + + events[0].state = K_POLL_STATE_NOT_READY; + events[1].state = K_POLL_STATE_NOT_READY; + + /* process host buffers first if any */ + buf = process_hbuf(); + +#else + node_rx = k_fifo_get(&recv_fifo, K_FOREVER); +#endif + BT_DBG("unblocked"); + + if (node_rx && !buf) { + /* process regular node from radio */ + buf = process_node(node_rx); + } if (buf) { if (buf->len) { @@ -161,13 +337,11 @@ static int cmd_handle(struct net_buf *buf) struct net_buf *evt; evt = hci_cmd_handle(buf); - if (!evt) { - return -EINVAL; + if (evt) { + BT_DBG("Replying with event of %u bytes", evt->len); + bt_recv_prio(evt); } - BT_DBG("Replying with event of %u bytes", evt->len); - bt_recv_prio(evt); - return 0; } @@ -185,9 +359,11 @@ static int hci_driver_send(struct net_buf *buf) type = bt_buf_get_type(buf); switch (type) { +#if defined(CONFIG_BLUETOOTH_CONN) case BT_BUF_ACL_OUT: err = hci_acl_handle(buf); break; +#endif case BT_BUF_CMD: err = cmd_handle(buf); break; @@ -212,12 +388,17 @@ static int hci_driver_open(void) DEBUG_INIT(); err = ll_init(&sem_prio_recv); - if (err) { BT_ERR("LL initialization failed: %u", err); return err; } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) + hci_init(&hbuf_signal); +#else + hci_init(NULL); +#endif + k_thread_spawn(prio_recv_thread_stack, sizeof(prio_recv_thread_stack), prio_recv_thread, NULL, NULL, NULL, K_PRIO_COOP(6), 0, K_NO_WAIT); diff --git a/subsys/bluetooth/controller/hci/hci_internal.h b/subsys/bluetooth/controller/hci/hci_internal.h index 679ce4ea5e96a..eba9198b21bf7 100644 --- a/subsys/bluetooth/controller/hci/hci_internal.h +++ b/subsys/bluetooth/controller/hci/hci_internal.h @@ -8,10 +8,27 @@ #ifndef _HCI_CONTROLLER_H_ #define _HCI_CONTROLLER_H_ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC) +extern s32_t hci_hbuf_total; +extern u32_t hci_hbuf_sent; +extern u32_t hci_hbuf_acked; +extern atomic_t hci_state_mask; + +#define HCI_STATE_BIT_RESET 0 +#endif + +#define HCI_CLASS_EVT_REQUIRED 0 +#define HCI_CLASS_EVT_DISCARDABLE 1 +#define HCI_CLASS_EVT_CONNECTION 2 +#define HCI_CLASS_ACL_DATA 3 + +void hci_init(struct k_poll_signal *signal_host_buf); struct net_buf *hci_cmd_handle(struct net_buf *cmd); -int hci_acl_handle(struct net_buf *acl); void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); +s8_t hci_get_class(struct radio_pdu_node_rx *node_rx); +#if defined(CONFIG_BLUETOOTH_CONN) +int hci_acl_handle(struct net_buf *acl); void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num); -bool hci_evt_is_discardable(struct radio_pdu_node_rx *node_rx); +#endif #endif /* _HCI_CONTROLLER_H_ */ diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.h b/subsys/bluetooth/controller/ll_sw/ctrl.h index c6fdb37428539..fcb0351cdd070 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl.h @@ -250,6 +250,7 @@ struct radio_le_chan_sel_algo { struct radio_pdu_node_rx_hdr { union { + sys_snode_t node; /* used by slist */ void *next; /* used also by k_fifo once pulled */ void *link; u8_t packet_release_last; diff --git a/subsys/net/ip/l2/bluetooth.c b/subsys/net/ip/l2/bluetooth.c index 103555b18f410..1ce112f914f8a 100644 --- a/subsys/net/ip/l2/bluetooth.c +++ b/subsys/net/ip/l2/bluetooth.c @@ -138,6 +138,7 @@ static void ipsp_connected(struct bt_l2cap_chan *chan) ll.addr = ctxt->dst.val; ll.len = sizeof(ctxt->dst.val); + ll.type = NET_LINK_BLUETOOTH; /* Add remote link-local address to the nbr cache to avoid sending ns: * https://tools.ietf.org/html/rfc7668#section-3.2.3 diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 7e15e5b54a63b..3b991b2484b9a 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -1673,6 +1673,11 @@ void net_if_init(struct k_sem *startup_sync) #endif } + if (iface == __net_if_start) { + NET_WARN("There is no network interface to work with!"); + return; + } + k_thread_spawn(tx_stack, sizeof(tx_stack), (k_thread_entry_t)net_if_tx_thread, startup_sync, NULL, NULL, K_PRIO_COOP(7), diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index eaa77a2370904..0447b81c07a68 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -216,6 +216,7 @@ int net_tcp_release(struct net_tcp *tcp) net_pkt_unref(pkt); } + tcp->ack_timer_cancelled = true; k_delayed_work_cancel(&tcp->ack_timer); k_timer_stop(&tcp->retry_timer); k_sem_reset(&tcp->connect_wait); diff --git a/tests/benchmarks/timing_info/Makefile b/tests/benchmarks/timing_info/Makefile new file mode 100644 index 0000000000000..4de50f93d4d3b --- /dev/null +++ b/tests/benchmarks/timing_info/Makefile @@ -0,0 +1,4 @@ +BOARD ?= qemu_x86 +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.inc diff --git a/tests/benchmarks/timing_info/README.txt b/tests/benchmarks/timing_info/README.txt new file mode 100644 index 0000000000000..1586b1a9ea2e7 --- /dev/null +++ b/tests/benchmarks/timing_info/README.txt @@ -0,0 +1,111 @@ +Title: Timing Information + +Description: + +Timing measurements for the following features of the OS. +1. Context switch + Time taken to compete the context switch, i.e time spent in _Swap function. +2. Interrupt latency + Time taken from the start of the common interrupt handler till the + actual ISR handler being called. +3. Tick overhead + Time spent by the cpu in the tick handler. +4. Thread Creation + Time spent in creating a thread. +5. Thread cancel + Time taken to cancel the thread which is not yet started execution. + So the time taken to complete the function call is measured. +6. Thread abort + Time taken to abort the thread which has already started execution. + So the time measured is from the start of the function call until the + another thread is swapped in. +7. Thread Suspend + The time measured is from the start of the function call until the current + thread is suspended and another thread is swapped in. +8. Thread Resume + The time measured is from the start of the function call until the required + thread is resumed by swap operation. +9. Thread Yield + The time measured is from the start of the function call until the higher priority + thread is swapped in. +10. Thread Sleep + The time measured is from the start of the function call until the current + thread is put on the timeout queue and another thread is swapped in. +11. Heap Malloc + The time to allocate heap memory in fixed size chunks. Continuously allocate + the memory from the pool. Average time taken to complete the function call + is measured. +12. Heap Free + Time to free heap memory in fixed size chunks. Continuously free + the memory that was allocated. Average time taken to complete the function call + is measured. +13. Semaphore Take with context switch + Taking a semaphore causes a thread waiting on the semaphore to be swapped in. + Thus Time measured is the time taken from the function call till the waiting + thread is swapped in. +14. Semaphore Give with context switch + Giving a semaphore causes a thread waiting on the semaphore to be swapped + in (higher priority). + Thus Time measured is the time taken from the function call till the waiting + thread is swapped in. +15. Semaphore Take without context switch + Time taken to take the semaphore. Thus time to complete the function + call is measured. +16. Semaphore Give without context switch + Time taken to give the semaphore. Thus time to complete the function + call is measured. +17. Mutex lock + Time taken to lock the mutex. Thus time to complete the function + call is measured. +18. Mutex unlock + Time taken to unlock the mutex. Thus time to complete the function + call is measured. +19. Message Queue Put with context switch + A thread is waiting for a message to arrive. The time taken from the start + of the function call till the waiting thread is swapped in is measured. +20. Message Queue Put without context switch + The time taken to complete the function call is measured. +21. Message Queue get with context switch + A thread has gone into waiting because the message queue is full. + When a get occurs this thread gets free to execute. The time taken from + the start of the function call till the waiting thread is + swapped in is measured. +22. Message Queue get without context switch + The time taken to complete the function call is measured. +23. MailBox synchronous put + The time taken from the start of the function call till the waiting thread + is swapped in is measured. +24. MailBox synchronous get + The time taken from the start of the function call till the waiting thread + is swapped in is measured. +25. MailBox asynchronous put + The time taken to complete the function call is measured. +26. MailBox get without context switch + The time taken to complete the function call is measured. + + +-------------------------------------------------------------------------------- + +Building and Running Project: + +This benchmark outputs to the console. It can be built and executed +on QEMU as follows: + + make qemu + +-------------------------------------------------------------------------------- + +Troubleshooting: + +Problems caused by out-dated project information can be addressed by +issuing one of the following commands then rebuilding the project: + + make clean # discard results of previous builds + # but keep existing configuration info +or + make pristine # discard results of previous builds + # and restore pre-defined configuration info + +-------------------------------------------------------------------------------- + +Sample Output: diff --git a/tests/benchmarks/timing_info/prj.conf b/tests/benchmarks/timing_info/prj.conf new file mode 100644 index 0000000000000..4cd820b63eeeb --- /dev/null +++ b/tests/benchmarks/timing_info/prj.conf @@ -0,0 +1,4 @@ +CONFIG_EXECUTION_BENCHMARKING=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_HEAP_MEM_POOL_SIZE=256 +CONFIG_MAIN_STACK_SIZE=2048 \ No newline at end of file diff --git a/tests/benchmarks/timing_info/src/Makefile b/tests/benchmarks/timing_info/src/Makefile new file mode 100644 index 0000000000000..5219ad793c368 --- /dev/null +++ b/tests/benchmarks/timing_info/src/Makefile @@ -0,0 +1,7 @@ +ccflags-y += -I$(ZEPHYR_BASE)/tests/include + +obj-$(CONFIG_EXECUTION_BENCHMARKING) += main_benchmark.o +obj-$(CONFIG_EXECUTION_BENCHMARKING) += thread_bench.o +obj-$(CONFIG_EXECUTION_BENCHMARKING) += yield_bench.o +obj-$(CONFIG_EXECUTION_BENCHMARKING) += semaphore_bench.o +obj-$(CONFIG_EXECUTION_BENCHMARKING) += msg_passing_bench.o diff --git a/tests/benchmarks/timing_info/src/main_benchmark.c b/tests/benchmarks/timing_info/src/main_benchmark.c new file mode 100644 index 0000000000000..2dec607142755 --- /dev/null +++ b/tests/benchmarks/timing_info/src/main_benchmark.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2015 Wind River Systems, Inc. + * Copyright (c) 2016 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Measure time + * + */ +#include +#include +#include +#include +#include "timing_info.h" + +void main(void) +{ + u32_t freq = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000000; + + TC_START("Time Measurement"); + TC_PRINT("Timing Results: Clock Frequency: %d MHz\n", freq); + + /*******************************************************************/ + /* System parameters and thread Benchmarking*/ + system_thread_bench(); + + /*******************************************************************/ + /* Thread yield*/ + yield_bench(); + + /*******************************************************************/ + /* heap Memory benchmarking*/ + heap_malloc_free_bench(); + + /*******************************************************************/ + /* Semaphore take and get*/ + semaphore_bench(); + + /*******************************************************************/ + /* mutex lock and unlock*/ + mutex_bench(); + + /*******************************************************************/ + /* mutex lock and unlock*/ + msg_passing_bench(); + + + TC_PRINT("Timing Measurement finished\n"); + + /* for sanity regression test utility. */ + TC_END_RESULT(TC_PASS); + TC_END_REPORT(TC_PASS); + +} \ No newline at end of file diff --git a/tests/benchmarks/timing_info/src/msg_passing_bench.c b/tests/benchmarks/timing_info/src/msg_passing_bench.c new file mode 100644 index 0000000000000..91bc447bbb7fd --- /dev/null +++ b/tests/benchmarks/timing_info/src/msg_passing_bench.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2013-2015 Wind River Systems, Inc. + * Copyright (c) 2016 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "timing_info.h" + +extern char sline[]; + +/* mailbox*/ +/* K_MBOX_DEFINE(test_msg_queue) */ +K_MSGQ_DEFINE(benchmark_q, sizeof(int), 10, 4); +K_MSGQ_DEFINE(benchmark_q_get, sizeof(int), 3, 4); +K_MBOX_DEFINE(benchmark_mbox); + +/* Declare a semaphore for the msgq*/ +K_SEM_DEFINE(mbox_sem, 1, 1); + +/* common location for the swap to write the tsc data*/ +extern u32_t __read_swap_end_tsc_value; +extern u64_t __common_var_swap_end_tsc; + +/* location of the time stamps*/ +u64_t __msg_q_put_state; +u64_t __msg_q_get_state; + +u64_t __msg_q_put_w_cxt_start_tsc; +u64_t __msg_q_put_w_cxt_end_tsc; + +u64_t __msg_q_put_wo_cxt_start_tsc; /* without context switch */ +u64_t __msg_q_put_wo_cxt_end_tsc; + +u64_t __msg_q_get_w_cxt_start_tsc; +u64_t __msg_q_get_w_cxt_end_tsc; + +u64_t msg_q_get_wo_cxt_start_tsc; +u64_t msg_q_get_wo_cxt_end_tsc; + +u32_t __mbox_sync_put_state; +u64_t mbox_sync_put_start_tsc; +u64_t mbox_sync_put_end_tsc; + +u32_t __mbox_sync_get_state; +u64_t mbox_sync_get_start_tsc; +u64_t mbox_sync_get_end_tsc; + +u64_t mbox_async_put_start_tsc; +u64_t mbox_async_put_end_tsc; + +u64_t mbox_get_w_cxt_start_tsc; +u64_t mbox_get_w_cxt_end_tsc; + +/*For benchmarking msg queues*/ +k_tid_t producer_w_cxt_switch_tid; +k_tid_t producer_wo_cxt_switch_tid; +k_tid_t producer_get_w_cxt_switch_tid; +k_tid_t consumer_get_w_cxt_switch_tid; +k_tid_t consumer_tid; +k_tid_t thread_mbox_sync_put_send_tid; +k_tid_t thread_mbox_sync_put_receive_tid; +k_tid_t thread_mbox_sync_get_send_tid; +k_tid_t thread_mbox_sync_get_receive_tid; +k_tid_t thread_mbox_async_put_send_tid; +k_tid_t thread_mbox_async_put_receive_tid; + +/* To time thread creation*/ +#define STACK_SIZE 500 +extern char __noinit __stack my_stack_area[STACK_SIZE]; +extern char __noinit __stack my_stack_area_0[STACK_SIZE]; + +/* thread functions*/ +void thread_producer_msgq_w_cxt_switch(void *p1, void *p2, void *p3); +void thread_producer_msgq_wo_cxt_switch(void *p1, void *p2, void *p3); + +void thread_producer_get_msgq_w_cxt_switch(void *p1, void *p2, void *p3); +void thread_consumer_get_msgq_w_cxt_switch(void *p1, void *p2, void *p3); + +void thread_mbox_sync_put_send(void *p1, void *p2, void *p3); +void thread_mbox_sync_put_receive(void *p1, void *p2, void *p3); + +void thread_mbox_sync_get_send(void *p1, void *p2, void *p3); +void thread_mbox_sync_get_receive(void *p1, void *p2, void *p3); + +void thread_mbox_async_put_send(void *p1, void *p2, void *p3); +void thread_mbox_async_put_receive(void *p1, void *p2, void *p3); + +volatile u64_t time_check; +int received_data_get; +int received_data_consumer; +int data_to_send; + +void msg_passing_bench(void) +{ + DECLARE_VAR(msg_q, put_w_cxt) + DECLARE_VAR(msg_q, put_wo_cxt) + + DECLARE_VAR(msg_q, get_w_cxt) + DECLARE_VAR(msg_q, get_wo_cxt) + + DECLARE_VAR(mbox, sync_put) + DECLARE_VAR(mbox, sync_get) + DECLARE_VAR(mbox, async_put) + + DECLARE_VAR(mbox, get_w_cxt) + + + /*******************************************************************/ + /* Msg queue for put*/ + int received_data = 0; + + producer_w_cxt_switch_tid = + k_thread_spawn(my_stack_area, STACK_SIZE, + thread_producer_msgq_w_cxt_switch, NULL, + NULL, NULL, 2 /*priority*/, 0, 50); + + u32_t msg_status = k_msgq_get(&benchmark_q, &received_data, 300); + + producer_wo_cxt_switch_tid = + k_thread_spawn(my_stack_area_0, STACK_SIZE, + thread_producer_msgq_wo_cxt_switch, + NULL, NULL, NULL, -2 /*priority*/, 0, 0); + + k_thread_abort(producer_w_cxt_switch_tid); + k_thread_abort(producer_wo_cxt_switch_tid); + __msg_q_put_w_cxt_end_tsc = ((u32_t)__common_var_swap_end_tsc); + ARG_UNUSED(msg_status); + + /*******************************************************************/ + + /* Msg queue for get*/ + + producer_get_w_cxt_switch_tid = + k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_producer_get_msgq_w_cxt_switch, NULL, + NULL, NULL, 1 /*priority*/, 0, 50); + consumer_get_w_cxt_switch_tid = + k_thread_spawn(my_stack_area_0, + STACK_SIZE, + thread_consumer_get_msgq_w_cxt_switch, + NULL, NULL, NULL, + 2 /*priority*/, 0, 50); + k_sleep(2000); /* make the main thread sleep */ + k_thread_abort(producer_get_w_cxt_switch_tid); + __msg_q_get_w_cxt_end_tsc = (__common_var_swap_end_tsc); + + /*******************************************************************/ + + /* Msg queue for get*/ + /* from previous step got the msg_q full now just do a simple read*/ + msg_q_get_wo_cxt_start_tsc = OS_GET_TIME(); + + received_data_get = k_msgq_get(&benchmark_q_get, + &received_data_consumer, + K_NO_WAIT); + + msg_q_get_wo_cxt_end_tsc = OS_GET_TIME(); + + + /*******************************************************************/ + + /* Msg box to benchmark sync put */ + + thread_mbox_sync_put_send_tid = + k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_mbox_sync_put_send, + NULL, NULL, NULL, + 2 /*priority*/, 0, 0); + thread_mbox_sync_put_receive_tid = + k_thread_spawn(my_stack_area_0, + STACK_SIZE, + thread_mbox_sync_put_receive, + NULL, NULL, NULL, + 1 /*priority*/, 0, 0); + k_sleep(1000); /* make the main thread sleep */ + mbox_sync_put_end_tsc = (__common_var_swap_end_tsc); + + /*******************************************************************/ + + /* Msg box to benchmark sync get */ + + thread_mbox_sync_get_send_tid = + k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_mbox_sync_get_send, + NULL, NULL, NULL, + 1 /*prio*/, 0, 0); + thread_mbox_sync_get_receive_tid = + k_thread_spawn(my_stack_area_0, + STACK_SIZE, + thread_mbox_sync_get_receive, NULL, + NULL, NULL, 2 /*priority*/, 0, 0); + k_sleep(1000); /* make the main thread sleep */ + mbox_sync_get_end_tsc = (__common_var_swap_end_tsc); + + /*******************************************************************/ + + /* Msg box to benchmark async put */ + + thread_mbox_async_put_send_tid = + k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_mbox_async_put_send, + NULL, NULL, NULL, + 2 /*prio*/, 0, 0); + thread_mbox_async_put_receive_tid = + k_thread_spawn(my_stack_area_0, + STACK_SIZE, + thread_mbox_async_put_receive, + NULL, NULL, NULL, + 3 /*priority*/, 0, 0); + k_sleep(1000); /* make the main thread sleep */ + + /*******************************************************************/ + int single_element_buffer = 0; + struct k_mbox_msg rx_msg = { + .size = sizeof(int), + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY + }; + mbox_get_w_cxt_start_tsc = OS_GET_TIME(); + + k_mbox_get(&benchmark_mbox, &rx_msg, &single_element_buffer, 300); + + mbox_get_w_cxt_end_tsc = OS_GET_TIME(); + + /*******************************************************************/ + + /* calculation for msg put with context switch */ + CALCULATE_TIME(__, msg_q, put_w_cxt) + + /* calculation for msg put without context switch */ + CALCULATE_TIME(__, msg_q, put_wo_cxt) + + /* calculation for msg get */ + CALCULATE_TIME(__, msg_q, get_w_cxt) + + /* calculation for msg get without context switch */ + CALCULATE_TIME(, msg_q, get_wo_cxt) + + /*calculation for msg box for sync put + * (i.e with a context to make the pending rx ready) + */ + CALCULATE_TIME(, mbox, sync_put) + + /*calculation for msg box for sync get + * (i.e with a context to make the pending tx ready) + */ + CALCULATE_TIME(, mbox, sync_get) + + /* calculation for msg box for async put */ + CALCULATE_TIME(, mbox, async_put) + + /* calculation for msg box for get without any context switch */ + CALCULATE_TIME(, mbox, get_w_cxt) + + /*******************************************************************/ + + /* Only print lower 32bit of time result */ + PRINT_F("Message Queue Put with context switch", + (u32_t)((__msg_q_put_w_cxt_end_tsc - + __msg_q_put_w_cxt_start_tsc) & 0xFFFFFFFFULL), + (u32_t) (total_msg_q_put_w_cxt_time & 0xFFFFFFFFULL)); + + PRINT_F("Message Queue Put without context switch", + (u32_t)((__msg_q_put_wo_cxt_end_tsc - + __msg_q_put_wo_cxt_start_tsc) & 0xFFFFFFFFULL), + (u32_t) (total_msg_q_put_wo_cxt_time & 0xFFFFFFFFULL)); + + PRINT_F("Message Queue get with context switch", + (u32_t)((__msg_q_get_w_cxt_end_tsc - + __msg_q_get_w_cxt_start_tsc) & 0xFFFFFFFFULL), + (u32_t) (total_msg_q_get_w_cxt_time & 0xFFFFFFFFULL)); + + PRINT_F("Message Queue get without context switch", + (u32_t)((msg_q_get_wo_cxt_end_tsc - + msg_q_get_wo_cxt_start_tsc) & 0xFFFFFFFFULL), + (u32_t) (total_msg_q_get_wo_cxt_time & 0xFFFFFFFFULL)); + + PRINT_F("MailBox synchronous put", + (u32_t)((mbox_sync_put_end_tsc - mbox_sync_put_start_tsc) + & 0xFFFFFFFFULL), + (u32_t) (total_mbox_sync_put_time & 0xFFFFFFFFULL)); + + PRINT_F("MailBox synchronous get", + (u32_t)((mbox_sync_get_end_tsc - mbox_sync_get_start_tsc) + & 0xFFFFFFFFULL), + (u32_t) (total_mbox_sync_get_time & 0xFFFFFFFFULL)); + + PRINT_F("MailBox asynchronous put", + (u32_t)((mbox_async_put_end_tsc - mbox_async_put_start_tsc) + & 0xFFFFFFFFULL), + (u32_t) (total_mbox_async_put_time & 0xFFFFFFFFULL)); + + PRINT_F("MailBox get without context switch", + (u32_t)((mbox_get_w_cxt_end_tsc - mbox_get_w_cxt_start_tsc) + & 0xFFFFFFFFULL), + (u32_t) (total_mbox_get_w_cxt_time & 0xFFFFFFFFULL)); + +} + +void thread_producer_msgq_w_cxt_switch(void *p1, void *p2, void *p3) +{ + int data_to_send = 5050; + + __read_swap_end_tsc_value = 1; + __msg_q_put_w_cxt_start_tsc = (u32_t) OS_GET_TIME(); + k_msgq_put(&benchmark_q, &data_to_send, K_NO_WAIT); +} + + +void thread_producer_msgq_wo_cxt_switch(void *p1, void *p2, void *p3) +{ + int data_to_send = 5050; + + __msg_q_put_wo_cxt_start_tsc = OS_GET_TIME(); + k_msgq_put(&benchmark_q, &data_to_send, K_NO_WAIT); + __msg_q_put_wo_cxt_end_tsc = OS_GET_TIME(); +} + + +void thread_producer_get_msgq_w_cxt_switch(void *p1, void *p2, void *p3) +{ + int status = 0; + + while (1) { + if (status == 0) { + data_to_send++; + } + status = k_msgq_put(&benchmark_q_get, &data_to_send, 20); + } +} + +void thread_consumer_get_msgq_w_cxt_switch(void *p1, void *p2, void *p3) +{ + producer_get_w_cxt_switch_tid->base.timeout.delta_ticks_from_prev = + _EXPIRED; + __read_swap_end_tsc_value = 1; + __msg_q_get_w_cxt_start_tsc = OS_GET_TIME(); + received_data_get = k_msgq_get(&benchmark_q_get, + &received_data_consumer, + 300); + time_check = OS_GET_TIME(); +} + + +void thread_mbox_sync_put_send(void *p1, void *p2, void *p3) +{ + int single_element_buffer = 1234; + struct k_mbox_msg tx_msg = { + .size = sizeof(int), + .info = 5050, + .tx_data = &single_element_buffer, + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY, + }; + + mbox_sync_put_start_tsc = OS_GET_TIME(); + __read_swap_end_tsc_value = 1; + k_mbox_put(&benchmark_mbox, &tx_msg, 300); + time_check = OS_GET_TIME(); +} + +void thread_mbox_sync_put_receive(void *p1, void *p2, void *p3) +{ + int single_element_buffer = 1234; + struct k_mbox_msg rx_msg = { + .size = sizeof(int), + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY + }; + + k_mbox_get(&benchmark_mbox, &rx_msg, &single_element_buffer, 300); +} + +void thread_mbox_sync_get_send(void *p1, void *p2, void *p3) +{ + int single_element_buffer = 1234; + struct k_mbox_msg tx_msg = { + .size = sizeof(int), + .info = 5050, + .tx_data = &single_element_buffer, + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY, + }; + + k_mbox_put(&benchmark_mbox, &tx_msg, 300); +} + +void thread_mbox_sync_get_receive(void *p1, void *p2, void *p3) +{ + int single_element_buffer; + struct k_mbox_msg rx_msg = { + .size = sizeof(int), + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY + }; + + __read_swap_end_tsc_value = 1; + mbox_sync_get_start_tsc = OS_GET_TIME(); + k_mbox_get(&benchmark_mbox, &rx_msg, &single_element_buffer, 300); +} + +void thread_mbox_async_put_send(void *p1, void *p2, void *p3) +{ + int single_element_buffer = 1234; + struct k_mbox_msg tx_msg = { + .size = sizeof(int), + .info = 5050, + .tx_data = &single_element_buffer, + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY, + }; + + mbox_async_put_start_tsc = OS_GET_TIME(); + k_mbox_async_put(&benchmark_mbox, &tx_msg, &mbox_sem); + mbox_async_put_end_tsc = OS_GET_TIME(); + k_mbox_async_put(&benchmark_mbox, &tx_msg, &mbox_sem); +} + +void thread_mbox_async_put_receive(void *p1, void *p2, void *p3) +{ + int single_element_buffer; + struct k_mbox_msg rx_msg = { + .size = sizeof(int), + .rx_source_thread = K_ANY, + .tx_target_thread = K_ANY + }; + + k_mbox_get(&benchmark_mbox, &rx_msg, &single_element_buffer, 300); + +} \ No newline at end of file diff --git a/tests/benchmarks/timing_info/src/semaphore_bench.c b/tests/benchmarks/timing_info/src/semaphore_bench.c new file mode 100644 index 0000000000000..dda7febcc7fe3 --- /dev/null +++ b/tests/benchmarks/timing_info/src/semaphore_bench.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include "timing_info.h" + + +extern char sline[]; + +K_SEM_DEFINE(sem_bench, 0, 1); +K_SEM_DEFINE(sem_bench_1, 0, 1); + +/* To time thread creation*/ +#define STACK_SIZE 500 +extern char __noinit __stack my_stack_area[STACK_SIZE]; +extern char __noinit __stack my_stack_area_0[STACK_SIZE]; + +/* u64_t thread_yield_start_tsc[1000]; */ +/* u64_t thread_yield_end_tsc[1000]; */ +u64_t thread_start_time; +u64_t thread_end_time; +u64_t sem_start_time; +u64_t sem_end_time; +u64_t sem_give_start_time; +u64_t sem_give_end_time; + +u32_t swap_called; +u64_t test_time2; +u64_t test_time1; + +void thread_sem0_test(void *p1, void *p2, void *p3); +void thread_sem1_test(void *p1, void *p2, void *p3); +void thread_sem0_give_test(void *p1, void *p2, void *p3); +void thread_sem1_give_test(void *p1, void *p2, void *p3); + +k_tid_t sem0_tid; +k_tid_t sem1_tid; + +extern u64_t __common_var_swap_end_tsc; +extern u32_t __read_swap_end_tsc_value; + +void semaphore_bench(void) +{ + + /* Thread yield*/ + + sem0_tid = k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_sem0_test, NULL, NULL, NULL, + 2 /*priority*/, 0, 0); + sem1_tid = k_thread_spawn(my_stack_area_0, + STACK_SIZE, thread_sem1_test, + NULL, NULL, NULL, + 2 /*priority*/, 0, 0); + + k_sleep(1000); + + + /* u64_t test_time1 = _tsc_read(); */ + sem_end_time = (__common_var_swap_end_tsc); + u32_t sem_cycles = sem_end_time - sem_start_time; + + sem0_tid = k_thread_spawn(my_stack_area, + STACK_SIZE, thread_sem0_give_test, + NULL, NULL, NULL, + 2 /*priority*/, 0, 0); + sem1_tid = k_thread_spawn(my_stack_area_0, + STACK_SIZE, thread_sem1_give_test, + NULL, NULL, NULL, + 2 /*priority*/, 0, 0); + + k_sleep(1000); + sem_give_end_time = (__common_var_swap_end_tsc); + u32_t sem_give_cycles = sem_give_end_time - sem_give_start_time; + + + /* Semaphore without context switch*/ + u32_t sem_give_wo_cxt_start = OS_GET_TIME(); + + k_sem_give(&sem_bench); + u32_t sem_give_wo_cxt_end = OS_GET_TIME(); + u32_t sem_give_wo_cxt_cycles = sem_give_wo_cxt_end - + sem_give_wo_cxt_start; + + u32_t sem_take_wo_cxt_start = OS_GET_TIME(); + + k_sem_take(&sem_bench, 10); + u32_t sem_take_wo_cxt_end = OS_GET_TIME(); + u32_t sem_take_wo_cxt_cycles = sem_take_wo_cxt_end - + sem_take_wo_cxt_start; + + /* TC_PRINT("test_time1 , %d cycles\n", (u32_t)test_time1); */ + /* TC_PRINT("test_time2 , %d cycles\n", (u32_t)test_time2); */ + + PRINT_F("Semaphore Take with context switch", + sem_cycles, SYS_CLOCK_HW_CYCLES_TO_NS(sem_cycles)); + PRINT_F("Semaphore Give with context switch", + sem_give_cycles, SYS_CLOCK_HW_CYCLES_TO_NS(sem_give_cycles)); + + PRINT_F("Semaphore Take without context switch", + sem_take_wo_cxt_cycles, + SYS_CLOCK_HW_CYCLES_TO_NS(sem_take_wo_cxt_cycles)); + PRINT_F("Semaphore Give without context switch", + sem_give_wo_cxt_cycles, + SYS_CLOCK_HW_CYCLES_TO_NS(sem_give_wo_cxt_cycles)); + +} +/******************************************************************************/ +K_MUTEX_DEFINE(mutex0); +void mutex_bench(void) +{ + u32_t mutex_lock_start_tsc; + u32_t mutex_lock_end_tsc; + u32_t mutex_lock_diff = 0; + + u32_t mutex_unlock_start_tsc; + u32_t mutex_unlock_end_tsc; + u32_t mutex_unlock_diff = 0; + + for (int i = 0; i < 1000; i++) { + mutex_lock_start_tsc = OS_GET_TIME(); + k_mutex_lock(&mutex0, 100); + mutex_lock_end_tsc = OS_GET_TIME(); + + mutex_unlock_start_tsc = OS_GET_TIME(); + k_mutex_unlock(&mutex0); + mutex_unlock_end_tsc = OS_GET_TIME(); + + mutex_lock_diff += (mutex_lock_end_tsc - mutex_lock_start_tsc); + mutex_unlock_diff += (mutex_unlock_end_tsc - + mutex_unlock_start_tsc); + } + + PRINT_F("Mutex lock", mutex_lock_diff / 1000, + SYS_CLOCK_HW_CYCLES_TO_NS(mutex_lock_diff / 1000)); + + PRINT_F("Mutex unlock", mutex_unlock_diff / 1000, + SYS_CLOCK_HW_CYCLES_TO_NS(mutex_unlock_diff / 1000)); + +} + +/******************************************************************************/ +void thread_sem1_test(void *p1, void *p2, void *p3) +{ + + k_sem_give(&sem_bench); /* sync the 2 threads*/ + + __read_swap_end_tsc_value = 1; + sem_start_time = OS_GET_TIME(); + k_sem_take(&sem_bench, 10); +} + +u32_t sem_count; +void thread_sem0_test(void *p1, void *p2, void *p3) +{ + k_sem_take(&sem_bench, 10);/* To sync threads */ + + k_sem_give(&sem_bench); + sem_count++; + k_thread_abort(sem0_tid); +} +/******************************************************************************/ +void thread_sem1_give_test(void *p1, void *p2, void *p3) +{ + k_sem_give(&sem_bench); /* sync the 2 threads*/ + + k_sem_take(&sem_bench_1, 1000); /* clear the previous sem_give*/ + /* test_time1 = OS_GET_TIME(); */ +} + +void thread_sem0_give_test(void *p1, void *p2, void *p3) +{ + k_sem_take(&sem_bench, 10);/* To sync threads */ + /* test_time2 = OS_GET_TIME(); */ + + /* To make sure that the sem give will cause a swap to occur */ + k_thread_priority_set(sem1_tid, 1); + + __read_swap_end_tsc_value = 1; + sem_give_start_time = OS_GET_TIME(); + k_sem_give(&sem_bench_1); + +} \ No newline at end of file diff --git a/tests/benchmarks/timing_info/src/thread_bench.c b/tests/benchmarks/timing_info/src/thread_bench.c new file mode 100644 index 0000000000000..d99dc1a69d1b6 --- /dev/null +++ b/tests/benchmarks/timing_info/src/thread_bench.c @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2013-2015 Wind River Systems, Inc. + * Copyright (c) 2016 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Measure time + * + */ +#include +#include +#include +#include +#include "timing_info.h" + +char sline[256]; +/* FILE *output_file = stdout; */ + +/* location of the time stamps*/ +u32_t __read_swap_end_tsc_value; +u64_t __common_var_swap_end_tsc; + +volatile u64_t thread_abort_end_tsc; +volatile u64_t thread_abort_start_tsc; + +/* Thread suspend*/ +volatile u64_t thread_suspend_start_tsc; +volatile u64_t thread_suspend_end_tsc; + +/* Thread resume*/ +volatile u64_t thread_resume_start_tsc; +volatile u64_t thread_resume_end_tsc; + +/* Thread sleep*/ +volatile u64_t thread_sleep_start_tsc; +volatile u64_t thread_sleep_end_tsc; + +/*For benchmarking msg queues*/ +k_tid_t producer_tid; +k_tid_t consumer_tid; + +/* To time thread creation*/ +#define STACK_SIZE 500 +char __noinit __stack my_stack_area[STACK_SIZE]; +char __noinit __stack my_stack_area_0[STACK_SIZE]; + +u32_t __read_swap_end_tsc_value_test = 1; +u64_t dummy_time; +u64_t start_time; +u64_t test_end_time; + +#if CONFIG_X86 +u32_t benchmarking_overhead_swap(void) +{ + + __asm__ __volatile__ ( + "pushl %eax\n\t" + "pushl %edx\n\t" + "rdtsc\n\t" + "mov %eax,start_time\n\t" + "mov %edx,start_time+4\n\t" + "cmp $0x1,__read_swap_end_tsc_value_test\n\t" + "jne time_read_not_needed_test\n\t" + "movw $0x2,__read_swap_end_tsc_value\n\t" + "pushl %eax\n\t" + "pushl %edx\n\t" + "rdtsc\n\t" + "mov %eax,dummy_time\n\t" + "mov %edx,dummy_time+4\n\t" + "pop %edx\n\t" + "pop %eax\n\t" + "time_read_not_needed_test:\n\t" + "rdtsc\n\t" + "mov %eax,test_end_time\n\t" + "mov %edx,test_end_time+4\n\t" + "pop %edx\n\t" + "pop %eax\n\t"); + + /* u64_t end_time = OS_GET_TIME(); */ + return(test_end_time - start_time); +} +#endif + +#if CONFIG_ARM +void read_systick_start_of_swap(void) +{ + __start_swap_tsc = (u32_t)SysTick->VAL; +} + +void read_systick_end_of_swap(void) +{ + if (__read_swap_end_tsc_value == 1) { + __read_swap_end_tsc_value = 2; + __common_var_swap_end_tsc = OS_GET_TIME(); + } +} + +void read_systick_start_of_isr(void) +{ + __start_intr_tsc = (u32_t)SysTick->VAL; +} + +void read_systick_end_of_isr(void) +{ + __end_intr_tsc = (u32_t)SysTick->VAL; +} + +void read_systick_start_of_tick_handler(void) +{ + __start_tick_tsc = (u32_t)SysTick->VAL; +} + +void read_systick_end_of_tick_handler(void) +{ + __end_tick_tsc = (u32_t)SysTick->VAL; +} + +#endif + + + +void test_thread_entry(void *p, void *p1, void *p2) +{ + static int i; + + i++; +} + + +void thread_swap_test(void *p1, void *p2, void *p3) +{ + __read_swap_end_tsc_value = 1; + thread_abort_start_tsc = OS_GET_TIME(); + k_thread_abort(_current); +} + +void thread_suspend_test(void *p1, void *p2, void *p3); +void yield_bench(void); +void heap_malloc_free_bench(void); +void main_sem_bench(void); +void main_mutex_bench(void); +void main_msg_bench(void); + +void system_thread_bench(void) +{ + u64_t total_intr_time; + u64_t total_tick_time; + + /*Thread create*/ + u64_t thread_create_start_tsc; + u64_t thread_create_end_tsc; + + DECLARE_VAR(thread, create) + + /*Thread cancel*/ + u64_t thread_cancel_start_tsc; + u64_t thread_cancel_end_tsc; + DECLARE_VAR(thread, cancel) + + /* Thread Abort*/ + DECLARE_VAR(thread, abort) + + /* Thread Suspend*/ + DECLARE_VAR(thread, suspend) + + /* Thread Resume*/ + DECLARE_VAR(thread, resume) + + + /* to measure context switch time */ + k_thread_spawn(my_stack_area_0, + STACK_SIZE, + thread_swap_test, + NULL, NULL, NULL, + -1 /*priority*/, 0, 0); + + thread_abort_end_tsc = (__common_var_swap_end_tsc); + __end_swap_tsc = __common_var_swap_end_tsc; + + + u32_t total_swap_cycles = __end_swap_tsc - + SUBTRACT_CLOCK_CYCLES(__start_swap_tsc); + + /* Interrupt latency*/ + total_intr_time = SYS_CLOCK_HW_CYCLES_TO_NS(__end_intr_tsc - + __start_intr_tsc); + + /* tick overhead*/ + total_tick_time = SYS_CLOCK_HW_CYCLES_TO_NS(__end_tick_tsc - + __start_tick_tsc); + + /*******************************************************************/ + /* thread create*/ + thread_create_start_tsc = OS_GET_TIME(); + + k_tid_t my_tid = k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_swap_test, + NULL, NULL, NULL, + 5 /*priority*/, 0, 10); + + thread_create_end_tsc = OS_GET_TIME(); + + /* thread Termination*/ + thread_cancel_start_tsc = OS_GET_TIME(); + s32_t ret_value_thread_cancel = k_thread_cancel(my_tid); + + thread_cancel_end_tsc = OS_GET_TIME(); + ARG_UNUSED(ret_value_thread_cancel); + + /* Thread suspend*/ + k_tid_t sus_res_tid = k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_suspend_test, + NULL, NULL, NULL, + -1 /*priority*/, 0, 0); + + thread_suspend_end_tsc = OS_GET_TIME(); + /* At this point test for resume*/ + k_thread_resume(sus_res_tid); + + /* calculation for creation */ + CALCULATE_TIME(, thread, create) + + /* calculation for cancel */ + CALCULATE_TIME(, thread, cancel) + + /* calculation for abort */ + CALCULATE_TIME(, thread, abort) + + /* calculation for suspend */ + CALCULATE_TIME(, thread, suspend) + + /* calculation for resume */ + thread_resume_start_tsc = thread_suspend_end_tsc; + CALCULATE_TIME(, thread, resume) + + /*******************************************************************/ + + /* Only print lower 32bit of time result */ + + PRINT_F("Context switch", + (u32_t)(total_swap_cycles & 0xFFFFFFFFULL), + (u32_t)SYS_CLOCK_HW_CYCLES_TO_NS(total_swap_cycles)); + + /*TC_PRINT("Swap Overhead:%d cycles\n", benchmarking_overhead_swap());*/ + + /*Interrupt latency */ + u32_t intr_latency_cycles = SUBTRACT_CLOCK_CYCLES(__end_intr_tsc) - + SUBTRACT_CLOCK_CYCLES(__start_intr_tsc); + + PRINT_F("Interrupt latency", + (u32_t)(intr_latency_cycles), + (u32_t) (SYS_CLOCK_HW_CYCLES_TO_NS(intr_latency_cycles))); + + /*tick overhead*/ + u32_t tick_overhead_cycles = SUBTRACT_CLOCK_CYCLES(__end_tick_tsc) - + SUBTRACT_CLOCK_CYCLES(__start_tick_tsc); + PRINT_F("Tick overhead", + (u32_t)(tick_overhead_cycles), + (u32_t) (SYS_CLOCK_HW_CYCLES_TO_NS(tick_overhead_cycles))); + + /*thread creation*/ + PRINT_F("Thread Creation", + (u32_t)((thread_create_end_tsc - thread_create_start_tsc) & + 0xFFFFFFFFULL), + (u32_t) (total_thread_create_time & 0xFFFFFFFFULL)); + + /*thread cancel*/ + PRINT_F("Thread cancel", + (u32_t)((thread_cancel_end_tsc - thread_cancel_start_tsc) & + 0xFFFFFFFFULL), + (u32_t) (total_thread_cancel_time & 0xFFFFFFFFULL)); + + /*thread abort*/ + PRINT_F("Thread abort", + (u32_t)((thread_abort_end_tsc - thread_abort_start_tsc) & + 0xFFFFFFFFULL), + (u32_t) (total_thread_abort_time & 0xFFFFFFFFULL)); + + /*thread suspend*/ + PRINT_F("Thread Suspend", + (u32_t)((thread_suspend_end_tsc - thread_suspend_start_tsc) & + 0xFFFFFFFFULL), + (u32_t) (total_thread_suspend_time & 0xFFFFFFFFULL)); + + /*thread resume*/ + PRINT_F("Thread Resume", + (u32_t)((thread_resume_end_tsc - thread_suspend_end_tsc) + & 0xFFFFFFFFULL), + (u32_t) (total_thread_resume_time & 0xFFFFFFFFULL)); + + +} + +void thread_suspend_test(void *p1, void *p2, void *p3) +{ + thread_suspend_start_tsc = OS_GET_TIME(); + k_thread_suspend(_current); + + /* comes to this line once its resumed*/ + thread_resume_end_tsc = OS_GET_TIME(); + + /* k_thread_suspend(_current); */ +} + +void heap_malloc_free_bench(void) +{ + /* heap malloc*/ + u64_t heap_malloc_start_tsc = 0; + u64_t heap_malloc_end_tsc = 0; + + /* heap free*/ + u64_t heap_free_start_tsc = 0; + u64_t heap_free_end_tsc = 0; + + s32_t count = 0; + u32_t sum_malloc = 0; + u32_t sum_free = 0; + + while (count++ != 100) { + heap_malloc_start_tsc = OS_GET_TIME(); + void *allocated_mem = k_malloc(10); + + heap_malloc_end_tsc = OS_GET_TIME(); + if (allocated_mem == NULL) { + TC_PRINT("\n Malloc failed at count %d\n", count); + break; + } + heap_free_start_tsc = OS_GET_TIME(); + k_free(allocated_mem); + heap_free_end_tsc = OS_GET_TIME(); + sum_malloc += heap_malloc_end_tsc - heap_malloc_start_tsc; + sum_free += heap_free_end_tsc - heap_free_start_tsc; + } + + PRINT_F("Heap Malloc", + (u32_t)((sum_malloc / count) & 0xFFFFFFFFULL), + (u32_t)(SYS_CLOCK_HW_CYCLES_TO_NS(sum_malloc / count))); + PRINT_F("Heap Free", + (u32_t)((sum_free / count) & 0xFFFFFFFFULL), + (u32_t)(SYS_CLOCK_HW_CYCLES_TO_NS(sum_free / count))); + +} \ No newline at end of file diff --git a/tests/benchmarks/timing_info/src/timing_info.h b/tests/benchmarks/timing_info/src/timing_info.h new file mode 100644 index 0000000000000..3f69b16ecfb78 --- /dev/null +++ b/tests/benchmarks/timing_info/src/timing_info.h @@ -0,0 +1,95 @@ +#include + + +#define CALCULATE_TIME(special_char, profile, name) \ + { \ + total_##profile##_##name##_time = SYS_CLOCK_HW_CYCLES_TO_NS( \ + special_char##profile##_##name##_end_tsc - \ + special_char##profile##_##name##_start_tsc); \ + } + +/*total_##profile##_##name##_time = + * profile##_##name##_end_us - profile##_##name##_start_us; + */ + +#define DECLARE_VAR(profile, name) \ + u64_t total_##profile##_##name##_time; + +extern u64_t __start_swap_tsc; +extern u64_t __end_swap_tsc; +extern u64_t __start_intr_tsc; +extern u64_t __end_intr_tsc; +extern u64_t __start_tick_tsc; +extern u64_t __end_tick_tsc; + + + +/* Function prototypes */ +void system_thread_bench(void); +void yield_bench(void); +void heap_malloc_free_bench(void); +void semaphore_bench(void); +void mutex_bench(void); +void msg_passing_bench(void); + +/* PRINT_F + * Macro to print a formatted output string. fprintf is used when + * Assumed that sline character array of SLINE_LEN + 1 characters + * is defined in the main file + */ + +/* #define CSV_FORMAT_OUTPUT */ +/* printf format defines. */ +#ifdef CSV_FORMAT_OUTPUT +#define FORMAT "%-45s,%4u,%5u\n" +#else +#define FORMAT "%-45s:%4u cycles , %5u ns\n" +#endif +#include + +#define GET_2ND_ARG(first, second, ...) (second) +#define GET_3ND_ARG(first, second, third, ...) (third) + +/* Enable this macro to print all the measurements. + * Note: Some measurements in few architectures are not valid + */ +/* #define PRINT_ALL_MEASUREMENTS */ +#ifndef PRINT_ALL_MEASUREMENTS +/*If the measured cycles is greater than 10000 then one of the following is + * possible. + * 1. the selected measurement is not supported in the architecture + * 2. The measurement went wrong somewhere.(less likely to happen) + */ +#define PRINT_F(...) \ + { \ + if ((GET_2ND_ARG(__VA_ARGS__) <= 20000) && \ + (GET_2ND_ARG(__VA_ARGS__) != 0)) { \ + snprintf(sline, 254, FORMAT, ##__VA_ARGS__); \ + TC_PRINT("%s", sline); \ + } \ + } +#else +/* Prints all outputs*/ +#define PRINT_F(...) \ + { \ + snprintf(sline, 254, FORMAT, ##__VA_ARGS__); \ + TC_PRINT("%s", sline); \ + } + +#endif + + +/* If we are using x86 based controller we tend to read the tsc value which is + * always incrementing i.e count up counter. + * If we are using the ARM based controllers the systick is a + * count down counter. + * Hence to calculate the cycles taken up by the code we need to adjust the + * values accordingly. + * + * NOTE: Needed only when reading value from end of swap operation + */ +#if CONFIG_ARM +#define SUBTRACT_CLOCK_CYCLES(val) (SysTick->LOAD - (u32_t)val) +#else +#define SUBTRACT_CLOCK_CYCLES(val) (val) +#endif diff --git a/tests/benchmarks/timing_info/src/yield_bench.c b/tests/benchmarks/timing_info/src/yield_bench.c new file mode 100644 index 0000000000000..8da053cbe41c3 --- /dev/null +++ b/tests/benchmarks/timing_info/src/yield_bench.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include "timing_info.h" + +K_SEM_DEFINE(yield_sem, 0, 1); + +/* To time thread creation*/ +#define STACK_SIZE 500 +extern char __noinit __stack my_stack_area[STACK_SIZE]; +extern char __noinit __stack my_stack_area_0[STACK_SIZE]; + +/* u64_t thread_yield_start_tsc[1000]; */ +/* u64_t thread_yield_end_tsc[1000]; */ +/* location of the time stamps*/ +extern u32_t __read_swap_end_tsc_value; +extern u64_t __common_var_swap_end_tsc; +extern char sline[]; + +u64_t thread_sleep_start_tsc; +u64_t thread_sleep_end_tsc; +u64_t thread_start_time; +u64_t thread_end_time; +static u32_t count; + +void thread_yield0_test(void *p1, void *p2, void *p3); +void thread_yield1_test(void *p1, void *p2, void *p3); + +k_tid_t yield0_tid; +k_tid_t yield1_tid; +void yield_bench(void) +{ + + /* Thread yield*/ + + yield0_tid = k_thread_spawn(my_stack_area, + STACK_SIZE, + thread_yield0_test, + NULL, NULL, NULL, + 0 /*priority*/, 0, 0); + + yield1_tid = k_thread_spawn(my_stack_area_0, + STACK_SIZE, + thread_yield1_test, + NULL, NULL, NULL, + 0 /*priority*/, 0, 0); + + /*read the time of start of the sleep till the swap happens */ + __read_swap_end_tsc_value = 1; + + thread_sleep_start_tsc = OS_GET_TIME(); + k_sleep(1000); + thread_sleep_end_tsc = ((u32_t)__common_var_swap_end_tsc); + + u32_t yield_cycles = (thread_end_time - thread_start_time) / 2000; + u32_t sleep_cycles = thread_sleep_end_tsc - thread_sleep_start_tsc; + + PRINT_F("Thread Yield", yield_cycles, + SYS_CLOCK_HW_CYCLES_TO_NS(yield_cycles)); + PRINT_F("Thread Sleep", sleep_cycles, + SYS_CLOCK_HW_CYCLES_TO_NS(sleep_cycles)); + +} + + +void thread_yield0_test(void *p1, void *p2, void *p3) +{ + k_sem_take(&yield_sem, 10); + thread_start_time = OS_GET_TIME(); + while (count != 1000) { + count++; + k_yield(); + } + thread_end_time = OS_GET_TIME(); + k_thread_abort(yield1_tid); +} + +void thread_yield1_test(void *p1, void *p2, void *p3) +{ + k_sem_give(&yield_sem); + while (1) { + k_yield(); + } +} \ No newline at end of file diff --git a/tests/benchmarks/timing_info/testcase.ini b/tests/benchmarks/timing_info/testcase.ini new file mode 100644 index 0000000000000..717188e0d5d69 --- /dev/null +++ b/tests/benchmarks/timing_info/testcase.ini @@ -0,0 +1,3 @@ +[test] +tags = benchmark +arch_whitelist = x86 arm diff --git a/tests/bluetooth/init/prj_controller.conf b/tests/bluetooth/init/prj_controller.conf index 43c1ebd22e9ab..31da439215574 100644 --- a/tests/bluetooth/init/prj_controller.conf +++ b/tests/bluetooth/init/prj_controller.conf @@ -4,6 +4,7 @@ CONFIG_BLUETOOTH_CONTROLLER_WORKER_PRIO=0 CONFIG_BLUETOOTH_CONTROLLER_JOB_PRIO=0 CONFIG_BLUETOOTH_CONTROLLER_XTAL_ADVANCED=y CONFIG_BLUETOOTH_CONTROLLER_SCHED_ADVANCED=y +CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC=y CONFIG_BLUETOOTH_PERIPHERAL=y CONFIG_BLUETOOTH_CENTRAL=y CONFIG_BLUETOOTH_SMP=y diff --git a/tests/kernel/fatal/testcase.ini b/tests/kernel/fatal/testcase.ini index 914a14535fcb0..63fbe6d020c59 100644 --- a/tests/kernel/fatal/testcase.ini +++ b/tests/kernel/fatal/testcase.ini @@ -1,2 +1,2 @@ [test] -tags = core +tags = core ignore_faults diff --git a/tests/kernel/test_tickless/src/timestamps.c b/tests/kernel/test_tickless/src/timestamps.c index 8c097c4b324f2..ff8bac1da06a7 100644 --- a/tests/kernel/test_tickless/src/timestamps.c +++ b/tests/kernel/test_tickless/src/timestamps.c @@ -237,7 +237,7 @@ void _TimestampClose(void) _TIMESTAMP_CTRL = 0x0; /* disable oscillator */ } -#elif defined(CONFIG_SOC_ATMEL_SAM3) +#elif defined(CONFIG_SOC_SERIES_SAM3X) /* Atmel SAM3 family processor - use RTT (Real-time Timer) */ #include diff --git a/tests/kernel/test_tickless/testcase.ini b/tests/kernel/test_tickless/testcase.ini index d217bfd1d61ae..8903dde6c3fbd 100644 --- a/tests/kernel/test_tickless/testcase.ini +++ b/tests/kernel/test_tickless/testcase.ini @@ -2,5 +2,5 @@ tags = core arch_exclude = nios2 filter = CONFIG_X86 or (CONFIG_ARM and - (CONFIG_SOC_MK64F12 or CONFIG_SOC_ATMEL_SAM3)) or + (CONFIG_SOC_MK64F12 or CONFIG_SOC_SERIES_SAM3X)) or (CONFIG_ARC and CONFIG_SOC_QUARK_SE_C1000_SS) diff --git a/tests/lib/json/src/main.c b/tests/lib/json/src/main.c index 6100c622f074d..945d8ace52bb7 100644 --- a/tests/lib/json/src/main.c +++ b/tests/lib/json/src/main.c @@ -24,28 +24,22 @@ struct test_struct { size_t some_array_len; }; -#define FIELD(struct_, member_, type_) { \ - .field_name = #member_, \ - .field_name_len = sizeof(#member_) - 1, \ - .offset = offsetof(struct_, member_), \ - .type = type_ \ -} static const struct json_obj_descr nested_descr[] = { - FIELD(struct test_nested, nested_int, JSON_TOK_NUMBER), - FIELD(struct test_nested, nested_bool, JSON_TOK_TRUE), - FIELD(struct test_nested, nested_string, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int, JSON_TOK_NUMBER), + JSON_OBJ_DESCR_PRIM(struct test_nested, nested_bool, JSON_TOK_TRUE), + JSON_OBJ_DESCR_PRIM(struct test_nested, nested_string, + JSON_TOK_STRING), }; static const struct json_obj_descr test_descr[] = { - FIELD(struct test_struct, some_string, JSON_TOK_STRING), - FIELD(struct test_struct, some_int, JSON_TOK_NUMBER), - FIELD(struct test_struct, some_bool, JSON_TOK_TRUE), + JSON_OBJ_DESCR_PRIM(struct test_struct, some_string, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(struct test_struct, some_int, JSON_TOK_NUMBER), + JSON_OBJ_DESCR_PRIM(struct test_struct, some_bool, JSON_TOK_TRUE), JSON_OBJ_DESCR_OBJECT(struct test_struct, some_nested_struct, nested_descr), JSON_OBJ_DESCR_ARRAY(struct test_struct, some_array, 16, some_array_len, JSON_TOK_NUMBER), }; -#undef FIELD static void test_json_encoding(void) {