From 0f0027bb87a409a79ad4a91f3b9b7cf48850874e Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Fri, 23 Feb 2024 19:09:57 +0100 Subject: [PATCH 001/187] drivers: sam_can: fixed MCAN Register Base Address Before that fix, the default mrba was used; added DMA Base Address to DTSI. Fixes #68472 Signed-off-by: Sven Ginka --- drivers/can/can_sam.c | 10 +++++++++- dts/arm/atmel/same70.dtsi | 6 ++++-- dts/bindings/can/atmel,sam-can.yaml | 9 +++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/can/can_sam.c b/drivers/can/can_sam.c index a77c189ba0a54..23d9dd5089f65 100644 --- a/drivers/can/can_sam.c +++ b/drivers/can/can_sam.c @@ -25,6 +25,7 @@ struct can_sam_config { const struct atmel_sam_pmc_config clock_cfg; const struct pinctrl_dev_config *pcfg; int divider; + mm_reg_t dma_base; }; static int can_sam_read_reg(const struct device *dev, uint16_t reg, uint32_t *val) @@ -101,7 +102,13 @@ static int can_sam_init(const struct device *dev) return ret; } - ret = can_mcan_configure_mram(dev, 0U, sam_cfg->mram); + /* get actual message ram base address */ + uint32_t mrba = sam_cfg->mram & 0xFFFF0000; + + /* keep lower 16bit; update DMA Base Register */ + sys_write32(sam_cfg->dma_base, (sys_read32(sam_cfg->dma_base) & 0x0000FFFF) | mrba); + + ret = can_mcan_configure_mram(dev, mrba, sam_cfg->mram); if (ret != 0) { return ret; } @@ -174,6 +181,7 @@ static void config_can_##inst##_irq(void) .divider = DT_INST_PROP(inst, divider), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .config_irq = config_can_##inst##_irq, \ + .dma_base = (mm_reg_t) DT_INST_REG_ADDR_BY_NAME(inst, dma_base) \ }; \ \ static const struct can_mcan_config can_mcan_cfg_##inst = \ diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index 8fcaae9830720..fa954af21f5ca 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -439,7 +439,8 @@ can0: can@40030000 { compatible = "atmel,sam-can"; - reg = <0x40030000 0x100>; + reg = <0x40030000 0x100>, <0x40088110 0x04>; + reg-names = "m_can", "dma_base"; interrupts = <35 0>, <36 0>; interrupt-names = "int0", "int1"; clocks = <&pmc PMC_TYPE_PERIPHERAL 35>; @@ -450,7 +451,8 @@ can1: can@40034000 { compatible = "atmel,sam-can"; - reg = <0x40034000 0x100>; + reg = <0x40034000 0x100>, <0x40088114 0x4>; + reg-names = "m_can", "dma_base"; interrupts = <37 0>, <38 0>; interrupt-names = "int0", "int1"; clocks = <&pmc PMC_TYPE_PERIPHERAL 37>; diff --git a/dts/bindings/can/atmel,sam-can.yaml b/dts/bindings/can/atmel,sam-can.yaml index c224604fa0bd9..7c28ec56da20f 100644 --- a/dts/bindings/can/atmel,sam-can.yaml +++ b/dts/bindings/can/atmel,sam-can.yaml @@ -9,6 +9,15 @@ include: properties: reg: required: true + description: | + 2 reg blocks needed; Register block for the MCAN configuration registers; + Register block for the DMA Base Address + + reg-names: + type: string-array + required: true + description: | + description of reg blocks interrupts: required: true From fb0e7fc607fdbbb8b99183c80a33b13515c0434c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 26 Jun 2024 15:16:27 +0200 Subject: [PATCH 002/187] doc: release-notes: Add 3.7.0 release notes for networking Add 3.7.0 release notes for networking. Signed-off-by: Robert Lubos --- doc/releases/release-notes-3.7.rst | 212 +++++++++++++++++++++++++++-- 1 file changed, 204 insertions(+), 8 deletions(-) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 97514eadf2e8b..6e56ffd061099 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -536,42 +536,238 @@ Drivers and Sensors Networking ********** +* ARP: + + * Added support for gratuitous ARP transmission. + * Fixed a possible deadlock between TX and RX threads within ARP module. + * Fixed a possible ARP entry leak. + * Improved ARP debug logs. + +* CoAP: + + * Fixed CoAP observe age overflows. + * Increased upper limit for CoAP retransmissions (:kconfig:option:`CONFIG_COAP_MAX_RETRANSMIT`). + * Fixed CoAP observations in CoAP client library. + * Added new CoAP client :c:func:`coap_client_cancel_requests` API which allows + to cancel active observations. + * Fixed CoAP ID generation for responses in CoAP Server sample. + +* Connection manager: + + * Added support for new net_mgmt events, which allow to track IPv4 and IPv6 + connectivity independently: + + * :c:macro:`NET_EVENT_L4_IPV4_CONNECTED` + * :c:macro:`NET_EVENT_L4_IPV4_DISCONNECTED` + * :c:macro:`NET_EVENT_L4_IPV6_CONNECTED` + * :c:macro:`NET_EVENT_L4_IPV6_DISCONNECTED` + * DHCPv4: * Added support for encapsulated vendor specific options. By enabling :kconfig:option:`CONFIG_NET_DHCPV4_OPTION_CALLBACKS_VENDOR_SPECIFIC` callbacks can be registered with :c:func:`net_dhcpv4_add_option_vendor_callback` to handle these options after being initialised with :c:func:`net_dhcpv4_init_option_vendor_callback`. - * Added support for the "Vendor class identifier" option. Use the :kconfig:option:`CONFIG_NET_DHCPV4_VENDOR_CLASS_IDENTIFIER` to enable it and :kconfig:option:`CONFIG_NET_DHCPV4_VENDOR_CLASS_IDENTIFIER_STRING` to set it. - * The NTP server from the DHCPv4 option can now be used to set the system time. This is done by default, if :kconfig:option:`CONFIG_NET_CONFIG_CLOCK_SNTP_INIT` is enabled. + * The syslog server address can now be set with DHCPv4 option. This is done by + default, if :kconfig:option:`CONFIG_LOG_BACKEND_NET_USE_DHCPV4_OPTION` is enabled. + * Fixed a bug, where options with registered callbacks were not requested from + the server. + * Fixed a bug, where netmask received from the server was not applied correctly. + * Reimplemented DHCPv4 client RENEW/REBIND logic to be compliant with RFC2131. + * Improved declined addresses management in DHCPv4 server, which now can be + reused after configured time. + * Fixed including client ID option in DHCPv4 server responsed, according to RFC6842. + * Added :kconfig:option:`CONFIG_NET_DHCPV4_SERVER_NAK_UNRECOGNIZED_REQUESTS` which + allows to override RFC-defined behavior, and NAK requests from unrecognized + clients. + * Other minor fixes in DHCPv4 client and server implementations. + +* DHCPv6: + + * Fixed incorrect DHCPv6 events code base for net_mgmt events. + * Added :kconfig:option:`CONFIG_NET_DHCPV6_DUID_MAX_LEN` which allows to configure + maximum supported DUID length. + * Added documentation page for DHCPv6. + +* HTTP: + + * Added HTTP/2 server library and sample application with support for static, + dynamic and Websocket resource types. + * Added HTTP shell component. + * Improved HTTP client error reporting. + * Moved HTTP client library out of experimental. + +* IPSP: + + * Removed IPSP support. ``CONFIG_NET_L2_BT`` does not exist anymore. + +* IPv4: + + * Implemented IPv4 Address Conflict Detection, according to RFC 5227. + * Added :c:func:`net_ipv4_is_private_addr` API function. + * IPv4 netmask is now set individually for each address instead of being set + for the whole interface. + * Other minor fixes and improvements. + +* IPv6: + + * Implemented IPv6 Privacy Extensions according to RFC 8981. + * Added :c:func:`net_ipv6_is_private_addr` API function. + * Implemented reachability hint for IPv6. Upper layers can use + c:func:`net_if_nbr_reachability_hint` to report Neigbor reachability and + avoid unnecessary Neighbor Discovery solicitations. + * Added :kconfig:option:`CONFIG_NET_IPV6_MTU` allowing to set custom IPv6 MTU. + * Added :kconfig:option:`CONFIG_NET_MCAST_ROUTE_MAX_IFACES` which allows to set + multiple interfaces for multicast forwarding entries. + * Added :kconfig:option:`CONFIG_NET_MCAST_ROUTE_MLD_REPORTS` which allows to + report multicast routes in MLDv2 reports. + * Fixed IPv6 hop limit handling for multicast packets. + * Improved IPv6 Neighbor Discovery test coverage. + * Fixed a bug, where Neighbor Advertisement packets reporting Duplicate address + detection conflict were dropped. + * Other minor fixes and improvements. * LwM2M: - * Added new API function: + * Added new API functions: * :c:func:`lwm2m_set_bulk` + * :c:func:`lwm2m_rd_client_set_ctx` * Added new ``offset`` parameter to :c:type:`lwm2m_engine_set_data_cb_t` callback type. This affects post write and validate callbacks as well as some firmware callbacks. + * Fixed block context not being reset upon receiving block number 0 in block transfer. + * Fixed block size negotiation with the server in block transfer. + * Added :kconfig:option:`CONFIG_LWM2M_ENGINE_ALWAYS_REPORT_OBJ_VERSION` which + allows to force the client to always report object version. + * Block transfer is now possible with resource w/o registered callback. + * Fixed a bug, where an empty ACK sent from the registered callback would not + be sent immediately. + * Removed deprecated API functions and definitions. + * Other minor fixes and improvements. -* IPSP: +* mDNS: - * Removed IPSP support. ``CONFIG_NET_L2_BT`` does not exist anymore. + * Fixed an issue where the mDNS Responder did not work when the mDNS Resolver was also enabled. + The mDNS Resolver and mDNS Responder can now be used simultaneously. + +* Misc: + + * Implemented new networking POSIX APIs: + + * :c:func:`if_nameindex` + * :c:func:`inet_ntoa` + * :c:func:`inet_addr` + + * Improved overall networking API doxygen documentation. + * Converted TFTP library to use ``zsock_*`` API. + * Added SNTP :c:func:`sntp_simple_addr` API function to perform SNTP query + when the server IP address is already known. + * Added :kconfig:option:`CONFIG_NET_TC_THREAD_PRIO_CUSTOM` allowing to override + default traffic class threads priority. + * Fixed the IPv6 event handler initialization order in net config library. + * Reworked telnet shell backend to use sockets and socket services API. + * Fixed double dereference of IGMP packets. + * Moved from ``native_posix`` to ``native_sim`` support in various tests and + samples. + * Added support for copying user data in network buffers. + * Fixed cloning of zero sized network buffers. + * Added net_buf APIs to handle 40 bit data format. + * Added receive callback for dummy L2, applicable in certain use cases + (for example packet capture). + * Implemented pseudo interface, a.k.a "any" interface for packet capture use + case. + * Removed obsolete and unused ``tcp_first_msg`` :c:struct:`net_pkt` flag. + * Reworked LLMNR responder to use sockets and socket services API. + * Added new :zephyr:code-sample:`secure-mqtt-sensor-actuator` sample. + * Added support for partial L3 and L4 checksum offloading. + * Updated :zephyr:code-sample:`mqtt-azure` with new CA certificates, the current + on expires soon. + +* MQTT: + + * Added ALPN support for MQTT TLS backend. + * Added user data field in :c:struct:`mqtt_client` context structure. + +* Network Interface: + + * Added new API functions: + + * :c:func:`net_if_ipv4_maddr_foreach` + * :c:func:`net_if_ipv6_maddr_foreach` + + * Improved debug logging in the network interface code. + * Added reference counter to the :c:struct:`net_if_addr` structure. + * Fixed IPv6 DAD and MLDv2 operation when interface goes up. + * Other minor fixes. + +* OpenThread + + * Removed deprecated ``openthread_set_state_changed_cb()`` function. + * Added implementation of BLE TCAT advertisement API. + +* PPP + + * Removed deprecated ``gsm_modem`` driver and sample. + * Optimized memory allocation in PPP driver. + * Misc improvements in the :zephyr:code-sample:`cellular-modem` sample + +* Shell: + + * Added ``net ipv4 gateway`` command to set IPv4 gateway address. + * Added argument validation in network shell macros. + * Fixed net_mgmt sockets information printout. + * Reworked VLAN information printout. + * Added option to set random MAC address with ``net iface set_mac`` command. + * Added multicast join status when printing multicast address information. + +* Syslog: + + * Added new API functions: + + * :c:func:`log_backend_net_set_ip` to initialize syslog net backend with IP + address directly. + * :c:func:`log_backend_net_start` to facilitate syslog net backend activation. + + * Added structured logging support to syslog net backend. + * Added TCP support to syslog net backend. * TCP: + * Fixed possible deadlock when accepting new TCP connection. + * Fixed ACK number verification during connection teardown. + * Fixed a bug, where data bytes included in FIN packet were ignored. + * Fixed a possible TCP context leak in case initial SYN packet transmission failed. + * Deprecated ``CONFIG_NET_TCP_ACK_TIMEOUT`` as it was redundant with other configs. + * Improved debug logs, so that they're easier to follow under heavy load. * ISN generation now uses SHA-256 instead of MD5. Moreover it now relies on PSA APIs instead of legacy Mbed TLS functions for hash computation. -* mDNS: +* Websocket: - * Fixed an issue where the mDNS Responder did not work when the mDNS Resolver was also enabled. - The mDNS Resolver and mDNS Responder can now be used simultaneously. + * Added new Websocket APIs: + + * :c:func:`websocket_register` + * :c:func:`websocket_unregister` + + * Converted Websocket library to use ``zsock_*`` API. + * Added Object Core support to Websocket sockets. + +* zperf: + + * Fixed ``IP_TOS`` and ``IPV6_TCLASS`` options handling in zperf. + * Fixed throughput calculation during long zperf sessions. + * Fixed error on TCP upload session end in case multicast IP address was used. + * Fixed a bug, where IPv6 socket was bound with IPv4 address, giving error. + * Added an option to specify the network interface to use during zperf sessions. + * Added a new ``ZPERF_SESSION_PERIODIC_RESULT`` event for periodic updates + during TCP upload sessions. + * Fixed possible socket leak in case of errors during zperf session. USB *** From 39ddabe9150c081d16a9dd5b54ff31453cc10924 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Thu, 27 Jun 2024 14:43:53 +0200 Subject: [PATCH 003/187] doc: release: 3.7: Add note about LinkServer runner .hex support Added note about enabled flash support for Intel Hex files for the LinkServer runner. Signed-off-by: Andrej Butok --- doc/releases/release-notes-3.7.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 6e56ffd061099..a69aeaf5f8782 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -281,6 +281,8 @@ Build system and Infrastructure * Fixed issue whereby files used in a project (e.g. devicetree overlays or Kconfig fragments) were not correctly watched and CMake would not reconfigure if they were changed. + * Added flash support for Intel Hex files for the LinkServer runner. + Drivers and Sensors ******************* From 5eade6411617b41c453aee7f0b54824fa0ac878f Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 18 Jun 2024 10:42:32 -0700 Subject: [PATCH 004/187] dts: bindings: cpu: add definition for arm,cortex-m55 A binding for the m55 cpu was missing. Add the yaml files. Signed-off-by: Ryan McClelland --- dts/bindings/cpu/arm,cortex-m55.yaml | 8 ++++++++ dts/bindings/cpu/arm,cortex-m55f.yaml | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 dts/bindings/cpu/arm,cortex-m55.yaml create mode 100644 dts/bindings/cpu/arm,cortex-m55f.yaml diff --git a/dts/bindings/cpu/arm,cortex-m55.yaml b/dts/bindings/cpu/arm,cortex-m55.yaml new file mode 100644 index 0000000000000..21c55105bc436 --- /dev/null +++ b/dts/bindings/cpu/arm,cortex-m55.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +description: ARM Cortex-M55 CPU + +compatible: "arm,cortex-m55" + +include: arm,cortex-m.yaml diff --git a/dts/bindings/cpu/arm,cortex-m55f.yaml b/dts/bindings/cpu/arm,cortex-m55f.yaml new file mode 100644 index 0000000000000..ca6d8574605f3 --- /dev/null +++ b/dts/bindings/cpu/arm,cortex-m55f.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +description: ARM Cortex-M55F CPU + +compatible: "arm,cortex-m55f" + +include: arm,cortex-m.yaml From 8123bd6de7b4baef7bf46f4661bdf0ea848cb65a Mon Sep 17 00:00:00 2001 From: Hess Nathan Date: Tue, 25 Jun 2024 08:49:10 +0200 Subject: [PATCH 005/187] arch: x86: corrected parameter names - applied the exact parameter names of the interface to implementation Signed-off-by: Hess Nathan --- arch/x86/core/intel64/irq.c | 6 +++--- include/zephyr/arch/x86/arch.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/core/intel64/irq.c b/arch/x86/core/intel64/irq.c index f8e251b804613..51410646dbaf9 100644 --- a/arch/x86/core/intel64/irq.c +++ b/arch/x86/core/intel64/irq.c @@ -100,8 +100,8 @@ void z_x86_irq_connect_on_vector(unsigned int irq, */ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*func)(const void *arg), - const void *arg, uint32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { uint32_t key; int vector; @@ -124,7 +124,7 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, #endif /* CONFIG_INTEL_VTD_ICTL */ z_irq_controller_irq_config(vector, irq, flags); - z_x86_irq_connect_on_vector(irq, vector, func, arg); + z_x86_irq_connect_on_vector(irq, vector, routine, parameter); } irq_unlock(key); diff --git a/include/zephyr/arch/x86/arch.h b/include/zephyr/arch/x86/arch.h index 61036288671c8..90d2fa0c51a1a 100644 --- a/include/zephyr/arch/x86/arch.h +++ b/include/zephyr/arch/x86/arch.h @@ -216,7 +216,7 @@ static ALWAYS_INLINE int sys_test_and_clear_bit(mem_addr_t addr, * at build time and defined via the linker script. On Intel64, it's an array. */ -extern unsigned char _irq_to_interrupt_vector[]; +extern unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES]; #define Z_IRQ_TO_INTERRUPT_VECTOR(irq) \ ((unsigned int) _irq_to_interrupt_vector[(irq)]) From a213f55d74e0a6debe5c3c3f23643cb043dad7c8 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Thu, 27 Jun 2024 16:15:08 -0400 Subject: [PATCH 006/187] boards: nxp: mimxrt1170_evk: doc: remove LinkServer `west debug` limitation `west debug` is no longer an issue with LinkServer runner. Signed-off-by: Derek Snell --- boards/nxp/mimxrt1170_evk/doc/index.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/boards/nxp/mimxrt1170_evk/doc/index.rst b/boards/nxp/mimxrt1170_evk/doc/index.rst index 3055cde68065b..f3260f9c2734a 100644 --- a/boards/nxp/mimxrt1170_evk/doc/index.rst +++ b/boards/nxp/mimxrt1170_evk/doc/index.rst @@ -363,9 +363,6 @@ Using LinkServer ---------------- Known limitations with LinkServer and these boards include: -- ``west debug`` does not yet work correctly, and the application image is not -properly written to the memory. `NXP MCUXpresso for Visual Studio Code`_ -can be used to debug Zephyr applications with LinkServer. - ``west flash`` will not write images to non-flash locations. The flash command only works when all data in the image is written to flash memory regions. From f300c13846d0cb9deef0e10ad19b734e671d7058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nerijus=20Bend=C5=BEi=C5=ABnas?= Date: Thu, 27 Jun 2024 16:59:37 +0300 Subject: [PATCH 007/187] drivers: i2c: stm32: remove redundant new line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LOG_* adds "\n" by itself. Fixes redundant lines during startup: ``` [00:00:00.100,000] i2c_ll_stm32_v2: I2C TIMING = 0xb0f6343d [00:00:00.100,000] i2c_ll_stm32_v2: I2C TIMING = 0xb0f6343d [00:00:00.100,000] i2c_ll_stm32_v2: I2C TIMING = 0xb0f6343d [00:00:00.100,000] i2c_ll_stm32_v2: I2C TIMING = 0xb0f6343d [00:00:00.100,000] flash_stm32_qspi: Reading SFDP ``` Signed-off-by: Nerijus Bendžiūnas --- drivers/i2c/i2c_ll_stm32_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c index 24d51eed45ea7..e67ae28bbf90c 100644 --- a/drivers/i2c/i2c_ll_stm32_v2.c +++ b/drivers/i2c/i2c_ll_stm32_v2.c @@ -1119,7 +1119,7 @@ int stm32_i2c_configure_timing(const struct device *dev, uint32_t clock) return -EINVAL; } - LOG_INF("I2C TIMING = 0x%x\n", timing); + LOG_INF("I2C TIMING = 0x%x", timing); LL_I2C_SetTiming(i2c, timing); return 0; From 4b70319ec5b9b537abf23fb94216964af9ac8100 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 26 Jun 2024 11:26:33 +0200 Subject: [PATCH 008/187] logging: avoid overflow of package length in log_msg Check if the calculated package length exceeds the maximum possible value. Fixes #75015 Signed-off-by: Benedikt Schmidt --- subsys/logging/log_msg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 0d40c5b3155f3..b2b6aee9e21b6 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -358,6 +358,12 @@ void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source, plen = 0; } + if (plen > Z_LOG_MSG_MAX_PACKAGE) { + LOG_WRN("Message dropped because it exceeds size limitation (%u)", + (uint32_t)Z_LOG_MSG_MAX_PACKAGE); + return; + } + size_t msg_wlen = Z_LOG_MSG_ALIGNED_WLEN(plen, dlen); struct log_msg *msg; uint8_t *pkg; From c9361845247a4fa47a40f78fdd9004da9c949650 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 28 Jun 2024 15:10:44 +1000 Subject: [PATCH 009/187] bluetooth: correct `bt_le_scan_param` scan type The `type` parameter of `struct bt_le_scan_param` is documented as taking a `BT_LE_SCAN_TYPE_*` value, not a `BT_HCI_LE_SCAN_*` value. In practice this makes no difference as the values are defined as the same integer, but does result in `` not needing to be included. Signed-off-by: Jordan Yates --- samples/bluetooth/central_multilink/src/central_multilink.c | 2 +- samples/bluetooth/scan_adv/src/main.c | 3 +-- subsys/bluetooth/host/scan.c | 4 ++-- subsys/bluetooth/mesh/adv.c | 4 ++-- .../host/privacy/peripheral/src/tester_rpa_expired.c | 2 +- .../host/privacy/peripheral/src/tester_rpa_rotation.c | 2 +- tests/bsim/bluetooth/ll/advx/src/main.c | 2 +- tests/bsim/bluetooth/ll/bis/src/main.c | 4 ++-- tests/bsim/bluetooth/mesh/src/mesh_test.c | 2 +- 9 files changed, 12 insertions(+), 13 deletions(-) diff --git a/samples/bluetooth/central_multilink/src/central_multilink.c b/samples/bluetooth/central_multilink/src/central_multilink.c index 197021efe97ef..eb5989587fe46 100644 --- a/samples/bluetooth/central_multilink/src/central_multilink.c +++ b/samples/bluetooth/central_multilink/src/central_multilink.c @@ -90,7 +90,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, static void start_scan(void) { struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_PASSIVE, + .type = BT_LE_SCAN_TYPE_PASSIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = SCAN_INTERVAL, .window = SCAN_WINDOW, diff --git a/samples/bluetooth/scan_adv/src/main.c b/samples/bluetooth/scan_adv/src/main.c index 8ec06b81b3664..ed9d00359ef89 100644 --- a/samples/bluetooth/scan_adv/src/main.c +++ b/samples/bluetooth/scan_adv/src/main.c @@ -12,7 +12,6 @@ #include #include -#include static uint8_t mfg_data[] = { 0xff, 0xff, 0x00 }; @@ -29,7 +28,7 @@ static void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, int main(void) { struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_PASSIVE, + .type = BT_LE_SCAN_TYPE_PASSIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = 0x0010, .window = 0x0010, diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index ddbbe766813b7..29136cd504129 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1461,8 +1461,8 @@ void bt_hci_le_adv_report(struct net_buf *buf) static bool valid_le_scan_param(const struct bt_le_scan_param *param) { - if (param->type != BT_HCI_LE_SCAN_PASSIVE && - param->type != BT_HCI_LE_SCAN_ACTIVE) { + if (param->type != BT_LE_SCAN_TYPE_PASSIVE && + param->type != BT_LE_SCAN_TYPE_ACTIVE) { return false; } diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index d9b191120d174..afad7d1ac6d10 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -378,8 +378,8 @@ int bt_mesh_scan_active_set(bool active) int bt_mesh_scan_enable(void) { struct bt_le_scan_param scan_param = { - .type = active_scanning ? BT_HCI_LE_SCAN_ACTIVE : - BT_HCI_LE_SCAN_PASSIVE, + .type = active_scanning ? BT_LE_SCAN_TYPE_ACTIVE : + BT_LE_SCAN_TYPE_PASSIVE, .interval = MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW }; diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_expired.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_expired.c index 85153ac8eddce..0b939985a46cd 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_expired.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_expired.c @@ -108,7 +108,7 @@ void start_rpa_scanning(void) { /* Start passive scanning */ struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_PASSIVE, + .type = BT_LE_SCAN_TYPE_PASSIVE, .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, .interval = 0x0040, .window = 0x0020, diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_rotation.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_rotation.c index db363cd6ea032..f0e68785e32b5 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_rotation.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester_rpa_rotation.c @@ -122,7 +122,7 @@ void start_scanning(void) { /* Start passive scanning */ struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_PASSIVE, + .type = BT_LE_SCAN_TYPE_PASSIVE, .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, .interval = 0x0040, .window = 0x0020, diff --git a/tests/bsim/bluetooth/ll/advx/src/main.c b/tests/bsim/bluetooth/ll/advx/src/main.c index 9035650f2e137..cdc71c90691ef 100644 --- a/tests/bsim/bluetooth/ll/advx/src/main.c +++ b/tests/bsim/bluetooth/ll/advx/src/main.c @@ -1300,7 +1300,7 @@ static struct bt_le_per_adv_sync_cb sync_cb = { static void test_scanx_main(void) { struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_ACTIVE, + .type = BT_LE_SCAN_TYPE_ACTIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = 0x0004, .window = 0x0004, diff --git a/tests/bsim/bluetooth/ll/bis/src/main.c b/tests/bsim/bluetooth/ll/bis/src/main.c index 3689bf8ca7902..5fe2635565a8d 100644 --- a/tests/bsim/bluetooth/ll/bis/src/main.c +++ b/tests/bsim/bluetooth/ll/bis/src/main.c @@ -753,7 +753,7 @@ static struct bt_le_scan_cb scan_callbacks = { static void test_iso_recv_main(void) { struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_ACTIVE, + .type = BT_LE_SCAN_TYPE_ACTIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = 0x0004, .window = 0x0004, @@ -1028,7 +1028,7 @@ static void test_iso_recv_main(void) static void test_iso_recv_vs_dp_main(void) { struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_ACTIVE, + .type = BT_LE_SCAN_TYPE_ACTIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = 0x0004, .window = 0x0004, diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.c b/tests/bsim/bluetooth/mesh/src/mesh_test.c index 6865e5202ba4d..1edafd657c342 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.c +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.c @@ -569,7 +569,7 @@ void bt_mesh_test_send_over_adv(void *data, size_t len) int bt_mesh_test_wait_for_packet(bt_le_scan_cb_t scan_cb, struct k_sem *observer_sem, uint16_t wait) { struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_PASSIVE, + .type = BT_LE_SCAN_TYPE_PASSIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = BT_MESH_ADV_SCAN_UNIT(1000), .window = BT_MESH_ADV_SCAN_UNIT(1000) From 851f3ea7fde3a5d1e1abc8e646fa80fd0acd2369 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 26 Jun 2024 09:38:06 +0200 Subject: [PATCH 010/187] net: tcp: Delay ACK if no PSH flag is present Delay an ACK in case no PSH flag is present in the data packet. as described in RFC 813. This allows to reduce the number of ACK packets we send and thus improve the TCP download throughput. The results achieved on `nucleo_h723zg` board and the zperf sample are as follows: Before: 77.14 Mbps After: 93.14 Mbps Signed-off-by: Robert Lubos --- subsys/net/ip/tcp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index c44085bb323ad..d9fff6696a0fd 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2695,7 +2695,7 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt, } static enum net_verdict tcp_data_received(struct tcp *conn, struct net_pkt *pkt, - size_t *len) + size_t *len, bool psh) { enum net_verdict ret; @@ -2711,7 +2711,7 @@ static enum net_verdict tcp_data_received(struct tcp *conn, struct net_pkt *pkt, /* Delay ACK response in case of small window or missing PSH, * as described in RFC 813. */ - if (tcp_short_window(conn)) { + if (tcp_short_window(conn) || !psh) { k_work_schedule_for_queue(&tcp_work_q, &conn->ack_timer, ACK_DELAY); } else { @@ -3252,7 +3252,9 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) if (th) { if (th_seq(th) == conn->ack) { if (len > 0) { - verdict = tcp_data_received(conn, pkt, &len); + bool psh = FL(&fl, &, PSH); + + verdict = tcp_data_received(conn, pkt, &len, psh); if (verdict == NET_OK) { /* net_pkt owned by the recv fifo now */ pkt = NULL; From 5637e519fa5458540ff3a1ced3fcd3e817793bce Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 27 Jun 2024 22:32:16 +0200 Subject: [PATCH 011/187] doc: releases: migration-guide-3.7: Add not for BT_LE_ADV_PARAM The macro was modified in a way that may cause issues for some. See e.g. 15d66ccc23b05805ba8eab7c8afe2fb1db7ad4af for an example of it needing a change. The migration guide GH PR number refers to the PR that modified the macro. Signed-off-by: Emil Gydesen --- doc/releases/migration-guide-3.7.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/releases/migration-guide-3.7.rst b/doc/releases/migration-guide-3.7.rst index ae7575593321f..1fcf5f50a85fc 100644 --- a/doc/releases/migration-guide-3.7.rst +++ b/doc/releases/migration-guide-3.7.rst @@ -756,6 +756,22 @@ Bluetooth Host longer used in Zephyr 3.4.0 and later. Any references to this field should be removed. No further action is needed. +* :c:macro:`BT_LE_ADV_PARAM` now returns a :code:`const` pointer. + Any place where the result is stored in a local variable such as + :code:`struct bt_le_adv_param *param = BT_LE_ADV_CONN;` will need to + be updated to :code:`const struct bt_le_adv_param *param = BT_LE_ADV_CONN;` or use it for + initialization like :code:`struct bt_le_adv_param param = *BT_LE_ADV_CONN;` + + The change to :c:macro:`BT_LE_ADV_PARAM` also affects all of its derivatives, including but not + limited to: + + * :c:macro:`BT_LE_ADV_CONN` + * :c:macro:`BT_LE_ADV_NCONN` + * :c:macro:`BT_LE_EXT_ADV_SCAN` + * :c:macro:`BT_LE_EXT_ADV_CODED_NCONN_NAME` + + (:github:`75065`) + Bluetooth Crypto ================ From 687377d6b7e3c89e62656659bc848ff7a9aa60ea Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Fri, 28 Jun 2024 02:12:51 +0700 Subject: [PATCH 012/187] net: if: remove unused `eth_ctx` variable Removed the declaration and assignment of `eth_ctx` variable from `net_if_get_wifi_sta` and `net_if_get_wifi_sap` functions since it was not being used. Signed-off-by: Pisit Sawangvonganan --- subsys/net/ip/net_if.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 94cfdd1633626..47d73cfa62158 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -5686,10 +5686,7 @@ struct net_if *net_if_get_first_wifi(void) struct net_if *net_if_get_wifi_sta(void) { - struct ethernet_context *eth_ctx = NULL; - STRUCT_SECTION_FOREACH(net_if, iface) { - eth_ctx = net_if_l2_data(iface); if (net_if_is_wifi(iface) #ifdef CONFIG_WIFI_NM && (wifi_nm_get_type_iface(iface) == (1 << WIFI_TYPE_STA)) @@ -5703,10 +5700,7 @@ struct net_if *net_if_get_wifi_sta(void) struct net_if *net_if_get_wifi_sap(void) { - struct ethernet_context *eth_ctx = NULL; - STRUCT_SECTION_FOREACH(net_if, iface) { - eth_ctx = net_if_l2_data(iface); if (net_if_is_wifi(iface) #ifdef CONFIG_WIFI_NM && (wifi_nm_get_type_iface(iface) == (1 << WIFI_TYPE_SAP)) From 31091d2cbac029d0d9b8dc040fb56bec511abc94 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 26 Jun 2024 16:31:27 +0200 Subject: [PATCH 013/187] doc: release: 3.7: Add Flash Map release notes Add notes on changes in Flash Map. Signed-off-by: Dominik Ermel --- doc/releases/release-notes-3.7.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index a69aeaf5f8782..23b407dc4df62 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -886,6 +886,16 @@ Libraries / Subsystems * FS: It is now possible to truncate a file while opening using :c:func:`fs_open` and by passing ``FS_O_TRUNC`` flag. + * Flash Map: TinyCrypt has been replaced with PSA Crypto in Flash Area integrity check. + + * Flash Map: :c:func:`flash_area_flatten` has been added to be used where an erase + operation has been previously used for removing/scrambling data rather than + to prepare a device for a random data write. + + * Flash Map: :c:macro:`FIXED_PARTITION_NODE_OFFSET`, :c:macro:`FIXED_PARTITION_NODE_SIZE` + and :c:macro:`FIXED_PARTITION_NODE_DEVICE` have been added to allow obtaining + fixed partition information from a devicetree node rather than a label. + * POSIX API * LoRa/LoRaWAN From a1025a5fa9c60c8a73a8c425c143c8576a5b30c2 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 26 Jun 2024 16:19:28 +0200 Subject: [PATCH 014/187] MAINTAINERS: set area status to odd fixes if not maintained If no maintainers are present, area should not be considered maintained. Signed-off-by: Gerard Marull-Paretas --- MAINTAINERS.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index aa9e2cc22ab52..7742a7ae0046b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -783,8 +783,7 @@ DFU: - dfu Devicetree: - status: maintained - maintainers: [] + status: odd fixes collaborators: - decsny - galak @@ -804,8 +803,7 @@ Devicetree: - libraries.devicetree Devicetree Bindings: - status: maintained - maintainers: [] + status: odd fixes collaborators: - decsny - galak @@ -4132,8 +4130,7 @@ VFS: - filesystem West: - status: maintained - maintainers: [] + status: odd fixes collaborators: - mbolivar-ampere - carlescufi @@ -5030,7 +5027,7 @@ Random: # This area is to be converted to a subarea Testing with Renode: - status: maintained + status: odd fixes collaborators: - mateusz-holenko - fkokosinski From 5da730b791bc3a31590c238487e1bd7d39407d89 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 26 Jun 2024 16:20:11 +0200 Subject: [PATCH 015/187] scripts: get_maintainer: check maintenance status Error if an area is set as maintained but it has no maintainers assigned. Signed-off-by: Gerard Marull-Paretas --- scripts/get_maintainer.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/get_maintainer.py b/scripts/get_maintainer.py index 8e2a09b21522b..fdc9cada4f6e6 100755 --- a/scripts/get_maintainer.py +++ b/scripts/get_maintainer.py @@ -509,6 +509,9 @@ def ferr(msg): ferr("either 'files' or 'files-regex' (or both) must be specified " "for area '{}'".format(area_name)) + if not area_dict.get("maintainers") and area_dict.get("status") == "maintained": + ferr("maintained area '{}' with no maintainers".format(area_name)) + for list_name in "maintainers", "collaborators", "inform", "files", \ "files-regex", "labels", "tags", "tests": if list_name in area_dict: From 70c7fc8cfdbab973941e03585202b94c4d59f826 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 26 Jun 2024 16:19:03 +0200 Subject: [PATCH 016/187] doc: release: 3.7: Add release notes for Flash Flash API additions and new drivers. Signed-off-by: Dominik Ermel --- doc/releases/release-notes-3.7.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 23b407dc4df62..ac1f5c4e76f00 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -397,6 +397,19 @@ Drivers and Sensors * Flash * Added support for Ambiq Apollo3 series. + * Added support for multiple instances of the SPI NOR driver (spi_nor.c). + * Added preliminary support for non-erase devices with introduction of + device capabilities to c:struct:`flash_parameters` and the utility function + c:func:`flash_params_get_erase_cap` that allows to obtain the erase type + provided by a device; added c:macro:`FLASH_ERASE_C_EXPLICIT`, which is + currently the only supported erase type and is set by all flash devices. + * Added the c:func:`flash_flatten` function that can be used on devices, + with or without erase requirement, when erase has been used not for preparing + a device for a random data write, but rather to remove/scramble data from + that device. + * Added the c:func:`flash_fill` utility function which allows to write + a single value across a provided range in a selected device. + * Added support for RRAM on nrf54l15 devices. * GNSS From 7bb3f2838abdbc64d11cf8a022bae8cd427bc1da Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Wed, 26 Jun 2024 16:51:27 +0530 Subject: [PATCH 017/187] drivers: nxp_s32_canxl: add CANXL MRU handler Add CANXL MRU handler, use the same RX, TX IRQ number. Update the error priority that is lower priority than the the tx_rx_mru priority incase the error interrupt happens continuously, mru interrupt priority must be higher to get report error counter. Otherwise the mru interrupt can be delayed by error interrupt and never call to MRU handler. This fixes #75022. Signed-off-by: Cong Nguyen Huu --- drivers/can/can_nxp_s32_canxl.c | 9 ++++++++- dts/arm/nxp/nxp_s32z27x_r52.dtsi | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index 010f291ce160b..d3e7f5568233e 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -65,6 +65,7 @@ struct can_nxp_s32_config { CANXL_RXFIFO_Type * base_rx_fifo; CANXL_RXFIFO_CONTROL_Type *base_rx_fifo_ctrl; #endif + CANXL_MRU_Type * base_mru; uint8 instance; const struct device *clock_dev; clock_control_subsys_t clock_subsys; @@ -1003,11 +1004,16 @@ static int can_nxp_s32_init(const struct device *dev) return 0; } -static void can_nxp_s32_isr_rx_tx(const struct device *dev) +static void can_nxp_s32_isr_rx_tx_mru(const struct device *dev) { const struct can_nxp_s32_config *config = dev->config; Canexcel_Ip_RxTxIRQHandler(config->instance); + + if ((config->base_mru->CHXCONFIG[0u].CH_CFG0 & CANXL_MRU_CH_CFG0_CHE_MASK) + == CANXL_MRU_CH_CFG0_CHE_MASK) { + Canexcel_Ip_MruIRQHandler(config->instance); + } } static void can_nxp_s32_isr_error(const struct device *dev) @@ -1164,6 +1170,7 @@ static const struct can_driver_api can_nxp_s32_driver_api = { DT_INST_REG_ADDR_BY_NAME(n, rx_fifo), \ .base_rx_fifo_ctrl = (CANXL_RXFIFO_CONTROL_Type *) \ DT_INST_REG_ADDR_BY_NAME(n, rx_fifo_ctrl),)) \ + .base_mru = (CANXL_MRU_Type *)DT_INST_REG_ADDR_BY_NAME(n, mru), \ .instance = CAN_NXP_S32_HW_INSTANCE(n), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t) \ diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index c212400a6917d..e5b7e5d260ed0 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -695,12 +695,13 @@ compatible = "nxp,s32-canxl"; reg = <0x4741b000 0x1000>, <0x47423000 0x1000>, - <0x47425000 0x1000>; - reg-names = "sic", "rx_fifo", "rx_fifo_ctrl"; + <0x47425000 0x1000>, + <0x47427000 0x1000>; + reg-names = "sic", "rx_fifo", "rx_fifo_ctrl", "mru"; status = "disabled"; interrupts = , - ; - interrupt-names = "rx_tx", "error"; + ; + interrupt-names = "rx_tx_mru", "error"; clocks = <&clock NXP_S32_P5_CANXL_PE_CLK>; }; @@ -708,12 +709,13 @@ compatible = "nxp,s32-canxl"; reg = <0x4751b000 0x1000>, <0x47523000 0x1000>, - <0x47525000 0x1000>; - reg-names = "sic", "rx_fifo", "rx_fifo_ctrl"; + <0x47525000 0x1000>, + <0x47527000 0x1000>; + reg-names = "sic", "rx_fifo", "rx_fifo_ctrl", "mru"; status = "disabled"; interrupts = , - ; - interrupt-names = "rx_tx", "error"; + ; + interrupt-names = "rx_tx_mru", "error"; clocks = <&clock NXP_S32_P5_CANXL_PE_CLK>; }; }; From 924c3a538f67f2c1e76f681f9cdbb03985bde822 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 24 Jun 2024 20:59:51 +1000 Subject: [PATCH 018/187] everywhere: replace `#if IS_ENABLED()` as per docs Replace `#if IS_ENABLED()` with `#if defined()` as recommended by the documentation of `IS_ENABLED`. Signed-off-by: Jordan Yates --- arch/common/isr_tables.c | 12 +- drivers/cache/cache_andes.c | 16 +-- drivers/cache/cache_andes_l2.h | 4 +- drivers/flash/flash_simulator.c | 2 +- drivers/flash/flash_util.c | 4 +- drivers/flash/soc_flash_nrf.c | 2 +- drivers/flash/spi_flash_at45.c | 4 +- drivers/ieee802154/ieee802154_nrf5.c | 4 +- drivers/interrupt_controller/intc_plic.c | 4 +- drivers/ipm/ipm_imx.c | 2 +- drivers/regulator/regulator_da1469x.c | 2 +- drivers/serial/uart_pl011.c | 14 +-- drivers/spi/spi_dw.h | 2 +- drivers/spi/spi_pl022.c | 10 +- include/zephyr/bindesc.h | 112 +++++++++--------- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt.h | 2 +- include/zephyr/mgmt/mcumgr/mgmt/mgmt.h | 6 +- include/zephyr/mgmt/mcumgr/smp/smp.h | 4 +- include/zephyr/retention/blinfo.h | 2 +- include/zephyr/sw_isr_table.h | 4 +- include/zephyr/sys/mpsc_lockfree.h | 6 +- samples/drivers/soc_flash_nrf/src/main.c | 6 +- samples/subsys/fs/littlefs/src/main.c | 2 +- samples/subsys/usb/cdc_acm/src/main.c | 2 +- samples/subsys/usb/console/src/main.c | 2 +- samples/subsys/usb/hid-mouse/src/main.c | 2 +- samples/subsys/usb/mass/src/main.c | 2 +- .../src/feedback_nrf53.c | 2 +- subsys/bindesc/bindesc_build_time.c | 40 +++---- subsys/bindesc/bindesc_host_info.c | 20 ++-- subsys/bindesc/bindesc_version.c | 44 +++---- subsys/bluetooth/audio/tbs.c | 2 +- subsys/bluetooth/audio/tbs_client.c | 4 +- subsys/bluetooth/mesh/access.c | 6 +- subsys/bluetooth/mesh/cfg.c | 4 +- subsys/bluetooth/mesh/prov.h | 2 +- subsys/bluetooth/services/ots/ots_l2cap.c | 2 +- subsys/fs/fcb/fcb_elem_info.c | 8 +- subsys/ipc/ipc_service/lib/icmsg.c | 4 +- subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c | 14 +-- subsys/mgmt/mcumgr/mgmt/src/mgmt.c | 2 +- subsys/net/ip/net_pkt.c | 2 +- subsys/net/lib/lwm2m/lwm2m_registry.c | 4 +- subsys/shell/backends/shell_rtt.c | 2 +- subsys/storage/stream/stream_flash.c | 4 +- tests/bsim/bluetooth/mesh/src/test_beacon.c | 2 +- tests/drivers/disk/disk_access/src/main.c | 8 +- .../drivers/disk/disk_performance/src/main.c | 4 +- tests/drivers/flash/common/src/main.c | 4 +- tests/lib/gui/lvgl/src/main.c | 2 +- tests/subsys/pm/device_driver_init/src/main.c | 2 +- .../functional/src/settings_basic_test.c | 4 +- .../storage/stream/stream_flash/src/main.c | 4 +- 53 files changed, 215 insertions(+), 215 deletions(-) diff --git a/arch/common/isr_tables.c b/arch/common/isr_tables.c index b3bdd136e0c20..183f80738fe24 100644 --- a/arch/common/isr_tables.c +++ b/arch/common/isr_tables.c @@ -15,11 +15,11 @@ struct int_list_header { uint32_t table_size; uint32_t offset; -#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +#if defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) uint32_t swi_table_entry_size; uint32_t shared_isr_table_entry_size; uint32_t shared_isr_client_num_offset; -#endif /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ +#endif /* defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ }; /* These values are not included in the resulting binary, but instead form the @@ -29,13 +29,13 @@ struct int_list_header { Z_GENERIC_SECTION(.irq_info) __used struct int_list_header _iheader = { .table_size = IRQ_TABLE_SIZE, .offset = CONFIG_GEN_IRQ_START_VECTOR, -#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +#if defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) .swi_table_entry_size = sizeof(struct _isr_table_entry), -#if IS_ENABLED(CONFIG_SHARED_INTERRUPTS) +#if defined(CONFIG_SHARED_INTERRUPTS) .shared_isr_table_entry_size = sizeof(struct z_shared_isr_table_entry), .shared_isr_client_num_offset = offsetof(struct z_shared_isr_table_entry, client_num), -#endif /* IS_ENABLED(CONFIG_SHARED_INTERRUPTS) */ -#endif /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ +#endif /* defined(CONFIG_SHARED_INTERRUPTS) */ +#endif /* defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ }; /* These are placeholder tables. They will be replaced by the real tables diff --git a/drivers/cache/cache_andes.c b/drivers/cache/cache_andes.c index e9907cfaa462e..8008013a86d60 100644 --- a/drivers/cache/cache_andes.c +++ b/drivers/cache/cache_andes.c @@ -467,19 +467,19 @@ int cache_instr_flush_and_invd_range(void *addr, size_t size) return -ENOTSUP; } -#if IS_ENABLED(CONFIG_DCACHE_LINE_SIZE_DETECT) +#if defined(CONFIG_DCACHE_LINE_SIZE_DETECT) size_t cache_data_line_size_get(void) { return cache_cfg.data_line_size; } -#endif /* IS_ENABLED(CONFIG_DCACHE_LINE_SIZE_DETECT) */ +#endif /* defined(CONFIG_DCACHE_LINE_SIZE_DETECT) */ -#if IS_ENABLED(CONFIG_ICACHE_LINE_SIZE_DETECT) +#if defined(CONFIG_ICACHE_LINE_SIZE_DETECT) size_t cache_instr_line_size_get(void) { return cache_cfg.instr_line_size; } -#endif /* IS_ENABLED(CONFIG_ICACHE_LINE_SIZE_DETECT) */ +#endif /* defined(CONFIG_ICACHE_LINE_SIZE_DETECT) */ static int andes_cache_init(void) { @@ -492,7 +492,7 @@ static int andes_cache_init(void) LOG_ERR("Platform doesn't support I-cache, " "please disable CONFIG_ICACHE"); } -#if IS_ENABLED(CONFIG_ICACHE_LINE_SIZE_DETECT) +#if defined(CONFIG_ICACHE_LINE_SIZE_DETECT) /* Icache line size */ if (line_size <= 5) { cache_cfg.instr_line_size = 1 << (line_size + 2); @@ -507,7 +507,7 @@ static int andes_cache_init(void) #else LOG_ERR("Please specific the i-cache-line-size " "CPU0 property of the DT"); -#endif /* IS_ENABLED(CONFIG_ICACHE_LINE_SIZE_DETECT) */ +#endif /* defined(CONFIG_ICACHE_LINE_SIZE_DETECT) */ } if (IS_ENABLED(CONFIG_DCACHE)) { @@ -516,7 +516,7 @@ static int andes_cache_init(void) LOG_ERR("Platform doesn't support D-cache, " "please disable CONFIG_DCACHE"); } -#if IS_ENABLED(CONFIG_DCACHE_LINE_SIZE_DETECT) +#if defined(CONFIG_DCACHE_LINE_SIZE_DETECT) /* Dcache line size */ if (line_size <= 5) { cache_cfg.data_line_size = 1 << (line_size + 2); @@ -531,7 +531,7 @@ static int andes_cache_init(void) #else LOG_ERR("Please specific the d-cache-line-size " "CPU0 property of the DT"); -#endif /* IS_ENABLED(CONFIG_DCACHE_LINE_SIZE_DETECT) */ +#endif /* defined(CONFIG_DCACHE_LINE_SIZE_DETECT) */ } if (!(csr_read(NDS_MMSC_CFG) & MMSC_CFG_CCTLCSR)) { diff --git a/drivers/cache/cache_andes_l2.h b/drivers/cache/cache_andes_l2.h index d6de755182180..962bf837fd8c6 100644 --- a/drivers/cache/cache_andes_l2.h +++ b/drivers/cache/cache_andes_l2.h @@ -208,7 +208,7 @@ static ALWAYS_INLINE int nds_l2_cache_init(void) { unsigned long line_size; -#if IS_ENABLED(CONFIG_SYSCON) +#if defined(CONFIG_SYSCON) #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(syscon), andestech_atcsmu100, okay) uint32_t system_cfg; const struct device *syscon_dev = DEVICE_DT_GET(DT_NODELABEL(syscon)); @@ -228,7 +228,7 @@ static ALWAYS_INLINE int nds_l2_cache_init(void) return 0; } #endif /* andestech_atcsmu100 dts node status okay */ -#endif /* IS_ENABLED(CONFIG_SYSCON) */ +#endif /* defined(CONFIG_SYSCON) */ uint32_t l2c_ctrl; diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 3a7d578a250a6..204da43c22f80 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -274,7 +274,7 @@ static int flash_sim_write(const struct device *dev, const off_t offset, #endif /* CONFIG_FLASH_SIMULATOR_STATS */ /* only pull bits to zero */ -#if IS_ENABLED(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) #if FLASH_SIMULATOR_ERASE_VALUE == 0xFF *(MOCK_FLASH(offset + i)) &= *((uint8_t *)data + i); #else diff --git a/drivers/flash/flash_util.c b/drivers/flash/flash_util.c index 26acfdf65cc82..fcd6509b802f0 100644 --- a/drivers/flash/flash_util.c +++ b/drivers/flash/flash_util.c @@ -67,14 +67,14 @@ int z_impl_flash_flatten(const struct device *dev, off_t offset, size_t size) (const struct flash_driver_api *)dev->api; __maybe_unused const struct flash_parameters *params = api->get_parameters(dev); -#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) if ((flash_params_get_erase_cap(params) & FLASH_ERASE_C_EXPLICIT) && api->erase != NULL) { return api->erase(dev, offset, size); } #endif -#if IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) return flash_fill(dev, params->erase_value, offset, size); #else return -ENOSYS; diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index de9cfd423450d..c15722082a341 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -184,7 +184,7 @@ static int flash_nrf_write(const struct device *dev, off_t addr, return -EINVAL; } -#if !IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS) +#if !defined(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS) if (!is_aligned_32(addr) || (len % sizeof(uint32_t))) { LOG_ERR("not word-aligned: 0x%08lx:%zu", (unsigned long)addr, len); diff --git a/drivers/flash/spi_flash_at45.c b/drivers/flash/spi_flash_at45.c index a223fb0863d64..ebdf522480e7d 100644 --- a/drivers/flash/spi_flash_at45.c +++ b/drivers/flash/spi_flash_at45.c @@ -525,7 +525,7 @@ static void spi_flash_at45_pages_layout(const struct device *dev, *layout = &cfg->pages_layout; *layout_size = 1; } -#endif /* IS_ENABLED(CONFIG_FLASH_PAGE_LAYOUT) */ +#endif /* defined(CONFIG_FLASH_PAGE_LAYOUT) */ static int power_down_op(const struct device *dev, uint8_t opcode, uint32_t delay) @@ -636,7 +636,7 @@ static int spi_flash_at45_pm_action(const struct device *dev, return 0; } -#endif /* IS_ENABLED(CONFIG_PM_DEVICE) */ +#endif /* defined(CONFIG_PM_DEVICE) */ static const struct flash_parameters * flash_at45_get_parameters(const struct device *dev) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 13f4132a01dfd..613c913868bfd 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -739,7 +739,7 @@ static int nrf5_continuous_carrier(const struct device *dev) } #endif -#if !IS_ENABLED(CONFIG_IEEE802154_NRF5_EXT_IRQ_MGMT) +#if !defined(CONFIG_IEEE802154_NRF5_EXT_IRQ_MGMT) static void nrf5_radio_irq(const void *arg) { ARG_UNUSED(arg); @@ -752,7 +752,7 @@ static void nrf5_irq_config(const struct device *dev) { ARG_UNUSED(dev); -#if !IS_ENABLED(CONFIG_IEEE802154_NRF5_EXT_IRQ_MGMT) +#if !defined(CONFIG_IEEE802154_NRF5_EXT_IRQ_MGMT) IRQ_CONNECT(DT_IRQN(DT_NODELABEL(radio)), NRF_802154_IRQ_PRIORITY, nrf5_radio_irq, NULL, 0); irq_enable(DT_IRQN(DT_NODELABEL(radio))); #endif diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 144e448a04d4a..efebfc07f9d70 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -357,7 +357,7 @@ static void plic_irq_handler(const struct device *dev) z_irq_spurious(NULL); } -#if IS_ENABLED(PLIC_DRV_HAS_COMPAT(andestech_nceplic100)) +#if PLIC_DRV_HAS_COMPAT(andestech_nceplic100) trig_val = riscv_plic_irq_trig_val(dev, local_irq); /* * Edge-triggered interrupts on Andes NCEPLIC100 have to be acknowledged first before @@ -377,7 +377,7 @@ static void plic_irq_handler(const struct device *dev) * PLIC controller that the IRQ has been handled * for level triggered interrupts. */ -#if IS_ENABLED(PLIC_DRV_HAS_COMPAT(andestech_nceplic100)) +#if PLIC_DRV_HAS_COMPAT(andestech_nceplic100) /* For NCEPLIC100, handle only if level-triggered */ if (trig_val == PLIC_TRIG_LEVEL) { sys_write32(local_irq, claim_complete_addr); diff --git a/drivers/ipm/ipm_imx.c b/drivers/ipm/ipm_imx.c index 7a4b3b1e21011..b8e716af7b09d 100644 --- a/drivers/ipm/ipm_imx.c +++ b/drivers/ipm/ipm_imx.c @@ -167,7 +167,7 @@ static int imx_mu_ipm_send(const struct device *dev, int wait, uint32_t id, const struct imx_mu_config *config = dev->config; MU_Type *base = MU(config); uint32_t data32[IMX_IPM_DATA_REGS] = {0}; -#if !IS_ENABLED(CONFIG_HAS_MCUX) +#if !defined(CONFIG_HAS_MCUX) mu_status_t status; #endif int i; diff --git a/drivers/regulator/regulator_da1469x.c b/drivers/regulator/regulator_da1469x.c index fe6d6a8ccc1ff..2273fe363bdef 100644 --- a/drivers/regulator/regulator_da1469x.c +++ b/drivers/regulator/regulator_da1469x.c @@ -408,7 +408,7 @@ static int regulator_da1469x_init(const struct device *dev) return regulator_common_init(dev, 0); } -#if IS_ENABLED(CONFIG_PM_DEVICE) +#if defined(CONFIG_PM_DEVICE) static int regulator_da1469x_pm_action(const struct device *dev, enum pm_device_action action) { diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c index 160d6887f9d4c..54bebac9dd815 100644 --- a/drivers/serial/uart_pl011.c +++ b/drivers/serial/uart_pl011.c @@ -21,10 +21,10 @@ #if defined(CONFIG_PINCTRL) #include #endif -#if IS_ENABLED(CONFIG_RESET) +#if defined(CONFIG_RESET) #include #endif -#if IS_ENABLED(CONFIG_CLOCK_CONTROL) +#if defined(CONFIG_CLOCK_CONTROL) #include #endif @@ -41,10 +41,10 @@ struct pl011_config { #if defined(CONFIG_PINCTRL) const struct pinctrl_dev_config *pincfg; #endif -#if IS_ENABLED(CONFIG_RESET) +#if defined(CONFIG_RESET) const struct reset_dt_spec reset; #endif -#if IS_ENABLED(CONFIG_CLOCK_CONTROL) +#if defined(CONFIG_CLOCK_CONTROL) const struct device *clock_dev; clock_control_subsys_t clock_id; #endif @@ -445,7 +445,7 @@ static int pl011_init(const struct device *dev) DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); -#if IS_ENABLED(CONFIG_RESET) +#if defined(CONFIG_RESET) if (config->reset.dev) { ret = reset_line_toggle_dt(&config->reset); if (ret) { @@ -454,7 +454,7 @@ static int pl011_init(const struct device *dev) } #endif -#if IS_ENABLED(CONFIG_CLOCK_CONTROL) +#if defined(CONFIG_CLOCK_CONTROL) if (config->clock_dev) { clock_control_on(config->clock_dev, config->clock_id); clock_control_get_rate(config->clock_dev, config->clock_id, &data->clk_freq); @@ -560,7 +560,7 @@ static int pl011_init(const struct device *dev) #define PINCTRL_INIT(n) #endif /* CONFIG_PINCTRL */ -#if IS_ENABLED(CONFIG_RESET) +#if defined(CONFIG_RESET) #define RESET_INIT(n) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(0, resets), (.reset = RESET_DT_SPEC_INST_GET(n),)) #else diff --git a/drivers/spi/spi_dw.h b/drivers/spi/spi_dw.h index 6c073b4747160..e1df26d1c14ef 100644 --- a/drivers/spi/spi_dw.h +++ b/drivers/spi/spi_dw.h @@ -179,7 +179,7 @@ static int reg_test_bit(uint8_t bit, mm_reg_t addr, uint32_t off) /* Common registers settings, bits etc... */ /* CTRLR0 settings */ -#if !IS_ENABLED(CONFIG_SPI_DW_HSSI) +#if !defined(CONFIG_SPI_DW_HSSI) #define DW_SPI_CTRLR0_SCPH_BIT (6) #define DW_SPI_CTRLR0_SCPOL_BIT (7) #define DW_SPI_CTRLR0_TMOD_SHIFT (8) diff --git a/drivers/spi/spi_pl022.c b/drivers/spi/spi_pl022.c index ed30dddf1e1ef..817a826d4da7f 100644 --- a/drivers/spi/spi_pl022.c +++ b/drivers/spi/spi_pl022.c @@ -275,11 +275,11 @@ struct spi_pl022_cfg { const uint32_t reg; const uint32_t pclk; const bool dma_enabled; -#if IS_ENABLED(CONFIG_CLOCK_CONTROL) +#if defined(CONFIG_CLOCK_CONTROL) const struct device *clk_dev; const clock_control_subsys_t clk_id; #endif -#if IS_ENABLED(CONFIG_RESET) +#if defined(CONFIG_RESET) const struct reset_dt_spec reset; #endif #if defined(CONFIG_PINCTRL) @@ -354,7 +354,7 @@ static int spi_pl022_configure(const struct device *dev, return 0; } -#if IS_ENABLED(CONFIG_CLOCK_CONTROL) +#if defined(CONFIG_CLOCK_CONTROL) ret = clock_control_get_rate(cfg->clk_dev, cfg->clk_id, &pclk); if (ret < 0 || pclk == 0) { return -EINVAL; @@ -906,7 +906,7 @@ static int spi_pl022_init(const struct device *dev) struct spi_pl022_data *data = dev->data; int ret; -#if IS_ENABLED(CONFIG_CLOCK_CONTROL) +#if defined(CONFIG_CLOCK_CONTROL) if (cfg->clk_dev) { ret = clock_control_on(cfg->clk_dev, cfg->clk_id); if (ret < 0) { @@ -916,7 +916,7 @@ static int spi_pl022_init(const struct device *dev) } #endif -#if IS_ENABLED(CONFIG_RESET) +#if defined(CONFIG_RESET) if (cfg->reset.dev) { ret = reset_line_toggle_dt(&cfg->reset); if (ret < 0) { diff --git a/include/zephyr/bindesc.h b/include/zephyr/bindesc.h index a45e69a2b9cee..48cb71c401a77 100644 --- a/include/zephyr/bindesc.h +++ b/include/zephyr/bindesc.h @@ -128,7 +128,7 @@ extern "C" { * @endcond */ -#if !IS_ENABLED(_LINKER) +#if !defined(_LINKER) #include @@ -264,10 +264,6 @@ extern "C" { */ #define BINDESC_GET_SIZE(name) BINDESC_NAME(name).len -/** - * @} - */ - /* * An entry of the binary descriptor header. Each descriptor is * described by one of these entries. @@ -291,107 +287,111 @@ BUILD_ASSERT(offsetof(struct bindesc_entry, tag) == 0, "Incorrect memory layout" BUILD_ASSERT(offsetof(struct bindesc_entry, len) == 2, "Incorrect memory layout"); BUILD_ASSERT(offsetof(struct bindesc_entry, data) == 4, "Incorrect memory layout"); -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_STRING) extern const struct bindesc_entry BINDESC_NAME(kernel_version_string); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) extern const struct bindesc_entry BINDESC_NAME(kernel_version_major); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_MINOR) extern const struct bindesc_entry BINDESC_NAME(kernel_version_minor); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) extern const struct bindesc_entry BINDESC_NAME(kernel_version_patchlevel); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) extern const struct bindesc_entry BINDESC_NAME(kernel_version_number); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) +#if defined(CONFIG_BINDESC_APP_VERSION_STRING) extern const struct bindesc_entry BINDESC_NAME(app_version_string); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) +#if defined(CONFIG_BINDESC_APP_VERSION_MAJOR) extern const struct bindesc_entry BINDESC_NAME(app_version_major); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_MAJOR) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) +#if defined(CONFIG_BINDESC_APP_VERSION_MINOR) extern const struct bindesc_entry BINDESC_NAME(app_version_minor); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_MINOR) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) +#if defined(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) extern const struct bindesc_entry BINDESC_NAME(app_version_patchlevel); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) +#if defined(CONFIG_BINDESC_APP_VERSION_NUMBER) extern const struct bindesc_entry BINDESC_NAME(app_version_number); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_NUMBER) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) +#if defined(CONFIG_BINDESC_BUILD_TIME_YEAR) extern const struct bindesc_entry BINDESC_NAME(build_time_year); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_YEAR) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) +#if defined(CONFIG_BINDESC_BUILD_TIME_MONTH) extern const struct bindesc_entry BINDESC_NAME(build_time_month); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_MONTH) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) +#if defined(CONFIG_BINDESC_BUILD_TIME_DAY) extern const struct bindesc_entry BINDESC_NAME(build_time_day); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_DAY) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) +#if defined(CONFIG_BINDESC_BUILD_TIME_HOUR) extern const struct bindesc_entry BINDESC_NAME(build_time_hour); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_HOUR) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) +#if defined(CONFIG_BINDESC_BUILD_TIME_MINUTE) extern const struct bindesc_entry BINDESC_NAME(build_time_minute); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) +#if defined(CONFIG_BINDESC_BUILD_TIME_SECOND) extern const struct bindesc_entry BINDESC_NAME(build_time_second); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_SECOND) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) +#if defined(CONFIG_BINDESC_BUILD_TIME_UNIX) extern const struct bindesc_entry BINDESC_NAME(build_time_unix); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_UNIX) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) +#if defined(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) extern const struct bindesc_entry BINDESC_NAME(build_date_time_string); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ +#endif /* defined(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) +#if defined(CONFIG_BINDESC_BUILD_DATE_STRING) extern const struct bindesc_entry BINDESC_NAME(build_date_string); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */ +#endif /* defined(CONFIG_BINDESC_BUILD_DATE_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) +#if defined(CONFIG_BINDESC_BUILD_TIME_STRING) extern const struct bindesc_entry BINDESC_NAME(build_time_string); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_HOST_NAME) +#if defined(CONFIG_BINDESC_HOST_NAME) extern const struct bindesc_entry BINDESC_NAME(host_name); -#endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */ +#endif /* defined(CONFIG_BINDESC_HOST_NAME) */ -#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) +#if defined(CONFIG_BINDESC_C_COMPILER_NAME) extern const struct bindesc_entry BINDESC_NAME(c_compiler_name); -#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */ +#endif /* defined(CONFIG_BINDESC_C_COMPILER_NAME) */ -#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) +#if defined(CONFIG_BINDESC_C_COMPILER_VERSION) extern const struct bindesc_entry BINDESC_NAME(c_compiler_version); -#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */ +#endif /* defined(CONFIG_BINDESC_C_COMPILER_VERSION) */ -#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) +#if defined(CONFIG_BINDESC_CXX_COMPILER_NAME) extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_name); -#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */ +#endif /* defined(CONFIG_BINDESC_CXX_COMPILER_NAME) */ -#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) +#if defined(CONFIG_BINDESC_CXX_COMPILER_VERSION) extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_version); -#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ +#endif /* defined(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ -#endif /* !IS_ENABLED(_LINKER) */ +#endif /* !defined(_LINKER) */ + +/** + * @} + */ #ifdef __cplusplus } diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h index c11e423e26dd3..82e642c737577 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h @@ -345,7 +345,7 @@ int img_mgmt_state_confirm(void); */ int img_mgmt_vercmp(const struct image_version *a, const struct image_version *b); -#if IS_ENABLED(CONFIG_MCUMGR_GRP_IMG_MUTEX) +#if defined(CONFIG_MCUMGR_GRP_IMG_MUTEX) /* * @brief Will reset the image management state back to default (no ongoing upload), * requires that CONFIG_MCUMGR_GRP_IMG_MUTEX be enabled to allow for mutex diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h index 9a139b3a04b78..a247a1c283de9 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h @@ -74,7 +74,7 @@ typedef int (*mgmt_handler_fn)(struct smp_streamer *ctxt); struct mgmt_handler { mgmt_handler_fn mh_read; mgmt_handler_fn mh_write; -#if IS_ENABLED(CONFIG_MCUMGR_MGMT_HANDLER_USER_DATA) +#if defined(CONFIG_MCUMGR_MGMT_HANDLER_USER_DATA) void *user_data; #endif }; @@ -93,7 +93,7 @@ struct mgmt_group { /** The numeric ID of this group. */ uint16_t mg_group_id; -#if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) +#if defined(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) /** A function handler for translating version 2 SMP error codes to version 1 SMP error * codes (optional) */ @@ -152,7 +152,7 @@ const struct mgmt_group *mgmt_find_group(uint16_t group_id); */ const struct mgmt_handler *mgmt_get_handler(const struct mgmt_group *group, uint16_t command_id); -#if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) +#if defined(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) /** * @brief Finds a registered error translation function for converting from SMP * version 2 error codes to legacy SMP version 1 error codes. diff --git a/include/zephyr/mgmt/mcumgr/smp/smp.h b/include/zephyr/mgmt/mcumgr/smp/smp.h index fc148e2fad71e..c72461a939a32 100644 --- a/include/zephyr/mgmt/mcumgr/smp/smp.h +++ b/include/zephyr/mgmt/mcumgr/smp/smp.h @@ -56,7 +56,7 @@ struct cbor_nb_writer { struct net_buf *nb; zcbor_state_t zs[CONFIG_MCUMGR_SMP_CBOR_MAX_ENCODING_LEVELS + 2]; -#if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) +#if defined(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) uint16_t error_group; uint16_t error_ret; #endif @@ -127,7 +127,7 @@ __deprecated inline bool smp_add_cmd_ret(zcbor_state_t *zse, uint16_t group, uin return smp_add_cmd_err(zse, group, ret); } -#if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) +#if defined(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) /** @typedef smp_translate_error_fn * @brief Translates a SMP version 2 error response to a legacy SMP version 1 error code. * diff --git a/include/zephyr/retention/blinfo.h b/include/zephyr/retention/blinfo.h index e3a6e6b570d7a..78cd12459bc3b 100644 --- a/include/zephyr/retention/blinfo.h +++ b/include/zephyr/retention/blinfo.h @@ -33,7 +33,7 @@ extern "C" { * @{ */ -#if IS_ENABLED(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION) || defined(__DOXYGEN__) +#if defined(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION) || defined(__DOXYGEN__) /** * @brief Returns bootinfo information. * diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index ea708cba4f7d3..3636f49591e8e 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -183,7 +183,7 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; #define __MK_ISR_NAME(x, y) __isr_ ## x ## _irq_ ## y -#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +#if defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) #define _MK_ISR_ELEMENT_NAME(func, id) __MK_ISR_ELEMENT_NAME(func, id) #define __MK_ISR_ELEMENT_NAME(func, id) __isr_table_entry_ ## func ## _irq_ ## id @@ -264,7 +264,7 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; Z_ISR_DECLARE_DIRECT_C(irq, flags, func, __COUNTER__) -#else /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ +#else /* defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ /* Create an instance of struct _isr_list which gets put in the .intList * section. This gets consumed by gen_isr_tables.py which creates the vector diff --git a/include/zephyr/sys/mpsc_lockfree.h b/include/zephyr/sys/mpsc_lockfree.h index 3e6c89d99a051..ccf9bc4d5a1c7 100644 --- a/include/zephyr/sys/mpsc_lockfree.h +++ b/include/zephyr/sys/mpsc_lockfree.h @@ -50,7 +50,7 @@ extern "C" { * On SMP atomics *must* be used to ensure the pointers * are updated in the correct order. */ -#if IS_ENABLED(CONFIG_SMP) +#if defined(CONFIG_SMP) typedef atomic_ptr_t mpsc_ptr_t; @@ -58,7 +58,7 @@ typedef atomic_ptr_t mpsc_ptr_t; #define mpsc_ptr_set(ptr, val) atomic_ptr_set(&(ptr), val) #define mpsc_ptr_set_get(ptr, val) atomic_ptr_set(&(ptr), val) -#else /* IS_ENABLED(CONFIG_SMP) */ +#else /* defined(CONFIG_SMP) */ typedef struct mpsc_node *mpsc_ptr_t; @@ -71,7 +71,7 @@ typedef struct mpsc_node *mpsc_ptr_t; tmp; \ }) -#endif /* IS_ENABLED(CONFIG_SMP) */ +#endif /* defined(CONFIG_SMP) */ /** * @brief Queue member diff --git a/samples/drivers/soc_flash_nrf/src/main.c b/samples/drivers/soc_flash_nrf/src/main.c index d55214afcc515..0297a17d1f80e 100644 --- a/samples/drivers/soc_flash_nrf/src/main.c +++ b/samples/drivers/soc_flash_nrf/src/main.c @@ -28,10 +28,10 @@ #define FLASH_TEST_OFFSET2 0x41234 #define FLASH_TEST_PAGE_IDX 37 -#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \ - IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \ + defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) #define FLASH_PE_RUNTIME_CHECK(cond) (cond) -#elif IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) +#elif defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) #define FLASH_PE_RUNTIME_CHECK(cond) (true) #else /* Assumed IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) */ diff --git a/samples/subsys/fs/littlefs/src/main.c b/samples/subsys/fs/littlefs/src/main.c index 7723023013eb7..b04b998d7d5ae 100644 --- a/samples/subsys/fs/littlefs/src/main.c +++ b/samples/subsys/fs/littlefs/src/main.c @@ -312,7 +312,7 @@ static int littlefs_mount(struct fs_mount_t *mp) #if defined(CONFIG_DISK_DRIVER_SDMMC) #define DISK_NAME CONFIG_SDMMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_DISK_DRIVER_MMC) +#elif defined(CONFIG_DISK_DRIVER_MMC) #define DISK_NAME CONFIG_MMC_VOLUME_NAME #else #error "No disk device defined, is your board supported?" diff --git a/samples/subsys/usb/cdc_acm/src/main.c b/samples/subsys/usb/cdc_acm/src/main.c index 4dffe7cee6dae..ab1cbdc6a4c0e 100644 --- a/samples/subsys/usb/cdc_acm/src/main.c +++ b/samples/subsys/usb/cdc_acm/src/main.c @@ -106,7 +106,7 @@ static int enable_usb_device_next(void) return 0; } -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */ +#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ static void interrupt_handler(const struct device *dev, void *user_data) { diff --git a/samples/subsys/usb/console/src/main.c b/samples/subsys/usb/console/src/main.c index 538e768614a23..bf2230687e1c9 100644 --- a/samples/subsys/usb/console/src/main.c +++ b/samples/subsys/usb/console/src/main.c @@ -34,7 +34,7 @@ static int enable_usb_device_next(void) return 0; } -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */ +#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ int main(void) { diff --git a/samples/subsys/usb/hid-mouse/src/main.c b/samples/subsys/usb/hid-mouse/src/main.c index 28b27877acbaf..382453bbf8ac7 100644 --- a/samples/subsys/usb/hid-mouse/src/main.c +++ b/samples/subsys/usb/hid-mouse/src/main.c @@ -118,7 +118,7 @@ static int enable_usb_device_next(void) return 0; } -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */ +#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ int main(void) { diff --git a/samples/subsys/usb/mass/src/main.c b/samples/subsys/usb/mass/src/main.c index 733f6f90ea86f..d95d91ca74a7f 100644 --- a/samples/subsys/usb/mass/src/main.c +++ b/samples/subsys/usb/mass/src/main.c @@ -70,7 +70,7 @@ static int enable_usb_device_next(void) return 0; } -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */ +#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ static int setup_flash(struct fs_mount_t *mnt) { diff --git a/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf53.c b/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf53.c index e5f93a846fdfa..7e949d6121179 100644 --- a/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf53.c +++ b/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf53.c @@ -48,7 +48,7 @@ static const nrfx_timer_t feedback_timer_instance = * the 4 least significant bits (does not use the bits for extra precision). */ #define FEEDBACK_K 10 -#if IS_ENABLED(CONFIG_APP_USE_I2S_LRCLK_EDGES_COUNTER) +#if defined(CONFIG_APP_USE_I2S_LRCLK_EDGES_COUNTER) #define FEEDBACK_P 1 #else #define FEEDBACK_P 5 diff --git a/subsys/bindesc/bindesc_build_time.c b/subsys/bindesc/bindesc_build_time.c index fde98c0f00503..e0aeab261d1c7 100644 --- a/subsys/bindesc/bindesc_build_time.c +++ b/subsys/bindesc/bindesc_build_time.c @@ -10,43 +10,43 @@ /* Include generated header */ #include -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) +#if defined(CONFIG_BINDESC_BUILD_TIME_YEAR) BINDESC_UINT_DEFINE(build_time_year, BINDESC_ID_BUILD_TIME_YEAR, BUILD_TIME_YEAR); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_YEAR) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) +#if defined(CONFIG_BINDESC_BUILD_TIME_MONTH) BINDESC_UINT_DEFINE(build_time_month, BINDESC_ID_BUILD_TIME_MONTH, BUILD_TIME_MONTH); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_MONTH) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) +#if defined(CONFIG_BINDESC_BUILD_TIME_DAY) BINDESC_UINT_DEFINE(build_time_day, BINDESC_ID_BUILD_TIME_DAY, BUILD_TIME_DAY); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_DAY) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) +#if defined(CONFIG_BINDESC_BUILD_TIME_HOUR) BINDESC_UINT_DEFINE(build_time_hour, BINDESC_ID_BUILD_TIME_HOUR, BUILD_TIME_HOUR); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_HOUR) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) +#if defined(CONFIG_BINDESC_BUILD_TIME_MINUTE) BINDESC_UINT_DEFINE(build_time_minute, BINDESC_ID_BUILD_TIME_MINUTE, BUILD_TIME_MINUTE); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) +#if defined(CONFIG_BINDESC_BUILD_TIME_SECOND) BINDESC_UINT_DEFINE(build_time_second, BINDESC_ID_BUILD_TIME_SECOND, BUILD_TIME_SECOND); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_SECOND) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) +#if defined(CONFIG_BINDESC_BUILD_TIME_UNIX) BINDESC_UINT_DEFINE(build_time_unix, BINDESC_ID_BUILD_TIME_UNIX, BUILD_TIME_UNIX); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_UNIX) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) +#if defined(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) BINDESC_STR_DEFINE(build_date_time_string, BINDESC_ID_BUILD_DATE_TIME_STRING, BUILD_DATE_TIME_STRING); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ +#endif /* defined(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) +#if defined(CONFIG_BINDESC_BUILD_DATE_STRING) BINDESC_STR_DEFINE(build_date_string, BINDESC_ID_BUILD_DATE_STRING, BUILD_DATE_STRING); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */ +#endif /* defined(CONFIG_BINDESC_BUILD_DATE_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) +#if defined(CONFIG_BINDESC_BUILD_TIME_STRING) BINDESC_STR_DEFINE(build_time_string, BINDESC_ID_BUILD_TIME_STRING, BUILD_TIME_STRING); -#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */ +#endif /* defined(CONFIG_BINDESC_BUILD_TIME_STRING) */ diff --git a/subsys/bindesc/bindesc_host_info.c b/subsys/bindesc/bindesc_host_info.c index 6ecc43495d43f..56611b945230b 100644 --- a/subsys/bindesc/bindesc_host_info.c +++ b/subsys/bindesc/bindesc_host_info.c @@ -7,23 +7,23 @@ #include #include -#if IS_ENABLED(CONFIG_BINDESC_HOST_NAME) +#if defined(CONFIG_BINDESC_HOST_NAME) BINDESC_STR_DEFINE(host_name, BINDESC_ID_HOST_NAME, HOST_NAME); -#endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */ +#endif /* defined(CONFIG_BINDESC_HOST_NAME) */ -#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) +#if defined(CONFIG_BINDESC_C_COMPILER_NAME) BINDESC_STR_DEFINE(c_compiler_name, BINDESC_ID_C_COMPILER_NAME, C_COMPILER_NAME); -#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */ +#endif /* defined(CONFIG_BINDESC_C_COMPILER_NAME) */ -#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) +#if defined(CONFIG_BINDESC_C_COMPILER_VERSION) BINDESC_STR_DEFINE(c_compiler_version, BINDESC_ID_C_COMPILER_VERSION, C_COMPILER_VERSION); -#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */ +#endif /* defined(CONFIG_BINDESC_C_COMPILER_VERSION) */ -#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) +#if defined(CONFIG_BINDESC_CXX_COMPILER_NAME) BINDESC_STR_DEFINE(cxx_compiler_name, BINDESC_ID_CXX_COMPILER_NAME, CXX_COMPILER_NAME); -#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */ +#endif /* defined(CONFIG_BINDESC_CXX_COMPILER_NAME) */ -#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) +#if defined(CONFIG_BINDESC_CXX_COMPILER_VERSION) BINDESC_STR_DEFINE(cxx_compiler_version, BINDESC_ID_CXX_COMPILER_VERSION, CXX_COMPILER_VERSION); -#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ +#endif /* defined(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ diff --git a/subsys/bindesc/bindesc_version.c b/subsys/bindesc/bindesc_version.c index 76111ca17bb8c..ff8030585c299 100644 --- a/subsys/bindesc/bindesc_version.c +++ b/subsys/bindesc/bindesc_version.c @@ -8,57 +8,57 @@ #include #include -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_STRING) BINDESC_STR_DEFINE(kernel_version_string, BINDESC_ID_KERNEL_VERSION_STRING, KERNEL_VERSION_STRING); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) BINDESC_UINT_DEFINE(kernel_version_major, BINDESC_ID_KERNEL_VERSION_MAJOR, KERNEL_VERSION_MAJOR); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_MINOR) BINDESC_UINT_DEFINE(kernel_version_minor, BINDESC_ID_KERNEL_VERSION_MINOR, KERNEL_VERSION_MINOR); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) BINDESC_UINT_DEFINE(kernel_version_patchlevel, BINDESC_ID_KERNEL_VERSION_PATCHLEVEL, KERNEL_PATCHLEVEL); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ -#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) +#if defined(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) BINDESC_UINT_DEFINE(kernel_version_number, BINDESC_ID_KERNEL_VERSION_NUMBER, KERNEL_VERSION_NUMBER); -#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ +#endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ -#if IS_ENABLED(HAS_APP_VERSION) +#if defined(HAS_APP_VERSION) #include -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) +#if defined(CONFIG_BINDESC_APP_VERSION_STRING) BINDESC_STR_DEFINE(app_version_string, BINDESC_ID_APP_VERSION_STRING, APP_VERSION_STRING); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_STRING) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) +#if defined(CONFIG_BINDESC_APP_VERSION_MAJOR) BINDESC_UINT_DEFINE(app_version_major, BINDESC_ID_APP_VERSION_MAJOR, APP_VERSION_MAJOR); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_MAJOR) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) +#if defined(CONFIG_BINDESC_APP_VERSION_MINOR) BINDESC_UINT_DEFINE(app_version_minor, BINDESC_ID_APP_VERSION_MINOR, APP_VERSION_MINOR); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_MINOR) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) +#if defined(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) BINDESC_UINT_DEFINE(app_version_patchlevel, BINDESC_ID_APP_VERSION_PATCHLEVEL, APP_PATCHLEVEL); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ -#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) +#if defined(CONFIG_BINDESC_APP_VERSION_NUMBER) BINDESC_UINT_DEFINE(app_version_number, BINDESC_ID_APP_VERSION_NUMBER, APP_VERSION_NUMBER); -#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */ +#endif /* defined(CONFIG_BINDESC_APP_VERSION_NUMBER) */ -#endif /* IS_ENABLED(HAS_APP_VERSION) */ +#endif /* defined(HAS_APP_VERSION) */ diff --git a/subsys/bluetooth/audio/tbs.c b/subsys/bluetooth/audio/tbs.c index aa5be134f2de3..1a33985cf2be5 100644 --- a/subsys/bluetooth/audio/tbs.c +++ b/subsys/bluetooth/audio/tbs.c @@ -84,7 +84,7 @@ struct gtbs_service_inst { #else #define READ_BUF_SIZE (CONFIG_BT_TBS_MAX_CALLS * \ sizeof(struct bt_tbs_current_call_item)) -#endif /* IS_ENABLED(CONFIG_BT_GTBS) */ +#endif /* defined(CONFIG_BT_GTBS) */ NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, READ_BUF_SIZE); static struct tbs_service_inst svc_insts[CONFIG_BT_TBS_BEARER_COUNT]; diff --git a/subsys/bluetooth/audio/tbs_client.c b/subsys/bluetooth/audio/tbs_client.c index 2a29181328870..71c34f781fc3f 100644 --- a/subsys/bluetooth/audio/tbs_client.c +++ b/subsys/bluetooth/audio/tbs_client.c @@ -63,7 +63,7 @@ struct bt_tbs_server_inst { #endif /* CONFIG_BT_TBS_CLIENT_TBS */ #if defined(CONFIG_BT_TBS_CLIENT_GTBS) struct bt_tbs_instance gtbs_inst; -#endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */ +#endif /* defined(CONFIG_BT_TBS_CLIENT_GTBS) */ struct bt_gatt_discover_params discover_params; struct bt_tbs_instance *current_inst; }; @@ -1748,7 +1748,7 @@ static int primary_discover_gtbs(struct bt_conn *conn) return bt_gatt_discover(conn, params); } -#endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */ +#endif /* defined(CONFIG_BT_TBS_CLIENT_GTBS) */ /****************************** PUBLIC API ******************************/ diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 6358f1656fb9e..e095d9babdb9d 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -111,10 +111,10 @@ static const struct { uint8_t page; } comp_data_pages[] = { { "bt/mesh/cmp/0", 0, }, -#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) +#if defined(CONFIG_BT_MESH_COMP_PAGE_1) { "bt/mesh/cmp/1", 1, }, #endif -#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) +#if defined(CONFIG_BT_MESH_COMP_PAGE_2) { "bt/mesh/cmp/2", 2, }, #endif }; @@ -2617,7 +2617,7 @@ void bt_mesh_comp_data_clear(void) int bt_mesh_models_metadata_change_prepare(void) { -#if IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) return bt_mesh_models_metadata_store(); #else return -ENOTSUP; diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index 4fef60d5c8dba..155c2e616d558 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -137,7 +137,7 @@ uint8_t bt_mesh_priv_beacon_update_interval_get(void) int bt_mesh_od_priv_proxy_get(void) { -#if IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) return bt_mesh.on_demand_state; #else return -ENOTSUP; @@ -146,7 +146,7 @@ int bt_mesh_od_priv_proxy_get(void) int bt_mesh_od_priv_proxy_set(uint8_t on_demand_proxy) { -#if !IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) +#if !defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) return -ENOTSUP; #else diff --git a/subsys/bluetooth/mesh/prov.h b/subsys/bluetooth/mesh/prov.h index a88710639db14..00bd85952e0e5 100644 --- a/subsys/bluetooth/mesh/prov.h +++ b/subsys/bluetooth/mesh/prov.h @@ -78,7 +78,7 @@ NET_BUF_SIMPLE_DEFINE(name, PROV_BEARER_BUF_HEADROOM + PDU_OP_LEN + len + \ PROV_BEARER_BUF_TAILROOM) -#if IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM) +#if defined(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM) #define PROV_AUTH_MAX_LEN 32 #else #define PROV_AUTH_MAX_LEN 16 diff --git a/subsys/bluetooth/services/ots/ots_l2cap.c b/subsys/bluetooth/services/ots/ots_l2cap.c index ad169c5aee0bb..aa54036125700 100644 --- a/subsys/bluetooth/services/ots/ots_l2cap.c +++ b/subsys/bluetooth/services/ots/ots_l2cap.c @@ -24,7 +24,7 @@ */ #if defined(CONFIG_BT_OTS) LOG_MODULE_DECLARE(bt_ots, CONFIG_BT_OTS_LOG_LEVEL); -#elif IS_ENABLED(CONFIG_BT_OTS_CLIENT) +#elif defined(CONFIG_BT_OTS_CLIENT) LOG_MODULE_REGISTER(bt_ots, CONFIG_BT_OTS_LOG_LEVEL); #endif diff --git a/subsys/fs/fcb/fcb_elem_info.c b/subsys/fs/fcb/fcb_elem_info.c index 3bb6031ec2127..1cb9185740d94 100644 --- a/subsys/fs/fcb/fcb_elem_info.c +++ b/subsys/fs/fcb/fcb_elem_info.c @@ -66,7 +66,7 @@ fcb_elem_crc8(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *c8p) return 0; } -#if IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) +#if defined(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) /* Given the offset in flash sector, calculate the FCB entry data offset and size, and set * the fixed endmarker. */ @@ -97,7 +97,7 @@ fcb_elem_endmarker_fixed(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *em) *em = FCB_FIXED_ENDMARKER; return 0; } -#endif /* IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) */ +#endif /* defined(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) */ /* Given the offset in flash sector, calculate the FCB entry data offset and size, and calculate * the expected endmarker. @@ -105,11 +105,11 @@ fcb_elem_endmarker_fixed(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *em) int fcb_elem_endmarker(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *em) { -#if IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) +#if defined(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) if (_fcb->f_flags & FCB_FLAGS_CRC_DISABLED) { return fcb_elem_endmarker_fixed(_fcb, loc, em); } -#endif /* IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) */ +#endif /* defined(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) */ return fcb_elem_crc8(_fcb, loc, em); } diff --git a/subsys/ipc/ipc_service/lib/icmsg.c b/subsys/ipc/ipc_service/lib/icmsg.c index 61fa03689f40f..37fbc30d89eba 100644 --- a/subsys/ipc/ipc_service/lib/icmsg.c +++ b/subsys/ipc/ipc_service/lib/icmsg.c @@ -19,7 +19,7 @@ static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b, 0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34}; -#if IS_ENABLED(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) +#if defined(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) static K_THREAD_STACK_DEFINE(icmsg_stack, CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE); static struct k_work_q icmsg_workq; static struct k_work_q *const workq = &icmsg_workq; @@ -301,7 +301,7 @@ int icmsg_send(const struct icmsg_config_t *conf, return sent_bytes; } -#if IS_ENABLED(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) +#if defined(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) static int work_q_init(void) { diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index 4d87ea997cf01..ad46a538b4afd 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -423,19 +423,19 @@ os_mgmt_mcumgr_params(struct smp_streamer *ctxt) #if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) -#if IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP) +#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP) #define BOOTLOADER_MODE MCUBOOT_MODE_SINGLE_SLOT -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) +#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) #define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_SCRATCH -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) +#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) #define BOOTLOADER_MODE MCUBOOT_MODE_UPGRADE_ONLY -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) +#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) #define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_MOVE -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) +#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) #define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) +#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) #define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER) +#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER) #define BOOTLOADER_MODE MCUBOOT_MODE_FIRMWARE_LOADER #else #define BOOTLOADER_MODE -1 diff --git a/subsys/mgmt/mcumgr/mgmt/src/mgmt.c b/subsys/mgmt/mcumgr/mgmt/src/mgmt.c index adb2c8e4bcbeb..0495d3fb4d42d 100644 --- a/subsys/mgmt/mcumgr/mgmt/src/mgmt.c +++ b/subsys/mgmt/mcumgr/mgmt/src/mgmt.c @@ -103,7 +103,7 @@ mgmt_get_handler(const struct mgmt_group *group, uint16_t command_id) return &group->mg_handlers[command_id]; } -#if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) +#if defined(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) smp_translate_error_fn mgmt_find_error_translation_function(uint16_t group_id) { struct mgmt_group *group = NULL; diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index 7bfa4f8a2a74b..d0ee06487d6d6 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -1246,7 +1246,7 @@ int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size, net_pkt_append_buffer(pkt, buf); -#if IS_ENABLED(CONFIG_NET_BUF_FIXED_DATA_SIZE) +#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE) /* net_buf allocators shrink the buffer size to the requested size. * We don't want this behavior here, so restore the real size of the * last fragment. diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index bd4906144ac6e..ce59e488bf20a 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -106,7 +106,7 @@ void lwm2m_register_obj(struct lwm2m_engine_obj *obj) k_mutex_lock(®istry_lock, K_FOREVER); #if defined(CONFIG_LWM2M_ACCESS_CONTROL_ENABLE) /* If bootstrap, then bootstrap server should create the ac obj instances */ -#if !IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) +#if !defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) int server_obj_inst_id = lwm2m_server_short_id_to_inst(CONFIG_LWM2M_SERVER_DEFAULT_SSID); access_control_add_obj(obj->obj_id, server_obj_inst_id); @@ -169,7 +169,7 @@ static void engine_register_obj_inst(struct lwm2m_engine_obj_inst *obj_inst) { #if defined(CONFIG_LWM2M_ACCESS_CONTROL_ENABLE) /* If bootstrap, then bootstrap server should create the ac obj instances */ -#if !IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) +#if !defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) int server_obj_inst_id = lwm2m_server_short_id_to_inst(CONFIG_LWM2M_SERVER_DEFAULT_SSID); access_control_add(obj_inst->obj->obj_id, obj_inst->obj_inst_id, server_obj_inst_id); diff --git a/subsys/shell/backends/shell_rtt.c b/subsys/shell/backends/shell_rtt.c index 4a874ba9ce84a..c8b10cb2567ea 100644 --- a/subsys/shell/backends/shell_rtt.c +++ b/subsys/shell/backends/shell_rtt.c @@ -15,7 +15,7 @@ #define RTT_UNLOCK() \ COND_CODE_0(CONFIG_SHELL_BACKEND_RTT_BUFFER, (SEGGER_RTT_UNLOCK()), ()) -#if IS_ENABLED(CONFIG_LOG_BACKEND_RTT) +#if defined(CONFIG_LOG_BACKEND_RTT) BUILD_ASSERT(!(CONFIG_SHELL_BACKEND_RTT_BUFFER == CONFIG_LOG_BACKEND_RTT_BUFFER), "Conflicting log RTT backend enabled on the same channel"); #endif diff --git a/subsys/storage/stream/stream_flash.c b/subsys/storage/stream/stream_flash.c index b9bd63df411be..0ff0c4578ff86 100644 --- a/subsys/storage/stream/stream_flash.c +++ b/subsys/storage/stream/stream_flash.c @@ -76,10 +76,10 @@ static int settings_direct_loader(const char *key, size_t len, int stream_flash_erase_page(struct stream_flash_ctx *ctx, off_t off) { -#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) int rc; struct flash_pages_info page; -#if IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) /* There are both types of devices */ const struct flash_parameters *fparams = flash_get_parameters(ctx->fdev); diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index 04e89671a5f7c..e4b77fcbb75b7 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -1532,7 +1532,7 @@ static void test_tx_priv_beacon_cache(void) PASS(); } -#if IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) +#if defined(CONFIG_BT_MESH_GATT_PROXY) static uint8_t test_net_key_3[16] = {0x12, 0x54, 0xab, 0x1e}; diff --git a/tests/drivers/disk/disk_access/src/main.c b/tests/drivers/disk/disk_access/src/main.c index 4e0348c0a0d80..8e26cc0356eaf 100644 --- a/tests/drivers/disk/disk_access/src/main.c +++ b/tests/drivers/disk/disk_access/src/main.c @@ -22,13 +22,13 @@ #if defined(CONFIG_DISK_DRIVER_SDMMC) #define DISK_NAME_PHYS CONFIG_SDMMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_DISK_DRIVER_MMC) +#elif defined(CONFIG_DISK_DRIVER_MMC) #define DISK_NAME_PHYS CONFIG_MMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_DISK_DRIVER_FLASH) +#elif defined(CONFIG_DISK_DRIVER_FLASH) #define DISK_NAME_PHYS "NAND" -#elif IS_ENABLED(CONFIG_NVME) +#elif defined(CONFIG_NVME) #define DISK_NAME_PHYS "nvme0n0" -#elif IS_ENABLED(CONFIG_DISK_DRIVER_RAM) +#elif defined(CONFIG_DISK_DRIVER_RAM) /* Since ramdisk is enabled by default on e.g. qemu boards, it needs to be checked last to not * override other backends. */ diff --git a/tests/drivers/disk/disk_performance/src/main.c b/tests/drivers/disk/disk_performance/src/main.c index 7d3a67b7a519b..0042cde68ee66 100644 --- a/tests/drivers/disk/disk_performance/src/main.c +++ b/tests/drivers/disk/disk_performance/src/main.c @@ -14,9 +14,9 @@ #if defined(CONFIG_DISK_DRIVER_SDMMC) #define DISK_NAME CONFIG_SDMMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_DISK_DRIVER_MMC) +#elif defined(CONFIG_DISK_DRIVER_MMC) #define DISK_NAME CONFIG_MMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_NVME) +#elif defined(CONFIG_NVME) #define DISK_NAME "nvme0n0" #else #error "No disk device defined, is your board supported?" diff --git a/tests/drivers/flash/common/src/main.c b/tests/drivers/flash/common/src/main.c index 4eeb492099372..048542bf31b6d 100644 --- a/tests/drivers/flash/common/src/main.c +++ b/tests/drivers/flash/common/src/main.c @@ -44,8 +44,8 @@ #define EXPECTED_SIZE 512 -#if !IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \ - !IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#if !defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \ + !defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) #error There is no flash device enabled or it is missing Kconfig options #endif diff --git a/tests/lib/gui/lvgl/src/main.c b/tests/lib/gui/lvgl/src/main.c index 6475e63ddd008..8ee495d936aed 100644 --- a/tests/lib/gui/lvgl/src/main.c +++ b/tests/lib/gui/lvgl/src/main.c @@ -19,7 +19,7 @@ #ifdef CONFIG_DISK_DRIVER_SDMMC #define DISK_NAME CONFIG_SDMMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_DISK_DRIVER_MMC) +#elif defined(CONFIG_DISK_DRIVER_MMC) #define DISK_NAME CONFIG_MMC_VOLUME_NAME #else #error "No disk device defined, is your board supported?" diff --git a/tests/subsys/pm/device_driver_init/src/main.c b/tests/subsys/pm/device_driver_init/src/main.c index d01a83d3ca68d..014e02a59409b 100644 --- a/tests/subsys/pm/device_driver_init/src/main.c +++ b/tests/subsys/pm/device_driver_init/src/main.c @@ -29,7 +29,7 @@ ZTEST(device_driver_init, test_device_driver_init) { -#if IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) +#if defined(CONFIG_PM_DEVICE_RUNTIME) enum pm_device_state state; int rc; state = -1; diff --git a/tests/subsys/settings/functional/src/settings_basic_test.c b/tests/subsys/settings/functional/src/settings_basic_test.c index 5798605a5a709..f77c87db71d73 100644 --- a/tests/subsys/settings/functional/src/settings_basic_test.c +++ b/tests/subsys/settings/functional/src/settings_basic_test.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(settings_basic_test); #if DT_HAS_CHOSEN(zephyr_settings_partition) #define TEST_FLASH_AREA_ID DT_FIXED_PARTITION_ID(DT_CHOSEN(zephyr_settings_partition)) #endif -#elif IS_ENABLED(CONFIG_SETTINGS_FILE) +#elif defined(CONFIG_SETTINGS_FILE) #include #include #else @@ -38,7 +38,7 @@ LOG_MODULE_REGISTER(settings_basic_test); */ ZTEST(settings_functional, test_clear_settings) { -#if !IS_ENABLED(CONFIG_SETTINGS_FILE) +#if !defined(CONFIG_SETTINGS_FILE) const struct flash_area *fap; int rc; diff --git a/tests/subsys/storage/stream/stream_flash/src/main.c b/tests/subsys/storage/stream/stream_flash/src/main.c index 7b4627101c236..58fbb6e35bbb2 100644 --- a/tests/subsys/storage/stream/stream_flash/src/main.c +++ b/tests/subsys/storage/stream/stream_flash/src/main.c @@ -72,9 +72,9 @@ int stream_flash_callback(uint8_t *buf, size_t len, size_t offset) static void erase_flash(void) { -#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) int rc; -#if IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) const struct flash_parameters *fparam = flash_get_parameters(fdev); if (!(flash_params_get_erase_cap(fparam) & FLASH_ERASE_C_EXPLICIT)) { From 1b5b6ea3c017f7a204c926c0d8b56af8fc2ef784 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 25 Jun 2024 17:21:54 +0200 Subject: [PATCH 019/187] Bluetooth: ASCS: Validate num_ases in CP requests Add validation of the number of ASEs in control point write requests. This validates that the number of ASEs in the control point is not greater than the total number of ASEs we support. This also validates that the GATT MTU is large enough to hold all the responses from the write since those can only be sent as notifications and never be truncated. Finally this validates and updates the size of the buffer used to hold the responses, which may be an optimization for some builds. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/ascs.c | 133 +++++++---- .../audio/ascs/src/test_ase_control_params.c | 208 +++++++++++++++++- 2 files changed, 297 insertions(+), 44 deletions(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 1a10523e49495..17aeda10edb31 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -57,6 +57,8 @@ LOG_MODULE_REGISTER(bt_ascs, CONFIG_BT_ASCS_LOG_LEVEL); (CONFIG_BT_ASCS_ASE_SNK_COUNT + \ CONFIG_BT_ASCS_ASE_SRC_COUNT) +#define NTF_HEADER_SIZE (3) /* opcode (1) + handle (2) */ + BUILD_ASSERT(CONFIG_BT_ASCS_MAX_ACTIVE_ASES <= MAX(MAX_ASES_SESSIONS, CONFIG_BT_ISO_MAX_CHAN), "Max active ASEs are set to more than actual number of ASEs or ISOs"); @@ -99,8 +101,9 @@ static struct bt_ascs_ase { * writing */ BUILD_ASSERT( - BT_ATT_BUF_SIZE - 3 >= ASE_BUF_SIZE || - DIV_ROUND_UP(ASE_BUF_SIZE, (BT_ATT_BUF_SIZE - 3)) <= CONFIG_BT_ATT_PREPARE_COUNT, + (BT_ATT_BUF_SIZE - NTF_HEADER_SIZE) >= ASE_BUF_SIZE || + DIV_ROUND_UP(ASE_BUF_SIZE, (BT_ATT_BUF_SIZE - NTF_HEADER_SIZE)) <= + CONFIG_BT_ATT_PREPARE_COUNT, "CONFIG_BT_ATT_PREPARE_COUNT not large enough to cover the maximum supported ASCS value"); /* It is mandatory to support long writes in ASCS unconditionally, and thus @@ -189,9 +192,19 @@ static void ase_free(struct bt_ascs_ase *ase) (void)k_work_cancel_delayable(&ase->state_transition_work); } +static uint16_t get_max_ntf_size(struct bt_conn *conn) +{ + const uint16_t mtu = conn == NULL ? 0 : bt_gatt_get_mtu(conn); + + if (mtu > NTF_HEADER_SIZE) { + return mtu - NTF_HEADER_SIZE; + } + + return 0U; +} + static int ase_state_notify(struct bt_ascs_ase *ase) { - const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ struct bt_conn *conn = ase->conn; struct bt_conn_info conn_info; uint16_t max_ntf_size; @@ -217,7 +230,7 @@ static int ase_state_notify(struct bt_ascs_ase *ase) ascs_ep_get_status(&ase->ep, &ase_buf); - max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; + max_ntf_size = get_max_ntf_size(conn); ntf_size = MIN(max_ntf_size, ase_buf.len); if (ntf_size < ase_buf.len) { @@ -1094,15 +1107,23 @@ static void ascs_ase_cfg_changed(const struct bt_gatt_attr *attr, LOG_DBG("attr %p value 0x%04x", attr, value); } -NET_BUF_SIMPLE_DEFINE_STATIC(rsp_buf, CONFIG_BT_L2CAP_TX_MTU); +#define CP_RSP_BUF_SIZE \ + (sizeof(struct bt_ascs_cp_rsp) + (ASE_COUNT * sizeof(struct bt_ascs_cp_ase_rsp))) + +/* Ensure that the cp_rsp_buf can fit in any notification + * (sizeof buffer - header for notification) + */ +BUILD_ASSERT(BT_ATT_BUF_SIZE - NTF_HEADER_SIZE >= CP_RSP_BUF_SIZE, + "BT_ATT_BUF_SIZE not large enough to hold responses for all ASEs"); +NET_BUF_SIMPLE_DEFINE_STATIC(cp_rsp_buf, CP_RSP_BUF_SIZE); static void ascs_cp_rsp_init(uint8_t op) { struct bt_ascs_cp_rsp *rsp; - net_buf_simple_reset(&rsp_buf); + net_buf_simple_reset(&cp_rsp_buf); - rsp = net_buf_simple_add(&rsp_buf, sizeof(*rsp)); + rsp = net_buf_simple_add(&cp_rsp_buf, sizeof(*rsp)); rsp->op = op; rsp->num_ase = 0; } @@ -1110,13 +1131,13 @@ static void ascs_cp_rsp_init(uint8_t op) /* Add response to an opcode/ASE ID */ static void ascs_cp_rsp_add(uint8_t id, uint8_t code, uint8_t reason) { - struct bt_ascs_cp_rsp *rsp = (void *)rsp_buf.__buf; + struct bt_ascs_cp_rsp *rsp = (void *)cp_rsp_buf.__buf; struct bt_ascs_cp_ase_rsp *ase_rsp; LOG_DBG("id 0x%02x code %s (0x%02x) reason %s (0x%02x)", id, bt_ascs_rsp_str(code), code, bt_ascs_reason_str(reason), reason); - if (rsp->num_ase == 0xff) { + if (rsp->num_ase == BT_ASCS_UNSUPP_OR_LENGTH_ERR_NUM_ASE) { return; } @@ -1133,7 +1154,7 @@ static void ascs_cp_rsp_add(uint8_t id, uint8_t code, uint8_t reason) break; } - ase_rsp = net_buf_simple_add(&rsp_buf, sizeof(*ase_rsp)); + ase_rsp = net_buf_simple_add(&cp_rsp_buf, sizeof(*ase_rsp)); ase_rsp->id = id; ase_rsp->code = code; ase_rsp->reason = reason; @@ -1742,7 +1763,42 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream, return 0; } -static bool is_valid_config_len(struct net_buf_simple *buf) +static uint16_t get_max_ase_rsp_for_conn(struct bt_conn *conn) +{ + const uint16_t max_ntf_size = get_max_ntf_size(conn); + const size_t rsp_hdr_size = sizeof(struct bt_ascs_cp_rsp); + + if (max_ntf_size > rsp_hdr_size) { + return (max_ntf_size - rsp_hdr_size) / sizeof(struct bt_ascs_cp_ase_rsp); + } + + return 0U; +} + +static bool is_valid_num_ases(struct bt_conn *conn, uint8_t num_ases) +{ + const uint16_t max_ase_rsp = get_max_ase_rsp_for_conn(conn); + + if (num_ases < 1U) { + LOG_WRN("Number_of_ASEs parameter value is less than 1"); + return false; + } else if (num_ases > ASE_COUNT) { + /* If the request is for more ASEs than we have, we just reject the request */ + LOG_DBG("Number_of_ASEs parameter value (%u) is greater than %d", num_ases, + ASE_COUNT); + return false; + } else if (num_ases > max_ase_rsp) { + /* If the request is for more ASEs than we can respond to, we reject the request */ + LOG_DBG("Number_of_ASEs parameter value (%u) is greater than what we can respond " + "to (%u) based on the MTU", + num_ases, max_ase_rsp); + return false; + } + + return true; +} + +static bool is_valid_config_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_config_op *op; struct net_buf_simple_state state; @@ -1755,8 +1811,7 @@ static bool is_valid_config_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -1792,7 +1847,7 @@ static ssize_t ascs_config(struct bt_conn *conn, struct net_buf_simple *buf) const struct bt_ascs_config_op *req; const struct bt_ascs_config *cfg; - if (!is_valid_config_len(buf)) { + if (!is_valid_config_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -1960,7 +2015,7 @@ static void ase_qos(struct bt_ascs_ase *ase, uint8_t cig_id, uint8_t cis_id, *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE); } -static bool is_valid_qos_len(struct net_buf_simple *buf) +static bool is_valid_qos_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_qos_op *op; struct net_buf_simple_state state; @@ -1974,8 +2029,7 @@ static bool is_valid_qos_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -2001,7 +2055,7 @@ static ssize_t ascs_qos(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_qos_op *req; - if (!is_valid_qos_len(buf)) { + if (!is_valid_qos_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -2342,7 +2396,7 @@ static int ase_enable(struct bt_ascs_ase *ase, struct bt_ascs_metadata *meta) return 0; } -static bool is_valid_enable_len(struct net_buf_simple *buf) +static bool is_valid_enable_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_enable_op *op; struct net_buf_simple_state state; @@ -2355,8 +2409,7 @@ static bool is_valid_enable_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -2393,7 +2446,7 @@ static ssize_t ascs_enable(struct bt_conn *conn, struct net_buf_simple *buf) struct bt_ascs_metadata *meta; int i; - if (!is_valid_enable_len(buf)) { + if (!is_valid_enable_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -2487,7 +2540,7 @@ static void ase_start(struct bt_ascs_ase *ase) ascs_cp_rsp_success(ASE_ID(ase)); } -static bool is_valid_start_len(struct net_buf_simple *buf) +static bool is_valid_start_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_start_op *op; struct net_buf_simple_state state; @@ -2500,8 +2553,7 @@ static bool is_valid_start_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -2520,7 +2572,7 @@ static ssize_t ascs_start(struct bt_conn *conn, struct net_buf_simple *buf) const struct bt_ascs_start_op *req; int i; - if (!is_valid_start_len(buf)) { + if (!is_valid_start_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -2570,7 +2622,7 @@ static ssize_t ascs_start(struct bt_conn *conn, struct net_buf_simple *buf) return buf->size; } -static bool is_valid_disable_len(struct net_buf_simple *buf) +static bool is_valid_disable_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_disable_op *op; struct net_buf_simple_state state; @@ -2583,8 +2635,7 @@ static bool is_valid_disable_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -2602,7 +2653,7 @@ static ssize_t ascs_disable(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_disable_op *req; - if (!is_valid_disable_len(buf)) { + if (!is_valid_disable_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -2700,7 +2751,7 @@ static void ase_stop(struct bt_ascs_ase *ase) ascs_cp_rsp_success(ASE_ID(ase)); } -static bool is_valid_stop_len(struct net_buf_simple *buf) +static bool is_valid_stop_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_stop_op *op; struct net_buf_simple_state state; @@ -2713,7 +2764,7 @@ static bool is_valid_stop_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { + if (op->num_ases < 1U) { LOG_WRN("Number_of_ASEs parameter value is less than 1"); return false; } @@ -2733,7 +2784,7 @@ static ssize_t ascs_stop(struct bt_conn *conn, struct net_buf_simple *buf) const struct bt_ascs_start_op *req; int i; - if (!is_valid_stop_len(buf)) { + if (!is_valid_stop_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -2783,7 +2834,7 @@ static ssize_t ascs_stop(struct bt_conn *conn, struct net_buf_simple *buf) return buf->size; } -static bool is_valid_metadata_len(struct net_buf_simple *buf) +static bool is_valid_metadata_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_metadata_op *op; struct net_buf_simple_state state; @@ -2796,8 +2847,7 @@ static bool is_valid_metadata_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -2834,7 +2884,7 @@ static ssize_t ascs_metadata(struct bt_conn *conn, struct net_buf_simple *buf) struct bt_ascs_metadata *meta; int i; - if (!is_valid_metadata_len(buf)) { + if (!is_valid_metadata_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -2877,7 +2927,7 @@ static ssize_t ascs_metadata(struct bt_conn *conn, struct net_buf_simple *buf) return buf->size; } -static bool is_valid_release_len(struct net_buf_simple *buf) +static bool is_valid_release_len(struct bt_conn *conn, struct net_buf_simple *buf) { const struct bt_ascs_release_op *op; struct net_buf_simple_state state; @@ -2890,8 +2940,7 @@ static bool is_valid_release_len(struct net_buf_simple *buf) } op = net_buf_simple_pull_mem(buf, sizeof(*op)); - if (op->num_ases < 1) { - LOG_WRN("Number_of_ASEs parameter value is less than 1"); + if (!is_valid_num_ases(conn, op->num_ases)) { return false; } @@ -2910,7 +2959,7 @@ static ssize_t ascs_release(struct bt_conn *conn, struct net_buf_simple *buf) const struct bt_ascs_release_op *req; int i; - if (!is_valid_release_len(buf)) { + if (!is_valid_release_len(conn, buf)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -3018,7 +3067,7 @@ static ssize_t ascs_cp_write(struct bt_conn *conn, } respond: - control_point_notify(conn, rsp_buf.data, rsp_buf.len); + control_point_notify(conn, cp_rsp_buf.data, cp_rsp_buf.len); return len; } diff --git a/tests/bluetooth/audio/ascs/src/test_ase_control_params.c b/tests/bluetooth/audio/ascs/src/test_ase_control_params.c index b2bbf82fd8ae4..a89af5bf170d9 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_control_params.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_control_params.c @@ -6,6 +6,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -24,6 +25,7 @@ #include "iso.h" #include "test_common.h" +#include "ztest_assert.h" struct test_ase_control_params_fixture { struct bt_conn conn; @@ -167,6 +169,30 @@ ZTEST_F(test_ase_control_params, test_codec_configure_number_of_ases_0x00) test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_codec_configure_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + const uint8_t buf[] = { + 0x01, /* Opcode = Config Codec */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + 0x01, /* ASE_ID[0] */ + 0x01, /* Target_Latency[0] = Target low latency */ + 0x02, /* Target_PHY[0] = LE 2M PHY */ + 0x06, /* Codec_ID[0].Coding_Format = LC3 */ + 0x00, 0x00, /* Codec_ID[0].Company_ID */ + 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */ + 0x00, /* Codec_Specific_Configuration_Length[0] */ + }; + + test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf)); +} + /* * Test correctly formatted ASE Control Point 'Invalid Length' notification is sent * @@ -340,6 +366,11 @@ static int unicast_server_cb_config_custom_fake(struct bt_conn *conn, const stru ZTEST_F(test_ase_control_params, test_codec_configure_invalid_ase_id_unavailable) { + /* Test requires support for at least 2 ASEs */ + if (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT < 2) { + ztest_test_skip(); + } + const uint8_t ase_id_valid = 0x01; const uint8_t ase_id_invalid = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; @@ -513,6 +544,35 @@ ZTEST_F(test_ase_control_params, test_config_qos_number_of_ases_0x00) &fixture->stream, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_config_qos_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + const uint8_t ase_id = test_ase_id_get(fixture->ase); + const uint8_t buf[] = { + 0x02, /* Opcode = Config QoS */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + 0x01, /* CIG_ID[0] */ + 0x01, /* CIS_ID[0] */ + 0xFF, 0x00, 0x00, /* SDU_Interval[0] */ + 0x00, /* Framing[0] */ + 0x02, /* PHY[0] */ + 0x64, 0x00, /* Max_SDU[0] */ + 0x02, /* Retransmission_Number[0] */ + 0x0A, 0x00, /* Max_Transport_Latency[0] */ + 0x40, 0x9C, 0x00, /* Presentation_Delay[0] */ + }; + + test_config_qos_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, + &fixture->stream, buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_config_qos_too_short) { const uint8_t ase_id = test_ase_id_get(fixture->ase); @@ -593,6 +653,27 @@ ZTEST_F(test_ase_control_params, test_enable_number_of_ases_0x00) buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_enable_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + const uint8_t ase_id = test_ase_id_get(fixture->ase); + const uint8_t buf[] = { + 0x03, /* Opcode = Enable */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + 0x00, /* Metadata_Length[0] */ + }; + + test_enable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, &fixture->stream, + buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_enable_too_long) { const uint8_t ase_id = test_ase_id_get(fixture->ase); @@ -638,6 +719,11 @@ ZTEST_F(test_ase_control_params, test_enable_metadata_too_short) ZTEST_F(test_ase_control_params, test_enable_invalid_ase_id) { + /* Test requires support for at least 2 ASEs */ + if (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT < 2) { + ztest_test_skip(); + } + const uint8_t ase_id_valid = 0x01; const uint8_t ase_id_invalid = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; @@ -731,7 +817,7 @@ ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_0x00) test_ase_src_get(1, &ase); zassume_not_null(ase); - ase_id = test_ase_id_get(fixture->ase); + ase_id = test_ase_id_get(ase); const uint8_t buf[] = { 0x04, /* Opcode = Receiver Start Ready */ @@ -743,6 +829,32 @@ ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_0x00) &fixture->stream, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const struct bt_gatt_attr *ase; + + Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC); + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + test_ase_src_get(1, &ase); + zassume_not_null(ase); + const uint8_t ase_id = test_ase_id_get(ase); + + const uint8_t buf[] = { + 0x04, /* Opcode = Receiver Start Ready */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + }; + + test_receiver_start_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, + &fixture->stream, buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_receiver_start_ready_too_long) { const struct bt_gatt_attr *ase; @@ -818,6 +930,26 @@ ZTEST_F(test_ase_control_params, test_disable_number_of_ases_0x00) &fixture->stream, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_disable_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + const uint8_t ase_id = test_ase_id_get(fixture->ase); + const uint8_t buf[] = { + 0x05, /* Opcode = Disable */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + }; + + test_disable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, + &fixture->stream, buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_disable_too_long) { const uint8_t ase_id = test_ase_id_get(fixture->ase); @@ -875,7 +1007,7 @@ ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_0x00) test_ase_src_get(1, &ase); zassume_not_null(ase); - ase_id = test_ase_id_get(fixture->ase); + ase_id = test_ase_id_get(ase); const uint8_t buf[] = { 0x06, /* Opcode = Receiver Stop Ready */ @@ -887,6 +1019,32 @@ ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_0x00) &fixture->stream, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const struct bt_gatt_attr *ase; + + Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC); + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + test_ase_src_get(1, &ase); + zassume_not_null(ase); + const uint8_t ase_id = test_ase_id_get(ase); + + const uint8_t buf[] = { + 0x06, /* Opcode = Receiver Stop Ready */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + }; + + test_receiver_stop_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, + &fixture->stream, buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_receiver_stop_ready_too_long) { const struct bt_gatt_attr *ase; @@ -963,6 +1121,27 @@ ZTEST_F(test_ase_control_params, test_update_metadata_number_of_ases_0x00) &fixture->stream, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_update_metadata_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + const uint8_t ase_id = test_ase_id_get(fixture->ase); + const uint8_t buf[] = { + 0x07, /* Opcode = Update Metadata */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + 0x00, /* Metadata_Length[0] */ + }; + + test_update_metadata_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, + &fixture->stream, buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_update_metadata_too_long) { const uint8_t ase_id = test_ase_id_get(fixture->ase); @@ -1008,6 +1187,11 @@ ZTEST_F(test_ase_control_params, test_update_metadata_metadata_too_short) ZTEST_F(test_ase_control_params, test_update_metadata_invalid_ase_id) { + /* Test requires support for at least 2 ASEs */ + if (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT < 2) { + ztest_test_skip(); + } + const uint8_t ase_id_valid = 0x01; const uint8_t ase_id_invalid = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; @@ -1074,6 +1258,26 @@ ZTEST_F(test_ase_control_params, test_release_number_of_ases_0x00) &fixture->stream, buf, sizeof(buf)); } +ZTEST_F(test_ase_control_params, test_release_number_of_ases_above_max) +{ + const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + + /* Skip if number of ASEs configured is high enough to support any value in the write req */ + if (ase_cnt > UINT8_MAX) { + ztest_test_skip(); + } + + const uint8_t ase_id = test_ase_id_get(fixture->ase); + const uint8_t buf[] = { + 0x08, /* Opcode = Release */ + (uint8_t)ase_cnt, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + }; + + test_release_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, + &fixture->stream, buf, sizeof(buf)); +} + ZTEST_F(test_ase_control_params, test_release_too_long) { const uint8_t ase_id = test_ase_id_get(fixture->ase); From 4d6568bfee9fdb128aa4c3648fa9a85a984ed1ca Mon Sep 17 00:00:00 2001 From: Nikolay Agishev Date: Wed, 19 Jun 2024 19:13:26 +0300 Subject: [PATCH 020/187] ARCMWDT: Fix cbprintf issue with omitted function prototype MWDT requires function to be declared with argument types. This PR provides explisitly type cast for out routine inside z_cbvprintf_impl(). This PR also actual to LLVM-based compilers with strict rules of compilation. It covers warnings generated with additional flag -Wincompatible-function-pointer-types-strict. This fixes https://github.com/zephyrproject-rtos/zephyr/issues/74562 Signed-off-by: Nikolay Agishev --- include/zephyr/sys/cbprintf.h | 6 ++++++ lib/os/cbprintf_complete.c | 6 ++++-- lib/os/cbprintf_nano.c | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/zephyr/sys/cbprintf.h b/include/zephyr/sys/cbprintf.h index 43fe4f921e8df..2055eb6a0475b 100644 --- a/include/zephyr/sys/cbprintf.h +++ b/include/zephyr/sys/cbprintf.h @@ -302,6 +302,12 @@ typedef int (*cbprintf_cb)(int c, void *ctx); typedef int (*cbprintf_cb)(/* int c, void *ctx */); #endif +/* Create local cbprintf_cb type to make calng-based compilers happy when handles + * OUTC() macro (see below). With strict rules (Wincompatible-function-pointer-types-strict) + * it's prohibited to pass arguments with mismatched types. + */ +typedef int (*cbprintf_cb_local)(int c, void *ctx); + /** @brief Signature for a cbprintf multibyte callback function. * * @param buf data. diff --git a/lib/os/cbprintf_complete.c b/lib/os/cbprintf_complete.c index f9fdca1481f82..58502da63501a 100644 --- a/lib/os/cbprintf_complete.c +++ b/lib/os/cbprintf_complete.c @@ -1345,12 +1345,13 @@ static inline void store_count(const struct conversion *conv, } /* Outline function to emit all characters in [sp, ep). */ -static int outs(cbprintf_cb out, +static int outs(cbprintf_cb __out, void *ctx, const char *sp, const char *ep) { size_t count = 0; + cbprintf_cb_local out = __out; while ((sp < ep) || ((ep == NULL) && *sp)) { int rc = out((int)*sp, ctx); @@ -1365,12 +1366,13 @@ static int outs(cbprintf_cb out, return (int)count; } -int z_cbvprintf_impl(cbprintf_cb out, void *ctx, const char *fp, +int z_cbvprintf_impl(cbprintf_cb __out, void *ctx, const char *fp, va_list ap, uint32_t flags) { char buf[CONVERTED_BUFLEN]; size_t count = 0; sint_value_type sint; + cbprintf_cb_local out = __out; const bool tagged_ap = (flags & Z_CBVPRINTF_PROCESS_FLAG_TAGGED_ARGS) == Z_CBVPRINTF_PROCESS_FLAG_TAGGED_ARGS; diff --git a/lib/os/cbprintf_nano.c b/lib/os/cbprintf_nano.c index d719fe8e66358..e4342939a9a5f 100644 --- a/lib/os/cbprintf_nano.c +++ b/lib/os/cbprintf_nano.c @@ -73,7 +73,7 @@ static inline int convert_value(uint_value_type num, unsigned int base, * * @return printed byte count if CONFIG_CBPRINTF_LIBC_SUBSTS is set */ -int z_cbvprintf_impl(cbprintf_cb out, void *ctx, const char *fmt, +int z_cbvprintf_impl(cbprintf_cb __out, void *ctx, const char *fmt, va_list ap, uint32_t flags) { size_t count = 0; @@ -81,6 +81,7 @@ int z_cbvprintf_impl(cbprintf_cb out, void *ctx, const char *fmt, char *prefix, *data; int min_width, precision, data_len; char padding_mode, length_mod, special; + cbprintf_cb_local out = __out; const bool tagged_ap = (flags & Z_CBVPRINTF_PROCESS_FLAG_TAGGED_ARGS) == Z_CBVPRINTF_PROCESS_FLAG_TAGGED_ARGS; From 24aa3632c7269516161fde9624644488d574a191 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 20 Jun 2024 14:17:22 +0200 Subject: [PATCH 021/187] drivers: udc_dwc: remove rwup flag The driver does not implement host_wakeup, remove rwup capability flag. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_dwc2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 6ca435f4537b0..fd9f11ccde435 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -2029,7 +2029,6 @@ static int dwc2_driver_preinit(const struct device *dev) k_mutex_init(&data->mutex); - data->caps.rwup = true; data->caps.addr_before_status = true; data->caps.mps0 = UDC_MPS0_64; From 3dd58e7c27c9ad2bee5a7a279b43112cb16d35d6 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 8 Nov 2023 12:01:59 +0900 Subject: [PATCH 022/187] fb: cfb: Fix CFB_FONT_MSB_FIRST font rendering I broke the rendering of the CFB_FONT_MSB_FIRST font in the previously committed #53796. I will correct the entire font rendering process to make it easier to remove the restriction that the vertical size of the font must be a multiple of 8. Signed-off-by: TOKITA Hiroshi --- subsys/fb/cfb.c | 106 ++++++++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/subsys/fb/cfb.c b/subsys/fb/cfb.c index 379066e3b534c..569d610cbeb4a 100644 --- a/subsys/fb/cfb.c +++ b/subsys/fb/cfb.c @@ -7,6 +7,7 @@ #include #include #include +#include #define LOG_LEVEL CONFIG_CFB_LOG_LEVEL #include @@ -15,6 +16,9 @@ LOG_MODULE_REGISTER(cfb); STRUCT_SECTION_START_EXTERN(cfb_font); STRUCT_SECTION_END_EXTERN(cfb_font); +#define LSB_BIT_MASK(x) BIT_MASK(x) +#define MSB_BIT_MASK(x) (BIT_MASK(x) << (8 - x)) + static inline uint8_t byte_reverse(uint8_t b) { b = (b & 0xf0) >> 4 | (b & 0x0f) << 4; @@ -92,8 +96,9 @@ static uint8_t draw_char_vtmono(const struct char_framebuffer *fb, bool draw_bg) { const struct cfb_font *fptr = &(fb->fonts[fb->font_idx]); - const bool need_reverse = (((fb->screen_info & SCREEN_INFO_MONO_MSB_FIRST) != 0) - != ((fptr->caps & CFB_FONT_MSB_FIRST) != 0)); + const bool font_is_msbfirst = ((fptr->caps & CFB_FONT_MSB_FIRST) != 0); + const bool need_reverse = + (((fb->screen_info & SCREEN_INFO_MONO_MSB_FIRST) != 0) != font_is_msbfirst); uint8_t *glyph_ptr; if (c < fptr->first_char || c > fptr->last_char) { @@ -108,7 +113,7 @@ static uint8_t draw_char_vtmono(const struct char_framebuffer *fb, for (size_t g_x = 0; g_x < fptr->width; g_x++) { const int16_t fb_x = x + g_x; - for (size_t g_y = 0; g_y < fptr->height; g_y++) { + for (size_t g_y = 0; g_y < fptr->height;) { /* * Process glyph rendering in the y direction * by separating per 8-line boundaries. @@ -117,66 +122,87 @@ static uint8_t draw_char_vtmono(const struct char_framebuffer *fb, const int16_t fb_y = y + g_y; const size_t fb_index = (fb_y / 8U) * fb->x_res + fb_x; const size_t offset = y % 8; + const uint8_t bottom_lines = ((offset + fptr->height) % 8); uint8_t bg_mask; uint8_t byte; + uint8_t next_byte; if (fb_x < 0 || fb->x_res <= fb_x || fb_y < 0 || fb->y_res <= fb_y) { + g_y++; continue; } - byte = get_glyph_byte(glyph_ptr, fptr, g_x, g_y / 8); - - if (offset == 0) { - /* - * The start row is on an 8-line boundary. - * Therefore, it can set the value directly. - */ - bg_mask = 0; - g_y += 7; - } else if (g_y == 0) { + if (offset == 0 || g_y == 0) { /* - * If the starting row is not on the 8-line boundary, - * shift the glyph to the starting line, and create a mask - * from the 8-line boundary to the starting line. + * The case of drawing the first line of the glyphs or + * starting to draw with a tile-aligned position case. + * In this case, no character is above it. + * So, we process assume that nothing is drawn above. */ - byte = byte << offset; - bg_mask = BIT_MASK(offset); - g_y += (7 - offset); + byte = 0; + next_byte = get_glyph_byte(glyph_ptr, fptr, g_x, g_y / 8); } else { + byte = get_glyph_byte(glyph_ptr, fptr, g_x, g_y / 8); + next_byte = get_glyph_byte(glyph_ptr, fptr, g_x, (g_y + 8) / 8); + } + + if (font_is_msbfirst) { /* - * After the starting row, read and concatenate the next 8-rows - * glyph and clip to the 8-line boundary and write 8-lines - * at the time. - * Create a mask to prevent overwriting the drawing contents - * after the end row. + * Extract the necessary 8 bits from the combined 2 tiles of glyphs. */ - const size_t lines = ((fptr->height - g_y) < 8) ? offset : 8; - - if (lines == 8) { - uint16_t byte2 = byte; + byte = ((byte << 8) | next_byte) >> (offset); - byte2 |= (get_glyph_byte(glyph_ptr, fptr, g_x, - (g_y + 8) / 8)) - << 8; - byte = (byte2 >> (8 - offset)) & BIT_MASK(lines); + if (g_y == 0) { + /* + * Create a mask that does not draw offset white space. + */ + bg_mask = BIT_MASK(8 - offset); } else { - byte = (byte >> (8 - offset)) & BIT_MASK(lines); + /* + * The drawing of the second line onwards + * is aligned with the tile, so it draws all the bits. + */ + bg_mask = 0xFF; + } + } else { + byte = ((next_byte << 8) | byte) >> (8 - offset); + if (g_y == 0) { + bg_mask = BIT_MASK(8 - offset) << offset; + } else { + bg_mask = 0xFF; } - - bg_mask = (BIT_MASK(8 - lines) << (lines)) & 0xFF; - g_y += (lines - 1); } - if (need_reverse) { - byte = byte_reverse(byte); - bg_mask = byte_reverse(bg_mask); + /* + * Clip the bottom margin to protect existing draw contents. + */ + if (((fptr->height - g_y) < 8) && (bottom_lines != 0)) { + const uint8_t clip = font_is_msbfirst ? MSB_BIT_MASK(bottom_lines) + : LSB_BIT_MASK(bottom_lines); + + bg_mask &= clip; + byte &= clip; } if (draw_bg) { - fb->buf[fb_index] &= bg_mask; + if (need_reverse) { + bg_mask = byte_reverse(bg_mask); + } + fb->buf[fb_index] &= ~bg_mask; } + if (need_reverse) { + byte = byte_reverse(byte); + } fb->buf[fb_index] |= byte; + + if (g_y == 0) { + g_y += (8 - offset); + } else if ((fptr->height - g_y) >= 8) { + g_y += 8; + } else { + g_y += bottom_lines; + } } } From f72c97f7e9d39768f24eb2567f371ceebe8dd204 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 28 Jan 2024 18:18:40 +0900 Subject: [PATCH 023/187] fb: cfb: Add framebuffer deinitialize function Add the `cfb_framebuffer_deinit` function for deinitializing the framebuffer. Signed-off-by: TOKITA Hiroshi --- include/zephyr/display/cfb.h | 7 +++++++ subsys/fb/cfb.c | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/zephyr/display/cfb.h b/include/zephyr/display/cfb.h index 9d425be464e8a..6d10debe676c3 100644 --- a/include/zephyr/display/cfb.h +++ b/include/zephyr/display/cfb.h @@ -241,6 +241,13 @@ int cfb_get_numof_fonts(const struct device *dev); */ int cfb_framebuffer_init(const struct device *dev); +/** + * @brief Deinitialize Character Framebuffer. + * + * @param dev Pointer to device structure for driver instance + */ +void cfb_framebuffer_deinit(const struct device *dev); + #ifdef __cplusplus } #endif diff --git a/subsys/fb/cfb.c b/subsys/fb/cfb.c index 569d610cbeb4a..e817cb4e1b163 100644 --- a/subsys/fb/cfb.c +++ b/subsys/fb/cfb.c @@ -593,3 +593,14 @@ int cfb_framebuffer_init(const struct device *dev) return 0; } + +void cfb_framebuffer_deinit(const struct device *dev) +{ + struct char_framebuffer *fb = &char_fb; + + if (fb->buf) { + k_free(fb->buf); + fb->buf = NULL; + } + +} From 877b8f2fdc7252751d0414db73d935dc5fc1e58d Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 14 Jan 2024 10:38:12 +0900 Subject: [PATCH 024/187] tests: subsys: display: cfb: Add CFB tests Add test cases for testing basic CFB functions. These tests cannot run in CI because the CI environment has no display. Mark these tests as `build_only`. Signed-off-by: TOKITA Hiroshi --- tests/subsys/display/cfb/basic/CMakeLists.txt | 34 + tests/subsys/display/cfb/basic/Kconfig | 9 + tests/subsys/display/cfb/basic/prj.conf | 11 + .../cfb/basic/src/cfb_font_rectspace1016.c | 19 + .../basic/src/cfb_font_rectspace1016_msb.c | 19 + tests/subsys/display/cfb/basic/src/clear.c | 62 ++ .../subsys/display/cfb/basic/src/draw_line.c | 134 ++++ .../subsys/display/cfb/basic/src/draw_point.c | 162 ++++ .../subsys/display/cfb/basic/src/draw_rect.c | 155 ++++ .../cfb/basic/src/draw_text_rectspace1016.c | 210 +++++ tests/subsys/display/cfb/basic/src/invert.c | 68 ++ .../display/cfb/basic/src/invert_area.c | 112 +++ .../cfb/basic/src/print_rectspace1016.c | 222 ++++++ tests/subsys/display/cfb/basic/src/testdata.c | 726 ++++++++++++++++++ tests/subsys/display/cfb/basic/src/testdata.h | 23 + tests/subsys/display/cfb/basic/src/utils.c | 185 +++++ tests/subsys/display/cfb/basic/src/utils.h | 27 + tests/subsys/display/cfb/basic/testcase.yaml | 58 ++ 18 files changed, 2236 insertions(+) create mode 100644 tests/subsys/display/cfb/basic/CMakeLists.txt create mode 100644 tests/subsys/display/cfb/basic/Kconfig create mode 100644 tests/subsys/display/cfb/basic/prj.conf create mode 100644 tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016.c create mode 100644 tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016_msb.c create mode 100644 tests/subsys/display/cfb/basic/src/clear.c create mode 100644 tests/subsys/display/cfb/basic/src/draw_line.c create mode 100644 tests/subsys/display/cfb/basic/src/draw_point.c create mode 100644 tests/subsys/display/cfb/basic/src/draw_rect.c create mode 100644 tests/subsys/display/cfb/basic/src/draw_text_rectspace1016.c create mode 100644 tests/subsys/display/cfb/basic/src/invert.c create mode 100644 tests/subsys/display/cfb/basic/src/invert_area.c create mode 100644 tests/subsys/display/cfb/basic/src/print_rectspace1016.c create mode 100644 tests/subsys/display/cfb/basic/src/testdata.c create mode 100644 tests/subsys/display/cfb/basic/src/testdata.h create mode 100644 tests/subsys/display/cfb/basic/src/utils.c create mode 100644 tests/subsys/display/cfb/basic/src/utils.h create mode 100644 tests/subsys/display/cfb/basic/testcase.yaml diff --git a/tests/subsys/display/cfb/basic/CMakeLists.txt b/tests/subsys/display/cfb/basic/CMakeLists.txt new file mode 100644 index 0000000000000..5126b0ec6aab8 --- /dev/null +++ b/tests/subsys/display/cfb/basic/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(cfb_basic) + +if(CONFIG_TEST_MSB_FIRST_FONT) + target_sources(app PRIVATE src/testdata.c + src/utils.c + src/clear.c + src/draw_point.c + src/draw_line.c + src/draw_rect.c + src/draw_text_rectspace1016.c + src/invert.c + src/invert_area.c + src/print_rectspace1016.c + src/cfb_font_rectspace1016_msb.c) +else() + target_sources(app PRIVATE src/testdata.c + src/utils.c + src/clear.c + src/draw_point.c + src/draw_line.c + src/draw_rect.c + src/draw_text_rectspace1016.c + src/invert.c + src/invert_area.c + src/print_rectspace1016.c + src/cfb_font_rectspace1016.c) +endif() diff --git a/tests/subsys/display/cfb/basic/Kconfig b/tests/subsys/display/cfb/basic/Kconfig new file mode 100644 index 0000000000000..b64e9572e355e --- /dev/null +++ b/tests/subsys/display/cfb/basic/Kconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +config TEST_MSB_FIRST_FONT + bool "Use MSB_FIRST font" diff --git a/tests/subsys/display/cfb/basic/prj.conf b/tests/subsys/display/cfb/basic/prj.conf new file mode 100644 index 0000000000000..37c9eb19e5738 --- /dev/null +++ b/tests/subsys/display/cfb/basic/prj.conf @@ -0,0 +1,11 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_DISPLAY=y +CONFIG_CHARACTER_FRAMEBUFFER=y +CONFIG_CHARACTER_FRAMEBUFFER_USE_DEFAULT_FONTS=n + +CONFIG_HEAP_MEM_POOL_SIZE=16384 + +CONFIG_LOG=y diff --git a/tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016.c b/tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016.c new file mode 100644 index 0000000000000..dc4b95d4c3e44 --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +const uint8_t cfb_font_1016_rectspace[1][20] = { + /* */ + { + 0xFF, 0xFF, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xFF, 0xFF, + }, +}; + +FONT_ENTRY_DEFINE(font1016_rectspace, 10, 16, CFB_FONT_MONO_VPACKED, cfb_font_1016_rectspace, 32, + 33); diff --git a/tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016_msb.c b/tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016_msb.c new file mode 100644 index 0000000000000..460cea0202bce --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/cfb_font_rectspace1016_msb.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +const uint8_t cfb_font_1016_rectspace[1][20] = { + /* */ + { + 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, + 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xFF, 0xFF, + }, +}; + +FONT_ENTRY_DEFINE(font1016_rectspace, 10, 16, CFB_FONT_MONO_VPACKED | CFB_FONT_MSB_FIRST, + cfb_font_1016_rectspace, 32, 33); diff --git a/tests/subsys/display/cfb/basic/src/clear.c b/tests/subsys/display/cfb/basic/src/clear.c new file mode 100644 index 0000000000000..b0359564de800 --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/clear.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(clear, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0xAA before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + memset(read_buffer, 0xAA, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +ZTEST(clear, test_clear_false) +{ + zassert_ok(cfb_framebuffer_clear(dev, false)); + + /* checking memory not updated */ + zassert_false(verify_color_inside_rect(0, 0, 320, 240, 0x0)); +} + +ZTEST(clear, test_clear_true) +{ + zassert_ok(cfb_framebuffer_clear(dev, true)); + + zassert_true(verify_color_inside_rect(0, 0, 320, 240, 0x0)); +} + +ZTEST_SUITE(clear, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/draw_line.c b/tests/subsys/display/cfb/basic/src/draw_line.c new file mode 100644 index 0000000000000..1b2c3d5118abf --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/draw_line.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(draw_line, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +ZTEST(draw_line, test_draw_line_top_end) +{ + struct cfb_position start = {0, 0}; + struct cfb_position end = {display_width, 0}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, 1, 0xFFFFFF)); +} + +ZTEST(draw_line, test_draw_line_left_end) +{ + struct cfb_position start = {0, 0}; + struct cfb_position end = {0, display_height}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, 1, display_height, 0xFFFFFF)); +} + +ZTEST(draw_line, test_draw_right_end) +{ + struct cfb_position start = {display_width - 1, 0}; + struct cfb_position end = {display_width - 1, display_height}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(display_width - 1, 0, 1, display_height, 0xFFFFFF)); +} + +ZTEST(draw_line, test_draw_line_bottom_end) +{ + struct cfb_position start = {0, 239}; + struct cfb_position end = {display_width, 239}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, display_height - 1, display_width, 1, 0xFFFFFF)); +} + +ZTEST(draw_line, test_render_twice_on_same_tile) +{ + struct cfb_position start = {0, 0}; + struct cfb_position end = {display_width, 0}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + start.y = 7; + end.y = 7; + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, 1, 0xFFFFFF)); + zassert_true(verify_color_inside_rect(0, 1, display_width, 6, 0x0)); + zassert_true(verify_color_inside_rect(0, 7, display_width, 1, 0xFFFFFF)); + zassert_true(verify_color_inside_rect(0, 8, display_width, 232, 0x0)); +} + +ZTEST(draw_line, test_crossing_diagonally_end_to_end) +{ + struct cfb_position start = {0, 0}; + struct cfb_position end = {320, 240}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + for (size_t i = 0; i < 10; i++) { + zassert_true(verify_image(32 * i, 24 * i, diagonal3224, 32, 24)); + } +} + +ZTEST(draw_line, test_crossing_diagonally_from_outside_area) +{ + struct cfb_position start = {-32, -48}; + struct cfb_position end = {384, 264}; + + zassert_ok(cfb_draw_line(dev, &start, &end)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + for (size_t i = 0; i < 9; i++) { + zassert_true(verify_image(32 + 32 * i, 24 * i, diagonal3224, 32, 24)); + } +} + +ZTEST_SUITE(draw_line, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/draw_point.c b/tests/subsys/display/cfb/basic/src/draw_point.c new file mode 100644 index 0000000000000..ef78f212dc6d5 --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/draw_point.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(draw_point, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +/* + * normal rendering + */ +ZTEST(draw_point, test_draw_point_at_0_0) +{ + struct cfb_position pos = {0, 0}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_pixel_and_bg(0, 0, 1, 0)); +} + +ZTEST(draw_point, test_draw_point_at_1_1) +{ + struct cfb_position pos = {1, 1}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_pixel_and_bg(1, 1, 1, 0)); +} + +/* + * around tile border + */ +ZTEST(draw_point, test_draw_pont_at_9_15) +{ + struct cfb_position pos = {9, 15}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_pixel_and_bg(9, 15, 1, 0)); +} + +ZTEST(draw_point, test_draw_point_at_10_16) +{ + struct cfb_position pos = {10, 16}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_pixel_and_bg(10, 16, 1, 0)); +} + +ZTEST(draw_point, test_draw_point_at_11_17) +{ + struct cfb_position pos = {11, 17}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_pixel_and_bg(11, 17, 1, 0)); +} + +ZTEST(draw_point, test_draw_point_twice_on_same_tile) +{ + struct cfb_position pos = {10, 0}; + + pos.y = 7; + zassert_ok(cfb_draw_point(dev, &pos)); + + pos.y = 8; + zassert_ok(cfb_draw_point(dev, &pos)); + + pos.y = 9; + zassert_ok(cfb_draw_point(dev, &pos)); + + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(10, 7, 1, 3, 0xFFFFFF)); + zassert_true(verify_color_outside_rect(10, 7, 1, 3, 0x0)); +} + +ZTEST(draw_point, test_draw_point_outside_top_left) +{ + struct cfb_position pos = {0, -1}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0)); +} + +ZTEST(draw_point, test_draw_point_outside_top_right) +{ + struct cfb_position pos = {display_width, 0}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0)); +} + +ZTEST(draw_point, test_draw_point_outside_bottom_right) +{ + struct cfb_position pos = {0, display_height}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0)); +} + +ZTEST(draw_point, test_draw_point_outside_bottom_left) +{ + struct cfb_position pos = {-1, display_height}; + + zassert_ok(cfb_draw_point(dev, &pos)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0)); +} + +ZTEST_SUITE(draw_point, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/draw_rect.c b/tests/subsys/display/cfb/basic/src/draw_rect.c new file mode 100644 index 0000000000000..2c6b81d5d8b4f --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/draw_rect.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(draw_rect, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +/* + * normal rendering + */ +ZTEST(draw_rect, test_draw_rect_1123_at_0_0) +{ + struct cfb_position start = {0, 0}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image_and_bg(0, 0, rectspace1123, 11, 23, 0), ""); +} + +ZTEST(draw_rect, test_draw_rect_1123_at_1_1) +{ + struct cfb_position start = {1, 1}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image_and_bg(1, 1, rectspace1123, 11, 23, 0), ""); +} + +/* tile border case */ +ZTEST(draw_rect, test_draw_rect_1123_at_9_15) +{ + struct cfb_position start = {9, 15}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image_and_bg(9, 15, rectspace1123, 11, 23, 0), ""); +} + +ZTEST(draw_rect, test_draw_rect_1123_at_10_16) +{ + struct cfb_position start = {10, 16}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image_and_bg(10, 16, rectspace1123, 11, 23, 0), ""); +} + +ZTEST(draw_rect, test_draw_rect_1123_at_11_17) +{ + struct cfb_position start = {11, 17}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image_and_bg(11, 17, rectspace1123, 11, 23, 0), ""); +} + +/* + * Case of including coordinates outside the area + */ +ZTEST(draw_rect, test_draw_rect_1123_outside_top_left) +{ + struct cfb_position start = {-(11 - 3), -(23 - 4)}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image_and_bg(0, 0, outside_top_left, 3, 4, 0), ""); +} + +ZTEST(draw_rect, test_draw_rect_1123_outside_top_right) +{ + struct cfb_position start = {display_width - 5, -(23 - 8)}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image(display_width - 5, 0, outside_top_right, 5, 8), ""); +} + +ZTEST(draw_rect, test_draw_rect_1123_outside_bottom_right) +{ + struct cfb_position start = {display_width - 3, display_height - 5}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true( + verify_image(display_width - 3, display_height - 5, outside_bottom_right, 3, 5), + ""); +} + +ZTEST(draw_rect, test_draw_rect_1123_outside_bottom_left) +{ + struct cfb_position start = {-(11 - 3), display_height - 14}; + struct cfb_position end = {start.x + 10, start.y + 22}; + + zassert_ok(cfb_draw_rect(dev, &start, &end), ""); + zassert_ok(cfb_framebuffer_finalize(dev), ""); + + zassert_true(verify_image(0, display_height - 14, outside_bottom_left, 3, 14), ""); +} + +ZTEST_SUITE(draw_rect, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/draw_text_rectspace1016.c b/tests/subsys/display/cfb/basic/src/draw_text_rectspace1016.c new file mode 100644 index 0000000000000..faee4885601ac --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/draw_text_rectspace1016.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(draw_text_rectspace1016, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + uint8_t font_width; + uint8_t font_height; + bool font_found = false; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); + + for (int idx = 0; idx < cfb_get_numof_fonts(dev); idx++) { + if (cfb_get_font_size(dev, idx, &font_width, &font_height)) { + break; + } + + if (font_width == 10 && font_height == 16) { + cfb_framebuffer_set_font(dev, idx); + font_found = true; + break; + } + } + + zassert_true(font_found); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +/* + * normal rendering + */ +ZTEST(draw_text_rectspace1016, test_draw_text_at_0_0) +{ + zassert_ok(cfb_draw_text(dev, " ", 0, 0)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 0, rectspace1016, 10, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_1_1) +{ + zassert_ok(cfb_draw_text(dev, " ", 1, 1)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(1, 1, rectspace1016, 10, 16, 0)); +} + +/* + * around tile border + */ +ZTEST(draw_text_rectspace1016, test_draw_text_at_9_15) +{ + zassert_ok(cfb_draw_text(dev, " ", 9, 15)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(9, 15, rectspace1016, 10, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_10_16) +{ + zassert_ok(cfb_draw_text(dev, " ", 10, 16)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(10, 16, rectspace1016, 10, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_11_17) +{ + zassert_ok(cfb_draw_text(dev, " ", 11, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(11, 17, rectspace1016, 10, 16, 0)); +} + +/* + * with kerning + */ +ZTEST(draw_text_rectspace1016, test_draw_text_at_0_0_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", 0, 0)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 0, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_1_1_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", 1, 1)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(1, 1, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_9_15_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", 9, 15)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(9, 15, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_10_16_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", 10, 16)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(10, 16, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_at_11_17_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", 11, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(11, 17, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_kerning_3_within_right_border) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", display_width - 23, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(display_width - 23, 17, kerning_3_2rectspace1016, 23, 16)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_kerning_3_over_right_border) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_draw_text(dev, " ", display_width - 22, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true( + verify_image(display_width - 22, 17, kerning_3_rightclip_1_2rectspace1016, 22, 16)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_outside_top_left) +{ + zassert_ok(cfb_draw_text(dev, " ", -(10 - 3), -(16 - 4))); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 0, outside_top_left, 3, 4, 0)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_outside_top_right) +{ + zassert_ok(cfb_draw_text(dev, " ", display_width - 5, -(16 - 8))); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(display_width - 5, 0, outside_top_right, 5, 8)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_outside_bottom_right) +{ + zassert_ok(cfb_draw_text(dev, " ", display_width - 3, display_height - 5)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true( + verify_image(display_width - 3, display_height - 5, outside_bottom_right, 3, 5)); +} + +ZTEST(draw_text_rectspace1016, test_draw_text_outside_bottom_left) +{ + zassert_ok(cfb_draw_text(dev, " ", -(10 - 3), display_height - 14)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(0, display_height - 14, outside_bottom_left, 3, 14)); +} + +ZTEST_SUITE(draw_text_rectspace1016, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/invert.c b/tests/subsys/display/cfb/basic/src/invert.c new file mode 100644 index 0000000000000..fb13c6bc9e621 --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/invert.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(invert, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +ZTEST(invert, test_invert) +{ + zassert_ok(cfb_framebuffer_invert(dev)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, 320, 240, 0xFFFFFF)); +} + +ZTEST(invert, test_invert_contents) +{ + zassert_ok(cfb_invert_area(dev, 10, 10, 10, 10)); + zassert_ok(cfb_framebuffer_finalize(dev)); + zassert_true(verify_color_outside_rect(10, 10, 10, 10, 0)); + zassert_true(verify_color_inside_rect(10, 10, 10, 10, 0xFFFFFF)); + + zassert_ok(cfb_framebuffer_invert(dev)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_outside_rect(10, 10, 10, 10, 0xFFFFFF)); +} + +ZTEST_SUITE(invert, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/invert_area.c b/tests/subsys/display/cfb/basic/src/invert_area.c new file mode 100644 index 0000000000000..98b86559ff161 --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/invert_area.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(invert_area, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +ZTEST(invert_area, test_invert_area_whole_screen) +{ + zassert_ok(cfb_invert_area(dev, 0, 0, 320, 240)); + zassert_ok(cfb_framebuffer_finalize(dev), "cfb_framebuffer_finalize failed"); + + zassert_true(verify_color_inside_rect(0, 0, 320, 240, 0xFFFFFF)); +} + +ZTEST(invert_area, test_invert_area_overlapped_2times) +{ + zassert_ok(cfb_invert_area(dev, 33, 37, 79, 77)); + zassert_ok(cfb_invert_area(dev, 100, 37, 53, 77)); + zassert_ok(cfb_framebuffer_finalize(dev), "cfb_framebuffer_finalize failed"); + + zassert_true(verify_color_inside_rect(33, 37, 67, 77, 0xFFFFFF)); + zassert_true(verify_color_inside_rect(100, 37, 12, 77, 0x0)); + zassert_true(verify_color_inside_rect(112, 37, 41, 77, 0xFFFFFF)); + zassert_true(verify_color_outside_rect(33, 37, 120, 77, 0x0)); +} + +ZTEST(invert_area, test_invert_area_overlap_top_left) +{ + int err; + + err = cfb_invert_area(dev, -10, -10, 20, 20); + zassert_not_ok(err, "out of rect"); +} + +ZTEST(invert_area, test_invert_area_overlap_top_right) +{ + int err; + + err = cfb_invert_area(dev, 230, -10, 20, 20); + zassert_not_ok(err, "out of rect"); +} + +ZTEST(invert_area, test_invert_area_overlap_bottom_left) +{ + int err; + + err = cfb_invert_area(dev, -10, display_height - 10, 20, 20); + zassert_not_ok(err, "out of rect"); +} + +ZTEST(invert_area, test_invert_area_overlap_bottom_right) +{ + zassert_ok(cfb_invert_area(dev, display_width - 10, display_height - 10, 20, 20)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(display_width - 10, display_height - 10, 10, 10, + 0xFFFFFF)); + zassert_true( + verify_color_outside_rect(display_width - 10, display_height - 10, 10, 10, 0x0)); +} + +ZTEST(invert_area, test_invert_area_outside_top_left) +{ + zassert_not_ok(cfb_invert_area(dev, -10, -10, 10, 10), "out of rect"); +} + +ZTEST(invert_area, test_invert_area_outside_bottom_right) +{ + zassert_not_ok(cfb_invert_area(dev, display_width, display_height, 20, 20), "out of rect"); +} + +ZTEST_SUITE(invert_area, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/print_rectspace1016.c b/tests/subsys/display/cfb/basic/src/print_rectspace1016.c new file mode 100644 index 0000000000000..f1cf9dddfe4ab --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/print_rectspace1016.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "testdata.h" +#include "utils.h" + +LOG_MODULE_REGISTER(print_rectspace1016, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); + +/** + * Fill the buffer with 0 before running tests. + */ +static void cfb_test_before(void *text_fixture) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + uint8_t font_width; + uint8_t font_height; + bool font_found = false; + + memset(read_buffer, 0, sizeof(read_buffer)); + zassert_ok(display_write(dev, 0, 0, &desc, read_buffer)); + + zassert_ok(display_blanking_off(dev)); + + zassert_ok(cfb_framebuffer_init(dev)); + + for (int idx = 0; idx < cfb_get_numof_fonts(dev); idx++) { + if (cfb_get_font_size(dev, idx, &font_width, &font_height)) { + break; + } + + if (font_width == 10 && font_height == 16) { + cfb_framebuffer_set_font(dev, idx); + font_found = true; + break; + } + } + + zassert_true(font_found); +} + +static void cfb_test_after(void *test_fixture) +{ + cfb_framebuffer_deinit(dev); +} + +/* + * normal rendering + */ +ZTEST(print_rectspace1016, test_print_at_0_0) +{ + zassert_ok(cfb_print(dev, " ", 0, 0)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 0, rectspace1016, 10, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_1_1) +{ + zassert_ok(cfb_print(dev, " ", 1, 1)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(1, 1, rectspace1016, 10, 16, 0)); +} + +/* + * around tile border + */ +ZTEST(print_rectspace1016, test_print_at_9_15) +{ + zassert_ok(cfb_print(dev, " ", 9, 15)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(9, 15, rectspace1016, 10, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_10_16) +{ + zassert_ok(cfb_print(dev, " ", 10, 16)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(10, 16, rectspace1016, 10, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_11_17) +{ + zassert_ok(cfb_print(dev, " ", 11, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(11, 17, rectspace1016, 10, 16, 0)); +} + +/* + * kerning + */ +ZTEST(print_rectspace1016, test_print_at_0_0_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", 0, 0)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 0, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_1_1_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", 1, 1)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(1, 1, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_9_15_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", 9, 15)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(9, 15, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_10_16_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", 10, 16)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(10, 16, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_at_11_17_kerning_3) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", 11, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(11, 17, kerning_3_2rectspace1016, 23, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_kerning_3_within_right_border) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", display_width - 23, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(display_width - 23, 17, kerning_3_2rectspace1016, 23, 16)); +} + +ZTEST(print_rectspace1016, test_print_kerning_3_text_wrap) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", display_width - 22, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(display_width - 22, 17, rectspace1016, 10, 16)); + zassert_true(verify_image(0, 33, rectspace1016, 10, 16)); +} + +ZTEST(print_rectspace1016, test_print_outside_top_left) +{ + zassert_ok(cfb_print(dev, " ", -(10 - 3), -(16 - 4))); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 0, outside_top_left, 3, 4, 0)); +} + +ZTEST(print_rectspace1016, test_print_outside_top_right) +{ + zassert_ok(cfb_print(dev, " ", display_width - 5, -8)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image_and_bg(0, 8, rectspace1016, 10, 16, 0)); +} + +ZTEST(print_rectspace1016, test_print_outside_bottom_right) +{ + zassert_ok(cfb_print(dev, " ", display_width - 3, display_height - 5)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0)); +} + +ZTEST(print_rectspace1016, test_print_outside_bottom_left) +{ + zassert_ok(cfb_print(dev, " ", -(10 - 3), display_height - 14)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(0, display_height - 14, outside_bottom_left, 3, 14)); +} + +ZTEST(print_rectspace1016, test_print_wrap_to_3_lines) +{ + cfb_set_kerning(dev, 3); + zassert_ok(cfb_print(dev, " ", 160, 17)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_image(160, 17, kerning_3_12rectspace1016, 153, 16)); + zassert_true(verify_image(0, 33, kerning_3_12rectspace1016, 153, 16)); + zassert_true(verify_image(156, 33, kerning_3_12rectspace1016, 153, 16)); + zassert_true(verify_image(0, 49, kerning_3_12rectspace1016, 153, 16)); + zassert_true(verify_image(13, 49, kerning_3_12rectspace1016, 153, 16)); +} + +ZTEST_SUITE(print_rectspace1016, NULL, NULL, cfb_test_before, cfb_test_after, NULL); diff --git a/tests/subsys/display/cfb/basic/src/testdata.c b/tests/subsys/display/cfb/basic/src/testdata.c new file mode 100644 index 0000000000000..b15b6918ae2ca --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/testdata.c @@ -0,0 +1,726 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +uint32_t diagonal3224[] = { + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, +}; + +uint32_t kerning_3_12rectspace1016[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +}; + +uint32_t kerning_3_2rectspace1016[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +}; + +uint32_t kerning_3_rightclip_1_2rectspace1016[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, +}; + +uint32_t outside_bottom_left[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, +}; + +uint32_t outside_bottom_right[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, +}; + +uint32_t outside_top_left[] = { + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +}; + +uint32_t outside_top_right[] = { + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +}; + +uint32_t rectspace1016[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +}; + +uint32_t rectspace1123[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, +}; + +#ifdef MAIN + +#include +#include + +/* + * Code to export embedded data as ppm + */ + +int to_ppm(const char *filename, uint32_t *buf, size_t w, size_t h) +{ + FILE *f = fopen(filename, "w"); + + fprintf(f, "P3\n"); + fprintf(f, "# %s\n", filename); + fprintf(f, "%lu %lu\n", w, h); + fprintf(f, "255\n"); + + for (size_t i = 0; i < (w * h); i++) { + fprintf(f, "%3d ", (buf[i] & 0xFF0000) >> 16); + fprintf(f, "%3d ", (buf[i] & 0x00FF00) >> 8); + fprintf(f, "%3d\n", (buf[i] & 0x0000FF) >> 0); + } + + fclose(f); + + return 0; +} + +int main(int argc, char *argv[]) +{ + to_ppm("diagonal3224.ppm", diagonal3224, 32, 24); + to_ppm("kerning_3_12rectspace1016.ppm", kerning_3_12rectspace1016, 153, 16); + to_ppm("kerning_3_2rectspace1016.ppm", kerning_3_2rectspace1016, 23, 16); + to_ppm("kerning_3_rightclip_1_2rectspace1016.ppm", kerning_3_rightclip_1_2rectspace1016, 22, + 16); + to_ppm("outside_bottom_left.ppm", outside_bottom_left, 3, 14); + to_ppm("outside_bottom_right.ppm", outside_bottom_right, 3, 5); + to_ppm("outside_top_left.ppm", outside_top_left, 3, 4); + to_ppm("outside_top_right.ppm", outside_top_right, 5, 8); + to_ppm("rectspace1016.ppm", rectspace1016, 10, 16); + to_ppm("rectspace1123.ppm", rectspace1123, 11, 23); + + return 0; +} + +#endif diff --git a/tests/subsys/display/cfb/basic/src/testdata.h b/tests/subsys/display/cfb/basic/src/testdata.h new file mode 100644 index 0000000000000..4a4db8de2fa3e --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/testdata.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TESTS_SUBSYS_DISPLAY_CFB_DRAW_TEXT_AND_PRINT_SRC_TESTDATA_H__ +#define TESTS_SUBSYS_DISPLAY_CFB_DRAW_TEXT_AND_PRINT_SRC_TESTDATA_H__ + +#include + +extern uint32_t diagonal3224[]; +extern uint32_t kerning_3_12rectspace1016[]; +extern uint32_t kerning_3_2rectspace1016[]; +extern uint32_t kerning_3_rightclip_1_2rectspace1016[]; +extern uint32_t outside_bottom_left[]; +extern uint32_t outside_bottom_right[]; +extern uint32_t outside_top_left[]; +extern uint32_t outside_top_right[]; +extern uint32_t rectspace1016[]; +extern uint32_t rectspace1123[]; + +#endif /* TESTS_SUBSYS_DISPLAY_CFB_DRAW_TEXT_AND_PRINT_SRC_TESTDATA_H__ */ diff --git a/tests/subsys/display/cfb/basic/src/utils.c b/tests/subsys/display/cfb/basic/src/utils.c new file mode 100644 index 0000000000000..c96c367c9a37c --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/utils.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utils.h" + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(cfb_test_draw_text_and_print_utils, CONFIG_CFB_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); +uint8_t read_buffer[DT_PROP(DT_CHOSEN(zephyr_display), width) * + DT_PROP(DT_CHOSEN(zephyr_display), height) * 4]; + +inline uint32_t mono_pixel_order(uint32_t order) +{ + if (IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_MSB_FIRST)) { + return BIT(7 - order); + } else { + return BIT(order); + } +} + +uint32_t display_pixel(int x, int y) +{ + const uint8_t *ptr = read_buffer + (display_width * (y / 8) + x); + struct display_capabilities display_caps; + + display_get_capabilities(dev, &display_caps); + + if (display_caps.current_pixel_format == PIXEL_FORMAT_MONO10) { + return !(*ptr & mono_pixel_order(y % 8)); + } + + return !!(*ptr & mono_pixel_order(y % 8)); +} + +uint32_t image_pixel(const uint32_t *img, size_t width, int x, int y) +{ + const uint32_t *ptr = img + (width * y + x); + + return !!(*ptr & 0xFFFFFF); +} + +bool verify_pixel(int x, int y, uint32_t color) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + zassert_ok(display_read(dev, 0, 0, &desc, read_buffer), "display_read failed"); + + return ((!!display_pixel(x, y)) == (!!color)); +} + +bool verify_image(int cmp_x, int cmp_y, const uint32_t *img, size_t width, size_t height) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + zassert_ok(display_read(dev, 0, 0, &desc, read_buffer), "display_read failed"); + + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + uint32_t disp_pix = display_pixel(cmp_x + x, cmp_y + y); + uint32_t img_pix = image_pixel(img, width, x, y); + + if (disp_pix != img_pix) { + LOG_INF("get_pixel(%d, %d) = %lu", x, y, disp_pix); + LOG_INF("pixel_color(%d, %d) = %lu", x, y, img_pix); + LOG_INF("disp@(0, %d) %p", y, read_buffer + (y * width / 8)); + LOG_HEXDUMP_INF(read_buffer + (y * width / 8), 64, ""); + LOG_INF("img@(0, %d) %p", y, (uint32_t *)img + (y * width)); + LOG_HEXDUMP_INF((uint32_t *)img + (y * width), 64, ""); + return false; + } + } + } + + return true; +} + +bool verify_color_inside_rect(int x, int y, size_t width, size_t height, uint32_t color) +{ + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width / 8, + }; + + zassert_ok(display_read(dev, 0, 0, &desc, read_buffer), "display_read failed"); + + for (size_t y_ = 0; y_ < height; y_++) { + for (size_t x_ = 0; x_ < width; x_++) { + uint32_t disp_pix = display_pixel(x + x_, y + y_); + + if (!!disp_pix != !!color) { + return false; + } + } + } + + return true; +} + +bool verify_color_outside_rect(int x, int y, size_t width, size_t height, uint32_t color) +{ + bool ret = true; + + if (x > 0) { + ret = verify_color_inside_rect(0, 0, x, y + height, color); + if (!ret) { + return false; + } + } + + if ((y + height) <= display_height) { + ret = verify_color_inside_rect(0, y + height, x + width, + display_height - (y + height), color); + if (!ret) { + return false; + } + } + + if ((x + width) <= display_width) { + ret = verify_color_inside_rect(x + width, y, display_width - (x + width), + display_height - y, color); + if (!ret) { + return false; + } + } + + if (y > 0) { + ret = verify_color_inside_rect(x, 0, display_width - x, y, color); + if (!ret) { + return false; + } + } + + return true; +} + +bool verify_image_and_bg(int x, int y, const uint32_t *img, size_t width, size_t height, + uint32_t color) +{ + bool ret = true; + + ret = verify_image(x, y, img, width, height); + if (!ret) { + return false; + } + + ret = verify_color_outside_rect(x, y, width, height, color); + + return ret; +} + +bool verify_pixel_and_bg(int x, int y, uint32_t pixcolor, uint32_t bgcolor) +{ + bool ret = true; + + ret = verify_pixel(x, y, pixcolor); + if (!ret) { + return false; + } + + ret = verify_color_outside_rect(x, y, 1, 1, bgcolor); + + return ret; +} diff --git a/tests/subsys/display/cfb/basic/src/utils.h b/tests/subsys/display/cfb/basic/src/utils.h new file mode 100644 index 0000000000000..c91375e93ce5a --- /dev/null +++ b/tests/subsys/display/cfb/basic/src/utils.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TESTS_SUBSYS_DISPLAY_CFB_DRAW_TEXT_AND_PRINT_SRC_UTILS_H__ +#define TESTS_SUBSYS_DISPLAY_CFB_DRAW_TEXT_AND_PRINT_SRC_UTILS_H__ + +#include +#include +#include + +extern uint8_t read_buffer[DT_PROP(DT_CHOSEN(zephyr_display), width) * + DT_PROP(DT_CHOSEN(zephyr_display), height) * 4]; + +uint32_t display_pixel(int x, int y); +uint32_t image_pixel(const uint32_t *img, size_t width, int x, int y); +bool verify_pixel(int x, int y, uint32_t color); +bool verify_image(int x, int y, const uint32_t *img, size_t width, size_t height); +bool verify_color_inside_rect(int x, int y, size_t width, size_t height, uint32_t color); +bool verify_color_outside_rect(int x, int y, size_t width, size_t height, uint32_t color); +bool verify_image_and_bg(int x, int y, const uint32_t *img, size_t width, size_t height, + uint32_t color); +bool verify_pixel_and_bg(int x, int y, uint32_t pixcolor, uint32_t bgcolor); + +#endif /* TESTS_SUBSYS_DISPLAY_CFB_DRAW_TEXT_AND_PRINT_SRC_UTILS_H__ */ diff --git a/tests/subsys/display/cfb/basic/testcase.yaml b/tests/subsys/display/cfb/basic/testcase.yaml new file mode 100644 index 0000000000000..e0c997101d160 --- /dev/null +++ b/tests/subsys/display/cfb/basic/testcase.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +common: + tags: + - subsys + - cfb + filter: dt_chosen_enabled("zephyr,display") + build_only: true # The CI environment has no display device +tests: + cfb.basic.mono01: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + cfb.basic.mono10: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO10=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + cfb.basic.mono01.lsbfirst: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_SDL_DISPLAY_MONO_MSB_FIRST=n + cfb.basic.mono10.lsbfirst: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO10=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_SDL_DISPLAY_MONO_MSB_FIRST=n + cfb.basic.mono01.msbfirst_font: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_TEST_MSB_FIRST_FONT=y + cfb.basic.mono10.msbfirst_font: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO10=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_TEST_MSB_FIRST_FONT=y + cfb.basic.mono01.lsbfirst.msbfirst_font: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_SDL_DISPLAY_MONO_MSB_FIRST=n + - CONFIG_TEST_MSB_FIRST_FONT=y + cfb.basic.mono10.lsbfirst.msbfirst_font: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO10=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_SDL_DISPLAY_MONO_MSB_FIRST=n + - CONFIG_TEST_MSB_FIRST_FONT=y From 2b3581312d7f47a018beac0df10c7828c4a14b56 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 20 Apr 2024 14:01:20 -0700 Subject: [PATCH 025/187] manifest: update cmsis-nn to v6.0.0 Update cmsis-nn to version 6.0.0. Revision history can be found at: https://arm-software.github.io/CMSIS-NN/latest/rev_hist.html Signed-off-by: Jordan Yates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 386efbe778bb2..d88f0a8911d43 100644 --- a/west.yml +++ b/west.yml @@ -124,7 +124,7 @@ manifest: revision: 6489e771e9c405f1763b52d64a3f17a1ec488ace path: modules/lib/cmsis-dsp - name: cmsis-nn - revision: 0c8669d81381ccf3b1a01d699f3b68b50134a99f + revision: ea987c1ca661be723de83bd159aed815d6cbd430 path: modules/lib/cmsis-nn - name: edtt revision: 8d7b543d4d2f2be0f78481e4e1d8d73a88024803 From 102a16edd61cc4240744092e26eb9fa88a10c4a2 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 13 Jun 2024 11:26:44 +1000 Subject: [PATCH 026/187] submanifests: update `tflite-micro` Update `tflite-micro` to the latest version. Signed-off-by: Jordan Yates --- modules/tflite-micro/CMakeLists.txt | 5 ++--- submanifests/optional.yaml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/tflite-micro/CMakeLists.txt b/modules/tflite-micro/CMakeLists.txt index ce1cd370c1afd..50a3935577453 100644 --- a/modules/tflite-micro/CMakeLists.txt +++ b/modules/tflite-micro/CMakeLists.txt @@ -51,13 +51,13 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/test_helper_custom_ops.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/recording_micro_allocator.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_time.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_string.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_profiler.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/flatbuffer_utils.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_graph.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/mock_micro_graph.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_interpreter.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_interpreter_context.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_interpreter_graph.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_allocator.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_context.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_log.cc @@ -83,7 +83,6 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/flatbuffer_conversions.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/error_reporter.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/tensor_utils.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/op_resolver.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/schema/schema_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/activations.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/activations_common.cc diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index a6a9048d17f4e..1d387e2c30442 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -46,7 +46,7 @@ manifest: groups: - optional - name: tflite-micro - revision: 1a34dcab41e7e0e667db72d6a40999c1ec9c510c + revision: 48613f7ba1ffbda46ad771a77a35408f48f922e9 path: optional/modules/lib/tflite-micro repo-path: tflite-micro remote: upstream From e543f8cc6efe825934934e8f00ed9c9d4f156d34 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 15 Jun 2024 12:33:38 +1000 Subject: [PATCH 027/187] modules: cmsis-nn: add `*_s4.c` sources Add new sources for 4 bit function variants to build system. Signed-off-by: Jordan Yates --- modules/cmsis-nn/CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/cmsis-nn/CMakeLists.txt b/modules/cmsis-nn/CMakeLists.txt index 9393a5ff21e06..ec55bafbcfa7a 100644 --- a/modules/cmsis-nn/CMakeLists.txt +++ b/modules/cmsis-nn/CMakeLists.txt @@ -33,21 +33,24 @@ if(CONFIG_CMSIS_NN) endif() if(CONFIG_CMSIS_NN_CONVOLUTION) - file(GLOB SRC "${CMSIS_NN_DIR}/Source/ConvolutionFunctions/*_s8*.c") + file(GLOB SRC_S4 "${CMSIS_NN_DIR}/Source/ConvolutionFunctions/*_s4*.c") + file(GLOB SRC_S8 "${CMSIS_NN_DIR}/Source/ConvolutionFunctions/*_s8*.c") file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/ConvolutionFunctions/*_s16*.c") - zephyr_library_sources(${SRC} ${SRC_S16}) + zephyr_library_sources(${SRC_S4} ${SRC_S8} ${SRC_S16}) endif() if(CONFIG_CMSIS_NN_FULLYCONNECTED) - file(GLOB SRC "${CMSIS_NN_DIR}/Source/FullyConnectedFunctions/*_s8.c") + file(GLOB SRC_S4 "${CMSIS_NN_DIR}/Source/FullyConnectedFunctions/*_s4.c") + file(GLOB SRC_S8 "${CMSIS_NN_DIR}/Source/FullyConnectedFunctions/*_s8.c") file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/FullyConnectedFunctions/*_s16*.c") - zephyr_library_sources(${SRC} ${SRC_S16}) + zephyr_library_sources(${SRC_S4} ${SRC_S8} ${SRC_S16}) endif() if(CONFIG_CMSIS_NN_NNSUPPORT) - file(GLOB SRC "${CMSIS_NN_DIR}/Source/NNSupportFunctions/*_s8*.c") + file(GLOB SRC_S4 "${CMSIS_NN_DIR}/Source/NNSupportFunctions/*_s4*.c") + file(GLOB SRC_S8 "${CMSIS_NN_DIR}/Source/NNSupportFunctions/*_s8*.c") file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/NNSupportFunctions/*_s16*.c") - zephyr_library_sources(${SRC} ${SRC_S16} + zephyr_library_sources(${SRC_S4} ${SRC_S8} ${SRC_S16} ${CMSIS_NN_DIR}/Source/NNSupportFunctions/arm_nntables.c ${CMSIS_NN_DIR}/Source/NNSupportFunctions/arm_q7_to_q15_with_offset.c ${CMSIS_NN_DIR}/Source/NNSupportFunctions/arm_s8_to_s16_unordered_with_offset.c) From 9add73da5ae50c4d408ec7a945ccc78149688bfe Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 10 Jun 2024 20:45:18 +1000 Subject: [PATCH 028/187] tests: lib: cmsis_nn: add missing filter dimension Specify the missing filter dimension that was the reason for the v6.0.0 version bump. Signed-off-by: Jordan Yates --- tests/lib/cmsis_nn/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/cmsis_nn/src/main.c b/tests/lib/cmsis_nn/src/main.c index 3eb7c200590f3..c7dbe3bc58ed4 100644 --- a/tests/lib/cmsis_nn/src/main.c +++ b/tests/lib/cmsis_nn/src/main.c @@ -170,6 +170,7 @@ ZTEST(cmsis_nn, test_convolve) input_dims.c = CONV_4_IN_CH; filter_dims.w = CONV_4_FILTER_X; filter_dims.h = CONV_4_FILTER_Y; + filter_dims.c = CONV_4_IN_CH; output_dims.w = CONV_4_OUTPUT_W; output_dims.h = CONV_4_OUTPUT_H; output_dims.c = CONV_4_OUT_CH; From eb912a9999a1fdaa43fa8668d35a9f07f27333e1 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 25 Jun 2024 20:23:03 +1000 Subject: [PATCH 029/187] samples: tflite-micro: add `REQUIRES_FLOAT_PRINTF` Add `CONFIG_REQUIRES_FLOAT_PRINTF=y` to tflite-micro samples as in the past the module was using its own `printf` implementation, but now uses our logging infrastructure. Signed-off-by: Jordan Yates --- samples/modules/tflite-micro/hello_world/prj.conf | 1 + samples/modules/tflite-micro/tflm_ethosu/prj.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/modules/tflite-micro/hello_world/prj.conf b/samples/modules/tflite-micro/hello_world/prj.conf index c4652d4f7c394..80c7d59270218 100644 --- a/samples/modules/tflite-micro/hello_world/prj.conf +++ b/samples/modules/tflite-micro/hello_world/prj.conf @@ -16,3 +16,4 @@ CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_TENSORFLOW_LITE_MICRO=y CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_REQUIRES_FLOAT_PRINTF=y diff --git a/samples/modules/tflite-micro/tflm_ethosu/prj.conf b/samples/modules/tflite-micro/tflm_ethosu/prj.conf index e4d4947b2981b..a1961668b0e5d 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/prj.conf +++ b/samples/modules/tflite-micro/tflm_ethosu/prj.conf @@ -6,3 +6,4 @@ CONFIG_TENSORFLOW_LITE_MICRO=y CONFIG_ARM_ETHOS_U=y CONFIG_HEAP_MEM_POOL_SIZE=16384 CONFIG_LOG=y +CONFIG_REQUIRES_FLOAT_PRINTF=y From 62312b35139e43c547a9a1b959614e5f042ac65c Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 10 Jun 2024 20:51:25 +1000 Subject: [PATCH 030/187] doc: release-notes: document CMSIS-NN upgrade Update the version update and link to the changelog. Signed-off-by: Jordan Yates --- doc/releases/release-notes-3.7.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index ac1f5c4e76f00..d5dc6f328a36a 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -864,6 +864,11 @@ Libraries / Subsystems for the Mbed TLS's p256-m driver PSA crypto library. This is a Cortex-M SW optimized implementation of secp256r1 curve. +* CMSIS-NN + + * CMSIS-NN was updated to v6.0.0 from v4.1.0: + https://arm-software.github.io/CMSIS-NN/latest/rev_hist.html + * Random * Besides the existing :c:func:`sys_rand32_get` function, :c:func:`sys_rand8_get`, From a2771182b4415b631f339a9569bf864ff394efc3 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 26 Jun 2024 13:42:47 +0200 Subject: [PATCH 031/187] Bluetooth: OTS: Add return validation of bt_uuid_create for client The OTS client did not validate the return value of bt_uuid_create. Signed-off-by: Emil Gydesen --- subsys/bluetooth/services/ots/ots_client.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/services/ots/ots_client.c b/subsys/bluetooth/services/ots/ots_client.c index f8f03d7200c99..3840b5ee34fcc 100644 --- a/subsys/bluetooth/services/ots/ots_client.c +++ b/subsys/bluetooth/services/ots/ots_client.c @@ -6,6 +6,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include @@ -976,7 +977,9 @@ static uint8_t read_obj_type_cb(struct bt_conn *conn, uint8_t err, struct bt_uuid *uuid = &inst->otc_inst->cur_object.type.uuid; - bt_uuid_create(uuid, data, length); + if (!bt_uuid_create(uuid, data, length)) { + return BT_GATT_ITER_STOP; + } bt_uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); LOG_DBG("UUID type read: %s", uuid_str); @@ -1672,8 +1675,10 @@ static int decode_record(struct net_buf_simple *buf, } uuid = net_buf_simple_pull_mem(buf, BT_UUID_SIZE_128); - bt_uuid_create(&rec->metadata.type.uuid, - uuid, BT_UUID_SIZE_128); + if (!bt_uuid_create(&rec->metadata.type.uuid, uuid, BT_UUID_SIZE_128)) { + LOG_DBG("Failed to create UUID"); + return -EINVAL; + } } else { if ((start_len - buf->len) + BT_UUID_SIZE_16 > rec->len) { LOG_WRN("incorrect DirListing record, reclen %u " From b7779b4447395f1ea54c077ce4ee83f014a66ca6 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 28 Jun 2024 11:01:09 +0300 Subject: [PATCH 032/187] doc: release-notes-3.7: Add notes for selected network components Added release notes for these network components: * DNS/mDNS/LLMNR * gPTP/PTP * Sockets * Capture API * Virtual interface * VLAN * Wi-Fi Signed-off-by: Jukka Rissanen --- doc/releases/release-notes-3.7.rst | 95 +++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index d5dc6f328a36a..13574353ffad2 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -532,21 +532,10 @@ Drivers and Sensors * Wi-Fi - * Added support for configuring RTS threshold. With this, users can set the RTS threshold value or - disable the RTS mechanism. - - * Added support for configuring AP parameters. With this, users can set AP parameters at - build and run time. - - * Added support to configure "max_inactivity" BSS parameter. Users can set this both build and runtime - duration to control the maximum time duration after which AP may disconnect a STA due to inactivity - from STA. - - * Added support to configure "inactivity_poll" BSS parameter. Users can set build only AP parameter - to control whether AP may poll the STA before throwing away STA due to inactivity. - - * Added support to configure "max_num_sta" BSS parameter. Users can set this both build and run time - parameter to control the maximum number of STA entries. + * Fixed message parsing for esp-at. + * Fixed esp-at connect failures. + * Implement :c:func:`bind` and :c:func:`recvfrom` for UDP sockets for esp-at. + * Added option for setting maximum data size for eswifi. Networking ********** @@ -596,7 +585,7 @@ Networking * Reimplemented DHCPv4 client RENEW/REBIND logic to be compliant with RFC2131. * Improved declined addresses management in DHCPv4 server, which now can be reused after configured time. - * Fixed including client ID option in DHCPv4 server responsed, according to RFC6842. + * Fixed including the client ID option in the DHCPv4 server response, according to RFC6842. * Added :kconfig:option:`CONFIG_NET_DHCPV4_SERVER_NAK_UNRECOGNIZED_REQUESTS` which allows to override RFC-defined behavior, and NAK requests from unrecognized clients. @@ -609,6 +598,25 @@ Networking maximum supported DUID length. * Added documentation page for DHCPv6. +* DNS/mDNS/LLMNR: + + * Fixed an issue where the mDNS Responder did not work when the mDNS Resolver was also enabled. + The mDNS Resolver and mDNS Responder can now be used simultaneously. + * Reworked LLMNR and mDNS responders, and DNS resolver to use sockets and socket services API. + * Added ANY query resource type. + * Added support for mDNS to provide records in runtime. + * Added support for caching DNS records. + * Fixed error codes returned when socket creation fails, and when all results have been returned. + * Fixed DNS retransmission timeout calculation. + +* gPTP/PTP: + + * Added support for IEEE 1588-2019 PTP. + * Added support for SO_TIMESTAMPING socket option to get timestamping information in socket + ancillary data. + * Fixed race condition on timestamp callback. + * Fixed clock master sync send SM if we are not the GM clock. + * HTTP: * Added HTTP/2 server library and sample application with support for static, @@ -666,19 +674,8 @@ Networking * Removed deprecated API functions and definitions. * Other minor fixes and improvements. -* mDNS: - - * Fixed an issue where the mDNS Responder did not work when the mDNS Resolver was also enabled. - The mDNS Resolver and mDNS Responder can now be used simultaneously. - * Misc: - * Implemented new networking POSIX APIs: - - * :c:func:`if_nameindex` - * :c:func:`inet_ntoa` - * :c:func:`inet_addr` - * Improved overall networking API doxygen documentation. * Converted TFTP library to use ``zsock_*`` API. * Added SNTP :c:func:`sntp_simple_addr` API function to perform SNTP query @@ -697,12 +694,16 @@ Networking (for example packet capture). * Implemented pseudo interface, a.k.a "any" interface for packet capture use case. + * Added cooded mode capture support. This allows non-IP based network data capture. + * Generate network events when starting or stopping packet capture. * Removed obsolete and unused ``tcp_first_msg`` :c:struct:`net_pkt` flag. - * Reworked LLMNR responder to use sockets and socket services API. * Added new :zephyr:code-sample:`secure-mqtt-sensor-actuator` sample. * Added support for partial L3 and L4 checksum offloading. * Updated :zephyr:code-sample:`mqtt-azure` with new CA certificates, the current on expires soon. + * Added new driver for Native Simulator offloaded sockets. + * Overhauled VLAN support to use Virtual network interfaces. + * Added statistics collection for Virtual network interfaces. * MQTT: @@ -731,6 +732,7 @@ Networking * Removed deprecated ``gsm_modem`` driver and sample. * Optimized memory allocation in PPP driver. * Misc improvements in the :zephyr:code-sample:`cellular-modem` sample + * Added PPP low level packet capture support. * Shell: @@ -741,6 +743,20 @@ Networking * Added option to set random MAC address with ``net iface set_mac`` command. * Added multicast join status when printing multicast address information. +* Sockets: + + * Implemented new networking POSIX APIs: + + * :c:func:`if_nameindex` + * :c:func:`inet_ntoa` + * :c:func:`inet_addr` + + * Added support for tracing socket API calls. + * TLS sockets are no longer experimental API. + * Fixed the protocol field endianness for ``AF_PACKET`` type sockets. + * Fixed :c:func:`getsockname` for TCP. + * Improve :c:func:`sendmsg` support when using DTLS sockets. + * Syslog: * Added new API functions: @@ -758,7 +774,7 @@ Networking * Fixed ACK number verification during connection teardown. * Fixed a bug, where data bytes included in FIN packet were ignored. * Fixed a possible TCP context leak in case initial SYN packet transmission failed. - * Deprecated ``CONFIG_NET_TCP_ACK_TIMEOUT`` as it was redundant with other configs. + * Deprecated :kconfig:option:`CONFIG_NET_TCP_ACK_TIMEOUT` as it was redundant with other configs. * Improved debug logs, so that they're easier to follow under heavy load. * ISN generation now uses SHA-256 instead of MD5. Moreover it now relies on PSA APIs instead of legacy Mbed TLS functions for hash computation. @@ -773,6 +789,27 @@ Networking * Converted Websocket library to use ``zsock_*`` API. * Added Object Core support to Websocket sockets. +* Wi-Fi: + + * Reduce memory usage of 5 GHz channel list. + * Added channel validity check in AP mode. + * Added support for BSSID configuration in connect call. + * Wifi shell help text fixes. Option parsing fixes. + * Support WPA auto personal security mode. + * Collect unicast received/sent network packet statistics. + * Added support for configuring RTS threshold. With this, users can set the RTS threshold + value or disable the RTS mechanism. + * Added support for configuring AP parameters. With this, users can set AP parameters at + build and run time. + * Added support to configure ``max_inactivity`` BSS parameter. Users can set this both + build and runtime duration to control the maximum time duration after which AP may + disconnect a STA due to inactivity from STA. + * Added support to configure ``inactivity_poll`` BSS parameter. Users can set build + only AP parameter to control whether AP may poll the STA before throwing away STA + due to inactivity. + * Added support to configure ``max_num_sta`` BSS parameter. Users can set this both + build and run time parameter to control the maximum number of STA entries. + * zperf: * Fixed ``IP_TOS`` and ``IPV6_TCLASS`` options handling in zperf. From 46a5ce98841c9efd66dfa4bd04bddf8cac2b6106 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 26 Jun 2024 16:17:02 +0200 Subject: [PATCH 033/187] debug: no UNALIGNED_ACCESS_SUPPORTED for cortex M0 or M0plus Set the UNALIGNED_ACCESS_SUPPORTED only for MCU with cortex M that are neither M0 nor M0plus Cortex M0 or M0plus mcus do not support un-aligned address access Signed-off-by: Francois Ramu --- subsys/debug/mipi_stp_decoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/debug/mipi_stp_decoder.c b/subsys/debug/mipi_stp_decoder.c index 39aacbdd4d766..4f320a7552696 100644 --- a/subsys/debug/mipi_stp_decoder.c +++ b/subsys/debug/mipi_stp_decoder.c @@ -6,7 +6,9 @@ #include #include -#if defined(CONFIG_CPU_CORTEX_M) && !defined(CONFIG_CPU_CORTEX_M0) +#if defined(CONFIG_CPU_CORTEX_M) && \ + !defined(CONFIG_CPU_CORTEX_M0) && \ + !defined(CONFIG_CPU_CORTEX_M0PLUS) #define UNALIGNED_ACCESS_SUPPORTED 1 #else #define UNALIGNED_ACCESS_SUPPORTED 0 From 19774e5f726cbd5f792375223e032fb739da2c6f Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 26 Jun 2024 13:50:00 +0200 Subject: [PATCH 034/187] doc: Bluetooth: Add sample app for CAP ini/acc in status table Add the sample application as existing for the CAP initiator and CAP acceptor. The samples are still in progress of being improved and fully featured, but they exist and can be used already now. Signed-off-by: Emil Gydesen --- .../bluetooth/api/audio/bluetooth-le-audio-arch.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst index ef4bf447d3d76..b59f39a90a9d5 100644 --- a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst +++ b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst @@ -141,13 +141,15 @@ Bluetooth Audio Stack. | | | | | - BSIM test | | | | | | | - Sample Application | | +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ - | CAP | Acceptor | 1.0 | 3.2 | - Feature complete | - Sample Application | + | CAP | Acceptor | 1.0 | 3.2 | - Feature complete | | | | | | | - Shell Module | | | | | | | - BSIM test | | + | | | | | - Sample Application | | | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ - | | Initiator | 1.0 | 3.3 | - Feature complete | - Sample Application | + | | Initiator | 1.0 | 3.3 | - Feature complete | | | | | | | - Shell Module | | | | | | | - BSIM test | | + | | | | | - Sample Application | | | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ | | Commander | | | - WIP | - Feature complete | | | | | | | - Shell Module | From c5c236bdabf76a51f790322d7bc5f6cfca63acdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Wed, 26 Jun 2024 13:43:16 +0200 Subject: [PATCH 035/187] samples: drivers: mbox: Fix overlays for nrf54h20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sample configuration 'nrf54h20_app_ppr' where: - cpuapp sends messages to cpuppr vevif channel 15, - cpuppr sends messages to cpuapp bellboard channel 18. Add sample configuration 'nrf54h20_rad_app' where: - cpuapp sends messages to cpurad bellboard channel 12, - cpurad sends messages to cpuapp bellboard channel 18. Signed-off-by: Sebastian Głąb --- samples/drivers/mbox/CMakeLists.txt | 1 + samples/drivers/mbox/Kconfig.sysbuild | 3 ++- .../nrf54h20dk_nrf54h20_cpuapp.overlay} | 8 ++++++-- .../nrf54h20dk_nrf54h20_cpuapp_bellboard.conf | 1 - .../nrf54h20dk_nrf54h20_cpuapp_vevif.conf | 1 - .../nrf54h20dk_nrf54h20_cpurad.overlay} | 10 +++++++--- samples/drivers/mbox/remote/CMakeLists.txt | 1 + .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay} | 10 +++++++--- .../boards/nrf54h20dk_nrf54h20_cpuppr.overlay} | 8 ++++++-- .../nrf54h20dk_nrf54h20_cpuppr_bellboard.conf | 1 - .../nrf54h20dk_nrf54h20_cpuppr_vevif.conf | 1 - samples/drivers/mbox/sample.yaml | 18 ++++++++---------- samples/drivers/mbox/sysbuild.cmake | 2 +- 13 files changed, 39 insertions(+), 26 deletions(-) rename samples/drivers/mbox/{remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.overlay => boards/nrf54h20dk_nrf54h20_cpuapp.overlay} (62%) delete mode 100644 samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.conf delete mode 100644 samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.conf rename samples/drivers/mbox/{remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.overlay => boards/nrf54h20dk_nrf54h20_cpurad.overlay} (54%) rename samples/drivers/mbox/{boards/nrf54h20dk_nrf54h20_cpuapp_vevif.overlay => remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay} (54%) rename samples/drivers/mbox/{boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.overlay => remote/boards/nrf54h20dk_nrf54h20_cpuppr.overlay} (62%) delete mode 100644 samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.conf delete mode 100644 samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.conf diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index e4fbfb89dee1f..658a18ac21f66 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -18,6 +18,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM7 OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0 OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR + CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD OR CONFIG_BOARD_NRF54L15PDK_NRF54L15_CPUAPP OR CONFIG_BOARD_STM32H747I_DISCO_STM32H747XX_M7) message(STATUS "${BOARD}${BOARD_QUALIFIERS} compile as Main in this sample") diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild index 080bea5b66577..077fb85db6456 100644 --- a/samples/drivers/mbox/Kconfig.sysbuild +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -14,6 +14,7 @@ string default "mimxrt1170_evk/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evk" default "mimxrt1160_evk/mimxrt1166/cm4" if $(BOARD) = "mimxrt1160_evk" default "lpcxpresso55s69/lpc55s69/cpu1" if $(BOARD) = "lpcxpresso55s69" - default "nrf54h20dk/nrf54h20/cpuppr" if $(BOARD) = "nrf54h20dk" + default "nrf54h20dk/nrf54h20/cpuppr" if "$(BOARD)${BOARD_QUALIFIERS}" = "nrf54h20dk/nrf54h20/cpuapp" + default "nrf54h20dk/nrf54h20/cpuapp" if "$(BOARD)${BOARD_QUALIFIERS}" = "nrf54h20dk/nrf54h20/cpurad" default "nrf54l15pdk/nrf54l15/cpuflpr" if $(BOARD) = "nrf54l15pdk" default "stm32h747i_disco/stm32h747xx/m4" if $(BOARD) = "stm32h747i_disco" diff --git a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.overlay b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp.overlay similarity index 62% rename from samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.overlay rename to samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index 53eec7c680cfe..2e5aba6d2f019 100644 --- a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.overlay +++ b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -6,11 +6,15 @@ / { mbox-consumer { compatible = "vnd,mbox-consumer"; - mboxes = <&cpuapp_bellboard 0>; - mbox-names = "tx"; + mboxes = <&cpuppr_vevif 15>, <&cpuapp_bellboard 18>; + mbox-names = "tx", "rx"; }; }; &cpuapp_bellboard { status = "okay"; }; + +&cpuppr_vevif { + status = "okay"; +}; diff --git a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.conf b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.conf deleted file mode 100644 index 0b6bc73d6bc16..0000000000000 --- a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_TX_ENABLED=n diff --git a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.conf b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.conf deleted file mode 100644 index 4596bc3a757db..0000000000000 --- a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_RX_ENABLED=n diff --git a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.overlay b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpurad.overlay similarity index 54% rename from samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.overlay rename to samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpurad.overlay index 365469e86bde0..d2230e8ef209c 100644 --- a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.overlay +++ b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -6,11 +6,15 @@ / { mbox-consumer { compatible = "vnd,mbox-consumer"; - mboxes = <&cpuppr_vevif 4>; - mbox-names = "rx"; + mboxes = <&cpuapp_bellboard 18>, <&cpurad_bellboard 12>; + mbox-names = "tx", "rx"; }; }; -&cpuppr_vevif { +&cpuapp_bellboard { + status = "okay"; +}; + +&cpurad_bellboard { status = "okay"; }; diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 08823f7b0fcbf..efaa24db0ce18 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -16,6 +16,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM4 OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU1 OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR + CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR CONFIG_BOARD_NRF54L15PDK_NRF54L15_CPUFLPR OR CONFIG_BOARD_NRF54L15PDK_NRF54L15_CPUFLPR_XIP OR CONFIG_BOARD_STM32H747I_DISCO_STM32H747XX_M4) diff --git a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.overlay b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay similarity index 54% rename from samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.overlay rename to samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index 4e01f9a79d559..899a7cb40a7fe 100644 --- a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_vevif.overlay +++ b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -6,11 +6,15 @@ / { mbox-consumer { compatible = "vnd,mbox-consumer"; - mboxes = <&cpuppr_vevif 4>; - mbox-names = "tx"; + mboxes = <&cpuapp_bellboard 18>, <&cpurad_bellboard 12>; + mbox-names = "rx", "tx"; }; }; -&cpuppr_vevif { +&cpuapp_bellboard { + status = "okay"; +}; + +&cpurad_bellboard { status = "okay"; }; diff --git a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.overlay b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr.overlay similarity index 62% rename from samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.overlay rename to samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr.overlay index 3618aab1d168d..049f2432695bf 100644 --- a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp_bellboard.overlay +++ b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr.overlay @@ -6,11 +6,15 @@ / { mbox-consumer { compatible = "vnd,mbox-consumer"; - mboxes = <&cpuapp_bellboard 0>; - mbox-names = "rx"; + mboxes = <&cpuppr_vevif 15>, <&cpuapp_bellboard 18>; + mbox-names = "rx", "tx"; }; }; &cpuapp_bellboard { status = "okay"; }; + +&cpuppr_vevif { + status = "okay"; +}; diff --git a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.conf b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.conf deleted file mode 100644 index 4596bc3a757db..0000000000000 --- a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_bellboard.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_RX_ENABLED=n diff --git a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.conf b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.conf deleted file mode 100644 index 0b6bc73d6bc16..0000000000000 --- a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuppr_vevif.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_TX_ENABLED=n diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index 8308e5907d8d3..01646f040bca2 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -24,13 +24,12 @@ tests: - "Ping \\(on channel 1\\)" - "Pong \\(on channel 1\\)" - sample.drivers.mbox.nrf54h20_vevif: + sample.drivers.mbox.nrf54h20_app_ppr: platform_allow: - nrf54h20dk/nrf54h20/cpuapp integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: - FILE_SUFFIX=vevif mbox_SNIPPET=nordic-ppr sysbuild: true harness: console @@ -38,23 +37,22 @@ tests: type: multi_line ordered: false regex: - - "Ping \\(on channel 4\\)" + - "Ping \\(on channel 15\\)" + - "Pong \\(on channel 18\\)" - sample.drivers.mbox.nrf54h20_bellboard: + sample.drivers.mbox.nrf54h20_rad_app: platform_allow: - - nrf54h20dk/nrf54h20/cpuapp + - nrf54h20dk/nrf54h20/cpurad integration_platforms: - - nrf54h20dk/nrf54h20/cpuapp - extra_args: - FILE_SUFFIX=bellboard - mbox_SNIPPET=nordic-ppr + - nrf54h20dk/nrf54h20/cpurad sysbuild: true harness: console harness_config: type: multi_line ordered: false regex: - - "Pong \\(on channel 0\\)" + - "Ping \\(on channel 18\\)" + - "Pong \\(on channel 12\\)" sample.drivers.mbox.simu: platform_allow: diff --git a/samples/drivers/mbox/sysbuild.cmake b/samples/drivers/mbox/sysbuild.cmake index 769d33d3f7766..e2a5a03b87eb6 100644 --- a/samples/drivers/mbox/sysbuild.cmake +++ b/samples/drivers/mbox/sysbuild.cmake @@ -4,7 +4,7 @@ if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "") message(FATAL_ERROR - "Target ${BOARD} not supported for this sample. " + "Target ${BOARD}${BOARD_QUALIFIERS} not supported for this sample. " "There is no remote board selected in Kconfig.sysbuild") endif() From d7bc45c6336775b715af4b75cf5c5af84ca91fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Wed, 26 Jun 2024 14:06:46 +0200 Subject: [PATCH 036/187] samples: drivers: mbox: Extend mbox sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Print on what board/core sample is executing. Print how many bytes of data can be sent in the mbox message (show use of mbox_mtu_get_dt()). Print how many channels are available for incoming and/or outgoing messages (show use of mbox_max_channels_get_dt()). Signed-off-by: Sebastian Głąb --- samples/drivers/mbox/remote/src/main.c | 7 ++++++- samples/drivers/mbox/src/main.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/samples/drivers/mbox/remote/src/main.c b/samples/drivers/mbox/remote/src/main.c index 9fe6c1a79d566..ee2a26c41c355 100644 --- a/samples/drivers/mbox/remote/src/main.c +++ b/samples/drivers/mbox/remote/src/main.c @@ -24,11 +24,13 @@ int main(void) { int ret; - printk("Hello from REMOTE\n"); + printk("Hello from REMOTE - %s\n", CONFIG_BOARD_TARGET); #ifdef CONFIG_RX_ENABLED const struct mbox_dt_spec rx_channel = MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), rx); + printk("Maximum RX channels: %d\n", mbox_max_channels_get_dt(&rx_channel)); + ret = mbox_register_callback_dt(&rx_channel, callback, NULL); if (ret < 0) { printk("Could not register callback (%d)\n", ret); @@ -45,6 +47,9 @@ int main(void) #ifdef CONFIG_TX_ENABLED const struct mbox_dt_spec tx_channel = MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), tx); + printk("Maximum bytes of data in the TX message: %d\n", mbox_mtu_get_dt(&tx_channel)); + printk("Maximum TX channels: %d\n", mbox_max_channels_get_dt(&tx_channel)); + while (1) { printk("Ping (on channel %d)\n", tx_channel.channel_id); diff --git a/samples/drivers/mbox/src/main.c b/samples/drivers/mbox/src/main.c index 221d7bd474f10..bf9690c868fbd 100644 --- a/samples/drivers/mbox/src/main.c +++ b/samples/drivers/mbox/src/main.c @@ -20,11 +20,13 @@ int main(void) { int ret; - printk("Hello from APP\n"); + printk("Hello from HOST - %s\n", CONFIG_BOARD_TARGET); #ifdef CONFIG_RX_ENABLED const struct mbox_dt_spec rx_channel = MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), rx); + printk("Maximum RX channels: %d\n", mbox_max_channels_get_dt(&rx_channel)); + ret = mbox_register_callback_dt(&rx_channel, callback, NULL); if (ret < 0) { printk("Could not register callback (%d)\n", ret); @@ -41,6 +43,9 @@ int main(void) #ifdef CONFIG_TX_ENABLED const struct mbox_dt_spec tx_channel = MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), tx); + printk("Maximum bytes of data in the TX message: %d\n", mbox_mtu_get_dt(&tx_channel)); + printk("Maximum TX channels: %d\n", mbox_max_channels_get_dt(&tx_channel)); + while (1) { k_sleep(K_MSEC(2000)); From 22187bd9a49bd6e0f03838e95fb2d16c27afe539 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 25 Jun 2024 16:37:25 -0700 Subject: [PATCH 037/187] pm: policy: Move device power state constraints to policy Move information about device power state constraints from device to policy. It slows down the constraints lookup since we now have to find the constraints for a device in a global array, but it saves resources because we don't need to add a reference to constraints in all devices instances. Signed-off-by: Flavio Ceolin --- include/zephyr/device.h | 74 ++------------------------- subsys/pm/policy.c | 107 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 76 deletions(-) diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 4f8c9a260a7d8..54494ffd864ba 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -422,10 +422,6 @@ struct device { */ Z_DEVICE_DEPS_CONST device_handle_t *deps; #endif /* CONFIG_DEVICE_DEPS */ -#if defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) || defined(__DOXYGEN__) - struct pm_state_constraint const *pm_constraints; - size_t pm_constraints_size; -#endif /* CONFIG_PM */ #if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__) /** * Reference to the device PM resources (only available if @@ -876,59 +872,6 @@ __syscall int device_init(const struct device *dev); } #endif /* CONFIG_DEVICE_DEPS */ - -#if defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) || defined(__DOXYGEN__) - -/** - * @brief Synthesize the name of the object that holds a device pm constraint. - * - * @param dev_id Device identifier. - */ -#define Z_DEVICE_PM_CONSTRAINTS_NAME(dev_id) _CONCAT(__devicepmconstraints_, dev_id) - -/** - * @brief initialize a device pm constraint with information from devicetree. - * - * @param node_id Node identifier. - */ -#define Z_PM_STATE_CONSTRAINT_DT_INIT(node_id) \ - { \ - .state = PM_STATE_DT_INIT(node_id), \ - .substate_id = DT_PROP_OR(node_id, substate_id, 0), \ - } - -#define Z_PM_STATE_FROM_DT_DEVICE(i, node_id) \ - COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, \ - zephyr_disabling_power_states, i), okay), \ - (Z_PM_STATE_CONSTRAINT_DT_INIT(DT_PHANDLE_BY_IDX(node_id, \ - zephyr_disabling_power_states, i)),), ()) - -/** - * @brief Helper macro to generate a list of device pm constraints. - */ -#define Z_PM_STATE_CONSTRAINTS_FROM_DT_DEVICE(node_id) \ - { \ - LISTIFY(DT_PROP_LEN_OR(node_id, zephyr_disabling_power_states, 0), \ - Z_PM_STATE_FROM_DT_DEVICE, (), node_id) \ - } - -/** - * @brief Define device pm constraints. - * - * Defines a list of `pm_state_constraint` for a specific device from its - * devicetree definition. - * - * This information tell us which power states would cause power loss - * and intended to be used by a device to set power state constraints when - * it is in the middle of an operation. - */ -#define Z_DEVICE_PM_CONSTRAINTS_DEFINE(node_id, dev_id, ...) \ - Z_DECL_ALIGN(struct pm_state_constraint) \ - Z_DEVICE_PM_CONSTRAINTS_NAME(dev_id)[] = \ - Z_PM_STATE_CONSTRAINTS_FROM_DT_DEVICE(node_id); - -#endif /* CONFIG_PM_POLICY_DEVICE_CONSTRAINTS */ - #if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__) /** * @brief Devicetree node labels associated with a device @@ -1068,7 +1011,7 @@ device_get_dt_nodelabels(const struct device *dev) * @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE */ #define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_, \ - constraints_size_, constraints_, dev_id_) \ + dev_id_) \ { \ .name = name_, \ .config = (config_), \ @@ -1076,10 +1019,6 @@ device_get_dt_nodelabels(const struct device *dev) .state = (state_), \ .data = (data_), \ IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \ - IF_ENABLED(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS, \ - (.pm_constraints = (constraints_),)) \ - IF_ENABLED(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS, \ - (.pm_constraints_size = (constraints_size_),)) \ IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) /**/ \ IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET(dev_id_),)) \ @@ -1111,14 +1050,13 @@ device_get_dt_nodelabels(const struct device *dev) * @param ... Optional dependencies, manually specified. */ #define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \ - deps, constraints) \ + deps) \ COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \ COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \ STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \ device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \ Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \ - Z_DEVICE_INIT(name, pm, data, config, api, state, deps, \ - DT_PROP_LEN_OR(node_id, zephyr_disabling_power_states, 0), constraints, dev_id) + Z_DEVICE_INIT(name, pm, data, config, api, state, deps, dev_id) /* deprecated device initialization levels */ #define Z_DEVICE_LEVEL_DEPRECATED_EARLY \ @@ -1203,15 +1141,11 @@ device_get_dt_nodelabels(const struct device *dev) IF_ENABLED(CONFIG_DEVICE_DEPS, \ (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \ \ - IF_ENABLED(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS, \ - (Z_DEVICE_PM_CONSTRAINTS_DEFINE(node_id, dev_id, __VA_ARGS__);))\ - \ IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);)) \ \ Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ - prio, api, state, Z_DEVICE_DEPS_NAME(dev_id), \ - Z_DEVICE_PM_CONSTRAINTS_NAME(dev_id)); \ + prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \ COND_CODE_1(DEVICE_DT_DEFER(node_id), \ (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \ init_fn)), \ diff --git a/subsys/pm/policy.c b/subsys/pm/policy.c index 942fb900bf953..ecb08233af060 100644 --- a/subsys/pm/policy.c +++ b/subsys/pm/policy.c @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -45,6 +47,87 @@ static struct { #endif +#if defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) + +struct pm_state_device_constraint { + const struct device *const dev; + size_t pm_constraints_size; + struct pm_state_constraint *constraints; +}; + +/** + * @brief Synthesize the name of the object that holds a device pm constraint. + * + * @param dev_id Device identifier. + */ +#define PM_CONSTRAINTS_NAME(node_id) _CONCAT(__devicepmconstraints_, node_id) + +/** + * @brief initialize a device pm constraint with information from devicetree. + * + * @param node_id Node identifier. + */ +#define PM_STATE_CONSTRAINT_INIT(node_id) \ + { \ + .state = PM_STATE_DT_INIT(node_id), \ + .substate_id = DT_PROP_OR(node_id, substate_id, 0), \ + } + +/** + * @brief Helper macro to define a device pm constraints. + */ +#define PM_STATE_CONSTRAINT_DEFINE(i, node_id) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, \ + zephyr_disabling_power_states, i), okay), \ + (PM_STATE_CONSTRAINT_INIT(DT_PHANDLE_BY_IDX(node_id, \ + zephyr_disabling_power_states, i)),), ()) + +/** + * @brief Helper macro to generate a list of device pm constraints. + */ +#define PM_STATE_CONSTRAINTS_DEFINE(node_id) \ + { \ + LISTIFY(DT_PROP_LEN_OR(node_id, zephyr_disabling_power_states, 0), \ + PM_STATE_CONSTRAINT_DEFINE, (), node_id) \ + } + +/** + * @brief Helper macro to define an array of device pm constraints. + */ +#define CONSTRAINTS_DEFINE(node_id) \ + Z_DECL_ALIGN(struct pm_state_constraint) \ + PM_CONSTRAINTS_NAME(node_id)[] = \ + PM_STATE_CONSTRAINTS_DEFINE(node_id); + +#define DEVICE_CONSTRAINTS_DEFINE(node_id) \ + COND_CODE_0(DT_NODE_HAS_PROP(node_id, zephyr_disabling_power_states), (), \ + (CONSTRAINTS_DEFINE(node_id))) + +DT_FOREACH_STATUS_OKAY_NODE(DEVICE_CONSTRAINTS_DEFINE) + +/** + * @brief Helper macro to initialize a pm state device constraint + */ +#define PM_STATE_DEVICE_CONSTRAINT_INIT(node_id) \ + { \ + .dev = DEVICE_DT_GET(node_id), \ + .pm_constraints_size = DT_PROP_LEN(node_id, zephyr_disabling_power_states), \ + .constraints = PM_CONSTRAINTS_NAME(node_id), \ + }, + +/** + * @brief Helper macro to initialize a pm state device constraint + */ +#define PM_STATE_DEVICE_CONSTRAINT_DEFINE(node_id) \ + COND_CODE_0(DT_NODE_HAS_PROP(node_id, zephyr_disabling_power_states), (), \ + (PM_STATE_DEVICE_CONSTRAINT_INIT(node_id))) + +static struct pm_state_device_constraint _devices_constraints[] = { + DT_FOREACH_STATUS_OKAY_NODE(PM_STATE_DEVICE_CONSTRAINT_DEFINE) +}; + +#endif /* CONFIG_PM_POLICY_DEVICE_CONSTRAINTS */ + /** Lock to synchronize access to the latency request list. */ static struct k_spinlock latency_lock; /** List of maximum latency requests. */ @@ -333,9 +416,15 @@ void pm_policy_event_unregister(struct pm_policy_event *evt) void pm_policy_device_power_lock_get(const struct device *dev) { #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state) && defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) - for (size_t i = 0; i < dev->pm_constraints_size; i++) { - pm_policy_state_lock_get(dev->pm_constraints[i].state, - dev->pm_constraints[i].substate_id); + for (size_t i = 0; i < ARRAY_SIZE(_devices_constraints); i++) { + if (_devices_constraints[i].dev == dev) { + for (size_t j = 0; j < _devices_constraints[i].pm_constraints_size; j++) { + pm_policy_state_lock_get( + _devices_constraints[i].constraints[j].state, + _devices_constraints[i].constraints[j].substate_id); + } + break; + } } #endif } @@ -343,9 +432,15 @@ void pm_policy_device_power_lock_get(const struct device *dev) void pm_policy_device_power_lock_put(const struct device *dev) { #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state) && defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) - for (size_t i = 0; i < dev->pm_constraints_size; i++) { - pm_policy_state_lock_put(dev->pm_constraints[i].state, - dev->pm_constraints[i].substate_id); + for (size_t i = 0; i < ARRAY_SIZE(_devices_constraints); i++) { + if (_devices_constraints[i].dev == dev) { + for (size_t j = 0; j < _devices_constraints[i].pm_constraints_size; j++) { + pm_policy_state_lock_put( + _devices_constraints[i].constraints[j].state, + _devices_constraints[i].constraints[j].substate_id); + } + break; + } } #endif } From 50959afbe6a866060e0bc67469e7179daa421718 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 25 Jun 2024 14:44:12 +0200 Subject: [PATCH 038/187] doc: west: Clarify basic west terms Terms like the west workspace or even west projects and modules were not documented prominently enough, prompting users to ask for additional clarification. This patch attempts to resolve this by adding terms and explanation of concepts to the glossary and west doc pages. Fixes #67376. Signed-off-by: Carles Cufi --- doc/develop/west/basics.rst | 14 ++++++++++---- doc/glossary.rst | 23 +++++++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/doc/develop/west/basics.rst b/doc/develop/west/basics.rst index 2695a4f8036bf..afedb33f5c892 100644 --- a/doc/develop/west/basics.rst +++ b/doc/develop/west/basics.rst @@ -6,14 +6,20 @@ Basics This page introduces west's basic concepts and provides references to further reading. -West's built-in commands allow you to work with *projects* (Git -repositories) under a common *workspace* directory. +West's built-in commands allow you to work with :term:`projects ` +(Git repositories) under a common :term:`workspace ` directory. + +West works in the following manner: the ``west init`` command creates the +:term:`west workspace`, and clones the :term:`manifest repo `, while the ``west update`` command initially clones, and later updates, the +:term:`projects ` listed in the manifest in the workspace. Example workspace ***************** -If you've followed the upstream Zephyr getting started guide, your -workspace looks like this: +If you've followed the :ref:`getting_started`, your local +:term:`west workspace`, which in this case is the folder named +:file:`zephyrproject` as well as all its subfolders, looks like this: .. code-block:: none diff --git a/doc/glossary.rst b/doc/glossary.rst index e9e892320c44f..7c643a9495e8f 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -173,15 +173,30 @@ Glossary of Terms :term:`west manifest`. Its location is given by the :ref:`manifest.path configuration option `. See :ref:`west-basics`. + west project + Each of the entries in a :term:`west manifest`, which describe a Git + repository that will be cloned and managed by west when working with the + corresponding :term:`west manifest repository`. Note that a west project + is different from a :term:`zephyr module`, although many projects are also + modules. See :ref:`west-manifests-projects` for additional information. + west workspace - A directory on your system with a :file:`.west` subdirectory and - a :term:`west manifest repository`. You clone the Zephyr source - code onto your system by creating a west workspace using the - ``west init`` command. See :ref:`west-basics`. + A folder on your system with a :file:`.west` subdirectory and a + :term:`west manifest repository` in it. You clone the Zephyr source code, + as well as that of its :term:`west projects ` onto your + system by creating a west workspace using the ``west init`` command. See + :ref:`west-basics`. XIP (eXecute In Place) a method of executing programs directly from long term storage rather than copying it into RAM, saving writable memory for dynamic data and not the static program code. + zephyr module + A Git repository containing a :file:`zephyr/module.yml` file, used by the + Zephyr build system to integrate the source code and configuration files + of the module into a regular Zephyr build. Zephyr modules may be west + projects, but they do not have to. See :ref:`modules` for additional + details. + .. _System on a chip: https://en.wikipedia.org/wiki/System_on_a_chip From 63ff077216d7c363e686daedee63650501dc8cf0 Mon Sep 17 00:00:00 2001 From: Ioannis Damigos Date: Tue, 25 Jun 2024 14:02:53 +0300 Subject: [PATCH 039/187] bme280: Update decoder to decode channels correctly Update bme280 sensor driver decoder to decode correctly the requested channels. Fixes issue #74927 Signed-off-by: Ioannis Damigos --- drivers/sensor/bosch/bme280/bme280.h | 8 +++ drivers/sensor/bosch/bme280/bme280_async.c | 42 ++++++++------ drivers/sensor/bosch/bme280/bme280_decoder.c | 59 +++++++++++++++----- 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/drivers/sensor/bosch/bme280/bme280.h b/drivers/sensor/bosch/bme280/bme280.h index 2499174d5e6d1..b386e6234f327 100644 --- a/drivers/sensor/bosch/bme280/bme280.h +++ b/drivers/sensor/bosch/bme280/bme280.h @@ -206,6 +206,14 @@ struct bme280_decoder_header { struct bme280_encoded_data { struct bme280_decoder_header header; + struct { + /** Set if `temp` has data */ + uint8_t has_temp: 1; + /** Set if `press` has data */ + uint8_t has_press: 1; + /** Set if `humidity` has data */ + uint8_t has_humidity: 1; + } __attribute__((__packed__)); struct bme280_reading reading; }; diff --git a/drivers/sensor/bosch/bme280/bme280_async.c b/drivers/sensor/bosch/bme280/bme280_async.c index 780a7a28c1e40..bd981102dcf26 100644 --- a/drivers/sensor/bosch/bme280/bme280_async.c +++ b/drivers/sensor/bosch/bme280/bme280_async.c @@ -20,21 +20,6 @@ void bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) const struct sensor_chan_spec *const channels = cfg->channels; const size_t num_channels = cfg->count; - /* Check if the requested channels are supported */ - for (size_t i = 0; i < num_channels; i++) { - switch (channels[i].chan_type) { - case SENSOR_CHAN_AMBIENT_TEMP: - case SENSOR_CHAN_HUMIDITY: - case SENSOR_CHAN_PRESS: - case SENSOR_CHAN_ALL: - break; - default: - LOG_ERR("Unsupported channel type %d", channels[i].chan_type); - rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); - return; - } - } - rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); if (rc != 0) { LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len); @@ -45,8 +30,33 @@ void bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) struct bme280_encoded_data *edata; edata = (struct bme280_encoded_data *)buf; - edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->has_temp = 0; + edata->has_humidity = 0; + edata->has_press = 0; + + /* Check if the requested channels are supported */ + for (size_t i = 0; i < num_channels; i++) { + switch (channels[i].chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + edata->has_temp = 1; + break; + case SENSOR_CHAN_HUMIDITY: + edata->has_humidity = 1; + break; + case SENSOR_CHAN_PRESS: + edata->has_press = 1; + break; + case SENSOR_CHAN_ALL: + edata->has_temp = 1; + edata->has_humidity = 1; + edata->has_press = 1; + break; + default: + continue; + break; + } + } rc = bme280_sample_fetch_helper(dev, SENSOR_CHAN_ALL, &edata->reading); if (rc != 0) { diff --git a/drivers/sensor/bosch/bme280/bme280_decoder.c b/drivers/sensor/bosch/bme280/bme280_decoder.c index 7158fd37d5a8c..469922c512188 100644 --- a/drivers/sensor/bosch/bme280/bme280_decoder.c +++ b/drivers/sensor/bosch/bme280/bme280_decoder.c @@ -10,12 +10,33 @@ static int bme280_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint16_t *frame_count) { - ARG_UNUSED(buffer); - ARG_UNUSED(chan_spec); + const struct bme280_encoded_data *edata = (const struct bme280_encoded_data *)buffer; + int32_t ret = -ENOTSUP; + + if (chan_spec.chan_idx != 0) { + return ret; + } /* This sensor lacks a FIFO; there will always only be one frame at a time. */ - *frame_count = 1; - return 0; + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + *frame_count = edata->has_temp ? 1 : 0; + break; + case SENSOR_CHAN_PRESS: + *frame_count = edata->has_press ? 1 : 0; + break; + case SENSOR_CHAN_HUMIDITY: + *frame_count = edata->has_humidity ? 1 : 0; + break; + default: + return ret; + } + + if (*frame_count > 0) { + ret = 0; + } + + return ret; } static int bme280_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, @@ -91,19 +112,31 @@ static int bme280_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec switch (chan_spec.chan_type) { case SENSOR_CHAN_AMBIENT_TEMP: - bme280_convert_signed_temp_raw_to_q31(edata->reading.comp_temp, - &out->readings[0].temperature); - out->shift = BME280_TEMP_SHIFT; + if (edata->has_temp) { + bme280_convert_signed_temp_raw_to_q31(edata->reading.comp_temp, + &out->readings[0].temperature); + out->shift = BME280_TEMP_SHIFT; + } else { + return -ENODATA; + } break; case SENSOR_CHAN_PRESS: - bme280_convert_unsigned_pressure_raw_to_q31(edata->reading.comp_press, - &out->readings[0].pressure); - out->shift = BME280_PRESS_SHIFT; + if (edata->has_press) { + bme280_convert_unsigned_pressure_raw_to_q31(edata->reading.comp_press, + &out->readings[0].pressure); + out->shift = BME280_PRESS_SHIFT; + } else { + return -ENODATA; + } break; case SENSOR_CHAN_HUMIDITY: - bme280_convert_unsigned_humidity_raw_to_q31(edata->reading.comp_humidity, - &out->readings[0].humidity); - out->shift = BME280_HUM_SHIFT; + if (edata->has_humidity) { + bme280_convert_unsigned_humidity_raw_to_q31(edata->reading.comp_humidity, + &out->readings[0].humidity); + out->shift = BME280_HUM_SHIFT; + } else { + return -ENODATA; + } break; default: return -EINVAL; From d55aaa06ee2e96de1331ef1c91a839447b57124d Mon Sep 17 00:00:00 2001 From: Louis Feller Date: Thu, 2 May 2024 15:26:05 +0200 Subject: [PATCH 040/187] west : runners : Fix error message when runners.yaml is not found. Adjust error message so that it clearly states runners.yaml is missing from /zephyr, instead of referencing CMake cache variable ZEPHYR_RUNNERS_YAML, which is no longer used (since 3124c02987071b045b33bbfa2d12606b2ff0a757 ). Also clean up that variable in CMake since it is no longer used (0 other references in entire tree). Fixes #70605 Signed-off-by: Louis Feller --- cmake/flash/CMakeLists.txt | 2 -- scripts/west_commands/run_common.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 9c2b18b6e898d..81929df05aab6 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -131,8 +131,6 @@ function(create_runners_yaml) # Write the final contents and set its location in the cache. file(GENERATE OUTPUT "${runners_yaml}" CONTENT $) - set(ZEPHYR_RUNNERS_YAML "${runners_yaml}" CACHE INTERNAL - "a configuration file for the runners Python package") endfunction() get_property(RUNNERS GLOBAL PROPERTY ZEPHYR_RUNNERS) diff --git a/scripts/west_commands/run_common.py b/scripts/west_commands/run_common.py index fd8a85749ea37..581e848b5d3b4 100644 --- a/scripts/west_commands/run_common.py +++ b/scripts/west_commands/run_common.py @@ -514,9 +514,9 @@ def rebuild(command, build_dir, args): def runners_yaml_path(build_dir, board): ret = Path(build_dir) / 'zephyr' / 'runners.yaml' if not ret.is_file(): - log.die(f'either a pristine build is needed, or board {board} ' - "doesn't support west flash/debug/simulate " - '(no ZEPHYR_RUNNERS_YAML in CMake cache)') + log.die(f'no runners.yaml found in {build_dir}/zephyr. ' + f"Either board {board} doesn't support west flash/debug/simulate," + ' or a pristine build is needed.') return ret def load_runners_yaml(path): From f276f2549089c7389330659431448f83e6a8714a Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 16 May 2024 10:42:02 -0700 Subject: [PATCH 041/187] logging: fix dictionary database not being generated Fix the dictionary database not being generated under some situations even though CONFIG_LOG_DICTIONARY_DB_TARGET is disabled. For example, build and run through QEMU via west build -t run. Signed-off-by: Daniel Leung --- CMakeLists.txt | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5d5b370153d6..1078ff4a52e5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1989,22 +1989,39 @@ elseif(CONFIG_LOG_MIPI_SYST_USE_CATALOG) endif() if(LOG_DICT_DB_NAME_ARG) - if (NOT CONFIG_LOG_DICTIONARY_DB_TARGET) - set(LOG_DICT_DB_ALL_TARGET ALL) - endif() - add_custom_command( - OUTPUT ${LOG_DICT_DB_NAME} - COMMAND + set(log_dict_gen_command ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/logging/dictionary/database_gen.py ${KERNEL_ELF_NAME} ${LOG_DICT_DB_NAME_ARG}=${LOG_DICT_DB_NAME} --build-header ${PROJECT_BINARY_DIR}/include/generated/zephyr/version.h - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMENT "Generating logging dictionary database: ${LOG_DICT_DB_NAME}" - DEPENDS ${logical_target_for_zephyr_elf} ) - add_custom_target(log_dict_db_gen ${LOG_DICT_DB_ALL_TARGET} DEPENDS ${LOG_DICT_DB_NAME}) + + if (NOT CONFIG_LOG_DICTIONARY_DB_TARGET) + # If not using a separate target for generating logging dictionary + # database, add the generation to post build command to make sure + # the database is actually being generated. + list(APPEND + post_build_commands + COMMAND ${CMAKE_COMMAND} -E echo "Generating logging dictionary database: ${LOG_DICT_DB_NAME}" + COMMAND ${log_dict_gen_command} + ) + list(APPEND + post_build_byproducts + ${LOG_DICT_DB_NAME} + ) + else() + # Seprate build target for generating logging dictionary database. + # This needs to be explicitly called/used to generate the database. + add_custom_command( + OUTPUT ${LOG_DICT_DB_NAME} + COMMAND ${log_dict_gen_command} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Generating logging dictionary database: ${LOG_DICT_DB_NAME}" + DEPENDS ${logical_target_for_zephyr_elf} + ) + add_custom_target(log_dict_db_gen DEPENDS ${LOG_DICT_DB_NAME}) + endif() endif() # Add post_build_commands to post-process the final .elf file produced by From 2433653b41b6620ab098b14edf9c4fe010e0472d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 17 May 2024 13:12:51 -0700 Subject: [PATCH 042/187] logging: dictionary: keep string section if always runtime If logging packages need to be created at runtime, the format strings need to be in memory for the packaging code to know what to be packed. So prevent stripping the logging string section if CONFIG_LOG_ALWAYS_RUNTIME is enabled. Signed-off-by: Daniel Leung --- subsys/logging/Kconfig.frontends | 2 +- subsys/logging/Kconfig.misc | 1 + subsys/logging/Kconfig.template.log_format_config | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/logging/Kconfig.frontends b/subsys/logging/Kconfig.frontends index 7a725421fb9e3..17e42d341ba2c 100644 --- a/subsys/logging/Kconfig.frontends +++ b/subsys/logging/Kconfig.frontends @@ -9,7 +9,7 @@ config LOG_FRONTEND_DICT_UART select MPSC_PBUF depends on UART_ASYNC_API || UART_INTERRUPT_DRIVEN imply LOG_FMT_SECTION - imply LOG_FMT_SECTION_STRIP + imply LOG_FMT_SECTION_STRIP if !LOG_ALWAYS_RUNTIME help Frontend sends data in binary dictionary mode. diff --git a/subsys/logging/Kconfig.misc b/subsys/logging/Kconfig.misc index 12ff0c00d0a4b..a78ab110d851c 100644 --- a/subsys/logging/Kconfig.misc +++ b/subsys/logging/Kconfig.misc @@ -61,6 +61,7 @@ config LOG_FMT_SECTION_STRIP depends on LOG_DICTIONARY_SUPPORT depends on LOG_FMT_SECTION depends on LINKER_DEVNULL_SUPPORT + depends on !LOG_ALWAYS_RUNTIME imply LINKER_DEVNULL_MEMORY imply LOG_FMT_STRING_VALIDATE diff --git a/subsys/logging/Kconfig.template.log_format_config b/subsys/logging/Kconfig.template.log_format_config index 0b2dbe0d403a9..14e112e4879ef 100644 --- a/subsys/logging/Kconfig.template.log_format_config +++ b/subsys/logging/Kconfig.template.log_format_config @@ -20,7 +20,7 @@ config LOG_BACKEND_$(backend)_OUTPUT_DICTIONARY bool "Dictionary" select LOG_DICTIONARY_SUPPORT imply LOG_FMT_SECTION - imply LOG_FMT_SECTION_STRIP + imply LOG_FMT_SECTION_STRIP if !LOG_ALWAYS_RUNTIME help Backend is in dictionary-based logging output mode. From 8105522ec4bf97d790ab12e84e89a44e7a8012e3 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 16 May 2024 14:32:41 -0700 Subject: [PATCH 043/187] scripts: logging/dictionary: extract DataTypes into its own file This extracts the DataTypes class into its own file. This is in preparation to add a new version of parser which can reuse this class. Signed-off-by: Daniel Leung --- .../dictionary_parser/data_types.py | 86 +++++++++++++++++++ .../dictionary_parser/log_parser_v1.py | 76 +--------------- 2 files changed, 87 insertions(+), 75 deletions(-) create mode 100644 scripts/logging/dictionary/dictionary_parser/data_types.py diff --git a/scripts/logging/dictionary/dictionary_parser/data_types.py b/scripts/logging/dictionary/dictionary_parser/data_types.py new file mode 100644 index 0000000000000..3b8b1eb5dc91f --- /dev/null +++ b/scripts/logging/dictionary/dictionary_parser/data_types.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +""" +Contains a class to describe data types used for +dictionary logging. +""" + +import struct + +class DataTypes(): + """Class regarding data types, their alignments and sizes""" + INT = 0 + UINT = 1 + LONG = 2 + ULONG = 3 + LONG_LONG = 4 + ULONG_LONG = 5 + PTR = 6 + DOUBLE = 7 + LONG_DOUBLE = 8 + NUM_TYPES = 9 + + def __init__(self, database): + self.database = database + self.data_types = {} + + if database.is_tgt_64bit(): + self.add_data_type(self.LONG, "q") + self.add_data_type(self.LONG_LONG, "q") + self.add_data_type(self.PTR, "Q") + else: + self.add_data_type(self.LONG, "i") + self.add_data_type(self.LONG_LONG, "q") + self.add_data_type(self.PTR, "I") + + self.add_data_type(self.INT, "i") + self.add_data_type(self.DOUBLE, "d") + self.add_data_type(self.LONG_DOUBLE, "d") + + + def add_data_type(self, data_type, fmt): + """Add one data type""" + if self.database.is_tgt_little_endian(): + endianness = "<" + else: + endianness = ">" + + formatter = endianness + fmt + + self.data_types[data_type] = {} + self.data_types[data_type]['fmt'] = formatter + + size = struct.calcsize(formatter) + + if data_type == self.LONG_DOUBLE: + # Python doesn't have long double but we still + # need to skip correct number of bytes + size = 16 + + self.data_types[data_type]['sizeof'] = size + + # Might need actual number for different architectures + # but these seem to work fine for now. + if self.database.is_tgt_64bit(): + self.data_types[data_type]['align'] = 8 + else: + self.data_types[data_type]['align'] = 4 + + + def get_sizeof(self, data_type): + """Get sizeof() of a data type""" + return self.data_types[data_type]['sizeof'] + + + def get_alignment(self, data_type): + """Get the alignment of a data type""" + return self.data_types[data_type]['align'] + + + def get_formatter(self, data_type): + """Get the formatter for a data type""" + return self.data_types[data_type]['fmt'] diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py index e065837781fa6..f58bc3a77ed71 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py @@ -18,6 +18,7 @@ from colorama import Fore from .log_parser import LogParser +from .data_types import DataTypes HEX_BYTES_IN_LINE = 16 @@ -92,81 +93,6 @@ def formalize_fmt_string(fmt_str): return new_str -class DataTypes(): - """Class regarding data types, their alignments and sizes""" - INT = 0 - UINT = 1 - LONG = 2 - ULONG = 3 - LONG_LONG = 4 - ULONG_LONG = 5 - PTR = 6 - DOUBLE = 7 - LONG_DOUBLE = 8 - NUM_TYPES = 9 - - def __init__(self, database): - self.database = database - self.data_types = {} - - if database.is_tgt_64bit(): - self.add_data_type(self.LONG, "q") - self.add_data_type(self.LONG_LONG, "q") - self.add_data_type(self.PTR, "Q") - else: - self.add_data_type(self.LONG, "i") - self.add_data_type(self.LONG_LONG, "q") - self.add_data_type(self.PTR, "I") - - self.add_data_type(self.INT, "i") - self.add_data_type(self.DOUBLE, "d") - self.add_data_type(self.LONG_DOUBLE, "d") - - - def add_data_type(self, data_type, fmt): - """Add one data type""" - if self.database.is_tgt_little_endian(): - endianness = "<" - else: - endianness = ">" - - formatter = endianness + fmt - - self.data_types[data_type] = {} - self.data_types[data_type]['fmt'] = formatter - - size = struct.calcsize(formatter) - - if data_type == self.LONG_DOUBLE: - # Python doesn't have long double but we still - # need to skip correct number of bytes - size = 16 - - self.data_types[data_type]['sizeof'] = size - - # Might need actual number for different architectures - # but these seem to work fine for now. - if self.database.is_tgt_64bit(): - self.data_types[data_type]['align'] = 8 - else: - self.data_types[data_type]['align'] = 4 - - - def get_sizeof(self, data_type): - """Get sizeof() of a data type""" - return self.data_types[data_type]['sizeof'] - - - def get_alignment(self, data_type): - """Get the alignment of a data type""" - return self.data_types[data_type]['align'] - - - def get_formatter(self, data_type): - """Get the formatter for a data type""" - return self.data_types[data_type]['fmt'] - - class LogParserV1(LogParser): """Log Parser V1""" def __init__(self, database): From 14fae9ea3a392dee3714f835d9eaafc42754445c Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 16 May 2024 14:05:25 -0700 Subject: [PATCH 044/187] scripts: logging/dictionary: fix long long alignment Printing long long requires alignment on 64-bit before parsing the actual argument. Or else the parser would be looking at some unrelated bits. So fix it. Signed-off-by: Daniel Leung --- .../dictionary_parser/data_types.py | 104 +++++++++++++++++- .../dictionary_parser/log_database.py | 3 + .../dictionary_parser/log_parser_v1.py | 8 +- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/scripts/logging/dictionary/dictionary_parser/data_types.py b/scripts/logging/dictionary/dictionary_parser/data_types.py index 3b8b1eb5dc91f..0ff4de7c34fce 100644 --- a/scripts/logging/dictionary/dictionary_parser/data_types.py +++ b/scripts/logging/dictionary/dictionary_parser/data_types.py @@ -42,6 +42,84 @@ def __init__(self, database): self.add_data_type(self.LONG_DOUBLE, "d") + @staticmethod + def get_stack_min_align(arch, is_tgt_64bit): + ''' + Correspond to the VA_STACK_ALIGN and VA_STACK_MIN_ALIGN + in cbprintf_internal.h. Note that there might be some + variations that is obtained via actually running through + the log parser. + + Return a tuple where the first element is stack alignment + value. The second element is true if alignment needs to + be further refined according to data type, false if not. + ''' + if arch == "arc": + if is_tgt_64bit: + need_further_align = True + stack_min_align = 8 + else: + need_further_align = False + stack_min_align = 1 + + elif arch == "arm64": + need_further_align = True + stack_min_align = 8 + + elif arch == "sparc": + need_further_align = False + stack_min_align = 1 + + elif arch == "x86": + if is_tgt_64bit: + need_further_align = True + stack_min_align = 8 + else: + need_further_align = False + stack_min_align = 1 + + elif arch == "riscv32e": + need_further_align = False + stack_min_align = 1 + + elif arch == "riscv": + need_further_align = True + + if is_tgt_64bit: + stack_min_align = 8 + else: + stack_min_align = 1 + + elif arch == "nios2": + need_further_align = False + stack_min_align = 1 + + else: + need_further_align = True + stack_min_align = 1 + + return (stack_min_align, need_further_align) + + + @staticmethod + def get_data_type_align(data_type, is_tgt_64bit): + ''' + Get the alignment for a particular data type. + ''' + if data_type == DataTypes.LONG_LONG: + align = 8 + elif data_type == DataTypes.LONG: + if is_tgt_64bit: + align = 8 + else: + align = 4 + else: + # va_list alignment is at least a integer + align = 4 + + return align + + def add_data_type(self, data_type, fmt): """Add one data type""" if self.database.is_tgt_little_endian(): @@ -66,9 +144,26 @@ def add_data_type(self, data_type, fmt): # Might need actual number for different architectures # but these seem to work fine for now. if self.database.is_tgt_64bit(): - self.data_types[data_type]['align'] = 8 + align = 8 else: - self.data_types[data_type]['align'] = 4 + align = 4 + + # 'align' is used to "jump" over an argument so it has + # to be at least size of the data type. + align = max(align, size) + self.data_types[data_type]['align'] = align + + # 'stack_align' should correspond to VA_STACK_ALIGN + # in cbprintf_internal.h + stack_align, need_more_align = DataTypes.get_stack_min_align( + self.database.get_arch(), + self.database.is_tgt_64bit()) + + if need_more_align: + stack_align = DataTypes.get_data_type_align(data_type, + self.database.is_tgt_64bit()) + + self.data_types[data_type]['stack_align'] = stack_align def get_sizeof(self, data_type): @@ -81,6 +176,11 @@ def get_alignment(self, data_type): return self.data_types[data_type]['align'] + def get_stack_alignment(self, data_type): + """Get the stack alignment of a data type""" + return self.data_types[data_type]['stack_align'] + + def get_formatter(self, data_type): """Get the formatter for a data type""" return self.data_types[data_type]['fmt'] diff --git a/scripts/logging/dictionary/dictionary_parser/log_database.py b/scripts/logging/dictionary/dictionary_parser/log_database.py index 3e7b37e396f3a..6c7f8d09c8c7f 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_database.py +++ b/scripts/logging/dictionary/dictionary_parser/log_database.py @@ -49,6 +49,9 @@ "posix" : { "kconfig": "CONFIG_ARCH_POSIX", }, + "riscv32e" : { + "kconfig": "CONFIG_RISCV_ISA_RV32E", + }, "riscv" : { "kconfig": "CONFIG_RISCV", }, diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py index f58bc3a77ed71..5bb6d030c35bc 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py @@ -217,6 +217,11 @@ def process_one_fmt_str(self, fmt_str, arg_list, string_tbl): size = self.data_types.get_sizeof(arg_data_type) unpack_fmt = self.data_types.get_formatter(arg_data_type) + # Align the argument list by rounding up + stack_align = self.data_types.get_stack_alignment(arg_data_type) + if stack_align > 1: + arg_offset = int((arg_offset + (align - 1)) / align) * align + one_arg = struct.unpack_from(unpack_fmt, arg_list, arg_offset)[0] if fmt == 's': @@ -226,7 +231,8 @@ def process_one_fmt_str(self, fmt_str, arg_list, string_tbl): arg_offset += size # Align the offset - arg_offset = int((arg_offset + align - 1) / align) * align + if stack_align > 1: + arg_offset = int((arg_offset + align - 1) / align) * align return tuple(args) From 52a067d8d15d26424f0074fbb15aa8e3bd0c1087 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 17 May 2024 13:32:38 -0700 Subject: [PATCH 045/187] scripts: logging/dictionary: refactor common parser functions... ... and put them into the LogParser class file instead of the verisoned parser. This is in preparation for introducing a new parser version. Signed-off-by: Daniel Leung --- .../dictionary_parser/log_parser.py | 38 +++++++++++++++++++ .../dictionary_parser/log_parser_v1.py | 37 +----------------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser.py b/scripts/logging/dictionary/dictionary_parser/log_parser.py index 31ca7bb46b849..c9565e97e695a 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser.py @@ -9,6 +9,41 @@ """ import abc +from colorama import Fore + +from .data_types import DataTypes + +LOG_LEVELS = [ + ('none', Fore.WHITE), + ('err', Fore.RED), + ('wrn', Fore.YELLOW), + ('inf', Fore.GREEN), + ('dbg', Fore.BLUE) +] + +def get_log_level_str_color(lvl): + """Convert numeric log level to string""" + if lvl < 0 or lvl >= len(LOG_LEVELS): + return ("unk", Fore.WHITE) + + return LOG_LEVELS[lvl] + + +def formalize_fmt_string(fmt_str): + """Replace unsupported formatter""" + new_str = fmt_str + + for spec in ['d', 'i', 'o', 'u', 'x', 'X']: + # Python doesn't support %ll for integer specifiers, so remove extra 'l' + new_str = new_str.replace("%ll" + spec, "%l" + spec) + + # Python doesn't support %hh for integer specifiers, so remove extra 'h' + new_str = new_str.replace("%hh" + spec, "%h" + spec) + + # No %p for pointer either, so use %x + new_str = new_str.replace("%p", "0x%x") + + return new_str class LogParser(abc.ABC): @@ -16,6 +51,9 @@ class LogParser(abc.ABC): def __init__(self, database): self.database = database + self.data_types = DataTypes(self.database) + + @abc.abstractmethod def parse_log_data(self, logdata, debug=False): """Parse log data""" diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py index 5bb6d030c35bc..56a1702216aba 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py @@ -17,20 +17,12 @@ import colorama from colorama import Fore -from .log_parser import LogParser +from .log_parser import (LogParser, get_log_level_str_color, formalize_fmt_string) from .data_types import DataTypes HEX_BYTES_IN_LINE = 16 -LOG_LEVELS = [ - ('none', Fore.WHITE), - ('err', Fore.RED), - ('wrn', Fore.YELLOW), - ('inf', Fore.GREEN), - ('dbg', Fore.BLUE) -] - # Need to keep sync with struct log_dict_output_msg_hdr in # include/logging/log_output_dict.h. # @@ -68,31 +60,6 @@ logger = logging.getLogger("parser") -def get_log_level_str_color(lvl): - """Convert numeric log level to string""" - if lvl < 0 or lvl >= len(LOG_LEVELS): - return ("unk", Fore.WHITE) - - return LOG_LEVELS[lvl] - - -def formalize_fmt_string(fmt_str): - """Replace unsupported formatter""" - new_str = fmt_str - - for spec in ['d', 'i', 'o', 'u', 'x', 'X']: - # Python doesn't support %ll for integer specifiers, so remove extra 'l' - new_str = new_str.replace("%ll" + spec, "%l" + spec) - - # Python doesn't support %hh for integer specifiers, so remove extra 'h' - new_str = new_str.replace("%hh" + spec, "%h" + spec) - - # No %p for pointer either, so use %x - new_str = new_str.replace("%p", "0x%x") - - return new_str - - class LogParserV1(LogParser): """Log Parser V1""" def __init__(self, database): @@ -116,8 +83,6 @@ def __init__(self, database): else: self.fmt_msg_timestamp = endian + FMT_MSG_TIMESTAMP_32 - self.data_types = DataTypes(self.database) - def __get_string(self, arg, arg_offset, string_tbl): one_str = self.database.find_string(arg) From ac187df18ef5012b21f2f5e4385bf60b3ba95020 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 17 May 2024 13:39:19 -0700 Subject: [PATCH 046/187] scripts: logging/dictionary: replace %#llx too Python does not really support long long double, so %llx cannot be formatted correctly, so we replace it with a simple %lx. There is another variant %#llx and we also need replace it to %#lx. Signed-off-by: Daniel Leung --- scripts/logging/dictionary/dictionary_parser/log_parser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser.py b/scripts/logging/dictionary/dictionary_parser/log_parser.py index c9565e97e695a..07b0419b7d0db 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser.py @@ -37,6 +37,9 @@ def formalize_fmt_string(fmt_str): # Python doesn't support %ll for integer specifiers, so remove extra 'l' new_str = new_str.replace("%ll" + spec, "%l" + spec) + if spec in ['x', 'X']: + new_str = new_str.replace("%#ll" + spec, "%#l" + spec) + # Python doesn't support %hh for integer specifiers, so remove extra 'h' new_str = new_str.replace("%hh" + spec, "%h" + spec) From b6aac1a23b2a1bd6a3999ee3d05be47b76caedde Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 16 May 2024 12:26:22 -0700 Subject: [PATCH 047/187] logging: dictionary: new verion 3 format The package_len has been extended from 10 bits to 11 bits in the log message header. So the format for dictionary logging also needs to be updated. Signed-off-by: Daniel Leung --- include/zephyr/logging/log_output_dict.h | 8 +- .../dictionary/dictionary_parser/__init__.py | 5 + .../dictionary_parser/log_database.py | 2 +- .../dictionary_parser/log_parser_v3.py | 383 ++++++++++++++++++ scripts/logging/dictionary/log_parser.py | 2 + 5 files changed, 395 insertions(+), 5 deletions(-) create mode 100644 scripts/logging/dictionary/dictionary_parser/log_parser_v3.py diff --git a/include/zephyr/logging/log_output_dict.h b/include/zephyr/logging/log_output_dict.h index 23271cf34950d..12ab2aaad800e 100644 --- a/include/zephyr/logging/log_output_dict.h +++ b/include/zephyr/logging/log_output_dict.h @@ -30,10 +30,10 @@ enum log_dict_output_msg_type { */ struct log_dict_output_normal_msg_hdr_t { uint8_t type; - uint32_t domain:3; - uint32_t level:3; - uint32_t package_len:10; - uint32_t data_len:12; + uint32_t domain:4; + uint32_t level:4; + uint32_t package_len:16; + uint32_t data_len:16; uintptr_t source; log_timestamp_t timestamp; } __packed; diff --git a/scripts/logging/dictionary/dictionary_parser/__init__.py b/scripts/logging/dictionary/dictionary_parser/__init__.py index 16f2f9ec8e9c0..67f70c128cee7 100644 --- a/scripts/logging/dictionary/dictionary_parser/__init__.py +++ b/scripts/logging/dictionary/dictionary_parser/__init__.py @@ -9,6 +9,7 @@ """ from .log_parser_v1 import LogParserV1 +from .log_parser_v3 import LogParserV3 def get_parser(database): @@ -19,4 +20,8 @@ def get_parser(database): if db_ver in [1, 2]: return LogParserV1(database) + # DB version 3 correspond to v3 parser + if db_ver == 3: + return LogParserV3(database) + return None diff --git a/scripts/logging/dictionary/dictionary_parser/log_database.py b/scripts/logging/dictionary/dictionary_parser/log_database.py index 6c7f8d09c8c7f..83e34e4abebb9 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_database.py +++ b/scripts/logging/dictionary/dictionary_parser/log_database.py @@ -65,7 +65,7 @@ class LogDatabase(): """Class of log database""" # Update this if database format of dictionary based logging # has changed - ZEPHYR_DICT_LOG_VER = 2 + ZEPHYR_DICT_LOG_VER = 3 LITTLE_ENDIAN = True BIG_ENDIAN = False diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser_v3.py b/scripts/logging/dictionary/dictionary_parser/log_parser_v3.py new file mode 100644 index 0000000000000..d6b3904e19662 --- /dev/null +++ b/scripts/logging/dictionary/dictionary_parser/log_parser_v3.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2021, 2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# Parsers are gonig to have very similar code. +# So tell pylint not to care. +# pylint: disable=duplicate-code + +""" +Dictionary-based Logging Parser Version 3 + +This contains the implementation of the parser for +version 3 databases. +""" + +import logging +import struct +import colorama +from colorama import Fore + +from .log_parser import (LogParser, get_log_level_str_color, formalize_fmt_string) +from .data_types import DataTypes + + +HEX_BYTES_IN_LINE = 16 + +# Need to keep sync with struct log_dict_output_msg_hdr in +# include/logging/log_output_dict.h. +# +# struct log_dict_output_normal_msg_hdr_t { +# uint8_t type; +# uint32_t domain:4; +# uint32_t level:4; +# uint32_t package_len:16; +# uint32_t data_len:16; +# uintptr_t source; +# log_timestamp_t timestamp; +# } __packed; +# +# Note "type" and "timestamp" are encoded separately below. +FMT_MSG_HDR_32 = "BHHI" +FMT_MSG_HDR_64 = "BHHQ" + +# Message type +# 0: normal message +# 1: number of dropped messages +FMT_MSG_TYPE = "B" + +# Depends on CONFIG_LOG_TIMESTAMP_64BIT +FMT_MSG_TIMESTAMP_32 = "I" +FMT_MSG_TIMESTAMP_64 = "Q" + +# Keep message types in sync with include/logging/log_output_dict.h +MSG_TYPE_NORMAL = 0 +MSG_TYPE_DROPPED = 1 + +# Number of dropped messages +FMT_DROPPED_CNT = "H" + + +logger = logging.getLogger("parser") + + +class LogParserV3(LogParser): + """Log Parser V1""" + def __init__(self, database): + super().__init__(database=database) + + if self.database.is_tgt_little_endian(): + endian = "<" + self.is_big_endian = False + else: + endian = ">" + self.is_big_endian = True + + self.fmt_msg_type = endian + FMT_MSG_TYPE + self.fmt_dropped_cnt = endian + FMT_DROPPED_CNT + + if self.database.is_tgt_64bit(): + self.fmt_msg_hdr = endian + FMT_MSG_HDR_64 + else: + self.fmt_msg_hdr = endian + FMT_MSG_HDR_32 + + if "CONFIG_LOG_TIMESTAMP_64BIT" in self.database.get_kconfigs(): + self.fmt_msg_timestamp = endian + FMT_MSG_TIMESTAMP_64 + else: + self.fmt_msg_timestamp = endian + FMT_MSG_TIMESTAMP_32 + + + def __get_string(self, arg, arg_offset, string_tbl): + one_str = self.database.find_string(arg) + if one_str is not None: + ret = one_str + else: + # The index from the string table is basically + # the order in va_list. Need to add to the index + # to skip the packaged string header and + # the format string. + str_idx = arg_offset + self.data_types.get_sizeof(DataTypes.PTR) * 2 + str_idx /= self.data_types.get_sizeof(DataTypes.INT) + + if int(str_idx) not in string_tbl: + ret = f'' + else: + ret = string_tbl[int(str_idx)] + + return ret + + + def process_one_fmt_str(self, fmt_str, arg_list, string_tbl): + """Parse the format string to extract arguments from + the binary arglist and return a tuple usable with + Python's string formatting""" + idx = 0 + arg_offset = 0 + arg_data_type = None + is_parsing = False + do_extract = False + + args = [] + + # Translated from cbvprintf_package() + for idx, fmt in enumerate(fmt_str): + if not is_parsing: + if fmt == '%': + is_parsing = True + arg_data_type = DataTypes.INT + continue + + elif fmt == '%': + # '%%' -> literal percentage sign + is_parsing = False + continue + + elif fmt == '*': + pass + + elif fmt.isdecimal() or str.lower(fmt) == 'l' \ + or fmt in (' ', '#', '-', '+', '.', 'h'): + # formatting modifiers, just ignore + continue + + elif fmt in ('j', 'z', 't'): + # intmax_t, size_t or ptrdiff_t + arg_data_type = DataTypes.LONG + + elif fmt in ('c', 'd', 'i', 'o', 'u') or str.lower(fmt) == 'x': + if fmt_str[idx - 1] == 'l': + if fmt_str[idx - 2] == 'l': + arg_data_type = DataTypes.LONG_LONG + else: + arg_data_type = DataTypes.LONG + else: + arg_data_type = DataTypes.INT + + is_parsing = False + do_extract = True + + elif fmt in ('s', 'p', 'n'): + arg_data_type = DataTypes.PTR + + is_parsing = False + do_extract = True + + elif str.lower(fmt) in ('a', 'e', 'f', 'g'): + # Python doesn't do"long double". + # + # Parse it as double (probably incorrect), but + # still have to skip enough bytes. + if fmt_str[idx - 1] == 'L': + arg_data_type = DataTypes.LONG_DOUBLE + else: + arg_data_type = DataTypes.DOUBLE + + is_parsing = False + do_extract = True + + else: + is_parsing = False + continue + + if do_extract: + do_extract = False + + align = self.data_types.get_alignment(arg_data_type) + size = self.data_types.get_sizeof(arg_data_type) + unpack_fmt = self.data_types.get_formatter(arg_data_type) + + # Align the argument list by rounding up + stack_align = self.data_types.get_stack_alignment(arg_data_type) + if stack_align > 1: + arg_offset = int((arg_offset + (align - 1)) / align) * align + + one_arg = struct.unpack_from(unpack_fmt, arg_list, arg_offset)[0] + + if fmt == 's': + one_arg = self.__get_string(one_arg, arg_offset, string_tbl) + + args.append(one_arg) + arg_offset += size + + # Align the offset + if stack_align > 1: + arg_offset = int((arg_offset + align - 1) / align) * align + + return tuple(args) + + + @staticmethod + def extract_string_table(str_tbl): + """Extract string table in a packaged log message""" + tbl = {} + + one_str = "" + next_new_string = True + # Translated from cbvprintf_package() + for one_ch in str_tbl: + if next_new_string: + str_idx = one_ch + next_new_string = False + continue + + if one_ch == 0: + tbl[str_idx] = one_str + one_str = "" + next_new_string = True + continue + + one_str += chr(one_ch) + + return tbl + + + @staticmethod + def print_hexdump(hex_data, prefix_len, color): + """Print hex dump""" + hex_vals = "" + chr_vals = "" + chr_done = 0 + + for one_hex in hex_data: + hex_vals += f'{one_hex:02x} ' + chr_vals += chr(one_hex) + chr_done += 1 + + if chr_done == HEX_BYTES_IN_LINE / 2: + hex_vals += " " + chr_vals += " " + + elif chr_done == HEX_BYTES_IN_LINE: + print(f"{color}%s%s|%s{Fore.RESET}" % ((" " * prefix_len), + hex_vals, chr_vals)) + hex_vals = "" + chr_vals = "" + chr_done = 0 + + if len(chr_vals) > 0: + hex_padding = " " * (HEX_BYTES_IN_LINE - chr_done) + print(f"{color}%s%s%s|%s{Fore.RESET}" % ((" " * prefix_len), + hex_vals, hex_padding, chr_vals)) + + + def parse_one_normal_msg(self, logdata, offset): + """Parse one normal log message and print the encoded message""" + # Parse log message header + domain_lvl, pkg_len, data_len, source_id = struct.unpack_from(self.fmt_msg_hdr, + logdata, offset) + offset += struct.calcsize(self.fmt_msg_hdr) + + timestamp = struct.unpack_from(self.fmt_msg_timestamp, logdata, offset)[0] + offset += struct.calcsize(self.fmt_msg_timestamp) + + # domain_id, level + if self.is_big_endian: + level = domain_lvl & 0x0F + domain_id = (domain_lvl >> 4) & 0x0F + else: + domain_id = domain_lvl & 0x0F + level = (domain_lvl >> 4) & 0x0F + + level_str, color = get_log_level_str_color(level) + source_id_str = self.database.get_log_source_string(domain_id, source_id) + + # Skip over data to point to next message (save as return value) + next_msg_offset = offset + pkg_len + data_len + + # Offset from beginning of cbprintf_packaged data to end of va_list arguments + offset_end_of_args = struct.unpack_from("B", logdata, offset)[0] + offset_end_of_args *= self.data_types.get_sizeof(DataTypes.INT) + offset_end_of_args += offset + + # Extra data after packaged log + extra_data = logdata[(offset + pkg_len):next_msg_offset] + + # Number of appended strings in package + num_packed_strings = struct.unpack_from("B", logdata, offset+1)[0] + + # Number of read-only string indexes + num_ro_str_indexes = struct.unpack_from("B", logdata, offset+2)[0] + offset_end_of_args += num_ro_str_indexes + + # Number of read-write string indexes + num_rw_str_indexes = struct.unpack_from("B", logdata, offset+3)[0] + offset_end_of_args += num_rw_str_indexes + + # Extract the string table in the packaged log message + string_tbl = self.extract_string_table(logdata[offset_end_of_args:(offset + pkg_len)]) + + if len(string_tbl) != num_packed_strings: + logger.error("------ Error extracting string table") + return None + + # Skip packaged string header + offset += self.data_types.get_sizeof(DataTypes.PTR) + + # Grab the format string + # + # Note the negative offset to __get_string(). It is because + # the offset begins at 0 for va_list. However, the format string + # itself is before the va_list, so need to go back the width of + # a pointer. + fmt_str_ptr = struct.unpack_from(self.data_types.get_formatter(DataTypes.PTR), + logdata, offset)[0] + fmt_str = self.__get_string(fmt_str_ptr, + -self.data_types.get_sizeof(DataTypes.PTR), + string_tbl) + offset += self.data_types.get_sizeof(DataTypes.PTR) + + if not fmt_str: + logger.error("------ Error getting format string at 0x%x", fmt_str_ptr) + return None + + args = self.process_one_fmt_str(fmt_str, logdata[offset:offset_end_of_args], string_tbl) + + fmt_str = formalize_fmt_string(fmt_str) + log_msg = fmt_str % args + + if level == 0: + print(f"{log_msg}", end='') + log_prefix = "" + else: + log_prefix = f"[{timestamp:>10}] <{level_str}> {source_id_str}: " + print(f"{color}%s%s{Fore.RESET}" % (log_prefix, log_msg)) + + if data_len > 0: + # Has hexdump data + self.print_hexdump(extra_data, len(log_prefix), color) + + # Point to next message + return next_msg_offset + + + def parse_log_data(self, logdata, debug=False): + """Parse binary log data and print the encoded log messages""" + offset = 0 + + while offset < len(logdata): + # Get message type + msg_type = struct.unpack_from(self.fmt_msg_type, logdata, offset)[0] + offset += struct.calcsize(self.fmt_msg_type) + + if msg_type == MSG_TYPE_DROPPED: + num_dropped = struct.unpack_from(self.fmt_dropped_cnt, logdata, offset) + offset += struct.calcsize(self.fmt_dropped_cnt) + + print(f"--- {num_dropped} messages dropped ---") + + elif msg_type == MSG_TYPE_NORMAL: + ret = self.parse_one_normal_msg(logdata, offset) + if ret is None: + return False + + offset = ret + + else: + logger.error("------ Unknown message type: %s", msg_type) + return False + + return True + +colorama.init() diff --git a/scripts/logging/dictionary/log_parser.py b/scripts/logging/dictionary/log_parser.py index eef60c03840fe..c2b20b0fda952 100755 --- a/scripts/logging/dictionary/log_parser.py +++ b/scripts/logging/dictionary/log_parser.py @@ -132,6 +132,8 @@ def main(): else: logger.debug("# Endianness: Big") + logger.debug("# Database version: %d", database.get_version()) + ret = log_parser.parse_log_data(logdata, debug=args.debug) if not ret: logger.error("ERROR: there were error(s) parsing log data") From 656330cd87722f7834865ce340b81fd37ae51d31 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 16 May 2024 17:04:04 -0700 Subject: [PATCH 048/187] scripts: logging/dictionary: fix annoying pylint warning pylint keeps failing and complaining about arg_data_type is used before assignment. So assign it to None to silence the warning. Signed-off-by: Daniel Leung --- scripts/logging/dictionary/dictionary_parser/log_parser_v1.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py index 56a1702216aba..124974e93109c 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py @@ -110,6 +110,7 @@ def process_one_fmt_str(self, fmt_str, arg_list, string_tbl): Python's string formatting""" idx = 0 arg_offset = 0 + arg_data_type = None is_parsing = False do_extract = False From f07ba9cbf38037976142b4d824a01634594f7970 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 24 May 2024 11:43:07 -0700 Subject: [PATCH 049/187] tests: logging: copy dictionary logging sample into tests This is in preparation for introducing pytest to test the output of dictionary logging. Code is the same, but the testcase.yaml is trimmed to only those that can be tested. Note that a copy is made instead of moving the whole sample over is simply due to various documentation having references to the sample. Since RST files under tests/ are not parsed for zephyr:code-sample:, the linking would have been vanished. Signed-off-by: Daniel Leung --- .../subsys/logging/dictionary/CMakeLists.txt | 8 ++ tests/subsys/logging/dictionary/prj.conf | 5 ++ tests/subsys/logging/dictionary/src/main.c | 88 +++++++++++++++++++ tests/subsys/logging/dictionary/testcase.yaml | 16 ++++ 4 files changed, 117 insertions(+) create mode 100644 tests/subsys/logging/dictionary/CMakeLists.txt create mode 100644 tests/subsys/logging/dictionary/prj.conf create mode 100644 tests/subsys/logging/dictionary/src/main.c create mode 100644 tests/subsys/logging/dictionary/testcase.yaml diff --git a/tests/subsys/logging/dictionary/CMakeLists.txt b/tests/subsys/logging/dictionary/CMakeLists.txt new file mode 100644 index 0000000000000..163d0c3ee51ec --- /dev/null +++ b/tests/subsys/logging/dictionary/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(logging_dictionary) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/logging/dictionary/prj.conf b/tests/subsys/logging/dictionary/prj.conf new file mode 100644 index 0000000000000..6bce0988cdc2f --- /dev/null +++ b/tests/subsys/logging/dictionary/prj.conf @@ -0,0 +1,5 @@ +CONFIG_LOG=y +CONFIG_LOG_PRINTK=y +CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX=y +CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY=y +CONFIG_LOG_BACKEND_UART=y diff --git a/tests/subsys/logging/dictionary/src/main.c b/tests/subsys/logging/dictionary/src/main.c new file mode 100644 index 0000000000000..24d6eee702f39 --- /dev/null +++ b/tests/subsys/logging/dictionary/src/main.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012-2014 Wind River Systems, Inc. + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(hello_world, LOG_LEVEL_DBG); + +static const char *hexdump_msg = "HEXDUMP! HEXDUMP@ HEXDUMP#"; + +int main(void) +{ + int8_t i8 = 1; + uint8_t u8 = 2; + int16_t i16 = 16; + uint16_t u16 = 17; + int32_t i32 = 32; + uint32_t u32 = 33; + int64_t i64 = 64; + uint64_t u64 = 65; + char c = '!'; + char *s = "static str"; + char *s1 = "c str"; + char vs0[32]; + char vs1[32]; + void *p = s; + + printk("Hello World! %s\n", CONFIG_BOARD); + + LOG_ERR("error string"); + LOG_DBG("debug string"); + LOG_INF("info string"); + + LOG_DBG("int8_t %" PRId8 ", uint8_t %" PRIu8, i8, u8); + LOG_DBG("int16_t %" PRId16 ", uint16_t %" PRIu16, i16, u16); + LOG_DBG("int32_t %" PRId32 ", uint32_t %" PRIu32, i32, u32); + LOG_DBG("int64_t %" PRId64 ", uint64_t %" PRIu64, i64, u64); + + memset(vs0, 0, sizeof(vs0)); + snprintk(&vs0[0], sizeof(vs0), "%s", "dynamic str"); + + memset(vs1, 0, sizeof(vs1)); + snprintk(&vs1[0], sizeof(vs1), "%s", "another dynamic str"); + + LOG_DBG("char %c", c); + LOG_DBG("s str %s %s", s, s1); + LOG_DBG("d str %s", vs0); + LOG_DBG("mixed str %s %s %s %s %s %s %s", vs0, "---", vs0, "---", vs1, "---", vs1); + LOG_DBG("mixed c/s %c %s %s %s %c", c, s, vs0, s, c); + + LOG_DBG("pointer %p", p); + + LOG_HEXDUMP_DBG(hexdump_msg, strlen(hexdump_msg), "For HeXdUmP!"); + +#ifdef CONFIG_FPU + float f = 66.67; + double d = 68.69; + + LOG_DBG("float %f, double %f", (double)f, d); +#ifdef CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE + long double ld = 70.71L; + + LOG_DBG("long double %Lf", ld); +#endif +#endif + return 0; +} + +static int rt_demo_cmd(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(sh); + LOG_ERR("demo %s", argc > 1 ? argv[1] : ""); + LOG_WRN("demo %s", argc > 1 ? argv[1] : ""); + LOG_INF("demo %s", argc > 1 ? argv[1] : ""); + LOG_DBG("demo %s", argc > 1 ? argv[1] : ""); + + return 0; +} + +SHELL_CMD_REGISTER(log_rt_demo, NULL, "Command can be used to test runtime filtering", rt_demo_cmd); diff --git a/tests/subsys/logging/dictionary/testcase.yaml b/tests/subsys/logging/dictionary/testcase.yaml new file mode 100644 index 0000000000000..9a71e947791f6 --- /dev/null +++ b/tests/subsys/logging/dictionary/testcase.yaml @@ -0,0 +1,16 @@ +tests: + logging.dictionary: + build_only: true + tags: logging + integration_platforms: + - qemu_x86 + - qemu_x86_64 + logging.dictionary.fpu: + build_only: true + tags: logging + filter: CONFIG_CPU_HAS_FPU + extra_configs: + - CONFIG_FPU=y + integration_platforms: + - qemu_x86 + - qemu_x86_64 From 264fc94d0606f837bd58e2d02eeb75e0b71f8f7f Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 15 May 2024 11:05:25 -0700 Subject: [PATCH 050/187] tests: logging/dictionary: enable pytest to test output Add pytest to test the output of dictionary logging to make sure the encoded logs can be decoded back into strings, and to also make sure the decoded logs have the expected strings. Signed-off-by: Daniel Leung --- tests/subsys/logging/dictionary/prj.conf | 4 + .../logging/dictionary/pytest/conftest.py | 14 ++ .../pytest/test_logging_dictionary.py | 159 ++++++++++++++++++ tests/subsys/logging/dictionary/src/main.c | 12 ++ tests/subsys/logging/dictionary/testcase.yaml | 22 ++- 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 tests/subsys/logging/dictionary/pytest/conftest.py create mode 100644 tests/subsys/logging/dictionary/pytest/test_logging_dictionary.py diff --git a/tests/subsys/logging/dictionary/prj.conf b/tests/subsys/logging/dictionary/prj.conf index 6bce0988cdc2f..2465b6cdd08a7 100644 --- a/tests/subsys/logging/dictionary/prj.conf +++ b/tests/subsys/logging/dictionary/prj.conf @@ -3,3 +3,7 @@ CONFIG_LOG_PRINTK=y CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX=y CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY=y CONFIG_LOG_BACKEND_UART=y + +# Immediate mode needed for twister/pytest +# to capture output without delays. +CONFIG_LOG_MODE_IMMEDIATE=y diff --git a/tests/subsys/logging/dictionary/pytest/conftest.py b/tests/subsys/logging/dictionary/pytest/conftest.py new file mode 100644 index 0000000000000..29d3de55d10bf --- /dev/null +++ b/tests/subsys/logging/dictionary/pytest/conftest.py @@ -0,0 +1,14 @@ +# +# Copyright (c) 2024 Intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import pytest + +def pytest_addoption(parser): + parser.addoption('--fpu', action="store_true") + +@pytest.fixture() +def is_fpu_build(request): + return request.config.getoption('--fpu') diff --git a/tests/subsys/logging/dictionary/pytest/test_logging_dictionary.py b/tests/subsys/logging/dictionary/pytest/test_logging_dictionary.py new file mode 100644 index 0000000000000..68548ce47677d --- /dev/null +++ b/tests/subsys/logging/dictionary/pytest/test_logging_dictionary.py @@ -0,0 +1,159 @@ +# +# Copyright (c) 2024 Intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +''' +Pytest harness to test the output of the dictionary logging. +''' + +import logging +import os +import shlex +import subprocess +import re + +from twister_harness import DeviceAdapter + +ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") + +logger = logging.getLogger(__name__) + +def process_logs(dut: DeviceAdapter, build_dir): + ''' + This grabs the encoded log from console and parse the log + through the dictionary logging parser. + + Returns the decoded log lines. + ''' + # Make sure the log parser script is there... + parser_script = os.path.join(ZEPHYR_BASE, "scripts", "logging", "dictionary", "log_parser.py") + assert os.path.isfile(parser_script) + logger.info(f'Log parser script: {parser_script}') + + # And also the dictionary JSON file is there... + dictionary_json = os.path.join(build_dir, "zephyr", "log_dictionary.json") + assert os.path.isfile(dictionary_json) + logger.info(f'Dictionary JSON: {dictionary_json}') + + # Read the encoded logs and save them to a file + # as the log parser requires file as input + handler_output = dut.readlines_until(regex = '^##ZLOGV1##[0-9]+', timeout = 10.0) + + encoded_logs = handler_output[-1] + + encoded_log_file = os.path.join(build_dir, "encoded.log") + with open(encoded_log_file, 'w', encoding='utf-8') as fp: + fp.write(encoded_logs) + + # Run the log parser + cmd = [parser_script, '--hex', dictionary_json, encoded_log_file] + logger.info(f'Running parser script: {shlex.join(cmd)}') + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + assert result.returncode == 0 + + # Grab the decoded log lines from stdout, print a copy and return it + decoded_logs = result.stdout + logger.info(f'Decoded logs: {decoded_logs}') + + return decoded_logs + + +def expected_regex_common(): + ''' + Return an array of compiled regular expression for matching + the decoded log lines. + ''' + return [ + # *** Booting Zephyr OS build *** + re.compile(r'^[*][*][*] Booting Zephyr OS build [0-9a-z.-]+'), + # Hello World! + re.compile(r'[\s]+Hello World! [\w-]+'), + # [ 10] hello_world: error string + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: error string'), + # [ 10] hello_world: main: debug string + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: debug string'), + # [ 10] hello_world: info string + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: info string'), + # [ 10] hello_world: main: int8_t 1, uint8_t 2 + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: int8_t 1, uint8_t 2'), + # [ 10] hello_world: main: int16_t 16, uint16_t 17 + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: int16_t 16, uint16_t 17'), + # [ 10] hello_world: main: int32_t 32, uint32_t 33 + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: int32_t 32, uint32_t 33'), + # [ 10] hello_world: main: int64_t 64, uint64_t 65 + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: int64_t 64, uint64_t 65'), + # [ 10] hello_world: main: char ! + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: char !'), + # [ 10] hello_world: main: s str static str c str + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: s str static str c str'), + # [ 10] hello_world: main: d str dynamic str + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: d str dynamic str'), + # [ 10] hello_world: main: mixed str dynamic str --- dynamic str \ + # --- another dynamic str --- another dynamic str + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: mixed str dynamic str ' + '--- dynamic str --- another dynamic str --- another dynamic str'), + # [ 10] hello_world: main: mixed c/s ! static str dynamic str static str ! + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: mixed c/s ! static str ' + 'dynamic str static str !'), + # [ 10] hello_world: main: pointer 0x1085f9 + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: pointer 0x[0-9a-f]+'), + # [ 10] hello_world: main: For HeXdUmP! + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: For HeXdUmP!'), + # 48 45 58 44 55 4d 50 21 20 48 45 58 44 55 4d 50 |HEXDUMP! HEXDUMP + re.compile(r'[\s]+[ ]+[0-9a-f ]{48,52}[|]HEXDUMP! HEXDUMP'), + # 40 20 48 45 58 44 55 4d 50 23 |@ HEXDUM P# + re.compile(r'[\s]+[ ]+[0-9a-f ]{48,52}[|]@ HEXDUM P#'), + ] + + +def expected_regex_fpu(): + ''' + Return an array of additional compiled regular expression for matching + the decoded log lines for FPU builds. + ''' + return [ + # [ 10] hello_world: main: float 66.669998, double 68.690000 + re.compile(r'[\s]+[\[][0-9,:\. ]+[\]] hello_world: main: ' + r'float 66[\.][0-9-\.]+, double 68[\.][0-9-\.]+'), + ] + + +def regex_matching(decoded_logs, expected_regex): + ''' + Given the decoded log lines and an array of compiled regular expression, + match all of them and display whether a line is found or not. + + Return True if all regular expressions have corresponding matches, + False otherwise. + ''' + regex_results = [ex_re.search(decoded_logs) for ex_re in expected_regex] + + # Using 1:1 mapping between regex_results and expected_regex, so + # cannot use enumeration. + # + # pylint: disable=consider-using-enumerate + for idx in range(len(regex_results)): + if regex_results[idx]: + logger.info(f'Found: {regex_results[idx].group(0).strip()}') + else: + logger.info(f'NOT FOUND: {expected_regex[idx]}') + + return all(regex_results) + + +def test_logging_dictionary(dut: DeviceAdapter, is_fpu_build): + ''' + Main entrance to setup test result validation. + ''' + build_dir = dut.device_config.build_dir + + logger.info(f'FPU build? {is_fpu_build}') + + decoded_logs = process_logs(dut, build_dir) + + assert regex_matching(decoded_logs, expected_regex_common()) + + if is_fpu_build: + assert regex_matching(decoded_logs, expected_regex_fpu()) diff --git a/tests/subsys/logging/dictionary/src/main.c b/tests/subsys/logging/dictionary/src/main.c index 24d6eee702f39..1e4b5f3fecf0e 100644 --- a/tests/subsys/logging/dictionary/src/main.c +++ b/tests/subsys/logging/dictionary/src/main.c @@ -71,6 +71,18 @@ int main(void) LOG_DBG("long double %Lf", ld); #endif #endif + +#if defined(CONFIG_STDOUT_CONSOLE) + /* + * When running through twister with pytest, we need to add a newline + * at the end of logging output for the output to be registered via + * pipe or FIFO in the pytest harness as reading is on a line-by-line + * basis. So send newline characters to flush the output. + */ + fputc('\r', stdout); + fputc('\n', stdout); +#endif + return 0; } diff --git a/tests/subsys/logging/dictionary/testcase.yaml b/tests/subsys/logging/dictionary/testcase.yaml index 9a71e947791f6..91f00946d7745 100644 --- a/tests/subsys/logging/dictionary/testcase.yaml +++ b/tests/subsys/logging/dictionary/testcase.yaml @@ -1,16 +1,34 @@ +common: + # For twister runs, the following arch/platforms use logging backends + # which do not output dictionary logging in hexidecimal format, + # and thus cannot be used for testing. Currently, only UART + # logging backend does that. + arch_exclude: + - posix + platform_exclude: + - qemu_xtensa + - qemu_xtensa/dc233c/mmu tests: logging.dictionary: - build_only: true tags: logging integration_platforms: - qemu_x86 - qemu_x86_64 + harness: pytest + harness_config: + pytest_root: + - "pytest/test_logging_dictionary.py" logging.dictionary.fpu: - build_only: true tags: logging filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_FPU=y + harness: pytest + harness_config: + pytest_root: + - "pytest/test_logging_dictionary.py" + pytest_args: + - "--fpu" integration_platforms: - qemu_x86 - qemu_x86_64 From b86f6a58645a1eb473d8abd91680d47a83ac9503 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 30 May 2024 18:56:14 +0530 Subject: [PATCH 051/187] net: sockets_service: Fix thread failure In case of thread failure, fix the registrations by properly managing the synchronization i.e. use conditional wait only if thread is being initialized or will be initialized, else check for success or failure without waiting for conditional variables. Fixes #73523. Signed-off-by: Chaitanya Tata --- subsys/net/lib/sockets/sockets_service.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_service.c b/subsys/net/lib/sockets/sockets_service.c index fc156b4070312..14d7a011bd9a9 100644 --- a/subsys/net/lib/sockets/sockets_service.c +++ b/subsys/net/lib/sockets/sockets_service.c @@ -13,7 +13,14 @@ LOG_MODULE_REGISTER(net_sock_svc, CONFIG_NET_SOCKETS_LOG_LEVEL); #include static int init_socket_service(void); -static bool init_done; + +enum SOCKET_SERVICE_THREAD_STATUS { + SOCKET_SERVICE_THREAD_UNINITIALIZED = 0, + SOCKET_SERVICE_THREAD_FAILED, + SOCKET_SERVICE_THREAD_STOPPED, + SOCKET_SERVICE_THREAD_RUNNING, +}; +static enum SOCKET_SERVICE_THREAD_STATUS thread_status; static K_MUTEX_DEFINE(lock); static K_CONDVAR_DEFINE(wait_start); @@ -52,8 +59,12 @@ int z_impl_net_socket_service_register(const struct net_socket_service_desc *svc k_mutex_lock(&lock, K_FOREVER); - if (!init_done) { + if (thread_status == SOCKET_SERVICE_THREAD_UNINITIALIZED) { (void)k_condvar_wait(&wait_start, &lock, K_FOREVER); + } else if (thread_status != SOCKET_SERVICE_THREAD_RUNNING) { + NET_ERR("Socket service thread not running, service %p register fails.", svc); + ret = -EIO; + goto out; } if (STRUCT_SECTION_START(net_socket_service_desc) > svc || @@ -219,7 +230,7 @@ static void socket_service_thread(void) goto out; } - init_done = true; + thread_status = SOCKET_SERVICE_THREAD_RUNNING; k_condvar_broadcast(&wait_start); ctx.events[0].fd = fd; @@ -274,11 +285,12 @@ static void socket_service_thread(void) out: NET_DBG("Socket service thread stopped"); - init_done = false; + thread_status = SOCKET_SERVICE_THREAD_STOPPED; return; fail: + thread_status = SOCKET_SERVICE_THREAD_FAILED; k_condvar_broadcast(&wait_start); } From a62d9207c81489d2721ee1f82e484d0109c153bb Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Wed, 26 Jun 2024 18:44:12 +0300 Subject: [PATCH 052/187] linker: nxp: adsp: add orphan linker section Add missing linker section to avoid warning about orphans when building with host compiler. Signed-off-by: Iuliana Prodan --- soc/nxp/imx/imx8/adsp/linker.ld | 2 ++ soc/nxp/imx/imx8ulp/adsp/linker.ld | 2 ++ soc/nxp/imx/imx8x/adsp/linker.ld | 2 ++ 3 files changed, 6 insertions(+) diff --git a/soc/nxp/imx/imx8/adsp/linker.ld b/soc/nxp/imx/imx8/adsp/linker.ld index 4843d50e57fd8..a0754d007dfe4 100644 --- a/soc/nxp/imx/imx8/adsp/linker.ld +++ b/soc/nxp/imx/imx8/adsp/linker.ld @@ -522,4 +522,6 @@ SECTIONS KEEP (*(.fw_metadata)) . = ALIGN(_EXT_MAN_ALIGN_); } >fw_metadata_seg :metadata_entries_phdr + + /DISCARD/ : { *(.note.GNU-stack) } } diff --git a/soc/nxp/imx/imx8ulp/adsp/linker.ld b/soc/nxp/imx/imx8ulp/adsp/linker.ld index f832d9c45da2f..a9f07e825ec3b 100644 --- a/soc/nxp/imx/imx8ulp/adsp/linker.ld +++ b/soc/nxp/imx/imx8ulp/adsp/linker.ld @@ -522,4 +522,6 @@ SECTIONS KEEP (*(.fw_metadata)) . = ALIGN(_EXT_MAN_ALIGN_); } >fw_metadata_seg :metadata_entries_phdr + + /DISCARD/ : { *(.note.GNU-stack) } } diff --git a/soc/nxp/imx/imx8x/adsp/linker.ld b/soc/nxp/imx/imx8x/adsp/linker.ld index 4843d50e57fd8..a0754d007dfe4 100644 --- a/soc/nxp/imx/imx8x/adsp/linker.ld +++ b/soc/nxp/imx/imx8x/adsp/linker.ld @@ -522,4 +522,6 @@ SECTIONS KEEP (*(.fw_metadata)) . = ALIGN(_EXT_MAN_ALIGN_); } >fw_metadata_seg :metadata_entries_phdr + + /DISCARD/ : { *(.note.GNU-stack) } } From a3a0f968f9769ead43b492bdc673589b1969f685 Mon Sep 17 00:00:00 2001 From: Adrien MARTIN Date: Wed, 26 Jun 2024 22:48:09 +0200 Subject: [PATCH 053/187] drivers: spi: gecko: propagate spi config error This commit catch the return code of the spi_config function and early returns on error so that high level spi transfer api gets the error too. Signed-off-by: Adrien MARTIN --- drivers/spi/spi_gecko.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_gecko.c b/drivers/spi/spi_gecko.c index 3c79bdb4e2f1b..56dd0cfd7f71e 100644 --- a/drivers/spi/spi_gecko.c +++ b/drivers/spi/spi_gecko.c @@ -346,8 +346,13 @@ static int spi_gecko_transceive(const struct device *dev, { struct spi_gecko_data *data = dev->data; uint16_t control = 0; + int ret; + + ret = spi_config(dev, config, &control); + if (ret < 0) { + return ret; + } - spi_config(dev, config, &control); spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); spi_gecko_xfer(dev, config); return 0; From 5495dca69f4459c5964762a6623cd6de35625a88 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 28 Jun 2024 12:16:16 -0700 Subject: [PATCH 054/187] xtensa: mmu: clear ZSR_DEPC_SAVE at boot ZSR_DEPC_SAVE is being used to determine whether we are faulting inside double exception if this is not zero. It is possible that the boot ROM or custom startup code leaves this non-zero, which would result in a fake triple fault. So clear it at boot. Note that the zeroing is done in MMU init code as these triple faults are not actual hardware ones but only semantics, and will occur once MMU is enabled. Fixes #75194 Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index f06b7f872126a..675949cb342f6 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -317,6 +317,13 @@ void xtensa_mmu_init(void) xtensa_init_paging(xtensa_kernel_ptables); + /* + * This is used to determine whether we are faulting inside double + * exception if this is not zero. Sometimes SoC starts with this not + * being set to zero. So clear it during boot. + */ + XTENSA_WSR(ZSR_DEPC_SAVE_STR, 0); + arch_xtensa_mmu_post_init(_current_cpu->id == 0); } From 36c77a742625dfc4f784f224fbbe7532f164d0cf Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 28 Jun 2024 10:42:02 -0300 Subject: [PATCH 055/187] hal_espressif: remove extra not-used constructor After #74682, any function with constructor attribution requires additional configuration. Due to some left-over and not-used code in hal_espressif with that attribution, some samples started failing. This is an additional to ##75063 Fixes #75169 Signed-off-by: Sylvio Alves --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d88f0a8911d43..b4495f50b0e81 100644 --- a/west.yml +++ b/west.yml @@ -157,7 +157,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 826077a9d9c762ea7033f137b992b1b36b4aeacb + revision: 61b977fd2b033c656b1b2fa07b3137872236f710 path: modules/hal/espressif west-commands: west/west-commands.yml groups: From c5ad0a2a99f050cd49ea394b765b20eaf7b96a27 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Jun 2024 15:56:17 +0200 Subject: [PATCH 056/187] samples: usb: mass: increase main stack size "ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0" observed on a few supported platforms when using SD card disk. Increase main stack size for next USB device stack configuration to prevent stack overflow. Signed-off-by: Johann Fischer --- samples/subsys/usb/mass/usbd_next_prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/usb/mass/usbd_next_prj.conf b/samples/subsys/usb/mass/usbd_next_prj.conf index 1f7345d25fd31..dd9d784070de5 100644 --- a/samples/subsys/usb/mass/usbd_next_prj.conf +++ b/samples/subsys/usb/mass/usbd_next_prj.conf @@ -12,4 +12,4 @@ CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y CONFIG_SAMPLE_USBD_PID=0x0008 CONFIG_SAMPLE_USBD_PRODUCT="USBD MSC sample" -CONFIG_MAIN_STACK_SIZE=1536 +CONFIG_MAIN_STACK_SIZE=2048 From 1c42b4485d7383db2fa34cf4a59c8839f9f47f6d Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Thu, 27 Jun 2024 09:23:43 +0200 Subject: [PATCH 057/187] maintainers: remove gopiotr from twister collaborators Piotr no longer works in Nordic and was not active in Zephyr since December 2023. Signed-off-by: Maciej Perkowski --- MAINTAINERS.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 7742a7ae0046b..a4065595b6754 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3044,7 +3044,6 @@ Twister: collaborators: - PerMac - hakehuang - - gopiotr - golowanow - gchwier - LukaszMrugala From 80190af7652e4484303b083004fb5e8931aefd33 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 26 Jun 2024 11:14:51 +0100 Subject: [PATCH 058/187] samples: Use DEFAULT_IMAGE for sysbuild Uses the variable for the default image when adding sysbuild dependencies so that they can be copied out-of-tree and still work Signed-off-by: Jamie McCrae --- samples/drivers/ipm/ipm_mcux/sysbuild.cmake | 4 ++-- samples/subsys/ipc/openamp/sysbuild.cmake | 4 ++-- samples/subsys/ipc/rpmsg_service/sysbuild.cmake | 2 +- samples/sysbuild/hello_world/sysbuild.cmake | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/samples/drivers/ipm/ipm_mcux/sysbuild.cmake b/samples/drivers/ipm/ipm_mcux/sysbuild.cmake index 6ca2faf7d3481..ead989529b3cf 100644 --- a/samples/drivers/ipm/ipm_mcux/sysbuild.cmake +++ b/samples/drivers/ipm/ipm_mcux/sysbuild.cmake @@ -12,8 +12,8 @@ ExternalZephyrProject_Add( # Add dependencies so that the remote sample will be built first # This is required because some primary cores need information from the # remote core's build, such as the output image's LMA -add_dependencies(ipm_mcux ipm_mcux_remote) -sysbuild_add_dependencies(CONFIGURE ipm_mcux ipm_mcux_remote) +add_dependencies(${DEFAULT_IMAGE} ipm_mcux_remote) +sysbuild_add_dependencies(CONFIGURE ${DEFAULT_IMAGE} ipm_mcux_remote) if(SB_CONFIG_BOOTLOADER_MCUBOOT) # Make sure MCUboot is flashed first diff --git a/samples/subsys/ipc/openamp/sysbuild.cmake b/samples/subsys/ipc/openamp/sysbuild.cmake index 7278a1af4d46e..467b493a769be 100644 --- a/samples/subsys/ipc/openamp/sysbuild.cmake +++ b/samples/subsys/ipc/openamp/sysbuild.cmake @@ -12,8 +12,8 @@ ExternalZephyrProject_Add( # Add dependencies so that the remote sample will be built first # This is required because some primary cores need information from the # remote core's build, such as the output image's LMA -add_dependencies(openamp openamp_remote) -sysbuild_add_dependencies(CONFIGURE openamp openamp_remote) +add_dependencies(${DEFAULT_IMAGE} openamp_remote) +sysbuild_add_dependencies(CONFIGURE ${DEFAULT_IMAGE} openamp_remote) if(SB_CONFIG_BOOTLOADER_MCUBOOT) # Make sure MCUboot is flashed first diff --git a/samples/subsys/ipc/rpmsg_service/sysbuild.cmake b/samples/subsys/ipc/rpmsg_service/sysbuild.cmake index 08af67aeb85e0..6cccae9bef976 100644 --- a/samples/subsys/ipc/rpmsg_service/sysbuild.cmake +++ b/samples/subsys/ipc/rpmsg_service/sysbuild.cmake @@ -12,4 +12,4 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_RPMSG_REMOTE_BOARD} ) -add_dependencies(rpmsg_service rpmsg_service_remote) +add_dependencies(${DEFAULT_IMAGE} rpmsg_service_remote) diff --git a/samples/sysbuild/hello_world/sysbuild.cmake b/samples/sysbuild/hello_world/sysbuild.cmake index b59062d881f17..c7c2615c665ac 100644 --- a/samples/sysbuild/hello_world/sysbuild.cmake +++ b/samples/sysbuild/hello_world/sysbuild.cmake @@ -11,5 +11,5 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_REMOTE_BOARD} ) -add_dependencies(hello_world remote) -sysbuild_add_dependencies(FLASH hello_world remote) +add_dependencies(${DEFAULT_IMAGE} remote) +sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} remote) From 283cdbb903d080ae2b5e10d699513ff582e80984 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 27 Jun 2024 09:14:20 +0000 Subject: [PATCH 059/187] tests: drivers: can: api: restore default bitrates Restore the default CAN bitrates after having tested setting bitrate and timing. This ensures the arbitration phase bitrate is proportional to the data phase bitrate, allowing CAN FD transmission tests to complete. Fixes: #73723 Signed-off-by: Henrik Brix Andersen --- tests/drivers/can/api/src/canfd.c | 6 ++++++ tests/drivers/can/api/src/classic.c | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/drivers/can/api/src/canfd.c b/tests/drivers/can/api/src/canfd.c index 6941c42e775b7..80703655d1fb9 100644 --- a/tests/drivers/can/api/src/canfd.c +++ b/tests/drivers/can/api/src/canfd.c @@ -388,6 +388,9 @@ ZTEST_USER(canfd, test_set_timing_data_min) err = can_set_timing_data(can_dev, can_get_timing_data_min(can_dev)); zassert_equal(err, 0, "failed to set minimum timing data parameters (err %d)", err); + err = can_set_bitrate_data(can_dev, CONFIG_CAN_DEFAULT_BITRATE_DATA); + zassert_equal(err, 0, "failed to restore default data bitrate"); + err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); } @@ -435,6 +438,9 @@ ZTEST_USER(canfd, test_set_timing_data_max) err = can_set_timing_data(can_dev, can_get_timing_data_max(can_dev)); zassert_equal(err, 0, "failed to set maximum timing data parameters (err %d)", err); + err = can_set_bitrate_data(can_dev, CONFIG_CAN_DEFAULT_BITRATE_DATA); + zassert_equal(err, 0, "failed to restore default data bitrate"); + err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); } diff --git a/tests/drivers/can/api/src/classic.c b/tests/drivers/can/api/src/classic.c index 077f547cad102..b762137f8cd27 100644 --- a/tests/drivers/can/api/src/classic.c +++ b/tests/drivers/can/api/src/classic.c @@ -529,6 +529,9 @@ ZTEST_USER(can_classic, test_set_bitrate) err = can_set_bitrate(can_dev, TEST_BITRATE_1); zassert_equal(err, 0, "failed to set bitrate"); + err = can_set_bitrate(can_dev, CONFIG_CAN_DEFAULT_BITRATE); + zassert_equal(err, 0, "failed to restore default bitrate"); + err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); } @@ -546,6 +549,9 @@ ZTEST_USER(can_classic, test_set_timing_min) err = can_set_timing(can_dev, can_get_timing_min(can_dev)); zassert_equal(err, 0, "failed to set minimum timing parameters (err %d)", err); + err = can_set_bitrate(can_dev, CONFIG_CAN_DEFAULT_BITRATE); + zassert_equal(err, 0, "failed to restore default bitrate"); + err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); } @@ -563,6 +569,9 @@ ZTEST_USER(can_classic, test_set_timing_max) err = can_set_timing(can_dev, can_get_timing_max(can_dev)); zassert_equal(err, 0, "failed to set maximum timing parameters (err %d)", err); + err = can_set_bitrate(can_dev, CONFIG_CAN_DEFAULT_BITRATE); + zassert_equal(err, 0, "failed to restore default bitrate"); + err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); } @@ -1180,10 +1189,13 @@ ZTEST_USER(can_classic, test_filters_preserved_through_bitrate_change) zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped"); err = can_set_bitrate(can_dev, TEST_BITRATE_2); - zassert_equal(err, 0, "failed to set bitrate"); + zassert_equal(err, 0, "failed to set bitrate 2"); err = can_set_bitrate(can_dev, TEST_BITRATE_1); - zassert_equal(err, 0, "failed to set bitrate"); + zassert_equal(err, 0, "failed to set bitrate 1"); + + err = can_set_bitrate(can_dev, CONFIG_CAN_DEFAULT_BITRATE); + zassert_equal(err, 0, "failed to restore default bitrate"); err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); From 7d93c8060c3af70329f076a3053cbd128fbe1e3b Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Jun 2024 14:42:15 +0200 Subject: [PATCH 060/187] drivers: udc_kinetis: add missing return statement Add the missing return statement to the branch where no slabs are available. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_kinetis.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/udc/udc_kinetis.c b/drivers/usb/udc/udc_kinetis.c index 38dd1db2d0406..b424ce0372487 100644 --- a/drivers/usb/udc/udc_kinetis.c +++ b/drivers/usb/udc/udc_kinetis.c @@ -448,6 +448,8 @@ static void usbfsotg_event_submit(const struct device *dev, ret = k_mem_slab_alloc(&usbfsotg_ee_slab, (void **)&ev, K_NO_WAIT); if (ret) { udc_submit_event(dev, UDC_EVT_ERROR, ret); + LOG_ERR("Failed to allocate slab"); + return; } ev->dev = dev; From b3f09f3a6f905bcd6e620c8002f7e7ee3eadec5d Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Jun 2024 15:38:04 +0200 Subject: [PATCH 061/187] drivers: udc_stm32: disable control endpoints in udc_disable() Disable control endpoints in udc_disable() implementation. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_stm32.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 157902a121640..8eb35ccc85f45 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -542,6 +542,16 @@ static int udc_stm32_disable(const struct device *dev) irq_disable(DT_INST_IRQN(0)); + if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) { + LOG_ERR("Failed to disable control endpoint"); + return -EIO; + } + + if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) { + LOG_ERR("Failed to disable control endpoint"); + return -EIO; + } + status = HAL_PCD_Stop(&priv->pcd); if (status != HAL_OK) { LOG_ERR("PCD_Stop failed, %d", (int)status); From 514dd3a883fff96ecf8280dbb48bf100817af84a Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Jun 2024 15:15:02 +0200 Subject: [PATCH 062/187] tests: drivers: udc: updates to pass testing on supported platforms Do not halt control endpoint, control endpoint may not be enabled when there no host is connected. Yield after buffer is queued to allow the driver to work. Tweak pool size and number of buffers to pass the test with high-speed drivers. Signed-off-by: Johann Fischer --- tests/drivers/udc/prj.conf | 4 ++-- tests/drivers/udc/src/main.c | 11 +++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/drivers/udc/prj.conf b/tests/drivers/udc/prj.conf index e57264e1a24d4..380d5e74b9963 100644 --- a/tests/drivers/udc/prj.conf +++ b/tests/drivers/udc/prj.conf @@ -5,6 +5,6 @@ CONFIG_LOG=y CONFIG_ZTEST=y CONFIG_UDC_DRIVER=y -CONFIG_UDC_BUF_COUNT=32 -CONFIG_UDC_BUF_POOL_SIZE=8192 +CONFIG_UDC_BUF_COUNT=16 +CONFIG_UDC_BUF_POOL_SIZE=16384 CONFIG_UDC_DRIVER_LOG_LEVEL_INF=y diff --git a/tests/drivers/udc/src/main.c b/tests/drivers/udc/src/main.c index 24e1eb4d1f2a5..97abbbd744800 100644 --- a/tests/drivers/udc/src/main.c +++ b/tests/drivers/udc/src/main.c @@ -212,11 +212,10 @@ static void test_udc_ep_halt(const struct device *dev, struct usb_ep_descriptor *ed) { /* Possible return values 0, -ENODEV, -ENOTSUP, -EPERM. */ - int err1, err2, err3; + int err1, err2; err1 = udc_ep_set_halt(dev, ed->bEndpointAddress); err2 = udc_ep_set_halt(dev, FALSE_EP_ADDR); - err3 = udc_ep_set_halt(dev, USB_CONTROL_EP_OUT); if (udc_is_enabled(dev)) { if (ed->bmAttributes == USB_EP_TYPE_ISO) { @@ -226,16 +225,13 @@ static void test_udc_ep_halt(const struct device *dev, } zassert_equal(err2, -ENODEV, "Not failed to set halt"); - zassert_equal(err3, 0, "Failed to set halt"); } else { zassert_equal(err1, -EPERM, "Not failed to set halt"); zassert_equal(err2, -EPERM, "Not failed to set halt"); - zassert_equal(err3, -EPERM, "Not failed to set halt"); } err1 = udc_ep_clear_halt(dev, ed->bEndpointAddress); err2 = udc_ep_clear_halt(dev, FALSE_EP_ADDR); - err3 = udc_ep_clear_halt(dev, USB_CONTROL_EP_OUT); if (udc_is_enabled(dev)) { if (ed->bmAttributes == USB_EP_TYPE_ISO) { @@ -245,11 +241,9 @@ static void test_udc_ep_halt(const struct device *dev, } zassert_equal(err2, -ENODEV, "Not failed to clear halt"); - zassert_equal(err3, 0, "Failed to clear halt"); } else { zassert_equal(err1, -EPERM, "Not failed to clear halt"); zassert_equal(err2, -EPERM, "Not failed to clear halt"); - zassert_equal(err3, -EPERM, "Not failed to clear halt"); } } @@ -332,7 +326,7 @@ static void test_udc_ep_api(const struct device *dev, zassert_ok(err, "Failed to enable endpoint"); /* It needs a little reserve for memory management overhead. */ - for (int n = 0; n < (CONFIG_UDC_BUF_COUNT - 2); n++) { + for (int n = 0; n < (CONFIG_UDC_BUF_COUNT - 4); n++) { buf = udc_ep_buf_alloc(dev, ed->bEndpointAddress, ed->wMaxPacketSize); zassert_not_null(buf, @@ -342,6 +336,7 @@ static void test_udc_ep_api(const struct device *dev, udc_ep_buf_set_zlp(buf); err = udc_ep_enqueue(dev, buf); zassert_ok(err, "Failed to queue request"); + k_yield(); } err = udc_ep_disable(dev, ed->bEndpointAddress); From a22e7c80ff10aac67af82a55cccd3d8a1792a5be Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Jun 2024 15:28:54 +0200 Subject: [PATCH 063/187] tests: drivers: udc: add build_only test case nRF54H20 USB device controller cannot be enabled without VBUS, but the device should not be connected to the host during testing. Add it to build_only section. Signed-off-by: Johann Fischer --- tests/drivers/udc/testcase.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/drivers/udc/testcase.yaml b/tests/drivers/udc/testcase.yaml index 9f71f11907b14..9427a1a97c971 100644 --- a/tests/drivers/udc/testcase.yaml +++ b/tests/drivers/udc/testcase.yaml @@ -7,6 +7,15 @@ tests: depends_on: usbd integration_platforms: - nrf52840dk/nrf52840 + platform_exclude: + - nrf54h20dk/nrf54h20/cpuapp + drivers.usb.udc.build_only: + build_only: true + # Platform excluded above, only to build, with justification. + platform_allow: + # The controller cannot be enabled without VBUS, but the device should + # not be connected to the host during testing. + - nrf54h20dk/nrf54h20/cpuapp drivers.usb.udc.skeleton: extra_args: - EXTRA_DTC_OVERLAY_FILE="udc_skeleton.overlay" From c0006c78590d5d5171eed36a1405732f7ab45f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 28 Jun 2024 17:11:30 +0200 Subject: [PATCH 064/187] logging: Do not store module name pointer when strings are stripped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When logging strings are stripped then addresses to log module names are invalid. Do not store that address in the const data structure associated with the logging module to avoid someone accessing it. Store null instead. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/zephyr/logging/log.h b/include/zephyr/logging/log.h index 7edfca9ad8fab..fbbefd6486676 100644 --- a/include/zephyr/logging/log.h +++ b/include/zephyr/logging/log.h @@ -328,7 +328,8 @@ void z_log_vprintk(const char *fmt, va_list ap); log_source_const_data, \ Z_LOG_ITEM_CONST_DATA(_name)) = \ { \ - .name = COND_CODE_1(CONFIG_LOG_FMT_SECTION, \ + .name = IS_ENABLED(LOG_FMT_SECTION_STRIP) ? NULL : \ + COND_CODE_1(CONFIG_LOG_FMT_SECTION, \ (UTIL_CAT(_name, _str)), (STRINGIFY(_name))), \ .level = (_level) \ } From ec36065ff40f7a6bcd363fff8ffacb5dc3a36c21 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 5 Jun 2024 15:18:59 +0200 Subject: [PATCH 065/187] tests: drivers: rtc: rtc_api: add config for alarm time mask RTCs support a variety of combinations of alarm time fields, set by the alarm time mask. Until now, alarm tests have selected only the minute and hour fields, as these are always supported, but some RTCs require setting every supported field when setting the alarm time, while other RTCs don't support setting every field. To support all RTCs in the test suite, a configuration has been added which makes the alarm time mask configurable. Boards can now define the specific alarm time mask they want to test within their boards .conf files. Additionally, the alarm tests have been refactored to not depend on the time.h library to determine the struct rtc_time times to set as these are constant, so they are now provided as const structs instead. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/rtc/rtc_api/Kconfig | 16 ++ tests/drivers/rtc/rtc_api/src/test_alarm.c | 162 +++++++++++------- .../rtc/rtc_api/src/test_alarm_callback.c | 81 ++++----- 3 files changed, 148 insertions(+), 111 deletions(-) create mode 100644 tests/drivers/rtc/rtc_api/Kconfig diff --git a/tests/drivers/rtc/rtc_api/Kconfig b/tests/drivers/rtc/rtc_api/Kconfig new file mode 100644 index 0000000000000..4881a68005094 --- /dev/null +++ b/tests/drivers/rtc/rtc_api/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +if RTC_ALARM + +config TEST_RTC_ALARM_TIME_MASK + int "Alarm fields to set" + default 6 + range 1 511 + help + Set the RTC_ALARM_TIME_MASK_ bitmask to use when setting + RTC alarms during testing. + +endif # RTC_ALARM diff --git a/tests/drivers/rtc/rtc_api/src/test_alarm.c b/tests/drivers/rtc/rtc_api/src/test_alarm.c index 5f81d05c87b42..4970ddf7b1720 100644 --- a/tests/drivers/rtc/rtc_api/src/test_alarm.c +++ b/tests/drivers/rtc/rtc_api/src/test_alarm.c @@ -9,29 +9,67 @@ #include #include #include -#include #include -#include - -/* Fri Jan 01 2021 13:29:50 GMT+0000 */ -#define RTC_TEST_ALARM_SET_TIME (1609507790) #define RTC_TEST_ALARM_TEST_NOT_PENDING_DELAY (3) #define RTC_TEST_ALARM_TEST_PENDING_DELAY (10) -#define RTC_TEST_ALARM_TIME_MINUTE (30) -#define RTC_TEST_ALARM_TIME_HOUR (13) static const struct device *rtc = DEVICE_DT_GET(DT_ALIAS(rtc)); static const uint16_t alarms_count = DT_PROP(DT_ALIAS(rtc), alarms_count); +static const uint16_t test_alarm_time_mask_set = CONFIG_TEST_RTC_ALARM_TIME_MASK; + +/* Fri Jan 01 2021 13:29:50 GMT+0000 */ +static const struct rtc_time test_rtc_time_set = { + .tm_sec = 50, + .tm_min = 29, + .tm_hour = 13, + .tm_mday = 1, + .tm_mon = 0, + .tm_year = 121, + .tm_wday = 5, + .tm_yday = 1, + .tm_isdst = -1, + .tm_nsec = 0, +}; + +/* Fri Jan 01 2021 13:30:00 GMT+0000 */ +static const struct rtc_time test_alarm_time_set = { + .tm_sec = 0, + .tm_min = 30, + .tm_hour = 13, + .tm_mday = 1, + .tm_mon = 0, + .tm_year = 121, + .tm_wday = 5, + .tm_yday = 1, + .tm_isdst = -1, + .tm_nsec = 0, +}; + +static const struct rtc_time test_alarm_time_invalid = { + .tm_sec = 70, + .tm_min = 70, + .tm_hour = 25, + .tm_mday = 35, + .tm_mon = 15, + .tm_year = 8000, + .tm_wday = 8, + .tm_yday = 370, + .tm_nsec = INT32_MAX, +}; + +static const uint16_t test_alarm_time_masks[] = { + RTC_ALARM_TIME_MASK_SECOND, RTC_ALARM_TIME_MASK_MINUTE, + RTC_ALARM_TIME_MASK_HOUR, RTC_ALARM_TIME_MASK_MONTHDAY, + RTC_ALARM_TIME_MASK_MONTH, RTC_ALARM_TIME_MASK_YEAR, + RTC_ALARM_TIME_MASK_WEEKDAY, RTC_ALARM_TIME_MASK_YEARDAY, + RTC_ALARM_TIME_MASK_NSEC +}; ZTEST(rtc_api, test_alarm) { int ret; - time_t timer_set; - struct rtc_time time_set; - struct rtc_time alarm_time_set; uint16_t alarm_time_mask_supported; - uint16_t alarm_time_mask_set; struct rtc_time alarm_time_get; uint16_t alarm_time_mask_get; @@ -53,29 +91,13 @@ ZTEST(rtc_api, test_alarm) /* Every supported alarm field should reject invalid values. */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_get_supported_fields(rtc, i, &alarm_time_mask_supported); - zassert_ok(ret, "Failed to get supported alarm %d fields", i); - alarm_time_set = (struct rtc_time) { - .tm_sec = 70, - .tm_min = 70, - .tm_hour = 25, - .tm_mday = 35, - .tm_mon = 15, - .tm_year = 8000, - .tm_wday = 8, - .tm_yday = 370, - .tm_nsec = INT32_MAX, - }; - uint16_t masks[] = {RTC_ALARM_TIME_MASK_SECOND, RTC_ALARM_TIME_MASK_MINUTE, - RTC_ALARM_TIME_MASK_HOUR, RTC_ALARM_TIME_MASK_MONTHDAY, - RTC_ALARM_TIME_MASK_MONTH, RTC_ALARM_TIME_MASK_YEAR, - RTC_ALARM_TIME_MASK_WEEKDAY, RTC_ALARM_TIME_MASK_YEARDAY, - RTC_ALARM_TIME_MASK_NSEC}; - ARRAY_FOR_EACH(masks, j) + ARRAY_FOR_EACH(test_alarm_time_masks, j) { - if (masks[j] & alarm_time_mask_supported) { - ret = rtc_alarm_set_time(rtc, i, masks[j], &alarm_time_set); + if (test_alarm_time_masks[j] & alarm_time_mask_supported) { + ret = rtc_alarm_set_time(rtc, i, test_alarm_time_masks[j], + &test_alarm_time_invalid); zassert_equal( -EINVAL, ret, "%s: RTC should reject invalid alarm %d time in field %zu.", @@ -87,61 +109,79 @@ ZTEST(rtc_api, test_alarm) /* Validate alarms supported fields */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_get_supported_fields(rtc, i, &alarm_time_mask_supported); - zassert_ok(ret, "Failed to get supported alarm %d fields", i); - /* Skip test if alarm does not support the minute and hour fields */ - if (((RTC_ALARM_TIME_MASK_MINUTE & alarm_time_mask_supported) == 0) || - ((RTC_TEST_ALARM_TIME_HOUR & alarm_time_mask_supported) == 0)) { - ztest_test_skip(); - } + ret = (test_alarm_time_mask_set & (~alarm_time_mask_supported)) ? -EINVAL : 0; + zassert_ok(ret, "Configured alarm time fields to set are not supported"); } - /* Set alarm time */ - alarm_time_set.tm_min = RTC_TEST_ALARM_TIME_MINUTE; - alarm_time_set.tm_hour = RTC_TEST_ALARM_TIME_HOUR; - alarm_time_mask_set = (RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR); - for (uint16_t i = 0; i < alarms_count; i++) { - ret = rtc_alarm_set_time(rtc, i, alarm_time_mask_set, &alarm_time_set); - + ret = rtc_alarm_set_time(rtc, i, test_alarm_time_mask_set, &test_alarm_time_set); zassert_ok(ret, "Failed to set alarm %d time", i); } /* Validate alarm time */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_get_time(rtc, i, &alarm_time_mask_get, &alarm_time_get); - zassert_ok(ret, "Failed to set alarm %d time", i); - zassert_equal(alarm_time_mask_get, alarm_time_mask_set, + zassert_equal(alarm_time_mask_get, test_alarm_time_mask_set, "Incorrect alarm %d time mask", i); - zassert_equal(alarm_time_get.tm_min, alarm_time_set.tm_min, - "Incorrect alarm %d time minute field", i); + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_SECOND) { + zassert_equal(alarm_time_get.tm_sec, test_alarm_time_set.tm_sec, + "Incorrect alarm %d tm_sec field", i); + } - zassert_equal(alarm_time_get.tm_hour, alarm_time_set.tm_hour, - "Incorrect alarm %d time hour field", i); - } + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_MINUTE) { + zassert_equal(alarm_time_get.tm_min, test_alarm_time_set.tm_min, + "Incorrect alarm %d tm_min field", i); + } - /* Initialize RTC time to set */ - timer_set = RTC_TEST_ALARM_SET_TIME; + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_HOUR) { + zassert_equal(alarm_time_get.tm_hour, test_alarm_time_set.tm_hour, + "Incorrect alarm %d tm_hour field", i); + } - gmtime_r(&timer_set, (struct tm *)(&time_set)); + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_MONTHDAY) { + zassert_equal(alarm_time_get.tm_mday, test_alarm_time_set.tm_mday, + "Incorrect alarm %d tm_mday field", i); + } - time_set.tm_isdst = -1; - time_set.tm_nsec = 0; + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_MONTH) { + zassert_equal(alarm_time_get.tm_mon, test_alarm_time_set.tm_mon, + "Incorrect alarm %d tm_mon field", i); + } + + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_YEAR) { + zassert_equal(alarm_time_get.tm_year, test_alarm_time_set.tm_year, + "Incorrect alarm %d tm_year field", i); + } + + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_WEEKDAY) { + zassert_equal(alarm_time_get.tm_wday, test_alarm_time_set.tm_wday, + "Incorrect alarm %d tm_wday field", i); + } + + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_YEARDAY) { + zassert_equal(alarm_time_get.tm_yday, test_alarm_time_set.tm_yday, + "Incorrect alarm %d tm_yday field", i); + } + + if (test_alarm_time_mask_set & RTC_ALARM_TIME_MASK_NSEC) { + zassert_equal(alarm_time_get.tm_nsec, test_alarm_time_set.tm_nsec, + "Incorrect alarm %d tm_nsec field", i); + } + } for (uint8_t k = 0; k < 2; k++) { /* Set RTC time */ - ret = rtc_set_time(rtc, &time_set); - + ret = rtc_set_time(rtc, &test_rtc_time_set); zassert_ok(ret, "Failed to set time"); /* Clear alarm pending status */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_is_pending(rtc, i); - zassert_true(ret > -1, "Failed to clear alarm %d pending status", i); } @@ -151,7 +191,6 @@ ZTEST(rtc_api, test_alarm) /* Validate alarm are not pending */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_is_pending(rtc, i); - zassert_ok(ret, "Alarm %d should not be pending", i); } @@ -161,7 +200,6 @@ ZTEST(rtc_api, test_alarm) /* Validate alarm is pending */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_is_pending(rtc, i); - zassert_equal(ret, 1, "Alarm %d should be pending", i); } } @@ -169,11 +207,9 @@ ZTEST(rtc_api, test_alarm) /* Disable and clear alarms */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_set_time(rtc, i, 0, NULL); - zassert_ok(ret, "Failed to disable alarm %d", i); ret = rtc_alarm_is_pending(rtc, i); - zassert_true(ret > -1, "Failed to clear alarm %d pending state", i); } } diff --git a/tests/drivers/rtc/rtc_api/src/test_alarm_callback.c b/tests/drivers/rtc/rtc_api/src/test_alarm_callback.c index f09cc351b7b43..106dfe236669c 100644 --- a/tests/drivers/rtc/rtc_api/src/test_alarm_callback.c +++ b/tests/drivers/rtc/rtc_api/src/test_alarm_callback.c @@ -9,16 +9,9 @@ #include #include #include -#include -#include - -/* Fri Jan 01 2021 13:29:50 GMT+0000 */ -#define RTC_TEST_ALARM_SET_TIME (1609507790) #define RTC_TEST_ALARM_TEST_NOT_CALLED_DELAY (3) #define RTC_TEST_ALARM_TEST_CALLED_DELAY (10) -#define RTC_TEST_ALARM_TIME_MINUTE (30) -#define RTC_TEST_ALARM_TIME_HOUR (13) static const struct device *rtc = DEVICE_DT_GET(DT_ALIAS(rtc)); static const uint16_t alarms_count = DT_PROP(DT_ALIAS(rtc), alarms_count); @@ -27,6 +20,36 @@ static uint32_t callback_user_data_even = 0x1234; static atomic_t callback_called_mask_odd; static atomic_t callback_called_mask_even; +static const uint16_t test_alarm_time_mask_set = CONFIG_TEST_RTC_ALARM_TIME_MASK; + +/* Fri Jan 01 2021 13:29:50 GMT+0000 */ +static const struct rtc_time test_rtc_time_set = { + .tm_sec = 50, + .tm_min = 29, + .tm_hour = 13, + .tm_mday = 1, + .tm_mon = 0, + .tm_year = 121, + .tm_wday = 5, + .tm_yday = 1, + .tm_isdst = -1, + .tm_nsec = 0, +}; + +/* Fri Jan 01 2021 13:30:00 GMT+0000 */ +static const struct rtc_time test_alarm_time_set = { + .tm_sec = 0, + .tm_min = 30, + .tm_hour = 13, + .tm_mday = 1, + .tm_mon = 0, + .tm_year = 121, + .tm_wday = 5, + .tm_yday = 1, + .tm_isdst = -1, + .tm_nsec = 0, +}; + static void test_rtc_alarm_callback_handler_odd(const struct device *dev, uint16_t id, void *user_data) { @@ -42,11 +65,6 @@ static void test_rtc_alarm_callback_handler_even(const struct device *dev, uint1 ZTEST(rtc_api, test_alarm_callback) { int ret; - time_t timer_set; - struct rtc_time time_set; - struct rtc_time alarm_time_set; - uint16_t alarm_time_mask_supported; - uint16_t alarm_time_mask_set; atomic_val_t callback_called_mask_status_odd; atomic_val_t callback_called_mask_status_even; bool callback_called_status; @@ -63,47 +81,18 @@ ZTEST(rtc_api, test_alarm_callback) } } - /* Validate alarms supported fields */ for (uint16_t i = 0; i < alarms_count; i++) { - ret = rtc_alarm_get_supported_fields(rtc, i, &alarm_time_mask_supported); - - zassert_ok(ret, "Failed to get supported alarm %d fields", i); - - /* Skip test if alarm does not support the minute and hour fields */ - if (((RTC_ALARM_TIME_MASK_MINUTE & alarm_time_mask_supported) == 0) || - ((RTC_TEST_ALARM_TIME_HOUR & alarm_time_mask_supported) == 0)) { - ztest_test_skip(); - } - } - - /* Set alarm time */ - alarm_time_set.tm_min = RTC_TEST_ALARM_TIME_MINUTE; - alarm_time_set.tm_hour = RTC_TEST_ALARM_TIME_HOUR; - alarm_time_mask_set = (RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR); - - for (uint16_t i = 0; i < alarms_count; i++) { - ret = rtc_alarm_set_time(rtc, i, alarm_time_mask_set, &alarm_time_set); - + ret = rtc_alarm_set_time(rtc, i, test_alarm_time_mask_set, &test_alarm_time_set); zassert_ok(ret, "Failed to set alarm %d time", i); } - /* Initialize RTC time to set */ - timer_set = RTC_TEST_ALARM_SET_TIME; - - gmtime_r(&timer_set, (struct tm *)(&time_set)); - - time_set.tm_isdst = -1; - time_set.tm_nsec = 0; - /* Set RTC time */ - ret = rtc_set_time(rtc, &time_set); - + ret = rtc_set_time(rtc, &test_rtc_time_set); zassert_ok(ret, "Failed to set time"); /* Clear alarm pending status */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_is_pending(rtc, i); - zassert_true(ret > -1, "Failed to clear alarm %d pending status", i); } @@ -153,23 +142,19 @@ ZTEST(rtc_api, test_alarm_callback) } /* Reset RTC time */ - ret = rtc_set_time(rtc, &time_set); - + ret = rtc_set_time(rtc, &test_rtc_time_set); zassert_ok(ret, "Failed to set time"); } /* Disable and clear alarms */ for (uint16_t i = 0; i < alarms_count; i++) { ret = rtc_alarm_set_callback(rtc, i, NULL, NULL); - zassert_ok(ret, "Failed to disable alarm %d callback", i); ret = rtc_alarm_set_time(rtc, i, 0, NULL); - zassert_ok(ret, "Failed to disable alarm %d", i); ret = rtc_alarm_is_pending(rtc, i); - zassert_true(ret > -1, "Failed to clear alarm %d pending state", i); } } From 9bcc82e7af7a42730698f249428893bcf3930d0f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 27 Jun 2024 14:42:00 +0300 Subject: [PATCH 066/187] net: wifi: shell: Avoid using sscanf The sscanf() is not available for minimal libc so it cannot be used. Use the net_bytes_from_str() that is provided for this purposes. Fixes #75029 Signed-off-by: Jukka Rissanen --- subsys/net/l2/wifi/wifi_shell.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index d450a9d76fe37..82b958c263840 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -567,10 +567,11 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv params->mfp = atoi(optarg); break; case 'm': - sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - ¶ms->bssid[0], ¶ms->bssid[1], - ¶ms->bssid[2], ¶ms->bssid[3], - ¶ms->bssid[4], ¶ms->bssid[5]); + if (net_bytes_from_str(params->bssid, sizeof(params->bssid), + optarg) < 0) { + PR_WARNING("Invalid MAC address\n"); + return -EINVAL; + } break; case 't': if (iface_mode == WIFI_MODE_INFRA) { From d3ea4f812dc9d8dbab19cf0193af412acb404499 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Thu, 27 Jun 2024 09:44:22 -0300 Subject: [PATCH 067/187] soc: esp32xx: always use section prologue with alignment ESP32 requires proper alignment between sections. There are some scenarios, as reported in #74533, that the section can get shifted, causing runtime failure. Making sure SECTION_PROLOGUE is used with ALIGN_WITH_INPUT will guarantee its consistency. Fixes #74533 Signed-off-by: Sylvio Alves --- soc/espressif/esp32/default.ld | 4 ++++ soc/espressif/esp32c3/default.ld | 4 ++++ soc/espressif/esp32c6/default.ld | 4 ++++ soc/espressif/esp32s2/default.ld | 4 ++++ soc/espressif/esp32s3/default.ld | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/soc/espressif/esp32/default.ld b/soc/espressif/esp32/default.ld index 919e8a9ef0f60..dec0309cb2c37 100644 --- a/soc/espressif/esp32/default.ld +++ b/soc/espressif/esp32/default.ld @@ -47,6 +47,10 @@ user_dram_2_seg_len = SRAM1_USER_SIZE; #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT diff --git a/soc/espressif/esp32c3/default.ld b/soc/espressif/esp32c3/default.ld index cd7308c15935c..62b161372248d 100644 --- a/soc/espressif/esp32c3/default.ld +++ b/soc/espressif/esp32c3/default.ld @@ -41,6 +41,10 @@ user_dram_seg_len = user_idram_size; #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + /* Global symbols required for espressif hal build */ MEMORY { diff --git a/soc/espressif/esp32c6/default.ld b/soc/espressif/esp32c6/default.ld index a1ec65aa1df7c..9d0b5f2ac21e8 100644 --- a/soc/espressif/esp32c6/default.ld +++ b/soc/espressif/esp32c6/default.ld @@ -34,6 +34,10 @@ user_sram_size = (user_sram_end - user_sram_org); #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > CACHED_REGION AT > lregion +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + /* TODO: add RTC support */ #define RESERVE_RTC_MEM 0 diff --git a/soc/espressif/esp32s2/default.ld b/soc/espressif/esp32s2/default.ld index 8621e65d2278e..5eadcd96803ea 100644 --- a/soc/espressif/esp32s2/default.ld +++ b/soc/espressif/esp32s2/default.ld @@ -42,6 +42,10 @@ user_dram_seg_len = user_idram_size; #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + #define RESERVE_RTC_MEM 0 MEMORY diff --git a/soc/espressif/esp32s3/default.ld b/soc/espressif/esp32s3/default.ld index ada1c12b93e3c..8f002c4b869cb 100644 --- a/soc/espressif/esp32s3/default.ld +++ b/soc/espressif/esp32s3/default.ld @@ -41,6 +41,10 @@ user_dram_seg_len = user_idram_size; #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT From 544886acc3fbba89585014aefb4801f06228486c Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Thu, 27 Jun 2024 14:45:27 -0700 Subject: [PATCH 068/187] lib/posix: Get uptime in ticks instead of cycles __z_clock_nanosleep function was getting current time in cycles, via k_cycle_get_32(), to perform its time calculations. However, when calling k_sleep() to actually sleep, times are measured in ticks. This causes a problem when there's a big skew between the uptime measured in cycles vs uptime measured in ticks: in some platforms, the system clock maybe up for a long time already when Zephyr starts counting ticks, for instance, while downloading an image via PXE. In this case, the calculations done inside __z_clock_nanosleep end up measuring a much bigger current time than expected, thus sleeping too much, basically all the time since system clock initialization. This patch fixes that by avoiding the cycle trip: stick to ticks, instead. They start counting from Zephyr initialization instead, which is the expected uptime. Fixes #69608 Signed-off-by: Ederson de Souza --- lib/posix/options/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/posix/options/clock.c b/lib/posix/options/clock.c index 9ef0375803a17..65cd207b10118 100644 --- a/lib/posix/options/clock.c +++ b/lib/posix/options/clock.c @@ -225,7 +225,7 @@ static int __z_clock_nanosleep(clockid_t clock_id, int flags, const struct times ns = rqtp->tv_sec * NSEC_PER_SEC + rqtp->tv_nsec; } - uptime_ns = k_cyc_to_ns_ceil64(k_cycle_get_32()); + uptime_ns = k_ticks_to_ns_ceil64(sys_clock_tick_get()); if (flags & TIMER_ABSTIME && clock_id == CLOCK_REALTIME) { key = k_spin_lock(&rt_clock_base_lock); From 2b26e25322f3494b1736b28bcb9fcd7d95453902 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Wed, 19 Jun 2024 16:52:34 +0200 Subject: [PATCH 069/187] twister: Add warning to the "-footprint-from-buildlog" flag The flag won't work with sysbuild since there is no way to reliably tell to a parser which data came from which image. fixes: #74092 Signed-off-by: Maciej Perkowski --- scripts/pylib/twister/twisterlib/environment.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 01b415ad820f1..b9c036f08f18a 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -413,7 +413,8 @@ def add_parse_arguments(parser = None): action = "store_true", help="Take ROM/RAM sections footprint summary values from the 'build.log' " "instead of 'objdump' results used otherwise." - "Requires --enable-size-report or one of the baseline comparison modes.") + "Requires --enable-size-report or one of the baseline comparison modes." + "Warning: the feature will not work correctly with sysbuild.") compare_group_option = footprint_group.add_mutually_exclusive_group() @@ -862,9 +863,13 @@ def parse_arguments(parser, args, options = None, on_init=True): sc.size_report() sys.exit(0) - if options.footprint_from_buildlog and not options.enable_size_report: - logger.error("--footprint-from-buildlog requires --enable-size-report") - sys.exit(1) + if options.footprint_from_buildlog: + logger.warning("WARNING: Using --footprint-from-buildlog will give inconsistent results " + "for configurations using sysbuild. It is recommended to not use this flag " + "when building configurations using sysbuild.") + if not options.enable_size_report: + logger.error("--footprint-from-buildlog requires --enable-size-report") + sys.exit(1) if len(options.extra_test_args) > 0: # extra_test_args is a list of CLI args that Twister did not recognize From 59d84e1643774532fdaa21f2ed3b2bc0b0c23b3d Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 24 Jun 2024 15:45:15 +0800 Subject: [PATCH 070/187] os: fdtable: include `zephyr/kernel.h` for `struct k_mutex` Was getting the following error: include/zephyr/sys/fdtable.h:150:38: warning: 'struct k_mutex' declared inside parameter list will not be visible outside of this definition or declaration 150 | struct k_mutex **lock); | ^~~~~~~ (#51667) tried to fix this by including `zephyr/sys/mutex.h`, but `struct k_mutex` is defined in `zephyr/kernel.h`, so include the latter instead. Signed-off-by: Yong Cong Sin --- include/zephyr/sys/fdtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index 871878eb53e09..37b25d57c75eb 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -11,7 +11,7 @@ /* FIXME: For native_posix ssize_t, off_t. */ #include -#include +#include #include /* File mode bits */ From 103a498400358b1b73cb6c216a50cd15ee439a53 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Thu, 27 Jun 2024 12:54:29 +0200 Subject: [PATCH 071/187] cmake: tf-m: create tfm_api dependency on tfm_s.hex Incremental builds for TF-M are not picked up by Zephyr linking stage. Code changes to tf-m repository results in a rebuild of TF-M and thus an updated tfm_s.hex (and other files). tfm_s.hex is merged together with the zephyr hex to form a final merged hex file for flashing. This is done as a post-build command, however such as step cannot take extra dependencies. The Zephyr target can have extra dependencies, however that will only ensure the dependency is brought up-to-date when Zephyr re-link, not re-linking Zephyr when the dependency changes. Therefore an object dependency is placed on the interface.c file for Zephyr TF-M interface implementation, which ensures the tfm_api library is brought up-to-date whenever TF-M rebuilds, and this update again ensures the Zephyr itself is re-linked whenever TF-M rebuilds. Signed-off-by: Torsten Rasmussen --- modules/trusted-firmware-m/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index b3d836490d618..4b91848639f4b 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -349,6 +349,13 @@ if (CONFIG_BUILD_WITH_TFM) interface/interface.c ) + # A dependency on tfm_s.hex for zephyr.elf will not cause a Zephyr re-link when + # tfm_s.hex is updated, as the hex is not a direct input on the executable. + # Instead we establish a source file dependency which ensures that tfm_api is + # updated when there are changes in tfm itself, this again will trigger an re-link + # of Zephyr.elf. + set_property(SOURCE interface/interface.c APPEND PROPERTY OBJECT_DEPENDS ${TFM_S_HEX_FILE}) + # Non-Secure interface to request system reboot if (CONFIG_TFM_PARTITION_PLATFORM AND NOT CONFIG_TFM_PARTITION_PLATFORM_CUSTOM_REBOOT) zephyr_library_sources(src/reboot.c) From 9a1813464178e5e5612ab4beedbebb131e44b1a9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 27 Jun 2024 10:20:29 +0300 Subject: [PATCH 072/187] samples: net: txtime: The option type should be int When setting boolean options using setsockopt(), the option type should be int as the size of the option type is checked and only int is accepted. Signed-off-by: Jukka Rissanen --- samples/net/sockets/txtime/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/net/sockets/txtime/src/main.c b/samples/net/sockets/txtime/src/main.c index 2bd41df40ac4e..f5f9df9647596 100644 --- a/samples/net/sockets/txtime/src/main.c +++ b/samples/net/sockets/txtime/src/main.c @@ -263,7 +263,7 @@ static int create_socket(struct net_if *iface, struct sockaddr *peer) { struct sockaddr local; socklen_t addrlen; - bool optval; + int optval; uint8_t priority; int sock; int ret; From 578bdc9e23d5e1e146f26b298654a11b11946cdd Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 27 Jun 2024 10:24:31 +0300 Subject: [PATCH 073/187] samples: net: txtime: Add support for native_sim board native_sim needs to enable PTP clock support Signed-off-by: Jukka Rissanen --- samples/net/sockets/txtime/boards/native_sim.conf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 samples/net/sockets/txtime/boards/native_sim.conf diff --git a/samples/net/sockets/txtime/boards/native_sim.conf b/samples/net/sockets/txtime/boards/native_sim.conf new file mode 100644 index 0000000000000..6e1628ae39113 --- /dev/null +++ b/samples/net/sockets/txtime/boards/native_sim.conf @@ -0,0 +1,2 @@ +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y +CONFIG_PTP=y From 609d2c84b48e53b65637d79ed29fc526349b4e04 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 27 Jun 2024 10:29:38 +0300 Subject: [PATCH 074/187] samples: net: txtime: Add e1000 overlay for qemu_x86 This allows user to run the sample in qemu_x86. Signed-off-by: Jukka Rissanen --- samples/net/sockets/txtime/overlay-e1000.conf | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 samples/net/sockets/txtime/overlay-e1000.conf diff --git a/samples/net/sockets/txtime/overlay-e1000.conf b/samples/net/sockets/txtime/overlay-e1000.conf new file mode 100644 index 0000000000000..d2880bd3587a3 --- /dev/null +++ b/samples/net/sockets/txtime/overlay-e1000.conf @@ -0,0 +1,6 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_QEMU_ETHERNET=y + +CONFIG_PCIE=y + +#CONFIG_ETHERNET_LOG_LEVEL_DBG=y From 03acf711ecb731955efffa73a95cdf451d8e006f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 27 Jun 2024 10:42:30 +0300 Subject: [PATCH 075/187] samples: net: txtime: Do not run qemu_x86 with twister The txtime can be run manually with qemu_x86 but it is enough to have native_sim compiled with twister. Signed-off-by: Jukka Rissanen --- samples/net/sockets/txtime/sample.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/net/sockets/txtime/sample.yaml b/samples/net/sockets/txtime/sample.yaml index 18613f4b87a3a..1627302ad5fa0 100644 --- a/samples/net/sockets/txtime/sample.yaml +++ b/samples/net/sockets/txtime/sample.yaml @@ -5,8 +5,6 @@ common: platform_allow: - native_sim - native_sim/native/64 - - qemu_x86 - - qemu_x86_64 integration_platforms: - native_sim sample: From 45c88239ac8aeddfa9ba6328bd3c2f505390c15b Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 27 Jun 2024 10:43:48 +0300 Subject: [PATCH 076/187] drivers: eth: e1000: Use double with PTP clock Instead of mixing floats and doubles, convert the code to use double so that we avoid float->double conversion warning from compiler. Signed-off-by: Jukka Rissanen --- drivers/ethernet/eth_e1000.c | 14 +++++++------- drivers/ethernet/eth_e1000_priv.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ethernet/eth_e1000.c b/drivers/ethernet/eth_e1000.c index 766ed79dec43e..31dd7e28b24cc 100644 --- a/drivers/ethernet/eth_e1000.c +++ b/drivers/ethernet/eth_e1000.c @@ -371,27 +371,27 @@ static int ptp_clock_e1000_rate_adjust(const struct device *dev, double ratio) float val; /* No change needed. */ - if (ratio == 1.0f) { + if (ratio == 1.0) { return 0; } ratio *= context->clk_ratio; /* Limit possible ratio. */ - if ((ratio > 1.0f + 1.0f/(2 * hw_inc)) || - (ratio < 1.0f - 1.0f/(2 * hw_inc))) { + if ((ratio > 1.0 + 1.0/(2.0 * hw_inc)) || + (ratio < 1.0 - 1.0/(2.0 * hw_inc))) { return -EINVAL; } /* Save new ratio. */ context->clk_ratio = ratio; - if (ratio < 1.0f) { + if (ratio < 1.0) { corr = hw_inc - 1; - val = 1.0f / (hw_inc * (1.0f - ratio)); - } else if (ratio > 1.0f) { + val = 1.0 / (hw_inc * (1.0 - ratio)); + } else if (ratio > 1.0) { corr = hw_inc + 1; - val = 1.0f / (hw_inc * (ratio - 1.0f)); + val = 1.0 / (hw_inc * (ratio - 1.0)); } else { val = 0; corr = hw_inc; diff --git a/drivers/ethernet/eth_e1000_priv.h b/drivers/ethernet/eth_e1000_priv.h index 2d0b6afa26d27..64b7497b917e8 100644 --- a/drivers/ethernet/eth_e1000_priv.h +++ b/drivers/ethernet/eth_e1000_priv.h @@ -92,7 +92,7 @@ struct e1000_dev { uint8_t rxb[NET_ETH_MTU]; #if defined(CONFIG_ETH_E1000_PTP_CLOCK) const struct device *ptp_clock; - float clk_ratio; + double clk_ratio; #endif }; From a7fff677ccce4b4aedd10060162aa6032ac2bcc1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 28 Jun 2024 12:27:44 +0200 Subject: [PATCH 077/187] release: Zephyr v3.7.0-rc2 Set the version to v3.7.0-rc2 Signed-off-by: Alberto Escolar Piedras --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6e31d4f8f8898..415da95a8064e 100644 --- a/VERSION +++ b/VERSION @@ -2,4 +2,4 @@ VERSION_MAJOR = 3 VERSION_MINOR = 7 PATCHLEVEL = 0 VERSION_TWEAK = 0 -EXTRAVERSION = rc1 +EXTRAVERSION = rc2 From ad3dfa3b4a48e488bf688608a790ba34f59fbbe4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 20 Jun 2024 21:54:28 -0700 Subject: [PATCH 078/187] bluetooth: host/classic: Fix possible buffer overflow Fix possible buffer overflow in rfcomm. Check the buffer len before read it. Signed-off-by: Flavio Ceolin --- subsys/bluetooth/host/classic/rfcomm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/bluetooth/host/classic/rfcomm.c b/subsys/bluetooth/host/classic/rfcomm.c index af67f2851b91d..f7a0c25c04406 100644 --- a/subsys/bluetooth/host/classic/rfcomm.c +++ b/subsys/bluetooth/host/classic/rfcomm.c @@ -1427,6 +1427,10 @@ static void rfcomm_handle_data(struct bt_rfcomm_session *session, } if (pf == BT_RFCOMM_PF_UIH_CREDIT) { + if (buf->len == 0) { + LOG_WRN("Data recvd is invalid"); + return; + } rfcomm_dlc_tx_give_credits(dlc, net_buf_pull_u8(buf)); } From 524ce6ff089a3717e12c05bbfb38cb2b3861f588 Mon Sep 17 00:00:00 2001 From: Andreas Klinger Date: Sun, 30 Jun 2024 13:01:38 +0200 Subject: [PATCH 079/187] drivers: gnss: gnss_u_blox_m10: fix compiler warning Fix warning on implicit declaration of function 'malloc' when compiling gnss_u_blox_m10.c. Signed-off-by: Andreas Klinger --- drivers/gnss/gnss_u_blox_m10.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gnss/gnss_u_blox_m10.c b/drivers/gnss/gnss_u_blox_m10.c index e5641ab634a93..c2cb82de09ba0 100644 --- a/drivers/gnss/gnss_u_blox_m10.c +++ b/drivers/gnss/gnss_u_blox_m10.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "gnss_nmea0183.h" #include "gnss_nmea0183_match.h" From fec92e0025cf2b7664cc892bdda8ded0d484e138 Mon Sep 17 00:00:00 2001 From: Chang Feng Date: Mon, 24 Jun 2024 18:40:40 +0800 Subject: [PATCH 080/187] driver: spi: gd32: fix spi reg clear wrong flag SPI DMATEN and DMAREN flags are in SPI_CTL1 register. fixed wrong register. Signed-off-by: Chang Feng --- drivers/spi/spi_gd32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_gd32.c b/drivers/spi/spi_gd32.c index c5c37a82f21dc..1dabc620bcf69 100644 --- a/drivers/spi/spi_gd32.c +++ b/drivers/spi/spi_gd32.c @@ -414,11 +414,13 @@ static int spi_gd32_transceive_impl(const struct device *dev, #ifdef CONFIG_SPI_GD32_DMA dma_error: + SPI_CTL1(cfg->reg) &= + ~(SPI_CTL1_DMATEN | SPI_CTL1_DMAREN); #endif spi_context_cs_control(&data->ctx, false); SPI_CTL0(cfg->reg) &= - ~(SPI_CTL0_SPIEN | SPI_CTL1_DMATEN | SPI_CTL1_DMAREN); + ~(SPI_CTL0_SPIEN); error: spi_context_release(&data->ctx, ret); From 2d877b3ed2d9c53c54c2f271bb15d5b1235a5d75 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Fri, 14 Jun 2024 15:45:14 -0700 Subject: [PATCH 081/187] drivers: clock_control: ra: fix issue with setting memwait cycles Setting the number of memory wait cycles must take place while the clock is set to 32MHz or less. This patch ensure the MEMWAIT register is changed before the clock is changed from its default value (of 8MHz). Note that in order to set MEMWAIT to 1 the power control mode must be set to high speed (which is why the lines of code interacting with the OPCCR register have also been moved). Signed-off-by: Ian Morris --- drivers/clock_control/clock_control_renesas_ra.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/clock_control/clock_control_renesas_ra.c b/drivers/clock_control/clock_control_renesas_ra.c index 26bb3ab3eb74d..0b058633151cf 100644 --- a/drivers/clock_control/clock_control_renesas_ra.c +++ b/drivers/clock_control/clock_control_renesas_ra.c @@ -286,6 +286,13 @@ static int clock_control_ra_init(const struct device *dev) } } + SYSTEM_write8(OPCCR_OFFSET, 0); + while ((SYSTEM_read8(OPCCR_OFFSET) & BIT(OPCCR_OPCMTSF_POS)) != 0) { + ; + } + + SYSTEM_write8(MEMWAIT_OFFSET, 1); + SYSTEM_write32(SCKDIVCR_OFFSET, SCKDIVCR_INIT_VALUE); SYSTEM_write8(SCKSCR_OFFSET, SCKSCR_INIT_VALUE); @@ -293,12 +300,6 @@ static int clock_control_ra_init(const struct device *dev) sysclk = SYSTEM_read8(SCKSCR_OFFSET); z_clock_hw_cycles_per_sec = clock_freqs[sysclk]; - SYSTEM_write8(OPCCR_OFFSET, 0); - while ((SYSTEM_read8(OPCCR_OFFSET) & BIT(OPCCR_OPCMTSF_POS)) != 0) { - ; - } - - SYSTEM_write8(MEMWAIT_OFFSET, 1); SYSTEM_write16(PRCR_OFFSET, PRCR_KEY); return 0; From 9dc6b9c338236355edb8b8f3c73ed46f594e60fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 1 Jul 2024 10:10:35 +0200 Subject: [PATCH 082/187] doc: css: Use body color for captions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that captions (tables, figures, ...) can be properly seen on both light and dark them by setting their text color to the default "body" color. Fixes #73190. Signed-off-by: Benjamin Cabé --- doc/_static/css/custom.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index a374fda4d37fe..b820543f3dedb 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -194,6 +194,9 @@ a.icon-home:visited { border-color: var(--code-border-color); } +.rst-content table.docutils caption, .rst-content table.field-list caption, .wy-table caption { + color: var(--body-color); +} .wy-table-odd td, .wy-table-striped tr:nth-child(2n-1) td, .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { From 81614e7f7d1a9fce26fa073276f66bb745e9509a Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Mon, 1 Jul 2024 09:27:04 +0200 Subject: [PATCH 083/187] doc: stm32h747i_disco: minor fix minor doc fix. Signed-off-by: Abderrahmane Jarmouni --- boards/st/stm32h747i_disco/doc/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/st/stm32h747i_disco/doc/index.rst b/boards/st/stm32h747i_disco/doc/index.rst index 06b8c88e1ace2..a9635dd2e40c3 100644 --- a/boards/st/stm32h747i_disco/doc/index.rst +++ b/boards/st/stm32h747i_disco/doc/index.rst @@ -175,11 +175,11 @@ support in Zephyr by adding the shield ``st_b_lcd40_dsi1_mb1166`` or .. note:: The shield comes in different hardware revisions, the MB1166-A09 is utilizing a NT35510 panel controller and shall specifically - use ``st_b_lcd40_dsi1_mb1166_a09`` as SHIELD when building + use ``st_b_lcd40_dsi1_mb1166_a09`` as SHIELD when building. Prior versions are utilizing an OTM8009a controller and shall - use shield name without postfix, that is: ``st_b_lcd40_dsi1_mb1166`` + use shield name without postfix, that is: ``st_b_lcd40_dsi1_mb1166``. Shield version is printed on a sticker placed below the two bottom - mounting holes and has the format: MB1166-Axx + mounting holes and has the format: MB1166-Axx. Resources sharing ================= From 31520936dde0015469b2a50c52573965d28276c0 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 30 Jun 2024 19:19:43 +0900 Subject: [PATCH 084/187] doc: release: 3.7: Release notes for Renesas EK-RA8M1 board Add Renesas EK-RA8M1 board that is supported in release 3.7 Signed-off-by: TOKITA Hiroshi --- doc/releases/release-notes-3.7.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 13574353ffad2..2a34e76d66688 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -235,6 +235,7 @@ Boards & SoC Support * Added support for :ref:`Seeed Studio XIAO RP2040 board `: ``xiao_rp2040``. * Added support for :ref:`Mikroe RA4M1 Clicker board `: ``mikroe_clicker_ra4m1``. * Added support for :ref:`Arduino UNO R4 WiFi board `: : ``arduino_uno_r4_wifi``. + * Added support for :ref:`Renesas EK-RA8M1 board `: ``ek_ra8m1``. * Added support for these Xtensa boards: From 20a54005da870ade3a0772070b7505adf1435875 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 30 Jun 2024 19:20:06 +0900 Subject: [PATCH 085/187] doc: release: 3.7: Remove the duplicated colon. Beautify the line about the support of the Arduino UNO R4 WiFi board. Signed-off-by: TOKITA Hiroshi --- doc/releases/release-notes-3.7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 2a34e76d66688..44ba97740a98a 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -234,7 +234,7 @@ Boards & SoC Support * Added support for :ref:`Raspberry Pi 5 board `: ``rpi_5``. * Added support for :ref:`Seeed Studio XIAO RP2040 board `: ``xiao_rp2040``. * Added support for :ref:`Mikroe RA4M1 Clicker board `: ``mikroe_clicker_ra4m1``. - * Added support for :ref:`Arduino UNO R4 WiFi board `: : ``arduino_uno_r4_wifi``. + * Added support for :ref:`Arduino UNO R4 WiFi board `: ``arduino_uno_r4_wifi``. * Added support for :ref:`Renesas EK-RA8M1 board `: ``ek_ra8m1``. * Added support for these Xtensa boards: From 3606f91ba8d125b8098d005ceebbfae14bfa742c Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 28 Jun 2024 19:17:10 +0000 Subject: [PATCH 086/187] boards: nxp: lpcxpresso55xxx: list USB device as supported List USB device and USB device "next" as supported on the NXP LPCXpresso55S16 (which uses dedicated USB RAM) and LPCXpresso55S36 (which does not use dedicated USB RAM). This allows testing these two implementations during CI runs. Signed-off-by: Henrik Brix Andersen --- boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml | 1 + boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml b/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml index e08460382fde6..f9380c7ab11cd 100644 --- a/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml +++ b/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml @@ -23,4 +23,5 @@ supported: - i2c - spi - usb_device + - usbd vendor: nxp diff --git a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml index 5a28b2149c54e..806fadc48d317 100644 --- a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml +++ b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml @@ -19,4 +19,6 @@ supported: - gpio - pwm - dac + - usb_device + - usbd vendor: nxp From dda6971ac7ffa49c4b5b678a8fc78997c51961de Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Fri, 28 Jun 2024 17:29:43 +0800 Subject: [PATCH 087/187] drivers/input: it8xxx2: Add critical section to prevent race conditions The KBS_KSOH1 register contains both keyboard and GPIO output settings. Not all bits are for the keyboard will be driven, so a critical section is needed to prevent race conditions. Signed-off-by: Tim Lin --- drivers/input/input_ite_it8xxx2_kbd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/input/input_ite_it8xxx2_kbd.c b/drivers/input/input_ite_it8xxx2_kbd.c index 5681b33183322..e03b87d45c16f 100644 --- a/drivers/input/input_ite_it8xxx2_kbd.c +++ b/drivers/input/input_ite_it8xxx2_kbd.c @@ -63,6 +63,7 @@ static void it8xxx2_kbd_drive_column(const struct device *dev, int col) const uint8_t ksol_mask = kso_mask & 0xff; const uint8_t ksoh1_mask = (kso_mask >> 8) & 0xff; uint32_t kso_val; + unsigned int key; /* Tri-state all outputs */ if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) { @@ -77,7 +78,17 @@ static void it8xxx2_kbd_drive_column(const struct device *dev, int col) /* Set KSO[17:0] output data */ inst->KBS_KSOL = (inst->KBS_KSOL & ~ksol_mask) | (kso_val & ksol_mask); + /* + * Disable global interrupts for critical section + * The KBS_KSOH1 register contains both keyboard and GPIO output settings. + * Not all bits are for the keyboard will be driven, so a critical section + * is needed to avoid race conditions. + */ + key = irq_lock(); inst->KBS_KSOH1 = (inst->KBS_KSOH1 & ~ksoh1_mask) | ((kso_val >> 8) & ksoh1_mask); + /* Restore interrupts */ + irq_unlock(key); + if (common->col_size > 16) { inst->KBS_KSOH2 = (kso_val >> 16) & 0xff; } From b3b952aa8b11167309f2b589210720261d70e7a5 Mon Sep 17 00:00:00 2001 From: Alessandro Manganaro Date: Thu, 27 Jun 2024 13:18:37 +0200 Subject: [PATCH 088/187] west.yml: STM32WBA55 BLE Ext Adv Fix STM32WBA55 BLE Extended Advertising issue (70935) fixed using a correct BLE Controller configuration. Signed-off-by: Alessandro Manganaro --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b4495f50b0e81..b056124c50db6 100644 --- a/west.yml +++ b/west.yml @@ -234,7 +234,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 855f195793df094644ce8b8617c01275408bbf58 + revision: d12e21e35d8d33c5fdf711d1a1c07f38c9295f70 path: modules/hal/stm32 groups: - hal From 5464e2b62a31f209a5ba84ad03c0d2ce7b6ff3fe Mon Sep 17 00:00:00 2001 From: Alessandro Manganaro Date: Thu, 27 Jun 2024 14:49:13 +0200 Subject: [PATCH 089/187] soc/st/stm32/st32wbax: STM32WBA55 BLE Ext Adv Fix SYSTEM_WORKQUEUE_STACK_SIZE increase is required to fix not only BLE Ext Adv (70935), but also other BLE use cases according STM32WBA HCI driver Signed-off-by: Alessandro Manganaro --- soc/st/stm32/stm32wbax/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/st/stm32/stm32wbax/Kconfig.defconfig b/soc/st/stm32/stm32wbax/Kconfig.defconfig index b6dfd878afd52..88e41074518df 100644 --- a/soc/st/stm32/stm32wbax/Kconfig.defconfig +++ b/soc/st/stm32/stm32wbax/Kconfig.defconfig @@ -35,6 +35,9 @@ config ENTROPY_STM32_CLK_CHECK config FPU default y +config SYSTEM_WORKQUEUE_STACK_SIZE + default 2048 + endif if PM_S2RAM From e61a85aec53b5aa5a334a5c6331e8c733e8a2f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 27 Jun 2024 11:39:50 +0200 Subject: [PATCH 090/187] drivers: ethernet: stm32: fix PTP on STM32F7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of recent update of stm32f7 HAL to cube version V1.17.2 the workaround for misspelled HAL_ETH_PTP_CONFIGURATED macro is not needed anymore, and causes PTP support to fail to compile. Signed-off-by: Benjamin Cabé --- drivers/ethernet/eth_stm32_hal_priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index 6402a9a306969..9502537ac5297 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -10,7 +10,7 @@ #include /* Naming of the ETH PTP Config Status changes depending on the stm32 serie */ -#if defined(CONFIG_SOC_SERIES_STM32F7X) || defined(CONFIG_SOC_SERIES_STM32F4X) +#if defined(CONFIG_SOC_SERIES_STM32F4X) #define ETH_STM32_PTP_CONFIGURED HAL_ETH_PTP_CONFIGURATED #define ETH_STM32_PTP_NOT_CONFIGURED HAL_ETH_PTP_NOT_CONFIGURATED #else From 69a4719376645ee93570dd64d8809cc5b643ae24 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 28 Jun 2024 11:10:50 +0800 Subject: [PATCH 091/187] dts: pinctrl: unify pinctrl binding for imx8mp/n/m Currently imx8mm/n use pinctrl binding of nxp,imx8m-pinctrl.yaml which is used for imx8mq series platforms, but imx8mm/n have different pinctrl hardware module with imx8mq, so change imx8mm/n to use binding of nxp,imx8mp-pinctrl.yaml as imx8mm, imx8mn and imx8mp have the same pinctrl hardware module. Signed-off-by: Jiafei Pan --- boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi | 6 +++--- boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi | 6 +++--- .../mimx8mm_phyboard_polis-pinctrl.dtsi | 8 ++++---- dts/arm/nxp/nxp_imx8mm_m4.dtsi | 5 +++++ dts/arm64/nxp/nxp_mimx8mm_a53.dtsi | 2 +- dts/arm64/nxp/nxp_mimx8mn_a53.dtsi | 2 +- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi b/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi index b994d31c67a2a..0568cc734b684 100644 --- a/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi +++ b/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NXP + * Copyright 2022,2024 NXP * SPDX-License-Identifier: Apache-2.0 * */ @@ -12,7 +12,7 @@ pinmux = <&iomuxc_uart2_rxd_uart_rx_uart2_rx>, <&iomuxc_uart2_txd_uart_tx_uart2_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; @@ -21,7 +21,7 @@ pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, <&iomuxc_uart4_txd_uart_tx_uart4_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; diff --git a/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi b/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi index ea200728c8afb..827e8e94a61c7 100644 --- a/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi +++ b/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022,2024 NXP * SPDX-License-Identifier: Apache-2.0 * */ @@ -12,7 +12,7 @@ pinmux = <&iomuxc_uart2_rxd_uart_rx_uart2_rx>, <&iomuxc_uart2_txd_uart_tx_uart2_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; @@ -21,7 +21,7 @@ pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, <&iomuxc_uart4_txd_uart_tx_uart4_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; diff --git a/boards/phytec/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis-pinctrl.dtsi b/boards/phytec/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis-pinctrl.dtsi index 91efe29d219ca..928908a616217 100644 --- a/boards/phytec/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis-pinctrl.dtsi +++ b/boards/phytec/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis-pinctrl.dtsi @@ -12,7 +12,7 @@ pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, <&iomuxc_uart4_txd_uart_tx_uart4_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; @@ -21,7 +21,7 @@ pinmux = <&iomuxc_uart3_rxd_uart_rx_uart3_rx>, <&iomuxc_uart3_txd_uart_tx_uart3_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; @@ -32,7 +32,7 @@ <&iomuxc_sai3_txfs_uart_tx_uart2_rx>, <&iomuxc_sai3_txc_uart_rx_uart2_tx>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; @@ -43,7 +43,7 @@ <&iomuxc_sai2_rxd0_uart_rts_b_uart1_rts_b>, <&iomuxc_sai2_txfs_uart_cts_b_uart1_cts_b>; slew-rate = "fast"; - drive-strength = "40-ohm"; + drive-strength = "x6"; }; }; }; diff --git a/dts/arm/nxp/nxp_imx8mm_m4.dtsi b/dts/arm/nxp/nxp_imx8mm_m4.dtsi index 87712243c4f95..59f95701ef099 100644 --- a/dts/arm/nxp/nxp_imx8mm_m4.dtsi +++ b/dts/arm/nxp/nxp_imx8mm_m4.dtsi @@ -5,3 +5,8 @@ */ #include + +&pinctrl { + status = "okay"; + compatible = "nxp,imx8mp-pinctrl"; +}; diff --git a/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi index 9c6564ce2697b..58412c35a6274 100644 --- a/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi @@ -100,7 +100,7 @@ status = "okay"; pinctrl: pinctrl { status = "okay"; - compatible = "nxp,imx8m-pinctrl"; + compatible = "nxp,imx8mp-pinctrl"; }; }; diff --git a/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi index ce7b840747bb7..2432877711f17 100644 --- a/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi @@ -100,7 +100,7 @@ status = "okay"; pinctrl: pinctrl { status = "okay"; - compatible = "nxp,imx8m-pinctrl"; + compatible = "nxp,imx8mp-pinctrl"; }; }; From 0e174fd65068fd9fbdf0e7a23abcb76fe5b436dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 26 Jun 2024 15:11:37 +0200 Subject: [PATCH 092/187] drivers: uart: uart_elementary: Add missing pull-ups to nrf54h20dk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing pull-up for RX pin in nrf54h20dk dual uart configuration. Lack of pull-up was causing test failures. Signed-off-by: Krzysztof Chruściński --- .../nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay b/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay index 23c36ee897442..f544d609adacd 100644 --- a/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay +++ b/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay @@ -6,8 +6,11 @@ &pinctrl { uart135_default_alt: uart135_default_alt { group1 { - psels = , - ; + psels = ; + bias-pull-up; + }; + group2 { + psels = ; }; }; @@ -32,8 +35,11 @@ dut: &uart135 { &pinctrl { uart137_default_alt: uart137_default_alt { group1 { - psels = , - ; + psels = ; + bias-pull-up; + }; + group2 { + psels = ; }; }; From d5c692d65e4b8db634a8352e10bbb3f171d0e474 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 27 Jun 2024 09:40:16 +0200 Subject: [PATCH 093/187] MAINTAINERS: add valeriosetti as collaborator for Mbed TLS module Previous commit 8defc560fe8fafe007604f8193fe299d284055b3 forgot to add valeriosetti also in "West project: mbedtls". This commit fixes this. Signed-off-by: Valerio Setti --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a4065595b6754..8771e28f49383 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4665,6 +4665,7 @@ West: - ceolin collaborators: - ithinuel + - valeriosetti files: - modules/mbedtls/ labels: From ca7a855be87d74fed7f26437b12d0cbe6addaf45 Mon Sep 17 00:00:00 2001 From: Hao Luo Date: Mon, 17 Jun 2024 10:20:33 +0800 Subject: [PATCH 094/187] drivers: i2c: bugfix for ambiq i2c driver Added k_sem_give for error return case. Changed enabled interrupt bits. Signed-off-by: Hao Luo --- drivers/i2c/i2c_ambiq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c_ambiq.c b/drivers/i2c/i2c_ambiq.c index f3c5b90e90031..3091f8875360d 100644 --- a/drivers/i2c/i2c_ambiq.c +++ b/drivers/i2c/i2c_ambiq.c @@ -60,7 +60,6 @@ static void i2c_ambiq_callback(void *callback_ctxt, uint32_t status) data->callback(dev, status, data->callback_data); } data->transfer_status = status; - k_sem_give(&data->transfer_sem); } #endif @@ -72,6 +71,7 @@ static void i2c_ambiq_isr(const struct device *dev) am_hal_iom_interrupt_status_get(data->iom_handler, false, &ui32Status); am_hal_iom_interrupt_clear(data->iom_handler, ui32Status); am_hal_iom_interrupt_service(data->iom_handler, ui32Status); + k_sem_give(&data->transfer_sem); } static int i2c_ambiq_read(const struct device *dev, struct i2c_msg *msg, uint16_t addr) @@ -197,6 +197,7 @@ static int i2c_ambiq_transfer(const struct device *dev, struct i2c_msg *msgs, ui } if (ret != 0) { + k_sem_give(&data->bus_sem); return ret; } } @@ -237,8 +238,8 @@ static int i2c_ambiq_init(const struct device *dev) } #ifdef CONFIG_I2C_AMBIQ_DMA - am_hal_iom_interrupt_clear(data->iom_handler, AM_HAL_IOM_INT_CQUPD | AM_HAL_IOM_INT_ERR); - am_hal_iom_interrupt_enable(data->iom_handler, AM_HAL_IOM_INT_CQUPD | AM_HAL_IOM_INT_ERR); + am_hal_iom_interrupt_clear(data->iom_handler, AM_HAL_IOM_INT_DCMP | AM_HAL_IOM_INT_CMDCMP); + am_hal_iom_interrupt_enable(data->iom_handler, AM_HAL_IOM_INT_DCMP | AM_HAL_IOM_INT_CMDCMP); config->irq_config_func(); #endif From 6b8c9ce201c97123cb26dde8d2e52a018130c422 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 26 Jun 2024 16:55:06 +0200 Subject: [PATCH 095/187] drivers: adc: stm32: check ldo ready bit For STM32H7, U5 and WBA, check the LDORDY bit of the ADC ISR register after enabling the internal regulator. This method is safer than the delay. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 3e5c67ad4586d..3f6b59073c283 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -1446,7 +1446,28 @@ static int adc_stm32_init(const struct device *dev) !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) LL_ADC_EnableInternalRegulator(adc); + /* Wait for Internal regulator stabilisation + * Some series have a dedicated status bit, others relie on a delay + */ +#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(ADC_VER_V5_V90) + /* ADC3 on H72x/H73x doesn't have the LDORDY status bit */ + if (adc == ADC3) { + k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); + } else { + while (LL_ADC_IsActiveFlag_LDORDY(adc) == 0) { + } + } +#elif defined(CONFIG_SOC_SERIES_STM32H7X) || \ + defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* Don't use LL_ADC_IsActiveFlag_LDORDY since not present in U5 LL (1.5.0) + * (internal issue 185106) + */ + while ((READ_BIT(adc->ISR, LL_ADC_FLAG_LDORDY) != (LL_ADC_FLAG_LDORDY))) { + } +#else k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); +#endif #endif if (config->irq_cfg_func) { From 2f8d50e8800376e21ece38ebe24ea349c0b1a4b0 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 26 Jun 2024 16:57:38 +0200 Subject: [PATCH 096/187] drivers: adc: stm32: apply extended calibration on u5 Some STM32U5 can apply an extended calibration to enhance the ADC performance. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 3f6b59073c283..b670b5506e397 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -22,6 +22,7 @@ #include #include #include +#include #if defined(CONFIG_SOC_SERIES_STM32U5X) #include #endif /* CONFIG_SOC_SERIES_STM32U5X */ @@ -535,6 +536,24 @@ static void adc_stm32_calibration_start(const struct device *dev) defined(CONFIG_SOC_SERIES_STM32WBAX) LL_ADC_StartCalibration(adc); #elif defined(CONFIG_SOC_SERIES_STM32U5X) + if (adc != ADC4) { + uint32_t dev_id = LL_DBGMCU_GetDeviceID(); + uint32_t rev_id = LL_DBGMCU_GetRevisionID(); + + /* Some U5 implement an extended calibration to enhance ADC performance. + * It is not available for ADC4. + * It is available on all U5 except U575/585 (dev ID 482) revision X (rev ID 2001). + * The code below applies the procedure described in RM0456 in the ADC chapter: + * "Extended calibration mode" + */ + if ((dev_id != 0x482UL) && (rev_id != 0x2001UL)) { + adc_stm32_enable(adc); + MODIFY_REG(adc->CR, ADC_CR_CALINDEX, 0x9UL << ADC_CR_CALINDEX_Pos); + MODIFY_REG(adc->CALFACT2, 0xFFFFFF00UL, 0x03021100UL); + SET_BIT(adc->CALFACT, ADC_CALFACT_LATCH_COEF); + adc_stm32_disable(adc); + } + } LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET); #elif defined(CONFIG_SOC_SERIES_STM32H7X) LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET, LL_ADC_SINGLE_ENDED); From 8c5a4123a5d2be9abd8ca61d5d2e76728f4dc4be Mon Sep 17 00:00:00 2001 From: Alex Fabre Date: Thu, 20 Jun 2024 13:06:02 +0200 Subject: [PATCH 097/187] boards: st: fix sysbuild multi image flash Problem: When flashing a multi-image project with STLink through sysbuild, the flash utility is told to erase the whole flash between each single image flash. Resulting in a partial flash where only the last image is effectively stored on flash... Correction: A `west flash` must not implicitly perform a mass erase on its own. If a flash erase is required, the option has to be passed manually. The problem is discussed in the following issue: zephyrproject-rtos/zephyr#69582 Due to CI tests errors, the correction is not applied on eval board `b_u585i_iot02a`. See following issue: zephyrproject-rtos/zephyr#75164 Signed-off-by: Alex Fabre --- boards/st/nucleo_h533re/board.cmake | 2 +- boards/st/nucleo_h563zi/board.cmake | 2 +- boards/st/nucleo_u575zi_q/board.cmake | 2 +- boards/st/stm32f429i_disc1/board.cmake | 2 +- boards/st/stm32h573i_dk/board.cmake | 2 +- boards/st/stm32h750b_dk/board.cmake | 2 +- boards/st/stm32h7b3i_dk/board.cmake | 2 +- boards/st/stm32h7s78_dk/board.cmake | 2 +- boards/st/stm32u5a9j_dk/board.cmake | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/boards/st/nucleo_h533re/board.cmake b/boards/st/nucleo_h533re/board.cmake index cec3a36c40362..97abaa6f5770e 100644 --- a/boards/st/nucleo_h533re/board.cmake +++ b/boards/st/nucleo_h533re/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(pyocd "--target=stm32h533retx") diff --git a/boards/st/nucleo_h563zi/board.cmake b/boards/st/nucleo_h563zi/board.cmake index 8899e82de7451..24b1a15215cc4 100644 --- a/boards/st/nucleo_h563zi/board.cmake +++ b/boards/st/nucleo_h563zi/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(pyocd "--target=stm32h563zitx") diff --git a/boards/st/nucleo_u575zi_q/board.cmake b/boards/st/nucleo_u575zi_q/board.cmake index a37e241d2ce08..44f3e8cbcfc47 100644 --- a/boards/st/nucleo_u575zi_q/board.cmake +++ b/boards/st/nucleo_u575zi_q/board.cmake @@ -1,4 +1,4 @@ -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(openocd "--tcl-port=6666") diff --git a/boards/st/stm32f429i_disc1/board.cmake b/boards/st/stm32f429i_disc1/board.cmake index 402b28d32c035..bc72082b038af 100644 --- a/boards/st/stm32f429i_disc1/board.cmake +++ b/boards/st/stm32f429i_disc1/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(jlink "--device=STM32F429ZI" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/st/stm32h573i_dk/board.cmake b/boards/st/stm32h573i_dk/board.cmake index 95bd27bc2000b..762f2e32b8577 100644 --- a/boards/st/stm32h573i_dk/board.cmake +++ b/boards/st/stm32h573i_dk/board.cmake @@ -4,7 +4,7 @@ if(CONFIG_STM32_MEMMAP) board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(stm32cubeprogrammer "--extload=MX25LM51245G_STM32H573I-DK-RevB-SFIx.stldr") else() -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") endif() board_runner_args(pyocd "--target=stm32h573iikx") diff --git a/boards/st/stm32h750b_dk/board.cmake b/boards/st/stm32h750b_dk/board.cmake index c38a92dfacc7d..b9fb74f99cf4a 100644 --- a/boards/st/stm32h750b_dk/board.cmake +++ b/boards/st/stm32h750b_dk/board.cmake @@ -7,7 +7,7 @@ if(CONFIG_STM32_MEMMAP) board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(stm32cubeprogrammer "--extload=MT25TL01G_STM32H750B-DISCO.stldr") else() -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw" ) +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw" ) endif() include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) diff --git a/boards/st/stm32h7b3i_dk/board.cmake b/boards/st/stm32h7b3i_dk/board.cmake index 027413fd66cf2..71ce6d59e4387 100644 --- a/boards/st/stm32h7b3i_dk/board.cmake +++ b/boards/st/stm32h7b3i_dk/board.cmake @@ -8,7 +8,7 @@ if(CONFIG_STM32_MEMMAP) board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(stm32cubeprogrammer "--extload=MX25LM51245G_STM32H7B3I-DISCO.stldr") else() -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw" ) +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw" ) endif() include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) diff --git a/boards/st/stm32h7s78_dk/board.cmake b/boards/st/stm32h7s78_dk/board.cmake index 04b6ed24de460..585770c48b451 100644 --- a/boards/st/stm32h7s78_dk/board.cmake +++ b/boards/st/stm32h7s78_dk/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) diff --git a/boards/st/stm32u5a9j_dk/board.cmake b/boards/st/stm32u5a9j_dk/board.cmake index dadc06c643e08..ac9a18d42fb72 100644 --- a/boards/st/stm32u5a9j_dk/board.cmake +++ b/boards/st/stm32u5a9j_dk/board.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 -board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(openocd "--tcl-port=6666") board_runner_args(openocd --cmd-pre-init "gdb_report_data_abort enable") From 4aa649536895855018bf9fa46aefbaa7363bf8c0 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 25 Jun 2024 16:20:45 +0200 Subject: [PATCH 098/187] device: add missing comma to Z_DEVICE_INIT When PM_DEVICE is enabled, pm_base needs to be expanded with a trailing comma. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 54494ffd864ba..cd282c3f0de42 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -1019,7 +1019,7 @@ device_get_dt_nodelabels(const struct device *dev) .state = (state_), \ .data = (data_), \ IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \ - IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) /**/ \ + IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),},)) /**/ \ IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET(dev_id_),)) \ } From bdc9fe02cac8532796a95a41d044b0ae405065ac Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 25 Jun 2024 16:21:47 +0200 Subject: [PATCH 099/187] device: only define/initialize metadata for DT devices Check if node identifier is valid to define and initialize device metadata. Without this patch, "software devices", ie, DEVICE_DEFINE, would fail to compile when enabling the device metadata feature. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/device.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/zephyr/device.h b/include/zephyr/device.h index cd282c3f0de42..2862c0befd38b 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -1008,10 +1008,11 @@ device_get_dt_nodelabels(const struct device *dev) * @param api_ Reference to device API ops. * @param state_ Reference to device state. * @param deps_ Reference to device dependencies. + * @param node_id_ Devicetree node identifier * @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE */ -#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_, \ - dev_id_) \ +#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_, node_id_, \ + dev_id_) \ { \ .name = name_, \ .config = (config_), \ @@ -1021,7 +1022,9 @@ device_get_dt_nodelabels(const struct device *dev) IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \ IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),},)) /**/ \ IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ - (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET(dev_id_),)) \ + (IF_ENABLED(DT_NODE_EXISTS(node_id_), \ + (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET( \ + dev_id_),)))) \ } /** @@ -1056,7 +1059,7 @@ device_get_dt_nodelabels(const struct device *dev) STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \ device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \ Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \ - Z_DEVICE_INIT(name, pm, data, config, api, state, deps, dev_id) + Z_DEVICE_INIT(name, pm, data, config, api, state, deps, node_id, dev_id) /* deprecated device initialization levels */ #define Z_DEVICE_LEVEL_DEPRECATED_EARLY \ @@ -1142,7 +1145,8 @@ device_get_dt_nodelabels(const struct device *dev) (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \ \ IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ - (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);)) \ + (IF_ENABLED(DT_NODE_EXISTS(node_id), \ + (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\ \ Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \ From f319192bf5381f35cceb14bf72159ef367dd8852 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 1 Jul 2024 15:46:39 +0200 Subject: [PATCH 100/187] ci: move github runners from macos-11 to macos-14 Move the GitHub runners currently on macos-11 to macos-14 as the former is no longer supported by GitHub. Signed-off-by: Henrik Brix Andersen --- .github/workflows/devicetree_checks.yml | 4 ++-- .github/workflows/west_cmds.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml index fd902ac457957..d0bf180c0f3f1 100644 --- a/.github/workflows/devicetree_checks.yml +++ b/.github/workflows/devicetree_checks.yml @@ -27,9 +27,9 @@ jobs: strategy: matrix: python-version: ['3.10', '3.11', '3.12'] - os: [ubuntu-22.04, macos-11, windows-2022] + os: [ubuntu-22.04, macos-14, windows-2022] exclude: - - os: macos-11 + - os: macos-14 python-version: 3.6 - os: windows-2022 python-version: 3.6 diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index c1e38695dc9e9..f3de00d82bb7b 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -30,9 +30,9 @@ jobs: strategy: matrix: python-version: ['3.10', '3.11', '3.12'] - os: [ubuntu-22.04, macos-11, windows-2022] + os: [ubuntu-22.04, macos-14, windows-2022] exclude: - - os: macos-11 + - os: macos-14 python-version: 3.6 - os: windows-2022 python-version: 3.6 From 03884a24a97aa56f9d1ea6b79ed4a7f2f3b38919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 1 Jul 2024 11:11:40 +0200 Subject: [PATCH 101/187] doc: esp32: fix rendering of MCUboot note MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use proper syntax to ensure rendering of the CONFIG_BOOTLOADER_MCUBOOT snippet is correct. Signed-off-by: Benjamin Cabé --- boards/espressif/esp32_devkitc_wroom/doc/index.rst | 7 ++++--- boards/espressif/esp32_devkitc_wrover/doc/index.rst | 7 ++++--- boards/espressif/esp32_ethernet_kit/doc/index.rst | 7 ++++--- boards/espressif/esp32c3_devkitm/doc/index.rst | 7 ++++--- boards/espressif/esp32c6_devkitc/doc/index.rst | 7 ++++--- boards/espressif/esp32s2_devkitc/doc/index.rst | 7 ++++--- boards/espressif/esp32s2_saola/doc/index.rst | 7 ++++--- boards/espressif/esp32s3_devkitc/doc/index.rst | 7 ++++--- boards/espressif/esp32s3_devkitm/doc/index.rst | 7 ++++--- boards/espressif/esp_wrover_kit/doc/index.rst | 7 ++++--- boards/franzininho/esp32s2_franzininho/doc/index.rst | 7 ++++--- boards/hardkernel/odroid_go/doc/index.rst | 7 ++++--- boards/heltec/heltec_wifi_lora32_v2/doc/index.rst | 7 ++++--- boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst | 7 ++++--- boards/lilygo/ttgo_lora32/doc/index.rst | 4 ++-- boards/lilygo/ttgo_t8c3/doc/index.rst | 7 ++++--- boards/luatos/esp32c3_luatos_core/doc/index.rst | 7 ++++--- boards/luatos/esp32s3_luatos_core/doc/index.rst | 7 ++++--- boards/m5stack/m5stickc_plus/doc/index.rst | 7 ++++--- boards/m5stack/stamp_c3/doc/index.rst | 7 ++++--- boards/olimex/olimex_esp32_evb/doc/index.rst | 7 ++++--- boards/others/icev_wireless/doc/index.rst | 7 ++++--- boards/seeed/xiao_esp32c3/doc/index.rst | 7 ++++--- boards/seeed/xiao_esp32s3/doc/index.rst | 7 ++++--- boards/vcc-gnd/yd_esp32/doc/index.rst | 7 ++++--- 25 files changed, 98 insertions(+), 74 deletions(-) diff --git a/boards/espressif/esp32_devkitc_wroom/doc/index.rst b/boards/espressif/esp32_devkitc_wroom/doc/index.rst index 58106b69ab6e0..d81c10d9fb5dc 100644 --- a/boards/espressif/esp32_devkitc_wroom/doc/index.rst +++ b/boards/espressif/esp32_devkitc_wroom/doc/index.rst @@ -141,9 +141,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32_devkitc_wrover/doc/index.rst b/boards/espressif/esp32_devkitc_wrover/doc/index.rst index 7a29912dfbc9d..8ada4229ee888 100644 --- a/boards/espressif/esp32_devkitc_wrover/doc/index.rst +++ b/boards/espressif/esp32_devkitc_wrover/doc/index.rst @@ -141,9 +141,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32_ethernet_kit/doc/index.rst b/boards/espressif/esp32_ethernet_kit/doc/index.rst index 2f8ff821aad21..180382858bc98 100644 --- a/boards/espressif/esp32_ethernet_kit/doc/index.rst +++ b/boards/espressif/esp32_ethernet_kit/doc/index.rst @@ -463,9 +463,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32c3_devkitm/doc/index.rst b/boards/espressif/esp32c3_devkitm/doc/index.rst index 9028d0c3cabd2..48b38b5be909f 100644 --- a/boards/espressif/esp32c3_devkitm/doc/index.rst +++ b/boards/espressif/esp32c3_devkitm/doc/index.rst @@ -116,9 +116,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32c6_devkitc/doc/index.rst b/boards/espressif/esp32c6_devkitc/doc/index.rst index 9eb87fe2a8acf..ba847d2a90b48 100644 --- a/boards/espressif/esp32c6_devkitc/doc/index.rst +++ b/boards/espressif/esp32c6_devkitc/doc/index.rst @@ -146,9 +146,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32s2_devkitc/doc/index.rst b/boards/espressif/esp32s2_devkitc/doc/index.rst index 427596e31473b..94e6c0c07ed62 100644 --- a/boards/espressif/esp32s2_devkitc/doc/index.rst +++ b/boards/espressif/esp32s2_devkitc/doc/index.rst @@ -112,9 +112,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32s2_saola/doc/index.rst b/boards/espressif/esp32s2_saola/doc/index.rst index 485614db8e7d8..9567efb208870 100644 --- a/boards/espressif/esp32s2_saola/doc/index.rst +++ b/boards/espressif/esp32s2_saola/doc/index.rst @@ -112,9 +112,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32s3_devkitc/doc/index.rst b/boards/espressif/esp32s3_devkitc/doc/index.rst index a7d6c7d60d5ae..c4287b4539ea3 100644 --- a/boards/espressif/esp32s3_devkitc/doc/index.rst +++ b/boards/espressif/esp32s3_devkitc/doc/index.rst @@ -161,9 +161,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp32s3_devkitm/doc/index.rst b/boards/espressif/esp32s3_devkitm/doc/index.rst index 17af80ed31869..de654567100f6 100644 --- a/boards/espressif/esp32s3_devkitm/doc/index.rst +++ b/boards/espressif/esp32s3_devkitm/doc/index.rst @@ -161,9 +161,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/espressif/esp_wrover_kit/doc/index.rst b/boards/espressif/esp_wrover_kit/doc/index.rst index fdef0efd6c709..24373e4a2ee82 100644 --- a/boards/espressif/esp_wrover_kit/doc/index.rst +++ b/boards/espressif/esp_wrover_kit/doc/index.rst @@ -527,9 +527,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/franzininho/esp32s2_franzininho/doc/index.rst b/boards/franzininho/esp32s2_franzininho/doc/index.rst index 54de95ecb4013..99ccf84c3be34 100644 --- a/boards/franzininho/esp32s2_franzininho/doc/index.rst +++ b/boards/franzininho/esp32s2_franzininho/doc/index.rst @@ -79,9 +79,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/hardkernel/odroid_go/doc/index.rst b/boards/hardkernel/odroid_go/doc/index.rst index 9fa4d107b1398..dce256d3b6cd4 100644 --- a/boards/hardkernel/odroid_go/doc/index.rst +++ b/boards/hardkernel/odroid_go/doc/index.rst @@ -120,9 +120,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst b/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst index b97a998051219..4fc7b0279477f 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst +++ b/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst @@ -67,9 +67,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst b/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst index 85470571981f4..a6b48d6c71a81 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst +++ b/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst @@ -181,9 +181,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/lilygo/ttgo_lora32/doc/index.rst b/boards/lilygo/ttgo_lora32/doc/index.rst index b149fa6fa0c55..5b6d3702f210a 100644 --- a/boards/lilygo/ttgo_lora32/doc/index.rst +++ b/boards/lilygo/ttgo_lora32/doc/index.rst @@ -111,9 +111,9 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. -.. code-block:: cfg + .. code-block:: cfg - CONFIG_BOOTLOADER_MCUBOOT=y + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/lilygo/ttgo_t8c3/doc/index.rst b/boards/lilygo/ttgo_t8c3/doc/index.rst index 73e092bb94ca0..51b2c212c5e7b 100644 --- a/boards/lilygo/ttgo_t8c3/doc/index.rst +++ b/boards/lilygo/ttgo_t8c3/doc/index.rst @@ -108,9 +108,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/luatos/esp32c3_luatos_core/doc/index.rst b/boards/luatos/esp32c3_luatos_core/doc/index.rst index 21c9a7bfc5998..1cd9c909b9b5a 100644 --- a/boards/luatos/esp32c3_luatos_core/doc/index.rst +++ b/boards/luatos/esp32c3_luatos_core/doc/index.rst @@ -134,9 +134,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/luatos/esp32s3_luatos_core/doc/index.rst b/boards/luatos/esp32s3_luatos_core/doc/index.rst index 687851ea6a441..c7ada6e3f9a4e 100644 --- a/boards/luatos/esp32s3_luatos_core/doc/index.rst +++ b/boards/luatos/esp32s3_luatos_core/doc/index.rst @@ -160,9 +160,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/m5stack/m5stickc_plus/doc/index.rst b/boards/m5stack/m5stickc_plus/doc/index.rst index 1e5907d50cd67..62a059b30e359 100644 --- a/boards/m5stack/m5stickc_plus/doc/index.rst +++ b/boards/m5stack/m5stickc_plus/doc/index.rst @@ -109,9 +109,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/m5stack/stamp_c3/doc/index.rst b/boards/m5stack/stamp_c3/doc/index.rst index 9ac2a05b7ec98..414f684d71d7e 100644 --- a/boards/m5stack/stamp_c3/doc/index.rst +++ b/boards/m5stack/stamp_c3/doc/index.rst @@ -78,9 +78,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/olimex/olimex_esp32_evb/doc/index.rst b/boards/olimex/olimex_esp32_evb/doc/index.rst index c5457d5612c7a..d640af8a52239 100644 --- a/boards/olimex/olimex_esp32_evb/doc/index.rst +++ b/boards/olimex/olimex_esp32_evb/doc/index.rst @@ -136,9 +136,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/others/icev_wireless/doc/index.rst b/boards/others/icev_wireless/doc/index.rst index 5484924e8d64d..c422ba3204b1a 100644 --- a/boards/others/icev_wireless/doc/index.rst +++ b/boards/others/icev_wireless/doc/index.rst @@ -123,9 +123,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/seeed/xiao_esp32c3/doc/index.rst b/boards/seeed/xiao_esp32c3/doc/index.rst index dc86a6c20ca7a..1aa5d48cdde89 100644 --- a/boards/seeed/xiao_esp32c3/doc/index.rst +++ b/boards/seeed/xiao_esp32c3/doc/index.rst @@ -105,9 +105,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/seeed/xiao_esp32s3/doc/index.rst b/boards/seeed/xiao_esp32s3/doc/index.rst index cca9a3d8a274f..8341a79b22a44 100644 --- a/boards/seeed/xiao_esp32s3/doc/index.rst +++ b/boards/seeed/xiao_esp32s3/doc/index.rst @@ -120,9 +120,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== diff --git a/boards/vcc-gnd/yd_esp32/doc/index.rst b/boards/vcc-gnd/yd_esp32/doc/index.rst index 236d076dfcb3a..bf7efff35c25f 100644 --- a/boards/vcc-gnd/yd_esp32/doc/index.rst +++ b/boards/vcc-gnd/yd_esp32/doc/index.rst @@ -141,9 +141,10 @@ There are two options to be used when building an application: User can select the MCUboot bootloader by adding the following line to the board default configuration file. - ``` - CONFIG_BOOTLOADER_MCUBOOT=y - ``` + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y Sysbuild ======== From 7f1e5c48aaaf66b760bcf00e588713189a91040e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 27 Jun 2024 16:48:40 +0200 Subject: [PATCH 102/187] net: ptp: fix offset check by adding missing int64_t cast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add cast to NSEC_PER_SEC macro to correctly check offset. Prior to this commit, the would eval to true incorrectly. Signed-off-by: Benjamin Cabé --- subsys/net/lib/ptp/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/ptp/clock.c b/subsys/net/lib/ptp/clock.c index 415c80152ce2d..180cc6b530fd9 100644 --- a/subsys/net/lib/ptp/clock.c +++ b/subsys/net/lib/ptp/clock.c @@ -521,7 +521,7 @@ void ptp_clock_synchronize(uint64_t ingress, uint64_t egress) offset = ptp_clk.timestamp.t2 - ptp_clk.timestamp.t1 - delay; /* If diff is too big, ptp_clk needs to be set first. */ - if (offset > NSEC_PER_SEC || offset < -NSEC_PER_SEC) { + if ((offset > (int64_t)NSEC_PER_SEC) || (offset < -(int64_t)NSEC_PER_SEC)) { struct net_ptp_time current; LOG_WRN("Clock offset exceeds 1 second."); From d3d8d98dfb4644d99159f69bcf5cf3c27e399368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 27 Jun 2024 16:50:23 +0200 Subject: [PATCH 103/187] net: ptp: fix incorrect req_timestamp decoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed incorrect use of ntoh to decode Delay_Req timestamp Signed-off-by: Benjamin Cabé --- subsys/net/lib/ptp/port.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/ptp/port.c b/subsys/net/lib/ptp/port.c index 1c6750a918cd8..29b8d4bc7a309 100644 --- a/subsys/net/lib/ptp/port.c +++ b/subsys/net/lib/ptp/port.c @@ -187,9 +187,9 @@ static void port_delay_req_timestamp_cb(struct net_pkt *pkt) return; } - req->timestamp.host._sec.high = ntohs(pkt->timestamp._sec.high); - req->timestamp.host._sec.low = ntohl(pkt->timestamp._sec.low); - req->timestamp.host.nanosecond = ntohl(pkt->timestamp.nanosecond); + req->timestamp.host._sec.high = pkt->timestamp._sec.high; + req->timestamp.host._sec.low = pkt->timestamp._sec.low; + req->timestamp.host.nanosecond = pkt->timestamp.nanosecond; LOG_DBG("Port %d registered timestamp for %d Delay_Req", port->port_ds.id.port_number, From f2c8ef7c05ec09fa13d141a781cfedc0e4ed068c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 27 Jun 2024 15:37:07 +0200 Subject: [PATCH 104/187] Bluetooth: BAP: Scan del: Overwrite metadata if len == 0 If the metadata length is 0 in the mod source operation, we set the length to 0 and memset the stored value. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_scan_delegator.c | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 6ba46a49c1f50..f7d50a3f4c306 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -835,22 +835,26 @@ static int scan_delegator_mod_src(struct bt_conn *conn, } for (int i = 0; i < num_subgroups; i++) { - /* If the metadata len is 0, we shall not overwrite the existing metadata */ - if (subgroups[i].metadata_len == 0) { - continue; - } + const bool metadata_len_changed = + subgroups[i].metadata_len != state->subgroups[i].metadata_len; - if (subgroups[i].metadata_len != state->subgroups[i].metadata_len) { + if (metadata_len_changed) { state->subgroups[i].metadata_len = subgroups[i].metadata_len; state_changed = true; } - if (memcmp(subgroups[i].metadata, state->subgroups[i].metadata, + if (metadata_len_changed || + memcmp(subgroups[i].metadata, state->subgroups[i].metadata, sizeof(subgroups[i].metadata)) != 0) { - (void)memcpy(state->subgroups[i].metadata, - subgroups[i].metadata, - state->subgroups[i].metadata_len); - state->subgroups[i].metadata_len = subgroups[i].metadata_len; + + if (state->subgroups[i].metadata_len == 0U) { + memset(state->subgroups[i].metadata, 0, + state->subgroups[i].metadata_len); + } else { + (void)memcpy(state->subgroups[i].metadata, subgroups[i].metadata, + state->subgroups[i].metadata_len); + } + state_changed = true; } } From a16625c83d79fd62cb27b34863c71978cec7313d Mon Sep 17 00:00:00 2001 From: Nikolay Agishev Date: Wed, 26 Jun 2024 17:25:58 +0300 Subject: [PATCH 105/187] ARCMWDT: Fix issues with posix types Fix posix pid_t type redifiniton (zephyr vs arcmwdtlib). Add omitted in arcmwdtlib type sigevent. This Fixes https://github.com/zephyrproject-rtos/zephyr/issues/75105 Signed-off-by: Nikolay Agishev --- include/zephyr/posix/posix_types.h | 2 ++ lib/libc/arcmwdt/include/signal.h | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 lib/libc/arcmwdt/include/signal.h diff --git a/include/zephyr/posix/posix_types.h b/include/zephyr/posix/posix_types.h index f90b21374fc8e..cbe51fa7e8f9f 100644 --- a/include/zephyr/posix/posix_types.h +++ b/include/zephyr/posix/posix_types.h @@ -21,7 +21,9 @@ extern "C" { #endif +#if !defined(CONFIG_ARCMWDT_LIBC) typedef int pid_t; +#endif #ifndef __useconds_t_defined typedef unsigned long useconds_t; diff --git a/lib/libc/arcmwdt/include/signal.h b/lib/libc/arcmwdt/include/signal.h new file mode 100644 index 0000000000000..cdd39d1ff1803 --- /dev/null +++ b/lib/libc/arcmwdt/include/signal.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Synopsys + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LIB_LIBC_ARCMWDT_INCLUDE_SIGNAL_H_ +#define LIB_LIBC_ARCMWDT_INCLUDE_SIGNAL_H_ + +#include + +#endif /* LIB_LIBC_ARCMWDT_INCLUDE_SIGNAL_H_ */ From 6d116a8e35e9a666523074c3d21d203016fea39a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 26 Jun 2024 17:12:36 +0200 Subject: [PATCH 106/187] doc: Bluetooth: Audio: Remake audio_arch to graphviz Remake the Bluetooth Audio Architecture figure to a graphviz version. This makes it easier to modify it directly in the .rst file. Signed-off-by: Emil Gydesen --- .../api/audio/bluetooth-le-audio-arch.rst | 16 +++++++++++----- .../bluetooth/api/audio/img/ble_audio_arch.svg | 4 ---- 2 files changed, 11 insertions(+), 9 deletions(-) delete mode 100644 doc/connectivity/bluetooth/api/audio/img/ble_audio_arch.svg diff --git a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst index b59f39a90a9d5..2ed98221bff07 100644 --- a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst +++ b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst @@ -3,11 +3,17 @@ LE Audio Stack ############## -.. figure:: img/ble_audio_arch.svg - :align: center - :alt: Bluetooth Audio Architecture - - Bluetooth Audio Architecture +.. graphviz:: + :caption: Bluetooth Audio Architecture + + digraph bluetooth_audio_arch { + r [shape=record, width=5, height=3 + label="{{TMAP | HAP | PBP | GMAP | ...} | + GAF | + {{{ GATT | GAP } | Low-level protocols (L2CAP, ATT, etc.)} | GAP | ISO} + | HCI Driver (USB, UART, SPI, virtual, etc.)}" + ]; + } Overall design ************** diff --git a/doc/connectivity/bluetooth/api/audio/img/ble_audio_arch.svg b/doc/connectivity/bluetooth/api/audio/img/ble_audio_arch.svg deleted file mode 100644 index 21190a0535342..0000000000000 --- a/doc/connectivity/bluetooth/api/audio/img/ble_audio_arch.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
HCI Driver (USB, UART, SPI, virtual, etc)
HCI Driver (USB, UART, SPI, virtual, etc)
Low-level protocols (L2CAP, ATT, etc)
Low-level protocols (L2CAP, ATT, etc)
GATT
GATT
SMP
SMP
GAP
GAP
GAF
GAF
TMAP
TMAP
HAP
HAP
PBP
PBP
...
...
ISO
ISO
Text is not SVG - cannot display
\ No newline at end of file From f87805e9d66fea062f533569781cfeefc18be415 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 26 Jun 2024 19:18:59 +0200 Subject: [PATCH 107/187] doc: Bluetooth: Audio: Remake gaf.svg to graphviz Remake the Generic audio framework (GAF) figure to a graphviz version. This makes it easier to modify it directly in the .rst file. This also adds the missing GMAP/GMAS. Signed-off-by: Emil Gydesen --- .../api/audio/bluetooth-le-audio-arch.rst | 150 +++++++++++++++++- .../bluetooth/api/audio/img/gaf.svg | 4 - 2 files changed, 145 insertions(+), 9 deletions(-) delete mode 100644 doc/connectivity/bluetooth/api/audio/img/gaf.svg diff --git a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst index 2ed98221bff07..886d644ed0b9b 100644 --- a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst +++ b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst @@ -48,11 +48,151 @@ audio streams or broadcast (unconnected) audio streams. GAF mandates the use of the LC3 codec, but also supports other codecs. -.. figure:: img/gaf.svg - :align: center - :alt: Generic Audio Framework - - Generic Audio Framework +.. graphviz:: + :caption: Generic Audio Framework (GAF) + + digraph gaf { + node [shape=record]; + edge [style=invis]; + compound=true; + nodesep=0.1; + + subgraph hap_layer { + cluster=true; + label="HAP"; + HAS; + BAS [style=dashed]; + IAS [style=dashed]; + } + + subgraph pbp_layer { + cluster=true; + label="PBP"; + PBS[style=invis]; // Make it possible to treat PBP like the others + } + + subgraph tmap_layer { + cluster=true; + label="TMAP"; + TMAS; + } + + subgraph gmap_layer { + cluster=true; + label="GMAP"; + GMAS; + } + + subgraph gaf_layer { + cluster=true; + label="Generic Audio Framework"; + + subgraph transition_and_coordination_control_layer { + cluster=true; + label="Transition and Coordination Control"; + style=dashed; + + subgraph cap_layer { + cluster=true; + style=solid; + label="CAP"; + CAS; + } + + subgraph csip_layer { + cluster=true; + style=solid; + label="CSIP"; + CSIS; + } + } + + subgraph stream_control_layer { + cluster=true; + label="Stream Control"; + style=dashed; + + subgraph bap_layer { + cluster=true; + label="BAP"; + style=solid; + PACS [style=dashed]; + ASCS [style=dashed]; + BASS [style=dashed]; + } + } + + subgraph content_control_layer { + cluster=true; + label="Content Control"; + style=dashed; + + subgraph mcp_layer { + cluster=true; + label="MCP"; + style=solid; + MCS; + } + + subgraph ccp_layer { + cluster=true; + label="CCP"; + style=solid; + TBS; + } + } + + subgraph rendering_and_capture_control_layer { + cluster=true; + label="Rendering and Capture Control"; + style=dashed; + + subgraph micp_layer { + cluster=true; + label="MICP"; + style=solid; + MICS; + MICP_AICS [style=dashed]; + } + + subgraph vcp_layer { + cluster=true; + label="VCP"; + style=solid; + VCS; + VOCS [style=dashed]; + VCP_AICS [style=dashed]; + } + } + } + + HAS -> CAS; + PBS -> CAS; + TMAS -> CAS; + GMAS -> CAS; + + CAS -> MCS; + CAS -> TBS; + CAS -> ASCS; + CAS -> PACS; + CAS -> BASS; + CAS -> MICS; + CAS -> MICP_AICS; + CAS -> VCS; + CAS -> VOCS; + CAS -> VCP_AICS; + + CSIS -> MCS; + CSIS -> TBS; + CSIS -> ASCS; + CSIS -> PACS; + CSIS -> BASS; + CSIS -> MICS; + CSIS -> MICP_AICS; + CSIS -> VCS; + CSIS -> VOCS; + CSIS -> VCP_AICS; + } The top-level profiles TMAP and HAP are not part of the GAF, but rather provide top-level requirements for how to use the GAF. diff --git a/doc/connectivity/bluetooth/api/audio/img/gaf.svg b/doc/connectivity/bluetooth/api/audio/img/gaf.svg deleted file mode 100644 index 1cc2739b53429..0000000000000 --- a/doc/connectivity/bluetooth/api/audio/img/gaf.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Generic Audio Framework
















Generic Audio Framework...
Stream Control
Stream Control
Rendering and Capture Control
Rendering and Capture Control
Content Control
Content Control
BAP



BAP...
PACS
PACS
ACSS
ACSS
BASS
BASS
MCP


 
MCP...
MCS
MCS
CCP


 
CCP...
TBS
TBS
CSIP


 
CSIP...
CSIS
CSIS
MICP


 
MICP...
MICS
MICS
VCP


 
VCP...
VCS
VCS
VOCS
VOCS
AICS
AICS
CAP


 
CAP...
CAS
CAS
TMAP


 
TMAP...
TMAS
TMAS
HAP


 
HAP...
HAS
HAS
BAS
BAS
IAS
IAS
AICS
AICS
PBP



PBP...
Transition and Coordination Control
Transition and Coordination Contr...
Text is not SVG - cannot display
\ No newline at end of file From ecbb185cab9a1ec60e0bdb189d6952ac6214aa24 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 27 Jun 2024 14:08:48 +0200 Subject: [PATCH 108/187] doc: Bluetooth: Audio: Remake zephyr_gaf.svg to graphviz Remake the Zephyr Generic audio framework (GAF) figure to a graphviz version. This makes it easier to modify it directly in the .rst file. This also adds the missing GMAP/GMAS. Signed-off-by: Emil Gydesen --- .../api/audio/bluetooth-le-audio-arch.rst | 154 +++++++++++++++++- .../bluetooth/api/audio/img/zephyr_gaf.svg | 4 - 2 files changed, 149 insertions(+), 9 deletions(-) delete mode 100644 doc/connectivity/bluetooth/api/audio/img/zephyr_gaf.svg diff --git a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst index 886d644ed0b9b..259063e3b585f 100644 --- a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst +++ b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst @@ -197,13 +197,157 @@ GAF mandates the use of the LC3 codec, but also supports other codecs. The top-level profiles TMAP and HAP are not part of the GAF, but rather provide top-level requirements for how to use the GAF. -GAF has been implemented in Zephyr with the following structure. +GAF and the top layer profiles gave been implemented in Zephyr with the following structure. -.. figure:: img/zephyr_gaf.svg - :align: center - :alt: Generic Audio Framework +.. graphviz:: + :caption: Zephyr Generic Audio Framework + + digraph gaf { + node [shape=record]; + edge [style=invis]; + compound=true; + nodesep=0.1; + + subgraph hap_layer { + cluster=true; + label="HAP"; + HAS_H [label="has.h"]; + BAS_H [label="bas.h"]; + IAS_H [label="ias.h"]; + } + + subgraph pbp_layer { + cluster=true; + label="PBP"; + PBP_H [label="pbp.h"]; // Make it possible to treat PBP like the others + } + + subgraph tmap_layer { + cluster=true; + label="TMAP"; + TMAP_H [label="tmap.h"]; + } + + subgraph gmap_layer { + cluster=true; + label="GMAP"; + GMAP_H [label="gmap.h"]; + GMAP_PRESET_H [label="gmap_lc3_preset.h"]; + } + + subgraph gaf_layer { + cluster=true; + label="Generic Audio Framework"; + AUDIO_H [label="audio.h"]; + LC3_H [label="lc3.h"]; + + subgraph transition_and_coordination_control_layer { + cluster=true; + label="Transition and Coordination Control"; + style=dashed; + + subgraph cap_layer { + cluster=true; + style=solid; + label="CAP"; + CAP_H [label="cap.h"]; + } + + subgraph csip_layer { + cluster=true; + style=solid; + label="CSIP"; + CSIP_H [label="csip.h"]; + } + } - Zephyr Generic Audio Framework + subgraph stream_control_layer { + cluster=true; + label="Stream Control"; + style=dashed; + + subgraph bap_layer { + cluster=true; + label="BAP"; + style=solid; + PACS_H [label="pacs.h"]; + BAP_H [label="bap.h"]; + BAP_PRESET_H [label="bap_lc3_preset.h"]; + } + } + + subgraph content_control_layer { + cluster=true; + label="Content Control"; + style=dashed; + + subgraph mcp_layer { + cluster=true; + label="MCP"; + style=solid; + MCS_H [label="mcs.h"]; + MCC_H [label="mcc.h"]; + MP_H [label="media_proxy.h"]; + } + + subgraph ccp_layer { + cluster=true; + label="CCP"; + style=solid; + TBS_H [label="tbs.h"]; + } + } + + subgraph rendering_and_capture_control_layer { + cluster=true; + label="Rendering and Capture Control"; + style=dashed; + + subgraph micp_layer { + cluster=true; + label="MICP"; + style=solid; + MICP_H [label="micp.h"]; + AICS_H [label="aics.h"]; + } + + subgraph vcp_layer { + cluster=true; + label="VCP"; + style=solid; + VCP_H [label="vcp.h"]; + VOCS_H [label="vocs.h"]; + AICS_H [label="aics.h"]; + } + } + } + + HAS_H -> CAP_H; + PBP_H -> CAP_H; + TMAP_H -> CAP_H; + GMAP_H -> CAP_H; + GMAP_PRESET_H -> CAP_H; + + CAP_H -> MCS_H; + CAP_H -> MCC_H; + CAP_H -> MP_H; + CAP_H -> TBS_H; + CAP_H -> BAP_H; + CAP_H -> BAP_PRESET_H; + CAP_H -> PACS_H; + CAP_H -> MICP_H; + CAP_H -> VCP_H; + + CSIP_H -> MCS_H; + CSIP_H -> MCC_H; + CSIP_H -> MP_H; + CSIP_H -> TBS_H; + CSIP_H -> BAP_H; + CSIP_H -> BAP_PRESET_H; + CSIP_H -> PACS_H; + CSIP_H -> MICP_H; + CSIP_H -> VCP_H; + } Bluetooth Audio Stack Status ============================ diff --git a/doc/connectivity/bluetooth/api/audio/img/zephyr_gaf.svg b/doc/connectivity/bluetooth/api/audio/img/zephyr_gaf.svg deleted file mode 100644 index 9eea9a77e7b1e..0000000000000 --- a/doc/connectivity/bluetooth/api/audio/img/zephyr_gaf.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Generic Audio Framework

























Generic Audio Framework...
Content Control
Content Control
Stream Control
Stream Control
Rendering and Capture Control
Rendering and Capture Control
BAP



BAP...
bap.h
bap.h
MCP


 
MCP...
mcs.h
mcs.h
MICP


 
MICP...
mics.h
mics.h
VCP


 
VCP...
vcs.h
vcs.h
vocs.h
vocs.h
aics.h
aics.h
aics.h
aics.h
Transition and Coordination Control
Transition and Coordination Cont...
CAP
CAP
cap.h
cap.h
CSIP


 
CSIP...
csis.h
csis.h
CCP
CCP
tbs.h
tbs.h
audio.h
audio.h
Text is not SVG - cannot display
\ No newline at end of file From e199b6a6cf6f7db4a236ba641a7b08c18b6b8abb Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 1 Jul 2024 15:29:53 +0200 Subject: [PATCH 109/187] MAINTAINERS: put the CANopen runner script under the CAN area Put the scripts/west_commands/runners/canopen_program.py script under the CAN area. Signed-off-by: Henrik Brix Andersen --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 8771e28f49383..d18919a362562 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1008,6 +1008,7 @@ Release Notes: - samples/modules/canopennode/ - samples/net/sockets/can/ - samples/subsys/canbus/ + - scripts/west_commands/runners/canopen_program.py - subsys/canbus/ - subsys/net/l2/canbus/ - tests/drivers/build_all/can/ From 4c1f66eeb1c91d5eb7728403e0090e8de012e9ed Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 1 Jul 2024 15:36:25 +0200 Subject: [PATCH 110/187] ci: ignore changes to the CANopen program download runner Ignore changes to the CANopen program download west runner in CI. This script is only executed when performing a DFU using the CANopen protocol via CAN, which is never triggered in CI anyways. Signed-off-by: Henrik Brix Andersen --- scripts/ci/twister_ignore.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index 329a26d4d1e07..52c3f4206183b 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -48,3 +48,4 @@ scripts/ci/pylintrc scripts/footprint/* scripts/set_assignees.py scripts/gitlint/zephyr_commit_rules.py +scripts/west_commands/runners/canopen_program.py From 5c65feb7b194e616b7a7b13524a9fb64e95e883a Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Tue, 2 Jan 2024 16:37:22 +0100 Subject: [PATCH 111/187] drivers: udc_stm32: implement driver API to get actual device speed Implement driver API to get actual device speed. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_stm32.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 8eb35ccc85f45..220ea17925f4f 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -778,6 +778,21 @@ static int udc_stm32_ep_dequeue(const struct device *dev, return 0; } +static enum udc_bus_speed udc_stm32_device_speed(const struct device *dev) +{ + struct udc_stm32_data *priv = udc_get_private(dev); + + if (priv->pcd.Init.speed == USBD_HS_SPEED) { + return UDC_BUS_SPEED_HS; + } + + if (priv->pcd.Init.speed == USBD_FS_SPEED) { + return UDC_BUS_SPEED_FS; + } + + return UDC_BUS_UNKNOWN; +} + static const struct udc_api udc_stm32_api = { .lock = udc_stm32_lock, .unlock = udc_stm32_unlock, @@ -794,6 +809,7 @@ static const struct udc_api udc_stm32_api = { .ep_clear_halt = udc_stm32_ep_clear_halt, .ep_enqueue = udc_stm32_ep_enqueue, .ep_dequeue = udc_stm32_ep_dequeue, + .device_speed = udc_stm32_device_speed, }; /* ----------------- Instance/Device specific data ----------------- */ From d3d585167130ef05a49bea568e0cfe990c980b08 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Sat, 2 Mar 2024 10:37:51 +0100 Subject: [PATCH 112/187] drivers: udc_stm32: handle ZLP flag A function, such as CDC ECM, can set the ZLP flag to handle a class-specific protocol. This is not to be confused with the ZLP role in control transfers. Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_stm32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 220ea17925f4f..39a795c984098 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -322,6 +322,13 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) return; } + if (udc_ep_buf_has_zlp(buf) && ep != USB_CONTROL_EP_IN) { + udc_ep_buf_clear_zlp(buf); + HAL_PCD_EP_Transmit(&priv->pcd, ep, buf->data, 0); + + return; + } + udc_buf_get(dev, ep); if (ep == USB_CONTROL_EP_IN) { From 610bb36c60882d9999f76235bfb8d401771f70ae Mon Sep 17 00:00:00 2001 From: Jan Zyczkowski Date: Thu, 27 Jun 2024 14:17:18 +0200 Subject: [PATCH 113/187] boards: nordic: Change NRFS logs to debug level Change NRFS logs to debug level not to break tests. Signed-off-by: Jan Zyczkowski --- .../nrfs/backends/nrfs_backend_ipc_service.c | 6 +-- modules/hal_nordic/nrfs/dvfs/ld_dvfs.c | 4 +- .../hal_nordic/nrfs/dvfs/ld_dvfs_handler.c | 46 +++++++++---------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c b/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c index 172b5957b2392..7d2e45f19946e 100644 --- a/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c +++ b/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c @@ -95,7 +95,7 @@ __weak void nrfs_backend_error_handler(enum nrfs_backend_error error_id, int err static void ipc_sysctrl_ept_bound(void *priv) { - LOG_INF("Bound to sysctrl."); + LOG_DBG("Bound to sysctrl."); k_event_post(&ipc_connected_event, IPC_INIT_DONE_EVENT); atomic_set(&ipc_cpusys_channel_config.status, CONNECTED); } @@ -150,7 +150,7 @@ static int ipc_channel_init(void) return ret; } - LOG_INF("ipc_service_open_instance() done."); + LOG_DBG("ipc_service_open_instance() done."); ret = ipc_service_register_endpoint(ch_cfg->ipc_instance, &ch_cfg->ipc_ept, @@ -160,7 +160,7 @@ static int ipc_channel_init(void) return ret; } - LOG_INF("ipc_service_register_endpoint() done."); + LOG_DBG("ipc_service_register_endpoint() done."); return ret; } diff --git a/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c b/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c index 883161e9f9236..047d961a59ce6 100644 --- a/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c +++ b/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c @@ -124,7 +124,7 @@ K_TIMER_DEFINE(dvfs_downscale_secure_timer, ld_dvfs_secure_downscale_timeout, NU */ __weak void ld_dvfs_secure_start_increased_power_consumption(void) { - LOG_INF("Start increased power consumption for DVFS sequence and start safety timer."); + LOG_DBG("Start increased power consumption for DVFS sequence and start safety timer."); k_timer_start(&dvfs_downscale_secure_timer, DOWNSCALE_SAFETY_TIMEOUT, K_NO_WAIT); atomic_set(&increased_power_consumption, 1); @@ -147,7 +147,7 @@ __weak void ld_dvfs_secure_start_increased_power_consumption(void) */ __weak void ld_dvfs_secure_stop_increased_power_consumption(void) { - LOG_INF("Stop increased power consumption for DVFS sequence."); + LOG_DBG("Stop increased power consumption for DVFS sequence."); k_timer_stop(&dvfs_downscale_secure_timer); atomic_set(&increased_power_consumption, 0); } diff --git a/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c b/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c index 20e879c4f737e..6a3a275685605 100644 --- a/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c +++ b/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c @@ -83,7 +83,7 @@ static bool dvfs_service_handler_freq_setting_allowed(enum dvfs_frequency_settin static enum dvfs_frequency_setting dvfs_service_handler_get_current_oppoint(void) { - LOG_INF("Current LD freq setting: %d", current_freq_setting); + LOG_DBG("Current LD freq setting: %d", current_freq_setting); return current_freq_setting; } @@ -103,12 +103,12 @@ static bool dvfs_service_handler_is_downscaling(enum dvfs_frequency_setting targ /* Function handling steps for scaling preparation. */ static void dvfs_service_handler_prepare_to_scale(enum dvfs_frequency_setting oppoint_freq) { - LOG_INF("Prepare to scale, oppoint freq %d", oppoint_freq); + LOG_DBG("Prepare to scale, oppoint freq %d", oppoint_freq); enum dvfs_frequency_setting new_oppoint = oppoint_freq; enum dvfs_frequency_setting current_oppoint = dvfs_service_handler_get_current_oppoint(); if (new_oppoint == current_oppoint) { - LOG_INF("New oppoint is same as previous, no change"); + LOG_DBG("New oppoint is same as previous, no change"); } else { ld_dvfs_configure_abb_for_transition(current_oppoint, new_oppoint); @@ -125,7 +125,7 @@ static void dvfs_service_handler_prepare_to_scale(enum dvfs_frequency_setting op /* Do background job during scaling process (e.g. increased power consumption during down-scale). */ static void dvfs_service_handler_scaling_background_job(enum dvfs_frequency_setting oppoint_freq) { - LOG_INF("Perform scaling background job if needed."); + LOG_DBG("Perform scaling background job if needed."); if (dvfs_service_handler_is_downscaling(oppoint_freq)) { k_sem_give(&dvfs_service_idle_sem); } @@ -134,7 +134,7 @@ static void dvfs_service_handler_scaling_background_job(enum dvfs_frequency_sett /* Perform scaling finnish procedure. */ static void dvfs_service_handler_scaling_finish(enum dvfs_frequency_setting oppoint_freq) { - LOG_INF("Scaling finnish oppoint freq %d", oppoint_freq); + LOG_DBG("Scaling finnish oppoint freq %d", oppoint_freq); ld_dvfs_scaling_finish(dvfs_service_handler_is_downscaling(oppoint_freq)); if (!dvfs_service_handler_is_downscaling(oppoint_freq)) { int32_t err = ld_dvfs_configure_hsfll(oppoint_freq); @@ -160,33 +160,33 @@ static void dvfs_service_handler_set_initial_hsfll_config(void) /* DVFS event handler callback function.*/ static void nrfs_dvfs_evt_handler(nrfs_dvfs_evt_t const *p_evt, void *context) { - LOG_INF("%s", __func__); + LOG_DBG("%s", __func__); switch (p_evt->type) { case NRFS_DVFS_EVT_INIT_PREPARATION: - LOG_INF("DVFS handler EVT_INIT_PREPARATION"); + LOG_DBG("DVFS handler EVT_INIT_PREPARATION"); #if defined(NRF_SECURE) ld_dvfs_clear_zbb(); dvfs_service_handler_nrfs_error_check( nrfs_dvfs_init_complete_request(get_next_context())); - LOG_INF("DVFS handler EVT_INIT_PREPARATION handled"); + LOG_DBG("DVFS handler EVT_INIT_PREPARATION handled"); #else LOG_ERR("DVFS handler - unexpected EVT_INIT_PREPARATION"); #endif break; case NRFS_DVFS_EVT_INIT_DONE: - LOG_INF("DVFS handler EVT_INIT_DONE"); + LOG_DBG("DVFS handler EVT_INIT_DONE"); dvfs_service_handler_set_initial_hsfll_config(); dvfs_service_handler_set_state_bit(DVFS_SERV_HDL_INIT_DONE_BIT_POS); k_sem_give(&dvfs_service_sync_sem); - LOG_INF("DVFS handler EVT_INIT_DONE handled"); + LOG_DBG("DVFS handler EVT_INIT_DONE handled"); break; case NRFS_DVFS_EVT_OPPOINT_REQ_CONFIRMED: /* Optional confirmation from sysctrl, wait for oppoint.*/ - LOG_INF("DVFS handler EVT_OPPOINT_REQ_CONFIRMED"); + LOG_DBG("DVFS handler EVT_OPPOINT_REQ_CONFIRMED"); break; case NRFS_DVFS_EVT_OPPOINT_SCALING_PREPARE: /*Target oppoint will be received here.*/ - LOG_INF("DVFS handler EVT_OPPOINT_SCALING_PREPARE"); + LOG_DBG("DVFS handler EVT_OPPOINT_SCALING_PREPARE"); #if !defined(NRF_SECURE) if (dvfs_service_handler_is_downscaling(p_evt->freq)) { #endif @@ -194,7 +194,7 @@ static void nrfs_dvfs_evt_handler(nrfs_dvfs_evt_t const *p_evt, void *context) dvfs_service_handler_nrfs_error_check( nrfs_dvfs_ready_to_scale(get_next_context())); dvfs_service_handler_scaling_background_job(p_evt->freq); - LOG_INF("DVFS handler EVT_OPPOINT_SCALING_PREPARE handled"); + LOG_DBG("DVFS handler EVT_OPPOINT_SCALING_PREPARE handled"); #if !defined(NRF_SECURE) current_freq_setting = p_evt->freq; } else { @@ -203,10 +203,10 @@ static void nrfs_dvfs_evt_handler(nrfs_dvfs_evt_t const *p_evt, void *context) #endif break; case NRFS_DVFS_EVT_OPPOINT_SCALING_DONE: - LOG_INF("DVFS handler EVT_OPPOINT_SCALING_DONE"); + LOG_DBG("DVFS handler EVT_OPPOINT_SCALING_DONE"); dvfs_service_handler_clear_state_bit(DVFS_SERV_HDL_FREQ_CHANGE_IN_PROGRESS_BIT_POS); dvfs_service_handler_scaling_finish(p_evt->freq); - LOG_INF("DVFS handler EVT_OPPOINT_SCALING_DONE handled"); + LOG_DBG("DVFS handler EVT_OPPOINT_SCALING_DONE handled"); break; case NRFS_DVFS_EVT_REJECT: LOG_ERR("DVFS handler - request rejected"); @@ -224,30 +224,30 @@ static void dvfs_service_handler_task(void *dummy0, void *dummy1, void *dummy2) ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); - LOG_INF("Trim ABB for default voltage."); + LOG_DBG("Trim ABB for default voltage."); ld_dvfs_init(); - LOG_INF("Waiting for backend init"); + LOG_DBG("Waiting for backend init"); /* Wait for ipc initialization */ nrfs_backend_wait_for_connection(K_FOREVER); nrfs_err_t status; - LOG_INF("nrfs_dvfs_init"); + LOG_DBG("nrfs_dvfs_init"); status = nrfs_dvfs_init(nrfs_dvfs_evt_handler); dvfs_service_handler_nrfs_error_check(status); - LOG_INF("nrfs_dvfs_init_prepare_request"); + LOG_DBG("nrfs_dvfs_init_prepare_request"); status = nrfs_dvfs_init_prepare_request(get_next_context()); dvfs_service_handler_nrfs_error_check(status); /* Wait for init*/ k_sem_take(&dvfs_service_sync_sem, K_FOREVER); - LOG_INF("DVFS init done."); + LOG_DBG("DVFS init done."); #if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_SCALE_DOWN_AFTER_INIT) - LOG_INF("Requesting lowest frequency oppoint."); + LOG_DBG("Requesting lowest frequency oppoint."); dvfs_service_handler_change_freq_setting(DVFS_FREQ_LOW); #endif @@ -271,12 +271,12 @@ K_THREAD_DEFINE(dvfs_service_handler_task_id, int32_t dvfs_service_handler_change_freq_setting(enum dvfs_frequency_setting freq_setting) { if (!dvfs_service_handler_init_done()) { - LOG_INF("Init not done!"); + LOG_WRN("Init not done!"); return -EAGAIN; } if (dvfs_service_handler_freq_change_in_progress()) { - LOG_INF("Frequency change in progress."); + LOG_DBG("Frequency change in progress."); return -EBUSY; } From a8c91206466356c1b258fcbdade75341e2e1e3bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 27 Jun 2024 06:20:07 +0200 Subject: [PATCH 114/187] lib: os: spsc_pbuf: Clarify using cache management in the module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Packet buffer can be used for sharing data between cores. In that case when any core has data cache then data cache handling must be enabled in the module. However, it shall never be enabled when the packet buffer is used on a single core. Adding that information to the documentation. Signed-off-by: Krzysztof Chruściński --- include/zephyr/sys/spsc_pbuf.h | 6 +++++- lib/os/Kconfig | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/zephyr/sys/spsc_pbuf.h b/include/zephyr/sys/spsc_pbuf.h index 0e7f018fa63cc..a65d15cc5c474 100644 --- a/include/zephyr/sys/spsc_pbuf.h +++ b/include/zephyr/sys/spsc_pbuf.h @@ -25,7 +25,11 @@ extern "C" { * @{ */ -/** @brief Flag indicating that cache shall be handled. */ +/** @brief Flag indicating that cache shall be handled. + * + * It shall be used only when packet buffer is shared between two cores as on a single + * core cache shall not be handled manually because it results in data corruption. + */ #define SPSC_PBUF_CACHE BIT(0) /** @brief Size of the field which stores maximum utilization. */ diff --git a/lib/os/Kconfig b/lib/os/Kconfig index fa52338e525f1..9ce3be2a66ebf 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -60,7 +60,9 @@ config SPSC_PBUF_CACHE_ALWAYS bool "Always handle cache" help Handle cache writeback and invalidation for all instances. Option used - to avoid runtime check and thus reduce memory footprint. + to avoid runtime check and thus reduce memory footprint. Beware! It shall + be used only if all packet buffer instances are used for data sharing + between cores. config SPSC_PBUF_CACHE_NEVER bool "Never handle cache" From a31c26144512810c2648ab8e49d0f73b20fe0566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 27 Jun 2024 06:22:37 +0200 Subject: [PATCH 115/187] tests: lib: spsc_pbuf: Do not run test with cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test was using a configuration which enforces cache management in the packet buffer. However it shall not be used if producer and consumer is the same core. Testing this configuration on a single core does not make sense as it actually fails on cores with data cache. Making this configuration build_only so it is checked against compilation errors. Signed-off-by: Krzysztof Chruściński --- tests/lib/spsc_pbuf/testcase.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/lib/spsc_pbuf/testcase.yaml b/tests/lib/spsc_pbuf/testcase.yaml index be39414e73ecf..98557fd2b4cf6 100644 --- a/tests/lib/spsc_pbuf/testcase.yaml +++ b/tests/lib/spsc_pbuf/testcase.yaml @@ -9,9 +9,10 @@ tests: libraries.spsc_pbuf.cache: integration_platforms: - native_sim - # Exclude platform which does not link with cache functions - platform_exclude: ast1030_evb - timeout: 120 + # This configuration only make sense for interprocessor data sharing so + # configuration can only be verified against compilation errors on a single core. + platform_allow: native_sim + build_only: true extra_configs: - CONFIG_SPSC_PBUF_CACHE_ALWAYS=y From 8ffca6e1cd9e5774f4ec23738082575fbd52a494 Mon Sep 17 00:00:00 2001 From: Hakan Jansson Date: Sun, 23 Jun 2024 18:21:39 +0200 Subject: [PATCH 116/187] boards: infineon: cyw920829m2evk_02: update documentation Update documentation, mainly to clarify use of onboard KitProg3 debug adapter and Infineon custom OpenOCD. Signed-off-by: Hakan Jansson --- .../doc/img/cyw920829m2evk_02.webp | Bin 52226 -> 57552 bytes .../infineon/cyw920829m2evk_02/doc/index.rst | 70 ++++++++++++------ 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/boards/infineon/cyw920829m2evk_02/doc/img/cyw920829m2evk_02.webp b/boards/infineon/cyw920829m2evk_02/doc/img/cyw920829m2evk_02.webp index 130fc8dac657555851a4e97f28e729fae72f28a4..a93d6f396969d9f78809b9630f45a6aa3278bf35 100644 GIT binary patch literal 57552 zcmV)RK(oJ6Nk&G<-~a$uMM6+kP&il$0000G0000V0|5I006|PpNUjS2009}bZ5ug| zTHpQ?e-3>_|0jU9%%?RSm+=dixvXB|LsH8Cj^eg$9Lf7{eZ9UTVgdlwOw^16Du3;~ zrOC9FF3j9wcBI<2wQS2d@B4i}ZjI;`HCuGO0_!vyjT@jcsM_obAUPz>q(8a8&vP2~ zpwD8zf5ZepV%tWNr0(&+nM(GYvr^rE3Xmk5wyjzF=>BKhwr$(CZQHhO+qP}nwso=h z`Z#yyM6C5S7bhYdxQ(Pp?xoqIS~|XafZRy7U0Ydef265A2tlQwMLq;U3gm!`jfE`( zph$uG{#{jfueCo~yn~1cM{FZ0QXjLccjuVi*5I)%`H$CsUjO~~zyAAQ|7|UP8bXBH z^bH1s_<2B0+Jq<>G>ZlsNl)Sw?u!AYW>!l>0U0c_%dBDp!>pHbY>$f)rpNtIvIji{1=(cz4KTSa+k}XiqVm_^X*C%!{`)*dkCxlLDYlTZG1u(?5{_X2@+1N#d zgd&os7*Z6h0mDF!QkVI>23Y&C*RYZ~_ENCqt_Tyblu04?w8{xSq#vXOjK@7;;Jfr! z-wqu*{8t@0`d1x3xMTm^0(O1w-;0mU0Q_9eW`|B!v*{ts*p@b?ep;Vp&CbL+h`AvT zW54h%e!8f7@%E$!&aUWNN~soUD{uDzVOFJA%Qia`aCb#q=%ZBa>cHQXwS`LIM+#u@ z>ZWqkI36&ww98@5Wt7!mWPQc!8#PQT`?V@jWP$7}ab(5vj_0ZZ-Q75#vb*i4w|4%$}0u z2bR}T@v4C7WRUgewOASxGw39lsqZjeb^RXwkh4Gw7UJn?iK0@QuO38=O=nG4bJk}15w`b>cErVC%Pi&b+IrW$Z#20 zRd$yL-$^mBw}*AOSZWV+oW!eQ6{A%Jtf7Pa;l5Gq=ehN-RQlP;x3!vTAprYoOw-Af zw$p%FCPhV4=x{~QKmAKwzP&!ctu?$p-Vdz{pw|^a)Xg=0F@-lo0(NCvG%kE# zF;?^eVys6UX?rb@aNT;jfMLt%dUH_5FaTk)j=fbAa8eyf{qAeWhLf-SBcv=_KQ1tB z#T|I*<&(!R&UK3n1fh@zL4KG%PGH@N5I;dg55fqQXJPXSVxZF?RCB11pQ7)Jj}rsR zM>sKb>=_;s@JKU!hzx`a4(UrO6hgTnc!UifeP8lHhDTb0M_Qr+VZ&7+BOj8fK$^ir zjM1HW7a1VKN)kK>Du4rIUJ|RmFCzot-m5~!;6W(#ROir0JL|fER;#rZ7#y`rU7vO- z!A5w@O9nhh@c4WyoNZ>=nVBX%)VH_W(g-4-H@CYBb0UTj--hB-^ z`o0cWfexI*i4Gpjs_vK{&NEY1gF`+$XrFmwMqO|j7@aMz-DHdzg~pi=tNRV5zT1j^ zDMi3T0v_S4rms9HCGru@@W2ScykrB9AykEf5DXcBN-{o-5DaM)BB|)tEvSs?Q5rIU z$Gi(4>)!RFZ@2+f->~CDlwb%{$2Cpxn70o~Fodc?@)1ttgA9)}Q_&eJb#IoBc}dfw z)HmFs>bNQLF~s2!HcHU<1=VrmLyyvVc^p(}P6*OkP!%#lP^h6F^j`H1x1cgcKKddv zKIUDNppbqTs@C-ifpKNn>O4A*yLHPIaG1t+1`Y-q299t@3>@oDvUzlvYziLc9XiB3 zKu6fj!9y0%5jOLbfB`&AqYR%sL5CT0n-ClqqE%=Qe5`xN!#E)jn}tW%q9aX6JdXRT zs)0w?RdrF1c^A70RUswl8@BK;5~?&l<|XkkK?(XIp$rKgLku3q)pP_N0(b~8C0SJu zGexNA1V}o<8wDGmCagUk0Bo@LMo`B*sV*-bWYrv#&;5G$FFa_}bAy#QJjn1M@PT|7 zCj%I)$nYTWasT3D-3cGUN1-Jn`i2uaObC5f#sv8&6v~BVz?fp}Mu)6&4IV>==#WlA zhjbRv(f5@sz$3f>kG|n&@aT(t3J)^@560mU9#hW+4+0&=m171V>$2$B8ai;^5v=ae zP6kfP*IBoL;4v7riOsaW33j*M;4dI`-WFX zaeb8GBdte?gsHyakkKKos?&c}2&%rwd3f~IAF;;?H?Xmfdh4;PvTAP1Z5=vr2_DpP zQ}W&w=pZ;cNch0eL54@zWOU#xAvKd=DiJAMj!MSeK<9g#sUviGVRx z&hAMPGYIP}9X$HJ0GW4@kG|nh%Oxm_3Zw;jkU<_-WCme13?F^Az$VBhvD zpCe|hT+m=!{#P~~e5=)?&kA2*U*~IXHz0D%%*?Z1^+=eha*=qY4r)q{?q?!-7FXxk zcgGf|8v9ZL`0Xy*{D(HnGW10zca~_NokjVzAKdtJ;0W`|eAUG=U*ckJUp!I#s}Z@? zoFNhmak#0aT|<`HMMWCgk6FE+LBv?+UmK;x;C@PrlJvHXS3M!0dGfcv|u7ir<0UyXMt7SJok%~9du|&UqtF+ z2Pm^z@~X?X4v|m0%IY!rh&{tQS++4t~6>;5gKf-Vky zC1Sjrx8=HDUu8z~;H!UTbJ?3i{`{?m+kn__vIg!K8(X6ElbyxAq*h|fF-36 zB2WrbO1D70OPgRGpb@CH8Ha_CZW|hHR>%_U>OdIIL>{5o3+#rb`8N)`ry>qbXDPu3 zR3tEd1ns0pWeF@>P!$N4;uYLRsEZImCc+vCS&=jsl!!os4))@wR)#Y4uYAeV1BFft z0sk&#BT3#%8>>)W(bz!jD}-3MZ$>Z_;3i{(KEmNc-E=nWi`X_tS~_h+xuK*TXNZPEmtRT!?0stgU9ZQuktu7Ozd)#4{zu|=|&jcRZ*5=6A}U5#*@w-0tz7*~JZR_wdH z+r{XxJ1vdz$G#LlwJ+8f*TJpU7top+0wY0wP3il~Z83Sw*Cdmgud&Lj!HEFkFTM}< zt(9E*jb2P6#>Sy!gz5n#FGs*YtxE-IyFx?^)uSE(DjVO}z1LqMtRDh`B1&5F&z2=2 z$fLae^ZL*0Kd=A1{`2}T7zY4WP&gp;)Bpew$O4@KDj);=0X~sFnn|UjD5$7)Tp17& z31eo`V5oBVj%rCi)7i!<-vgqp;=0uF477L|1wTHEN3bX}RhReJl3y>0 z|C7+emwfh)CKo+%mw&haUFS#t2d)3?fABqtzpZ*1^&9>l(I4)&tJkM*?tY=a;QcW@ zWWUY&we-vXiSxkg~HFSRX?A8 z7X82YPi)`P|Iq(AegY{?iU+9OP{y*G)ZTpq_)Bm^okAT0}@7ix~KmY&x{uO@sfB*l@@dx|6 z|NsB_`nh!QOm6qMNO&eUd)y>E6C1tm5*`VS-uDR)1jg@sgolD-cfGe!lWJ3B^x^)2~8J#3wcnzhEd@uJ#FE<)m@xFi|9R`5ALkiE{!8@3B^|6hRF zWpo1bmEU^hq|4XFFW(gr{vHIWUPyFNwf2}dEPPx_=4Y=xxQ89$RAT5mYhU`40B-*t zlmvvwIXg=V_!d%HBli2PE@{+to6qKrLY1`~vAO~qeZYD%Sdl~OQV;rFyF_>)NY_I_ zwyn*;E!(on6O8e+nJQ05vZRV&r>l-Ivo=X-wAI~cCuS36M?BA$A1aMmdh=2y)@uy& zWLEo3Jiddbk0-THb+eO+h5gTXc}FhGd9O>-RkoF~0l`%D0r+Jw#D2Jrk8X+k_g0P8 zzwF-Mv*&6AMc2!Bn?|KTfvKj%J>?yhP#ai=tEj&9n510tF-(-6*II;VE3X6SyUO7; zyM)7J2(+kf_x~W1yom+b)(D){di1cftkt}-RNPx_^TQz-IKe8E)v!K;I(m}N22+QW zg5C;wM6@iu^aoeyBk{>&eo(;6s%aiR>;;+X6_*e$>@#8}D~3DJi2I$L{V9l1jzbSN zI?Udq-oNS@2kv_z*;k$?xCOP%?xo-9)gx*M{}7*Yqwd7jULA@%*@xJ|yW6g-MX0b` zBn1>VGIaWx(QF1V3H}3}PP?~%ZUupL-e|LS zSoKR95Tb)Y88VBpBG%+lIUXkJmqpyzT7WM)eXly--MwVr?Y+blNX;z#J!dyP!nQ5xU>?B8lQb$864+{()>4$lDvCC#3l0A*aD?~y*1PHk~%B}B& zQI6XAfJbFGxg<4qxQlPlN-dE^e5RHE#IuzUN#^Kc4GIrd^+srRY#g>p&cBRN;YL1z zWvH$D+t3nY;U>_#Fjybov*`vVFOOemvn2rhe#(LMddl(BXnl@$_4yuomPDMI&go*2 zz-pnm>WADz{SYI5EY0!j5FYS6i@2el6EYX+U^^JI#=0Qc{)b$I@>!J{biqu-&wrxL4C-B$iuk|Og}6Sb`y1mUrw(yf#aYR2J&wW; zmg?<&Uy25GKtpkkX&1x*!GEU6MNOHGU;<2%3K~LJ-=u@$MN8~aRb7;W-@#4cl8JWk zwU{Ab9gLT7hWLgB8Td7}UycxVpen|z>k-HD{kBIIPeKfzmh^>EkmN}VUo(+-Bs6es z|HL`IwAQXkv!YTQ`0}+67UuT5cii)`Orcq16)2Cq%asAO8_|h>91i^f*C3Pz#+a%v6s*4pgmFI!YD0H&2z;Z89vFAg{CCyONTGLakTCc2RnF`)wxyZZC9r@XXK zNw1YqJiQ72MniB=05&-%XA|eMTc4Q0+B)i<-1CLfoE$LhDsVAM%_CPsLi66Tw&pR8 zj{eE9gpypEsp7KkGkuAbf)Ir8W$EJ%?P*z7KhUCkA$$xE(ogPrp{*+0Y9({H3-*?iYPFfa^ozMkE^ zAMOs6z=%zugFJbS70eKpuLs*Gk6QS0(!xMXkbd15y@~{5Z$+y45^-GcW?YL~K`ZY2 z6sx@MC~w$CM<911K%{tsny7$S#0b1(Rbl8oIkKPJeFUT|(I9<1?3v`S#n`BNs}u8d zHTz11^LwNbn@OeV%;wB5{`94Qu3-6tIj%0hqZk~$FuB12n{_SdjQ*lq4^CrUnB(3( z0}QJ}8@u>rZmJkl##JVo74Leo3*Hk8Bqf?O$OW$mRfb|;D`(=0%AN98E%@_vZa|1+ zKCHm-P3hYu?RkoDPzY(2E=ArkoMiO*@6eiak|@fMqD9&2XU;HfTZT71v5xaeP(MVTF#P9>3IB7jRhoT8$s@iwWQz7!by=>PeC|#flU2VMSO8SzDc7>@IPQGQhL43Ok zIFApZj<0em3L*S(bjJPd&+n1DwMBxFzb>cHW7ZNr4WJ!(O)UP!O3*i0@Vp+2VWR!( ze`Z*$UpRD#MdD3=PQg$16;%@8^312$8jqZIzyBH(H3-e(_DAry(msGb9#j&u-M2uj z^KXH5%$OMyLcAx7Rv;f5HlyorLs17`3`pFZ(nTm4VJMiyGg6BOgOT`6)MmJW_TU@+ zKR~Mm1+<)tB<{{`2O8qM$e+Q`~bZkXgLsT}Z z@@QftzYP7YvOx$#0VnRc^mn>nQXL%|IVH-dE< zY^J&ww4JWgsWLz>c_u3g-}F$3OHqub z2{QQHxy=Y`2Yu{>iBjMtD#;t(UPy@!xN|Wf2-zbkkx4Y0&Z*lQA;+lW$gk%hc3yZ? zDlHVE5aK-lep41Yx3Gw!4CcYsr%~4J-v(@tJ2aR7u#avPBxe~e>sXauF7ACy!Toy= zCs!9H^VG#{A66l}Y}qKtgdbzU^vZ$*984Gc{NMn8&SC$$1oC~qw6{Z&_T$`Xo7HD&>lF?%=; z5V6G+#(Gm*!qo!!G(X=)!C)xMxy+eGw5n9F(}EmAowNI8muCf0*v;MK^W8sJ&{I`?MF<>s%s2%s~P}9 zdIMt?X#yG3BW(d_TQo9RrIrvT&e=a0Ssm8A$NU{mz1RN{4huA%fU%Mmzc`Q+oDq1B zpJO6;kRmbFDwJctoK;h%y%a&@XiEG_+RcrPp=0r|*V!BP>Y?(*cllRGMRRKl1BNLE zut`g+EWy?UM<)@u?Ld`RTs0ch(|&$ablCKXaF?!RNW zHRCe|ek#jCi{a{uz#>+ow+>{mq$P1;&pJ~)N!5PS_r8;Qmja({g^Zds(%GQlva?bh zCtKm*jB^$7Xq!Pmx5;ud@LiZV*LqCsv}qpT>#*zkf0a)-K$DOAfG!gtp8JFmLGUgH z2n0u^*7NaFa<)O(M@l%uZzpErbjK*;(OEn@nrjalM4mXsfBS-kLg<*l3SQr9%Mye- zJ!4Qk#X61(lhAh zT$vS5ob<*Cj9ksCrU@-#j8MxMSd3sz<+kArNA(T=zMe*?;l8$~SQN;~Grsr7YxgP+ zGH;`VQ#Ux_tyovzY!Tqu4W4Q8B1nT`S+XELPYh{-E&cD_XA5em7qW93=@Z=&kBcQN zV-5DV>5OJ|>mf3l%8wxizj0EL{MDDa95?Xh(mSN{i;y2uxr6k^x!SX0;(RW0*nRtmx(lp$&Yj4^AGM`@EUH5Mx%;|fBfFMQnVXRM`zG_N; z*P5+*TM@n;>S7l_%_vKA&PfVx_D^{_iOAcOeC{A9QzXsU@zwyfcT+sWhIDk6w2Kpz z$?Lv)Q1JYM*E`}wDCTz~ox?IICnRR{vBX?YSqjJLTD92**fhe=@mj)UWDjYM)TN|% zB`RoWZGY@g$FRss7umO=PiTVPPH-^8Tp)j+i?F1w;P3SYAo8zEFYyjCPb6uUg1YG9 zI(r`LJ2d9uk~dTa`l1pMOLUNtmfOm0px}}oK_Xa)Kn%e+6eJ(31e+W74eU>=R``NX zFy(~fhfL(5kvq{?k3kXqe}kEfsSdHZed+PW%dPFh0B*y1}KlJ(Q$j)A9ZEUQ7{ zC0G%T7Jp+|bL|IXO`r8hkg-Go_WrjC+t;KrPQ=anqr~q038KT^V3SlOzrtzr8H@Vp zfMveklopx*^{;V6D9t1|W(@peD+`7jA-KVj;_<-HF#P|Nn7k6M-BGJF#)k6LIXo-9 zN`ilu995f1AG1mUMH@9V@%b*l6?T42q)I&%dGbh8H$Z~@N{x|@?ypv3uG2EN?U4`>iW$TA9fuVfG zF6{tx&-)|s#-;L91?$zn+*S&8ofk2~!|RA>M~xpuRYECTD&AiEPfu!%G%}cr7qMC0 z9EW=CSBPd_L2)w31$i=!-ho1l%Oo+&_kAqnA$(5n4$n_T0bcz|C*47_MFegMZQ|cv z;6PR@rQtdb%Yt50si-npvT{lYYPt^iS@JW$-aA+58%4|(6PPs?-=#lgic-SmrI@I- zJh|6?GNcN8hN|9g(|`@^?!_2qA}UJX54F%(iQhxz(|NAls_ksy|8E;%G#8UEECR70 z?<%F23l?awXBH@p>A|b;7g>Q823JPba~z)RxegF^lkgYQVQn(^!UmO+S3)uX2MRGsjl?A{=?7SOe0$^ejEL|`^(fh(Ud`RBcc#-;N8O&ptiuGJ0f4k%GWRE zC*U#=xw|<>3O%u$CNQ`is4YIi90P)fd_9ozJZPDEV~cj|vheJ&xh>Psa82~ZC#D5B zy%J=pbZ+9UMP!J$mQREt@D~(Yy?=*leznP}Wo5Q$>t6iWc^DjFo1V#B?`*f$Z?{JP_0RHdwKmY&$000000000000000000000000aKh>DMRRzIo>Mvd_ zW)Q-8)*#C+tqUgQcSNm4QSP3kFU;@0f85pPOPiAAP`w0leII-#toHti^aOK{#T4)5 zY^?i<)|zr{W@&?kp5C&xJCCEO2&h$tCZ zAwUuu0Z;hA2e~AawKL!dn8*V(E_EuC9KcBgVGNIkcgm0qOiXx-fJ=EKojFKs0R;m3 z4li$O13H!*6qmyfl#EZ+0XmBwN**E)PwSF(nLog%Z0(j*CQp@rRC5%Iu=yDnNwwm@ zCXuK>MD&3NKE!W=B&{Ta*c50wUjPGl>^3Xre%Ux3*0di3s27%A8VMj?LS$|m38(sY zmEm(7Bx?-Gkv>?1XJf94gnUsL1<~hLW#-;Gb;6GkPa8LCIj%g)U2jPQQR%kfs==P} zV_b40aN6z&7Rwt)sW;R}JyfK}TKpDF;DQ`SpVL+f_=je z#@9@x`24*%-TV}`?-m`uuR=^{1Kusvc~5OEgIV}VR#@Udu+-d3d{t6 zmkMrTw_Y(@J0xcnbg3an**{jPC0X1?WMB5(FwA3eZOWZYp^N(wP!u0A0DN~;>-o)Z$Ym6SXimiUSI4G5(x%lUW!$$KK$DG0T6(p;o zQHDcZb>troebW`s5BM$Ll#Pv;k|?fTm*nCGH)!ijv_}=wg+_d8PAoSnMgM=m%YP(i z%N&0SK@Y4}6%al^CG0Txw-^>tV(l<}58mR{qG}_{aIuUxcFb3{t%a49r2ur0F)(U0OoO^P~Z z^Sfvs(xw!APiXNSXveV^h_^Vl)y7)FnC{bPPsD2T>=Hd&-zFj+ZG zhf{1RlzzT_a0}{VWq7c_ZHWY+H&!i}q*kDI0=J?Cghb65<2@d?JX zcI)i>dAg!NhNAOs4Y!am|L-S6{n*42h~8biLT>8+uy|fcr)Y(=7C}qrO;6l5;daG- z&iBXeC^5ah(4HM8WTbm#5}Yq{f58I8pd+KlGYMUS(j4f(H=`^nE(Z2=GO2YRmP#U5blUUZAZvwga%aRl6!IXwO3Xx> z-ae6AN4yH~H-kv|cwoXOe+cD9rcJSjDZ_Tumk){(?QZtyN|4OV%TBrIi|Bd6=x)57 zD@L)X|0@U%(j~2el(V11yIuBA)wg9{m3q>{Ig&g~N6cyFdwJtMi46G%nIy_5(r3C&vr5f#2CAw~jW7rZ76!?l{5w6rHs z_SyCAZ=o|BQ%A|KP5fibhZr%*mpv$ zoiI@*eMzf|?;%>ozXngM<^7lgL5l^y858upr@?|%+;Acn+dI>P-uOGvAem084H^Aa zXxH91=2Fnow1i;$^2KjwbYBZaIkj}0;bQk`5ivKITW^8az z0{KUaXeL=jq&z-I@8~hl5D_*`GQD-Yzm_I|oy;wJhCR#71=@@DCl}ADASFEM^7$|| ztu)8BQ5VaWk)N!>9}vFoo#ANodsd?{!Q`Jr%;U6lQG79n(|TaMm@<@|qKQFlHPqcV zcP+*5mXYu2gvaLYU6q8eCK}Nd&|FS&nL<$SOOqN0N`%oArt%?NCeIjlHf4kFLi|K< z&krGN_P`ECAs<6*Ol*_--HWVR%}Os)^~Uz}e!APUMXS4)9AQe}wTgH*VYD(()}Rcs zwX#^+P}?aC7K+vkIvI(2EqmAb$qiF1se?!WgqNW#p^7b#e`v+?j}nuOyIj5wHu;IQ zlzvs_GgYnrmRV{3BOZfrd6VccZENJfM#rbT?y{SxJA{=BL^u1k4o9KJc+Alv`cXqu zD5zyD>J>Yv!uK2*Up^~&XRy6*S5uf_R!XMjW41$d=h=IAgxeGwEMr>Eh{;6Q1jZK( z7|GQ)+fj6i;=#(B=-~0nHAe);j=iwJ`Wv$Ns%2HMq?_5w_0huK+UXMU&>X5b+&4LVo~}46 z2el1d)j*klg7?k#9s3I~<(6|bkfd!Ba`^_J_ybuq7mEO9>dGCfAk2hsrC1`x_&scm z$(!{oZ^ASCctcK#=`Y~yc{(kl(RN9gsV$e;D0?VtKjyo_^Cg-%*i)QSuY?%)$tGUd z9E)+>@fv3AZiQFe&!zcyGa-YX&Ng|N6dl56k$P=!ddL9Yd5l&--kP=JH2MLJs|?|F zvNQ_@`Uvytb8MhXkcPLuFBZr$BoX4yLL;!pcl_GEqj2~rBX zMRQYUFZz1g9}svB@PH!O)8MG_;s(qz=TR|dJyR1 zkFw^@48%jb9CSG~KIhSwc;_9~+X>vLmOW5b{kyL`7kE;QY}ILYTQfS17mYZ zGdux&2)R7UFb6z>pze$zY9_Y!KGk9Ps`cW6bb)9oyBc)L$&=pl!s+ z*Nkq(jqAgsWRuck&+_A%$A&7HT+Ps`t60kWt>dAhR=O!K9$n&iXJYVX9snj`?o15( zeoKwy0=3fI@Anj8MHM(nMz$ByYNzr|&*QygdC> zjjwbL2jJ>wkR!>e+uYltGAWt*xe;F1LfSKI6C=JT*kI)2^`*LT8-MT5yO!L;(LByg`s-5i~WU82J<%gH-VTG`|cuwP6YtjOH6`uvLR?dN~B|X=|1% z>^DJ&x=j4;*YjW+T>88nb;MdBMXE^e;!8!yXUzPyp_r|Jk?lvBo~?pMhFTc%Sz%q3 zx*FW1S%XnGQ4fXQw7f3Ygc3Kere zb0o_R>1yShvLX!-0HOSA)++a6PFtW^P6Mg}n-jE07!1bCvn4psONjd_rcUP@E@7vd!oV>qR<^ zWtx2Q<0;5GW{I_atpm3ZUq4@RkmQmsY^Ij?e{o8{ zmnYcmx$Mumxn(V^>ZmN{&AgpztTlurWTfa{wND$HFA1^FL;n@fY?P&z>Bc{>vxp!+itFl z(-~WhK1L*O!NiGwm75N?XjRo0Dwsj^9{IvYOoi7QrWmeeXr(E9?WD^#t;Pod6?1}( zJ3tIB12Gqu_tjUWoBMAP^u>6wHx|O+!_xS~jlyoWJnXrZ?%3Yjdm8Z_7g_{<#Mihg zv@0R^;62No9M4q%JMpDce;69r_Bhc2LBh{rmxy2(@2iN6Kpy>6;yqy-r}c8CV_#c> zeEJd544{to+*`RNFGZT&DLE{zzTE%{ z*{|B^s!usO$^QUf*1?K-;Ei>E=Jzc%yT@$WDlppPm9*+zV;l*38a2<#VUPn?wX_P#n?L5$G^F{h|5<->#+(_s`VY zVKBXp{3GRuc$qxKNG2f5={x)V+AVTZO7n+gXEZ@%F^3uVcRKAp7xKh&eG@Xpf<<$i zaK)eS5Qvwf;XD;leY{#b)3p3)`iUX=tu?t@hM-!5DC`z z3j!k6%Oni0Q=l1AS5vP(I)kU^)eydgt^MWG9-S3Pf3K^bU`m5&L=mHQ)x^MYI5}m~ zqfCo43tvCDSm8M!PE0wD#z@ zm;dhzOY-A{<}Eoqu9wR#qJ^Ys0E`5jeLMKh&)-c>?F$-*M>U9y{d~H3Z9dWzHWqdz zz_BCdX9!7Z#zp{m8R*lOT!0gsixL%STehBs!o=u|2<$M9a%2^f`m5|^)1hG9^?r^&XMh&J?G@e4>@7{_jG-Pi z#jgF}&#WK8tKOa^5_bawS?8jJfrT0o|1j~2(IMw^8=qhU`w9!kPTP^y zm$c4BF1cMOG2M>HjkyZ*=JC1^?G!o+zy081&iQPJ+~+}Er&O})kpMc$fjT^vDl_cZ zY(WS+S3-3+f=s-ITC>vurg5dx!!rF2i;W1vGbd*_`!&2^A*PZcW;w!5+TVl+SjDR> z_~tdSe;7hFuwpFaP9H8hF`LItaTzh*Rf8ffSN{P?Yk3AmcmT?#h z6u{|cf+1J1PyjRw@KZ!M5QMsKIxx(^#POigtPXY)|GE_J3JGAFr5IC?Zs5Fc&N+lj zYw50hAwpE#1hVdbfw(!kHuomwG(h04Dk7ZdS%UaE)m@o-nd>Tp*c-rmCl1U37^^D1 zh_Mac%odLr@o164o1T*4dKpsQ=Ds$o*)e;RE-3|H|K2_Gea>f^VLot-b&{| zTyUiIKRoo2RL$ciu>yNclMukqnFMeA9qXVh0@(U~`cB8`^Te-iO5!8|iZM!rRl$uP zxx!!)nhjI&ww4EZcx8}z>w)W8KzvawRWZLUx?*T_C*<=8Htrb_{9>Lb%ut6(n_umE znSG*f?-$okqEM_r)Xrq2h%y2`zF;qLa4&E5&t@Fll|0d%VNs-2+v%0?+9KSbV=tw< z`9~Tr<=}mU8T3c3EZ>>r^QhVT)s8}FlyqDR<4oh!o+6zP8Wc_QPhZ|2<)eXuKrRY& z9M+-8s0h=q2ONdF+HTIZ#!11I`|8$o^APvEOOcs1xAg14g$q_~5qsl{ey8AZ5K|(N z?rTz{2WS8GPsT=SXt--u_cbdS`Ei3pI{z4m)mG)`|FbvJ915qqp zj9{n}&D54Z%Ju9Hm3Ici?D?6!>!Pw`&;w0eikq_pj?i5BgD5y}A zyci(@^+qM^bCdlxzkl)9VcI|RIYV&PF)yt1(?JPv^A5WJ0T+&!o%^A9!Y@5GEd@bq zfOP0N0$C1nI~qPjBf}1DE*5Nx+6*E&q6X7I2*xE*NL9Ld!u#d%XNB<`)CG2BFFA#I zeG8!!K;pn^C5sXbFmC;!THSV(Vk13hkcqrjU$3XJnEOOy`0LKaO;2`h6CFv;JL;Kz;cPb(0#{pO>9(8+FBqwt0dtG z02Nih#WoWq%}|^(&>Ba2wz6+QUnl9})^gQ+o9;YCLWO~;rOTj}6BBg8@o(Jg^oJzK zr`7=b>af+Rv+L{eJw+N+bof!`-Dubri|6#wGJxbGH33Qg0xAr}%l7Htv@rflm8-88 zdG}xy6VtmZ2(^z}KIxcU@%{84M zYg9oB2i3zl5pc~g6>Kf)SL`hky2ojfRV=j{(CI-;)gt-9uHPnQ$agMcw$5_|2Uc<2IdLq7~3HywlgKC3Xa^bk`@XAa- zCMNmJV=>Ib2U^YIh{k4y`F^GZ6{4az)F)jBaS@SAKn^RNTB^D9nb0Od+vpv@=~MIo z0p#xi{j>kIJAO5E-!cjx4xScn(@rR1~ZvTTuc@?Yuw z4Ed&$yfKuB6oi-QgrQ49A2AocvJpw zd@DfW$$k-uZD<8{Nu);tO6Fwg_`zHl%v%|E{O=_$29{Bak3mc}&i5)xV98s5FkB`s zSOQFz(n=L{B@UyOPBLGx;F(J5rz~n=y4UwDehWt)>I^ydr)zJ z3ffqLSjs4sS?$D%B{Hf0W#{&#YzP@Q@Y-U9we{VOlr6vr~@OH5=o52*-R&lx$jFkO8P+KK2*BHdn}Vq6JHA}gZyr#YIw z{Khwu;~D93Qu8Aa_JkpOcs0)E$jMFWWgC7$;SEa!LlG4Ru=k`cXm29T)^}BuBznk!=bz`Tq z7VMuk3#`vI_=Sb?P57DBLFyH0RP0KAsxKtliCE?y)r7QW@%1vLz{*jcmH;>=PU>HM z>_A31wnFqj@)$1;j%zMA311wTsK}*JY_9)(Sj~5FiHyYSyNoHINgb@&PlfN_wPfeg zfFgibDT3*q`?&pHA}CyrVESASn*qqy<61(AzK8Ep#J6(KXL$omz_lpQD*vPfQGAdM zA~eC|x^U&Iu{0PPO!1u?cqh#BE+ASlrtgEOK!_bG)9j0QlG3j~u7&u2Yh!)1^>L5D zkg8K$ZIB7``4mw?tUu|F4VV=FgH~Dg=h1T>H7Apy-0;@4fL&JA}1tjaPYZ zbwN^Nv#b>p^k0$Z2h9z~be-ob5kKM;#s7}DT#OJrLK?6FW<|fKuou+tgZ~|zl*der zq+)%trD6Xn!UG+4<#w@zLZ~C+h~0Za9?L+y+W za9yDduAOFp1RyE75|x(S#o>+S-HE8 z##Y}p!ae^+z09IQ7wZtlRY9}cd5Bi29j z9#S_aLEZS}&y4FxR^$+d)+ZORhtl*#q?mNGkUB0F-EtX^k|;xx!ga(aqF=%Y)N=Lb zwicaRC6z(dn1QJUZ^+?wBjiW|nezn9b8Sg#?D@*dImT>@y257n;?O4Z1$jfT#%hul z;tNQm3k;d}16`{#laT?Kyvc_Em7=Hr_X|m=U@^1<5%$cGz3#jRDczfrtCylXqVDxZ zI(+VW4$U-)9Z`@KLT^d;hbT|ZswG>qm<{1(EyVn}oEOUXoyrrU=r#>8Kk;2}mOJo- za${bDqmhvDoM(nU7x=$PZTaWg5HWvaw}cjG6ZPe!PM(T%3H*^N#L_u~s_JeD;tNm$ zaCytf9^9?PPUplNjam2Q2HJQ%!HYO)D@C*oH1e*D=uc>FeT|JRHM< z{tUOT8KSI*4T%aXHZ@5oUHA^nDMf!*zcW(l-`man#_;L0=9tVMkV-8Xwl|F(NeKvA z5pGd+4)wdpj=VW4+h?0jeNvOK;j9O2^=io^hJcm4J!>P{^+5@6Zmx-)c<9(I=F@!p z`iNe{M}jhN^3=u@Twm}@T#AxoFg~U;l;k6X;lg`b@}D@e$fJ}T4y9~!_Lq!0y?A5+ zWiZdEVUKcyzAYwbl8;6eXx?@jKw#U8s7v?cN_*#V)!pD2@8K@RE1sE@O_X}7?s9co=CpJsvV|0fVWMJNsSIQU7;U9=)MqFeYVHzu1` zG!fyC=@p~o>se)6?7}gWeb1h}<7RCdr@dD1-3H`xXq$uj$K{03B{*;tXY~;_+-o8j z-)P1M)V_d&bK!xDd~f3Mds@-K)ux1|fb$RsN#+iv%kNI|8#-#3h28au7_RFIXJ3=W z%x#TRz3`AxZbUZEhzpQmF@HC8cikF*))4xiznKBen;Kk4-C^d_#92#qwB%jP!~i{d z{-Kt%IT}`}aQ;=V5UD8C@lg8(TsObsuov9^2T)r?^sj5s5 zBM)yeN)_2nb&R>1>pgv`zo8NV*6FDBP`unU!6>bH7cK)hH8-A@!#%L}BoKrY$IB=- zQ`w6w)h+ttUFQuYc9}ZP@t{M-4t{1NRGM96St`(KNB9MhhMRH1D+h&IVe(@FGZWVG zhNY|x{*inqq-1US*^xgzy7#_ctE(U81(%BC0*)5oqIp1t1}&q*CbVM8>B64tn`JSL97-#rGLj$QHBOeIlAPD< z-BI!Bkb*3J5+wSS7xu zzQ0KaHc>yuhdCJ}1aDy=(58WSgHtcpyvpr@Du|Ihh$HD*dQvn=vRXwQ(aR*-a$TO5 zN(D!)du4ps)Vw)EndPxRIeCAsx)#ypnMos*8pA~NN+o9_szUyX^r~u-wkP_CDpY?c z-A36J9#PFLN}VVY?0g))k0F&t)=uTsDs(ruRun>}A4#!xU-L$%;^j<2D+|?`nb~;vQJRY@B^6q5Z6B%BuHUe1F zs#Fv8=R5QlC>XDe9qS4TPIIRAIp5=J`iXD_l=QmBQ!kMpBf)^2{6(ar8C?4mpIp=f zq|YGmZsBA#(BXq7E7lbXp%8sm-BwJIb?9onkg^S+ky{E3{CyyDaiWcL+*89= z-+qZdlDK(Ky>$MgJ4L{}!Q3`)F4|38n~fe0ylE5}341M8`OD-*o8L=5EnqnfVd-wc z?7+0ic^g=J7{O>qcDuA}p;-I3*e!M{*3pujDv7se)*EzU1v~|(Ec&r4YO|pWF;6ci zc=&XIE~-y|9|schWHGOnAt*LCk=!Q}g&)e51A_iAUF4o~FhY3v?zfrAFdTmycwGYz zS6H8A{2y_GdBrSqPY1PmB7B^rlX9{Zd{hGaiyni&Y8F^;w)JPeUQa^bH6Q$PmhKu8 zjqyNYS0f?r9MQA18Aaw1R>u8BfW5xL!jA)Ugu)}qHt_^m&cJNt4i9}p;G^d^%-Pw{ z_R`o;hYW+2{#+GDelG!<)!Uf~G4%jDl%{-Etwy!)olEes$NhBLSGJzwHivxRT1Y`JWqYZou)0bhsqX-wJd9pUB6d+EY-A# zMDw-m!zmX{WwEpuaHuG>YX-UCW8@>*DNBd|9SU4J60^P(!Fg}$I-e_inepH{HMj<5 zbuAAPbG||~mq7giVfrD`sF#33HfkB9OgR$5i9-O+jJgy6W3>9Wp6P~`mOz$P-hS@7 zdLJZ0)Ds+n(SM@9M(*=(_UBi1boGHMq%*axlHzPwDh(SHw}blX+>k4jCkpEMR09b8 z)5oMNCkj0cUu70>3OSHq(CNm{MBY>~Yn}oZVOpdu{+PY>O}DEXW(z*f&cRteUbLt0 z*Lx%WiZ=Het;5`-%j6RxeN$Ha4E0dR>2RsoS{`dX^s`YVY;F4%LE1?!*I2UkR%geB zXH7+5QI*t^ITQ@h+g@bmi>bi;m>~39$FFI^EIv~76!0nOh|p51cO+{0!_GV^V3~Gd zeJTGCt@HsA>4-%F-2pe!Z9u5`$>=%4riuf`hMabKD~P*+!)f;A&xyf@@tA9sqjT3K z&H|Z`cCz1%o(IHm%Ta`NX^bnnG?56*fDQbfxz%M#t(`ZI63rnWmLF(=#%(88ru z2MP?YcYx;%T7EWr+nn^OEJPqdB;Kf9QOkRgE%lzUd#q z8~H6E`2`Zu5~1&ify*nv8l=!vQYBP+{q@;GHwS$#c?6JJn2Sh}DW5Hi3(w2;5?7&` z`SqZk#Y>IAJzR%7GoH9ifnBYD@ZbVe!RrJJUHpVeSt==?RG8iK)e_Ep>) zU6k;7*CbNFkgrM78P9PH@g2JP*04zf{Wgrh=S<1G?y!<;={8cEex#9SRpm3lRc{j}REc zR$Pg-W#0i=%jb4=bWJ`*G3gS7(l)L}FfcH1hPZwymTO!Ee|gyCs)G)5Mr458v&&}d zabRn|4fpU)oM0hgtN)5%{%oJHnVYq!XSuPe*>``6uSLoAFmi4|Z0zRd@?p?SlwKZK z3*{||*u`)Ddoqe)M4I0l8tfOp4|7sCplQ3k`P9^Yn1w+3PdL8ArYfLZf}A|{Q&w!4 zJy9sPZ!Mb;%o6Brx%8vg;|8H|EJFXF--Cm7n3@+9tkFzR&anc4>kQX0}fdkln-BGwT8yW2+d=mmriKmx<1^a(RTTG$xIPMHyL~I|&U? z=EAFDVXwMqZ7M@PRO@aTgJOws=LAm+F-4)9lC4n*yf^em{W^84-=2HI*Tpx?8#EwW<19HFI)@vmqk7uSdY}OqZRiFh)?IO&)h(P_KB0?0+fg zdB`(;uiS9z|Qpk#v(;1sho zs*mw-S;A=RT?E=~^lU^N@7|eH43wmR0SCS%fRN(OOa41NXLg#HB5>aMf;|c^E@u%v z&TqG+0nOdg{f7o82*3wj)7&RO2&kiespBmCS2@nZ*Y}+ndCkSiw>ZyA*FXv5g)*Av z>MyGB7iDj~v{y{R#rmshuAIhXNigV0JpOC=Rv<9J_p|A46vSOAA$-0NTvrM;1TaA_ z@8UmKqL?q<_Oc)eh}(pjtF1vz_r|iRtsyaZihHCXB8zYJRZWP*SmtB&6*b-qLv zrvuP&8aIB^uVQNOeu@R|7h|3jMh0dJ&+B3&Rd1G_!&p)Qb?U5GM!Ar&qy8EvZARK5 znUT@lc(Tl4E}&X(?~wZ8_*F$5m+qSR~_I zM2akiz++8AO%2s@k}05PT^`)`8fg?!29d7&k*x zIADtsdJL2RXutmT?}{qqw7}tv$s$A(umQYg#yD=yyrKYoFaWkF&rmV|x&URUe^m+& z3a`Fq3o=Le$?Rt&<#jp7je$85-?Em+Y-;DLseXt&2K&r#3mtToeA#m+iUU2u+mxy& z8uZRU#=!MJYVO)vKN-&t)3v#fbJPCmGg)fhLYHnKIS}x(hoBDbeA#Qr$`#Dh`goBkc^F40|;iGaMNy z?Upajd=iF;e?y4KWplq+LU@GlxPf^O1is{62YAFIvcK#+C;xC^T+l?OxKCKI*okP3 z>tdBhRVEP~H7The8Dw+9s7AmeFthMKHV%Pfz(u#E@*t{cmVGKW2Fy}3BBxU6*mU<^ zJDdkBED26iUJo-c#Tnu_{_WiGh#sUvQfPJMmFKNi34qeBC6tGm>}ZFNgjA8XyAa`z0q%9Nn#$ELxTZU8 zm-~=v2EB?7Ar#KRq~!?G>;+>k#+P9aipF3PrJ<41ixIjDB->Wg06C_q8@W8MHh~%B zH^1>uJxcnJlVQbm^@T*^zv!<5 zNnV0*{Q$c9cMXsbM*T~bnw^tN=g!lZTlt5wv=u(I%4Rlhp@L|aK^ohl(rxm*-fW6w za6P1c&5T=>t;g>?r4nT0REENSLa?Ek!%#6KW7To(D2Jn3*1|6u`Ecu}yQIFa$h=kU zCAf-?-KLyxX!djom+7r)u^8!5kiu@=p?h6X>zSebXX`;OW-^vW?L@yg{#=ELENSZ6 zG}=y*(~^11S#KF%xD}nOHy@W2l`z@wds&M*PMXq7U&%n6EhDKuMvE^T!D+fE z)}rW!j|(qSa{}5MbQHDiBCJ|auEkMKVMhS;WDPpVQLi z3zdWsN{2$bv;LI95=dpw&-3#*=kn+00LTBW-v<~pw7ZqOr6qc_8^egsG=c*_&h6Gb z>)dl5rZG>~oFtoI7!Ej?6;t9eLmrIdHh1;tD+=6#-##Y=rD?CnMaBS{)Rw5j#Y)3I zgije8@fN8|JDu#3V!nN@r*n^?L2qlxLz0a&1o|4CS362kmpqb1MCjqw#~7rjvnO8^ z-E6F@!r)~;kD&b`V65vz^O3GP%43%9%{aw^(Rc{G&RHqp$gE4)azY_#7^70labO5q zl>HzBg}RJv&~$7S=gcQWw-|(J8|IyG3iA_RfmFWu(}bLHG~Oot8VMLA;UCzW7(&?WV|?=wgD$?OA?gu7f{V&}?ER zAf2sG5rd07B)D;%PVK!z$v4U>sNpr2J22lEoRoIw%5#-!470RHn+-P#e_c~NLu24u zDCz0$dng4|aw^%t0%bH*28yISo%}gzMy`o)wJE9 zS-5{bZbRxJSJSH+VsYk3`%sXMqv$VE?cXuUySw>j2_VcVrC7-j_^>oQ6REvB)oGmL zAPv|;p>-lIZ`WVnBAp#F3SD@-`dJC4l(y^&at$Qe^cORwzvv|<;jkkeMn|giQZlYT zM4(vST9ag4pqNG(mT&5|t|w@X&iQPzI7Omh6de@GeYe#Y1riw^6g9i*B)p{-P)fP? z{%z~sxjns5Y}4^5P&oa1eQM5a+9ga^!(nUU6;#nNhs*@0M37OE@Uxm#`_N6ZC0Z{~R4GZ(9#bg>)Mu>eAD!im#n)tnc&T zrK>jqOSNMW?vcEMc9**i%7Y;-HHuel85y z_J-rckWJB+dAmw6@2I?=#PUN1j#`5Q4xeMQ38$al2c1fHuv#(tzmW)&vRiqRz2 z<@9If?FF&Lv@@H{-Q$TLn%hskUGGJfhZh z(85f7eQ7@|^diJILFGj>W<6hY8eS%(z01jGpBhZ^`IHhA{;lCIVG%_Vqj@7h+15Qp zcgirphkVAFT@-QJ% zY`qrGIRp(SA9q;ylB1B<+Z3%c*_|y^LSqKcktyNWkVO9gpD?0|8Ll{|Ob_-5 zTVQ1_pxgOaJ5RkOa;xf3MpS0lL+XVUH0)r16_lLwHH9+52{7%K7Iy7fIX*Xe1DdH3 zjiz~^Y`fmn&LlxVJ|7#m6pV>K>D>P4V)2W#_Rhjdx$`3;?RE(EEn`13>7Lu=KfpBpBU}<^aZv;ep?Vs6snEfc``C`E7tP)Be z9Xn-Pw>)$S#N2;m(ZE+oe2=@TwdyyLD^h^sT`rW5Q6>02QIde&73Fpm5vet7Qg!#7 zBZe>*4dr+Y`EXqpK#7vA|AOVWV8Rp zcO(F8qq+(1rQe06tLWKMr|bB=+~ap0G;BkE<=pGZ`*cE_J9x*DUt2OzPOrcC50_S3 zDqY)*m|yQ>O-M!qj@pVw11m2H$(CSjW%7L1uS;p0$`NkgT%UmQh%NNl4}V4%{!KjQ zx}HtRwH7N^#e)%7!WVyYwzC51iom8~|Aw1!yp&7Ui1GnQrI=r9$R}IYk_}RZt|#Q zr6-qT^?)i&+hQ+a0IFwF0rX-Wkv%e`lNWn^y&cLXWFQY966Eo@Paft=+KU{Vg zD8!UvHfCN-m$^Ef^*CI}cyoVF#(>YbNKjcOF1SB0b0<3Q-?z zgOI5b&FnAqK{aB0V_ppmkq_GQ8XqMx>3NTEZED4rpz64Vt!A_m9ILBjUZXFb>@3ie z52t3Mi}(KKihr3Rmxp{_?+5`g%Jf-t(YxGcCy4jXYj*%>2Ts8t3_p+f72E97+Y0(- z!_UFa4JLO%Phv_II^z@0NbMTG@7&j8$C`0CWfi1;9{N&?h5pC%bMoi3KTEqXwM9ee zC#MGQkJh{xcZ$?0Qeu3m;A*FhA}WtIWweq3jDQtFt19_&mMn_nTcd2{2SP$=`h;9^ zgL;p(Bov!(y63lHQeNHQrajRqf!@z}kTdH$9v5CW@N$0kJ*R&jdxgDFWR%o}h_=pJ z=R24kLTqLbpj^uNRHHR(2>TOehMz z6=D=F*wiPX)LW5c&7nsk;eGDvzxV#*1gNM@^}8iV^=f1Qc0n3`D(ZGw96~gmnB5;1 ztq6<53*C@SsUe7<*~{~d($s0x-6TRKeMe#Orj&V+k?-#NNF&0}$|uw#r0;O^<#530 zTj1q|v6i2nI&vub?yO}aPL){FSd8FC-W%VwLJGjsXEsnhDmYjRBUDR!;c>CM^>FKN zUK^c}TpcLvk}3p5Fg+5fH^tvKV*7(@oN9<^Pll-SLmFl>ge~Y-t9qxM-{OWe^I|UT zHgTKH4A0O2tb978mAaiGH?SQC#bl)#iM2NIIXurwUMBSan1b;SFI|zy=ot{jl|P|h z?4fNHH|NG68`Xan?fV{sp?_%Jo6^_f5(TF=r4Pp{p99bnSTC3ypQu4?7JX4jGD?-eCp{U;?w%K|19;hE@q{bJd3Tc-##Pk=Q8W#U zd#|Pt+|cIpXo;RnPV0GT>M^#>CH%~x3JOU&BLBiZGl7!Q5OPY6GQbUJfN&@kT%}{p ztZ=(ToH_%7O@o^@7vAG;7Oa9-2FR}H zKsyKI_PLV!k8%u-6s&^ShH{8W!~Grvw{{_ss8{l2B9iuS@sZ7**ml4HN#kD1y(hOzcX9wRiFvpw^_RX#EqcyH`=UYjec zu6IIJ(lnA`Wl{s@yz;Gol-%n;U)cYLofZ-Hm3TJtPhQ;JjbE$5ov5_5mxx%fk+nO%F(0!Y&nWJASiyz08YUg;j|5~R9%F@?phqDkn#?Y z8E-J!q`^Sy9x?kFYVrntQq@vnBQWZ!y@T9MLqEyNc9r!3#8a(;u4U>BgM&uT>`iRw z3N5!-iA_Q_Y80~u=hdF?yd({!UaFK(GuPS=1l`WSm0I?fv}tH-*KHB2_Hao@^VKJn z6RoJE8086=_dTH9-7oa&^78?8g{MO27(IFD|F04f{A-~Y${Y3h(hQpHq)`uvT6)wy zU!F=w<}JV{kP4k~_-H+}H^EER3w#Ww#%W75S_mXZ0N|8oXfBr|(Zzr^Mx3E;BMkQL z)aWEX{rTP!nIP8mwBF4zdxwk?~3#H%*57E}PBbaAmP6;o`NTP-tX%?OUN} z-QYG+a*m#keRc!ARQvl0SNLM@Bxp}A&;`>c^Ls!lB!@aMyVaIFX*UM(^7TlQ2;M`# z#cAb)vWb4+_&@B`jlT2Y@wckyOW}>YxaIsy+)F*}bFUf)3(hyd zR7?eT)1i%B6B%2}exgff8fUOiBy-!$1$*Qi+3pj+$1(FkoUI|K&SydI=;QLRT{li?LILtM<@+o^yZ&{T|FhFA8l z=sg$#eZx8dLv_fL|J@U#T4h(DWMf$MLse+tImHwjpbz1d8a~s$XQdfsR&+*jpf_M} zwfFsHJl_SD?$CT2b3U?M1}YZfBEb0kXw!CBl>!TqgV=O)y+mvG8!E9KFY5pepM0V()z-bxZ^sitYAiERIaI#L3vI*p)og$76xk@zpM1?&SVCbGh3&csPPL z!(DDzG?)%Il9BY7JBG@N>pkeLwhyUmrGk~2U^3)%`^jov!;j|@J&g*~`BSINhL~FA zebk=1>;=?1A}dpuyek@hXR(+*Y2=A~Q$56AduhbHb{J`GxKV+T=XC0UDL8~A9!$sJ z)UrY`uHN!1Y8z0IZcJk0gOW>B|BLiVsx=83O4RF++9dz#SD}s*>bu)) zkh~%U(}Y_C@jEqF!MBI9&$}Z#y(rVS)*81Aqw}98Qe&EM)u7g!xqOV9RgtPKSXO1B zNJpOzT+7MWG=zOLNvTXm^OKUD?|*=H;L;RT;Az~?vxO6^<|O;$pS0;X(xg2ZSI>1$ zTunl>g0?S1v4ltl}|te>v;MX927VM{IU_e{J9xXR+rq9$qBdU2D zE+Ly_vjf>B5t4(*%pXcs)C!iRr~pic7T?E(Rlr^VXG%)ECCgK2DriAdLyWE^59sI* z?h3vgR68>7+w>YAAVuUE=Q3>U)${QJCoYa+pY4*ofFGp)ynEmk1?He~QJ1Thu1Hw# zIDpW+8L!9$W<*b#$A|hG!Vi>;T?Uamf9%FpcbpmgQ#5heA4$BpYi-c$EdM2($1D+m3|6Up)w8Dm&l> zjophM&_T0i;~Pd;IAfm%YA=U*kO@dHA%M3ZeklvoDgx!6qu-*WcH$4??JnZU&rrWODr_a;2e=){EcI$r7mX@7Z-(_u7_xN6e}PUR4%S4N9!{{ zY>hdsu>MYh1)ATD`|kH$8MaFP;IeUySS+KlMMYx+7|Tuq42I#LBz$NmOFBuV zflrUk#_{P{jwpakwce;>4pDb^Qb!GYH~tC{A`>X7OL+~1LA=D(ECELo=J!!!5w#&i zEj6fYFl(W3$64>`(fE2zgGz_b=Oq|Bboxj7c!fU!+!KX@Qb!iKQ~YdlDKtLsuz-bO z4P!SKOE8|?`=l%qA+-fI;&`o12IPeNi@NNul{`i>QtY^ZYxkM}{8_8HhQ_52MF|eb z8#dGo(?s3J92c;!#4F8XMfLZ;2=Y_{kKg^bx({V%v)3D|@L_akI&4Sls+M46jvj`| zbP#(t3NP~xOVH!F&mvVv!87!Aqp{NCSB2iSQ0ljufV?-4a16>;0KF`=(P-cA0m#@0 z1CLt%xu(Pe;ZQD*TivKHmBBU{H;_oDr955OIQ1eE=szrGr^4Q7l?9@|c)vKFNoxko z+-Kj^3=2Fu!hFG)0;daz^~UX`>i_;w+>!5qh^Pq@qw{haS5v=xh8!u!tJ1i`;*lYd z8T?zX(ePEPhdKq?nm`;-%FyvP(@y8_KP!g+8(sq6w}Ko7FIs>WF&7Y6y`!=j(&!nItv)x_Wx!$X!4Im&V1U~a~dG3xR1Igk0O!MP<~<%H~>~$ zSOKK9&GfO&pFt_sBnUNqx^=R2HAvLDYt~b6dBrchRK(uAF)v)i(?$rXO9YItlRw#I z_Av{^MkuekeHEstI>>UJFVufe&uHrOOh9OT{jBt-Yy^^E<$lW6Nzm}*kd)n)QK-(eL3rtRVcO6#V`%R>TYn5h}TBe+`u4L4<>kDNJv-%;y zn>gyZgks9MWfJ0J+uT&itu@fvo&Jwk!pB12w7k8$zMATW*kY*~>#=M# z4vF@mlGPO8_H+@x97XNvy&7lOkoFYw-=`ksgCweZ5}$wqIwE8p9~%3&!KdTUC+wyf z3(rEpqhrV_!^YN`fD7~r5`4wLk)fb?_r8;wuJQ~c-EpN)(t37Y(}E(;u#Dw6rut_$ zo~}etR0JS_b-HK3^Xz?hcu9S}TA4#`wrt^`I-B2U1BAs1+@-_nfzH_5-33QV$}oo+ zUV~-pEkH^_%aZ;cjzMvn7F-B`(3sepjhhNF{)*HOpXu>3nvUex9_) z&Kg^bc@f4uUx#LN<|r)7;NAO!Emifk{=eP7KFz!k!X4d&r-?lzP3EdmCKRjs{>}{cxFarD#%|F*7eWh_LY-CR{8LLG>OAy$< z&`YIwosZDfidq^wA-NodV->&w8z@^9ulU?;vpp1{8fqcmQf_$--dFiIiamg8p@o2m z>iJbmlx7*K_MkMYjybxf{3qU+RkiJ;12}d>6`>Q58of#bMHv^x7dar*8?ZH4sV9bI z=N?-!zgVQ8EMjOF?GI(=Tfuh+k)m135DcA8tiz;Q%M)?-+#Hmea{tztj`EbJg4kCk zExT;$OHDG!VVWnIVo3TcS$?BoW^Q_NV=I_z%yuM13{-5Vx%tSe6%B?}G}oUV{FNve z5$Yjjc_wn(l@=JbR;~~YZu8+gE<_DIEs5Tj{MTVl*ZV1|JXi5+N3p&F`+@10>&HY+o< z$B|zx!>o1LS5P8gLQ}~B-W21CaPdpLbOC7gDb)ZwqH)J#U*Eaq z6D@yvDDNN<#G!{~07_;HBC7@yoms6Wr@Fqm6#IooJt>-y$0-#2nl04(KBw`|j#^p@d@#f;Gu1oSH0+gDXis_fw(vYq7 zH3fUcg8{I^4U|!cW6TZGAF@X-ZgE>dW$K^zeiOpJdhJRDS6f$vd97Wd-juo5N7_daMc5al)liGJMQr$+Zyj zqcM*X(p5W`cGVM%aNrjde=#ZpHAbLo6&ZHWIsZbQnoxX4vS2!GInV$&93=o9w|l<5 zAR=gHf?>DnXcp@}Zx-?zA2k^rUa!se&@e<-+o)j?46WDInau>etoG=GMy2<+3Zh@% zJ9M5wSdWT#VCRpP^>32u-M{>R&H-{|?gKuJlsUex&A}A+=ga&;_TJ?+m$^M|VBf=; z^V>c-tGi0WBP5ZOh5su=g?PtLE+;RQ{_a@p;$^8ip8KGjmRYio5#$}R4K{u z)h^jB2AvC&%~bJ_u1qWXM5=FS^^V7T{RF-Hdt;B+7Ze8Yjw*70#FMo@D_<~)`_-%| zi(7Tl3e9DO@4=BsDtHG72=b?;q}44aG^?+N83aC@)dxDYy;?KXg>2lOg~J)4KvKpR^rQIUXf#*qQZgtG{|lLrNdVQ5CL{+XHF49s^a0397D0r{=uIw%I-+Bex%TrCbq3`u!m zxx6J?^y(||KTXLbLkze?s|@(o0)RgW__GjPvA+)aqq_Evf9#_3Tt+DI;0}cd++UoM z*m`=V&!SD#x5en}Up{Jk!ylh0R)Ew_Z>%Ff;fVtjk^{F_2h^1iWj?BBlf{r=x`nl* zW*zl^PI%(lpg$NwU_57VCgBlE)!OOv<&&642s&8+cU$?bwnzGe;TM(1xK<7cym*Hjd!h&M=A9eQ0Yi*HVZO9 zI9^xH0s+fT%f?_ZH7e%qnr|XY%&C0SS;3YepHrIq`IHhNkkK_Awwrs;^D7$H&s0-$ zgOvDar5w%pIooi~SGu4L#5kqDPQd6{wpK_qQOTe~Y<%#KawC*{in90o49i6T$j|*o zLuOQbC#Z8{L~Hr<&7kt-UAR~gt zKsqXD;4pTV$iC%Ni{4Mw|5Os4RP;>TxwxlSkL~N(p2QDT!tidyYwn-T(Pxm`yDChV zH&z4k{h^NiUMrCa*OI_9wINO?O>2-sFc8+o7RmIX#_Qcz!T9l*%H(*X?`xzWJEPys zzmTMoDgahaz)}f*?IT}uhzpj^DUy3v@cXjlXZr+hMYmWl7NflLNUUs0Ic_ohzUK0d zS8+gN+WP<2la4aPd&N0NK*h=mLZe6ni42y3bEc?d%Npnuq&E-DfLTwLGG9;C;zlB& zI+X;uB!C4yt?~yrEa)2*3pn+^Yn&1<;)G{d3eoGsbUkU_7SocPz2^spaiEtL#c0Kb zM?lxB$u>eLR)pBq(pT8GAtRF@Go@?WwxF6Far((Y^?lME2kVS65j}o zc?R8bjJSblF#Uo&J+#He(^;?s0TmqHfjfJ4UiF60k8STD_pw)R^8utPoLX8#nx!!K z4@r;PI88_W)i-2BCg$NgszGTl;GW2cp58fsKvv(-2M#VNUx3=2#kBwcKS030FXH03 zvTvO;G+tJYxS(hJX9z#tlWQayeHu%rHs|;21)ovavF_=mxQlMVVgn?r-_hm!NpX8@ zn+qd~M$qEzPz$Ls@0~kMnmgpn*dWZivE-8N4U2X&;%30C%K;YO| zAsj$slaX-P&ajgf*GJbj9LgIng`kYmJEThWbdq)3qmDw=8u8fph_LB>UyD^4w~!YF z2h{J%?}nuDgDEO@cp^FFXOkBOK?w^Jg|aj2Uu}M1-1_Kqs4|;>VM*uz(vrGv3vlcF z19tYUfy#X;%vzLR`>whdu0vD!&bHAQSmAu>MKjEXw(g4%RGmVuI77U>^gq0#1rPf0 z(gn~K_1g5C4VqZTq6Kt}YZ}R1jBCC4#&bUwSXfiL`KzH&y*i<870vQ#UjsSqwEAdQ z-}%H6f%w*sI-5)^(;x53ud;dBHK5j6h}~yc#EhLrY#=LOb$1_G>hpEtS~?$t&4PGT zY4xiZy5UbvvC_97!4S#EaoB<9sz#yx5n^ReH8QW)7S#)vIaIP|bpWOLHdo;-`4mik z<)QzzXI~4uF9qiwj^mL=fbm*vRBliA9f$x9M3rl$l5+pfR8&iO*Vp?pEOyw|5bJw;rI_Q&J54T=ude>e?UNstnYbx1>+H|Kg_XDM)@# z|LUz`%b`>QdMjLpd08%n*`*W4sJJ_OYa@xssi{vYss?haas|OWCu@qV&W^>4BAb>L z4<6PbB3pu_j?<){G;c9JqlVx4rS4>WXHRvOM?VZFPwI3IG6p;&>10zN2YSOLBO2az zIhBnSEDX}t%@w9Bx$QdChk@gzAOd?67nLszN>qZFm~7E^cI#X^S5|B^DV2=qRQSo_ z_~qHos7DY>^UxgZAdCP(c0y7u!n>r-CmqkVxuF|q8$hy_nT=$_sml0CkTe=cm#XkH z=^u=9@D_10yO2U2?E#CLAEHWc-B^_-HQQ(CZRlvot6BjkkVQ14z5@uTf)+25^6YE+0bc^nwcDE;ANPTh_1phTlZ#}({ zc#0RBx|I$tt7>0F26|w#1QB*7%P=JnfY~v*2M0`x6(niFf7h-$JJgQ%2wYx5(Sy@C zEv~5+xMOL>&JX??1)11JzrD?IIeytdl_!51zLEz<*xPt%D_Bt2+!=#cIRm^b^z?SZwb?@PiQ=KNEaHl(UYLu2H|{YkteH1qpby3G zdkd7+^goKbpt1B&jbfHBt8z8H)F99kt=pLa8n=w#weGsBlL+(UPgaZSTnXJQP;0EIU=qkRq}K@&6xQd`(FG&%>( zq&zNb(tDOLvnV?ACX8;bR((&UYPwe2v-j`11Se|v1}usI>J@NHvP0A%6Uc2BLqiNZ zsNb67u))>sv4x+^bG?a&@+#!f&TfUTwf`;Ka?s8T3{)KHJKNyRXpIzeDiQIg{I^D; z5Up!4DnjlKb#I0K6yA26rER^P&301L$oH+WMdY)dJg;$(9eneZBbZ9W&Uds^U{W>; zC<#rYczD``B%j%e8$|012iE|Y3dO@$^G+SYR%(^hivv&yjGxL?^Fd5nqOT$6@MK+} zYM)$>+h&(n_sPU-q?5GH5$>pO8SSDBdpT<{7f_pWaf>lM1iH9)f1*&u*-yK~FRbRr zLno_@bOQT^f_KT@|Hz0Mn+fnvT4N~!=sa9V4yp}<=YH#J<0z#N`*F=K8;duH8R#VR z_+TYI<9mz3P(QS!#Ers?uIj;RTIo`NIJDhO5RBpnulv|rm0rPapYh3&YN2)Nco6ml zf}uaNb6SxEF%g=He#s%as*K(LXxVZvv`K8L53$&uVcL;&DD+Coruj2Qc+(n@2+MQU z5E#|JtgCOac_sJfyj4pN?78Bt5m{E-zdGt1)qh%H+aDD02Kwc8o=Xjcu|@6ZK%6U> zle{$YNap6iL_%;!_|52@JQ_xBs?wzh+`_u@SP7f~>3`XT=#cB2fKG69Ah7%neu3t$uh#x6PzzjG zB4wPdl+){?rZW_urEzM$0BNL5(m0FZGIm@X9cz=RI?k?7zbYj_H`HP4DHwh{S)5FX zM-vl~q*B=Okl^uW74hR_!1R_=XxHyg@hSmRU^Xe~?17$*R*2xlA%Ze(Y{C}40IoOkCEo@yB>Vu;Baro8ryNt;8D>)y z)ZRNWbG9#Rh4Blv!dNk2Qk+)x^La3bkZWZMZNQxcdh{0X(Ud%!Zk7sqfGE^D2BFBw zhzoZ`>@sCkOKu4yD{=GtTzA(%Vlq84-7ICTE*)lIOK0)CY3g9faL&nYATL?qEhSDk zrUVG{psn%HMkuLEZD0YICG*>3O)BMy-(kh_Z|E8>ts=d8huL+zCfk*MV<^2PqTQBK z#b7>gM~)ZZ!)8xaG+onuIRu!c^C8W&dSH_XAR8m@E)K`vc>KSgV0>a;xPiLFq#Hb| z@Oc){+{xuq(I7CrWD%|>$K>`^x6b@-#;7qP(*Xl?@&Zhem;631jk{+{a+T<_H<4Q@ z7V>_&S2z4bns2Pgi(u`lbb*uQN}9g_Oz(PP6Er3-$bOdktrChiMV`ZIOB~#=2lu#u z%HjvC>|_RRpi+L8bxCB9>>-n3L?PdlPQ>@7@=554KmTY)SSE-A#{9YY^gCED1u~6T z2^gQE*yH61fo1Oup$Ovq?%3Iq`kv>59|adLq?Shu!%~5Z3Ast;Zhy>;h>Vh&9UeGK zmD8UfK(hr;0Kfb(RI0xI32E2#>texkP`Kj92yhT-mq7gMry&Q}vZLL*T8llmTRXDxI?c@k0Ttjc@bk z$8wb%g>^1k=1<{R2Qk4ta=6fq_V$~K9iS=@+epLzEv*u`dnf_XE{1%j9w*2pZ*FZB zQLbYSycg2mF^<1{YNgQes?C2hcy@&2#_WshaX6oR{v-sDYva%kjw(g zx9gPr*P0!hazoG*wRlzJxF`}nXglk@9Z?M}y^6^1)S|q-dyiP?yq$A)o%zumt^X}m za>LAtW3rTv<=-(E6ViBMSQF$9=>TK4xGY`1t63W<%^Rh0VdNyBC)Eea7Do^+;hRF!Ub9lz0QVw7v%YgX zxZ0GaAqW~XddL|<3-qoHke+(u(94#IxP-|4`P^$>u8jgvdr|(v+H|$I2#GvE{-dcf zY3SH+G9j}9>@ptZLl=+8EI`ZB+K{2xuq!2?Lf-o=3{dudr=ujm}fT1bRl)aL(!L9S`?LCRVk)2~8x!&{Q-8IXy3gCxhe)lfP>5umd@ z$rSTt_nJ-pqUOz;yN@FVmyGle*$q^+ik%~v$%z|1(kin*3q$&_xS`!+6)y!1H_qVA zTGfOns3#>(-S196YL;dcf)t6&Qk3CA%^0`F&mk<4iU3FQ5wi(k4pbjAp~>OmQpj$5 z)M{J?t4XNFvAPsO78Sd<9(BV1A%uOcUl;@SDob|8=?HW`nT)1kekwRd`M`>P_WT{p4hMgO%lf?z&x|eYzlyd;i_=6zWxQ? zS0UufTDCyf{n9(rV}SWG!aBs_Gjq4Wms@BIJis#T-_)2uH!e@a$H&HIL&jo-XfQUThSl3Z5CHI zb;XPtQoR8pkkqVOW%+m0k8xWFCzre-$EbemwgnR<_=2Y zjoK2jhNqF2=C`xX0X9Dj)P(AbV#fw_o<9*4=0Qd)I-?VQOu^P2AwBudQobx1>u{4& zN;1XqXnt1)qV9Od&q?Z|I{6?qipNA|m6=tJQYIcIB3xWhsC9xJc}PnnR2@3uz}9G5 z0Y!#Dr8v?!n*A@{0`te8;e;GIkr!G0a1?`T5mK7gJRf!FUkc26%Hv??!QHK8?%c?0 zFP#Bh<14ERSl=ui`mpZE_;~WbNY90qxN)~oMcYE?eAGv)tUMP7A^jXe1o`zl08`ve zu==f0sUGuz7ygXkyL$UkRR=H!v4hpE2%}%7>BRiv9>}l$kF|{}QrzW{lI1EOMkIX` zj&7uoDxJ#wV9x_U*{b3dOVf$+e=ygXYPS;+_iSofLjDJSuGkRDJwG3d6|ZWT!wGf7K7PlFn}$vJmbz;KY$sbJ!jnZDK|=Bi0?#h9?0r^ZNFJtkQ#Ao()}h$@=p&2z4!!a^`K^0gz@+ zLq~VCRwzO`$ngPXNe6WjQE@W_b33f0;-lVz#ZphS$Z0`MpHmx#*W3rKOjFYf@ zq%$-OdihHZV8Ix1iPivg$H5E;f*h+7Z8b}>G}D27ppWjH`U?&ViXbICHT##58PB@M zZWgjAkF6tP^;_2?0h@55-nR*?b5?tfxOCz0p}%2eun^=B5DD<>$kAUp0qfSMHt#LDe@IoUu4@ zCXnN+Pj4XGNQcGsisc-Y`VV!=2sioW*bgmcR{9al@w}&u5z)J-6hu72c85y>a_SuW;wmK*8IrdSI*|cbv060RCfrslevAd5Qr@} z7;7+f(>G7X$P#V`ad@h{f7E08c9?gH-JRbK9Z!uYN9uxUCloix|!e ztco_%zqDY^<1YFolFy$OkZTYz9Bz1P?EsDVr$iA8FjE1q%2?6ZXgTo+;@mws+_u2X zC{>w@EV2QR?A6Y^BYu|F9hBe~=Nvx4X$FE;AoQwt-e5Gz9Oy0l%wBr$|Nrwt&CW{$ zVIH^bEMq4)BHJGh5#bG7CGL>e{lh}RCfE{(1U>w-ptENp92G`xeU)c>p_zJ8F(SIl zYgC=?M`GN28(g%Lfj=xnuW?0FmEV-M&*Y!#9`{a+cw{K~kZ8cU;KzIT>$B5Oq12}H zBpmq9EP!eIg|tlr*a6^!0%#CmLEet-6ahVzbF@k~#tE^uUG^o_9J)y!-HM}T>a4n& z@_2`iD)x%?dI9qXSvzelADo%O?=ki`s)0M+xl}#FBhWduzfZoV=qr^eeFuGsLGfov zv)@WDjd-2t5DeJKFz&!0wT1;Hf7Vh^svU}txgc$;?mM~1W(_p9T_z@Gfob4NbLg^J zl5@h;4KLwgd=DB*y~Kn;X1EbGs=?zeEQDt~P=AHSCdid=8|;P5RJ{DjqwgaKj%Tkz zj)2E-elORa(zh+CD!Ubs5nx@k$(o% zKkRQR^Fki6oKpLjTTO8W)Rpy^LxTL%K99Fzap?Gs9c^JC?4vw!j9Bj;vhJCF&R!mD zHbc-ki3=UL$t?G5FL#D=RQtJkC6vquUtmV1$8bqg3SELN4U*sF`VW_+Zd|KcQLXGu zp$NI+8bRtSuR+bixO|jYU^n`925SZ@c_^oLiL|By@~T=pbl{Lv91hFI+hrh~%FJM! zoO2aRpsew#^RXBQVmZwp%DB^{Ji`xy3um8K6=r!JQVY>cW{v-CJDcK{CH2ZoPf^qp zy(WNzFX=`VZE#9-Q=(KQeAvrr&yx;j2dI}L*Yz#zqWH}sh&meCANzzNP0HsG`MoN?=ld8gTU+Lx(YXn7S7{S5 z*U#Aan|5b_5;0Gf40qju&^yq%LqL9+3g)Ki=untBxIYdMT&$*H`NreGuje315C(Zp zYrZtD==q=+hO>yz>kj{@*FtUTy3_#BjS|&*D)jBd?NJIBA0+SE?A@* z;_OoR(4S>guX9I)@z5N7ePfd%Xn}N<)snGhk=vmSa1WA|zLH+6w`Er!FG zfx}G7@Y&yn%m_tu6`$5;dn^GYzA0K2VcMW0Vyq%e=ev}(R?DgHc%+!Vm}B|_1!m!Y znRy?bfg0AExpOm11dAvAOhUiaoRyYy!xs(i3%At;6E0^qn9#Im@(9HwrUEKdO%OjM zkumrKEP+RZ+e%2_0Hz!`g^6HLubPmMg`n3%nTk#qKcM!M$hnRKhhOta@>TwjM$}d2 zBKzIDR*ahf+~IKwZz8<}^_ni|&xOL-G#x7|W70}gpFK6JIuphcB<-JU18e_d92Gdd z0rtP!ZW&yQsU}|rKCiu8{T3+AYF}?VRq=4JYU@y#-US?dbS9zh1U}^8)XGj1qJIYZ z)j4@f!$RMckI(UgLPQGH?l%_)U*T)3*aQ~FsSm8R#`^HJYAQVrn`~=NZXhv?U%ITA zl=4Ht|fl1lQoGP3+i7v_Uv)drs+|?*EahCKt?7TU)S(Us@_I ztW<`Ybu#%Wp**q1r_z_n9R!o^KbIi*HQ^7!wt&}@4yrXp1Ec&uvqm>*CegaCdmr}g zwKt6Enc~Jt?0xr7=yZ079t}AliNT;hA2oS}O2=v3*I0I^KArd}nZXc(r6!b{A1KQg zq$F;CWSTYzxvPV~y8ngOZBHn}rW5xSG{>85FC;0RLxX|d!ERV=;zyMwyyq}?JNHX0 zJ);!_qy^_s9dq>e&{4EV;S%`OxohejU!;lUMoF&Ef;5uiwI>E_7ch4fUH6)-6D`aXcfiwdj6f?y|4}LZz!geS zW1blXORG=Uhx?AJtYkHW*F;8Xd8uMucN%rABa^5dH$~uu5j2`Uv0<|*ccP){M05Wl z8b+3{qI`>jAYdiE1?ReA?iKZP-NB_^hECp+R}+$UE=r@VatC<@-eyAtp&h2F)p1mi z$PsgW-W~{MDMBsSQ#!UaM&!l^*q7d&?|8!KF0+|qQI(*2wiyAH+gZm9OoYIYJ@b(A z)vq0DqDfMJz;c*jjn?kniAs!o|9q3Tw%o-#4Ccg=CmovXy|wl^+gZV9YD zk^F|5orA#Xzh1uO6YkKFX#*yjSNdEHxsh23G0s5&vYa$#&;SjIiL7o@7s8ClYm74{ z%C)30AYB)o+dr=OQ1n%6;vA|qqOhJ*2Q1X>J*-6sY;)R=qf$k-jW40-t*EiW{NCuo zi`ahu{5QI{W>#-s0#MKW}{n+z_8rp0)xK-m!1^`7hc9BFt~P zDO@w&3lv?A6ZKBjkb8gvD-#FAf#v8TGsqL%*}aBY+B7ey_E)=_lN60L+VwGLgyYpHM7K!cT}qoDCcVpGmZ1k$Ml{w2_%p$vATxfx@! z@=sruIg~NxuAAD=-WaxxQcW)VnYe|Il{l$>Z1i(nBH6Ciao42-Z+BI)+f(xw0k;K+u z+YzXa;BltEhDL6_(ED3wH^RS~(g9c>RBn~UlOelkW9q*2F6$;pp7GtXfO|)RstKFW z4$mEXJU#lq$*Em_mU?icL#n6nF6@Z*b4#O&6dxm8=1=S_bav7;;q33Iao z(f&F)Z^nv2ZzkKNUx6A2({P@BL%PLlx(6y)GNAM>dkqgLhSr%J9COuVxvSfg*1L^c z@{og8di!pLgQxf$B$gcyaK7tq;EX1DU7KiGl87cxTPNVnf+J6=a*HB8RAb28q4GG-Wv2L8!me=ri|>#&IX z`t145kfd(6gOcqrrVeCCb?{5Ek*zXgabdIveu7wamx$>E zy#Z*S7VL~h)BYaz8DO{0_jqh(uxdUVor3tlt`=Z!WTJP^)L-77EJWc3nXjUtcqHl4 zwO`7ov3;2TON}^85az-no{|wl?2{T)DHARozr>gjEQF57r7LF2^WX3fQ-Cg2JR`mM zKz7*>z*3SVtCCzl5&627NEcP66iIpmj|X~?NCm&F(DYCKy77l#@4jEfBO7v`8L=!( z*$d(YE%{=u<9uGSjZ!cv01s_~KRDOyKVGR#HzlFVz+wLq3JKuifcMfyYJ&)xP!Hw_ z&FBr_+>1<^H|CQOU7tLIS^!^G?TN_VgzXt{ID{D7&fxsq_YJ5x$h`2ItomLPtRt>9 z0>qbl%xnh4<5N`#YKQ~q!-dct6V*O(^Q6O&CmJo70$N57ScdMlO{FoHEXsH6xUR#~ ze!#8Ae=XsNUkQ8d~6h9<2LO2Q> zh2*Hg>h)b+;&-yq?+OGf-qX&ay*7WVWS*j39~G^_`m}Pj|1B9~;mPMiR*be?(>u8a zT0aEG7EGhIivVhI7{*80c)PJv&H=*pSALE&c98h9xHPT*GdC9Q#V>$ppe${9;Ko6D z!}6@VX;QZ;&I~TK&T!MKTOQxM`u%B^Nc3Xrnq7^z9S^&z9nsY?ue6Xkp}n%}scA4? zue?XBjJl)`-j4y!wYs|`A;V|_`<7sn)PHXpUSmTCE3@!Xui{^kfRrN;Q=6$qTAtU4 zmk0n1_uw?0buige9jid%jhy=$V}rZq0CVWqn3~Mx;z0(vmXfITuFHdA7)_yv$-Sa{XIeHVD&v_iuH%>NNvA2Igo$IJIYi&F#}f+w*4zGQRs-GqJTTjRWBNg!$;fH;ow{=2okLej? zGUnug41xLrExuuwL?{~a&)FkFsspbhEIo0JT%NYC*EC=O`mo85^Z&{J&p>0EwI&^U zw!IaB_4}X6{P|v$Pf%h1(6SjKh0iAK)EK&+tI!nDaM~&O1fZ6N90YTL25H|-3(`2% zFe}!p$M71mqst`^tnE-_AN7=X==EE+|L{LMbtq`HKW)77C8oW^bv9but*LY~EqRWE z1CthwFvARo#RK!4CWv}X01~aGcjz`rDY<{VHI41OxG{&eT@=s{VL)#dJo>>~%zCPU z+Ri*GC)XeGIjJ5Z<)UvhZ1-jMeP3#iPIsu9^I`F~-%Z5^#+-V{v>)Bx|7g!aL$c|w zUQbXnYn0Mqu!bV3&^YQ4Am+6xPt31!(7dyajiI-bR$$XWAKJ+4y@UKE%sN0)^U$!$ z{IBD?-Z4t!xD)>}dGIKjm$9%o{g-H|G@lloXQykrd;3@2Y!G5yPa!yW>D zTilO@dLzjS_F~O!)W)D&b%DnAyr?;$4JX-ph64pjT8bDkMJ8 zu+D1zJyXgxUc3qBbZ*oGfStjiDIy>m^Ps>g{SL1kldO|DtNV8Qp@>`v9ZT(iu`uU* zayicB$rd;MEX|qI)P=m#f+Ry;>vUvuNo~jDnlgrt!muP`Z#&(4r%WoeE&F+w7M1Ix{t|jKdZamoI-J*=fRdr1B{rsw?r$h57ybb^gnU z+-WbeF3hkWi8oP``N@m!7faW#*EP&&VcPrrR4gXb5W_L@+ke<>9p^LeRgCo^1I9-Se|NW19N5BnGR69tho9IBv>UtSdOYN% zd`AYJI2nyb%2YU=7VPq>6_feR^%jw-BtBtca4%ZmP@t~l^-h*$_AI>7 zok=xvmE>|pZbc`b$H){fPc^x}=EEx9;+ai|61w2KO_oaw`bkD zeGZ|Dd%ePAa`;!Mgw{E=9rm1`hXxgD)hho(sJd` zN$)~f>(d7=Q z@4Wy2{KL3+IZ(23LBEdYa%1)qTkQxZ#eIf5tK12`Ny$unKvE?`eXsM^H4$eNawCBK zzo_!JSeH(m`1xx%bPK)Bjcq~C+^8q;1r7cr<{5N;u4N~4rX>a@28tj6@9f!F@40OE zXPSh24%Y4SZS4`pun|A!6Ss-EeL$5JCh8QvU$sl~2;PlBSC=IESm1vX07^AaV}<4Y zmO|+q%*q&FPYRXvAc%eHVnXYbjKd&+az6X#b9nnae zQy4&W&4zJXPQ2xbb{kX3u8C2hoX;v4$##@=!a9=oBVzP0dPZLeu42|-#jP{2`+~8!;ua*!p793ZKx;b*z1g$EYC!*Vf@cXC{%4=m4Y=5T4 zC2p%;P&xet1}NPl5K80#N~DPE#)w#>68@@UkDIapep z%KPPH52Jq@D7*GpjWMnrkLaO$~RvAhcH2-)}56Q&YJB_XcfhMu+G(Dc={}iKvHK# zUxU#h3zXTltIKRl+XgzR4;)+&1uM1O^C(Q#qsVUTFIlQBOEL?xHq(HM+^*mJ3MoSi z{P;|V>8cZ;CNg7XvbN-or%APtQ;_eGJ1PsB~>m8Pp*Fzhe2neHN@mYAkk zF~Mr@gseYZ`I3%*O=+t#lBj&Kvoyh$JUgQ4Y-q1bG$2Y8xu*fQB9WW2*x^$B#d61O zB{`9&(8skWR{tDLa~6rgf#Z#5h|-t-!ozHfY;ZQEW-1|BJkP5xsz5oOWAJJ7U8Uv3 zwQdbynhR0=^C+)wo$%0bdP?zH6%ghH563t(_5(j_QTsv*LLv6Ue}_kgnDiHgCwPKG zFKDY7_W!Ah>A#M-Pd?-%_1@ZJQ){TYDc0#=2|N*0-(L-eNPaGm{A)rtg>%WqsEp+^ z>U*Y$!eCSs?~?3i3Ej#myOG5zjO!^8RI%m!&)^;yxDPDko|Cop$3;z+2?PzeBYG+q zK;!zpi=-#wLapO9PZ#2pr%b|+DVp}gq6AxFGPPA#x_pdA>;MG#C3buAr`xr-7D_(W z@zW1LPGVFf2j9;%iM?90d5%x_j3_Ac_#-QACXehZ$A#SOz=U)`d~UA=CL;LL>FTU@ z^7w+}v<0U{a{^F-Uq_nxxZs)(u1tTts~zFhzYDW04ezmVT$b-~FO9DIp?E{z>F|F& zYh9gCA7Md%^_Z@8TeyQLZ+sION~9;}IGeQV(owt2C!gRY}_YsJG!-o_MIiB=%%W0=zLvP zrRl8^8fvt(ErQTZO#~dP*(wPk6@$>3BZo--FeCXo*R7(`2rq{x(xasbPF4Oj@C+__kuzq#I>QR(LgssVU zcT_F2rQ8gPp?oCge3&h3ErwFC$SK?iWLxCNV1x{(K|ZoE`FKssgk%AP3;E!0 ztL1)+`WWBs*!!7IPDr=FvXsNmO`E$%(}ciPsUb|Z`?o@}$5jQaDmHS* z(>C#ogOPIIeUsT~L4r1M95LF93-zo_%Li4c2_q+?yDqXj+6$*YPVIAkRh(bPXR6&p zvCwDT{dZm^r+cJULCtS>`N;p0aC1Xw(oO5?yj^yg{M(u~^R-;GKTh3xrK=?`=gv&i zToow%b8oVEQo(5q^Bmk*9AQccs2~s|Fot<6>7F?nM!LWQbS7Ti9M1s%5y^S%pOD5i3v+vki&3ubvYB>u1{j-C8_QdDVe)C?3v*82&`f z8vp5eJa&UM8pSoY<~Xkce5otN9oJ_%5IuQPRjYHSW@)d2jb>*Iuj~}RLsi9zb1E;R zcwjkw%P^aNtq+%fbW2x4rw~|))U?EX@JzQ!!VE!lfmnX^LMLqz^Oj@f%=1L*-J1vR z`DlOA;+yKY2!_DO0#gHbz)JCelnGg71S4~6(AuXaU#~nm#lO5RdGH+ZX5bKh8=ctQ znqrl}7|CcIuYtv>JBa6f0!jdPun{QVqc-C5Vo64J=W=(jV)shkS&328i&E?d&dd~t zh+|VP90>3O4NM4s+v!>;1f2xW^_Va|Dm56&rD|P*wOJt1u1t=QaPoLiJ57;&Z!r6b z4(Tz5C+?^23BK5{Nsnx|_@EZCcn=oJzjht+Z1R!<7f#w(Zv7O3r4pmTwCJCN<-Hzr zoBrSQG~7kqHr{K7&QqwM(fH*gR))_mlmgmd+=Io~z_3#xn|1n`PwS61It!{G6c{1( zI*$=C3vFXm2+EU0HZcBU>Xz~BYuaKvfIfu`Tqe)%m|W(?G5xoXh22PMOl#wVjby@m z$Y06Dg%y63D|UP8Nsh*;MOCKxJ~E3xyq$1#dh3T~6&0alH3OzUr?*nIz}Zy%aHa-5 z`loBzv+bZzm~Z;Wgr4G?2&vG>G6WwUlWVDQcTaAo*X8O#dWZ|t$vXGjOIvL~oG@so zkrZUy0ZRq~<%(&NvSHhgFDvH&UR$ZI9(|M(g3GDaaH|4B-E!7jyUMG!jM({Si|<*6S2IoN{0wq!VJJ;6*O}L1TM0(gH7i~O(NOf zRTNV9t3Y~EZANr;ThD7p95GnbO8|b?Sl8%FbfaC05KjlNWBDR>km7J>EEi|uvV4o) z(;iu#{wNN*Bx@mJ(qt|z&28o(D9nw0l9#gNivv}qY%(=RI*O$&Y!JGIRGk9--Mx+J z!{}kvHC{khA6L?u!joVDZq2m-l!qx7d2hxzEA-{s`fchs{E}*qLu8szT)3^J3%ECS zd|b*4OKduZgd@^%3QQVQJwe%Sj!}b*bOw)niZVn*{)Bmz!JKskQm`sqh0Qmn^Ccb< zjfv_;T&+*b@YHtW@4se@%Rc~ZDqb}NnOV!F-K`2+Kl&D^Hgps%k5Lu7_VWv1&3tBV z{pN8~LNsY{WWHwrEkz<;mJA5!>~|b>GyAwQEKOvG68s{kLUwL3SB-ZpNuG6NHr!=@ z;LX6b#1y81q&S=UM;9A}T;Z~QNrqc)sW+sL&>17wg3PuT30yzGsmD5c{2Bq>?M96^%q~ zo>&{5nmQl?^jVe#u@63F&@uaQ=ZojOXj1)≦7nOvx!4os#;KQpw?A3U_yO=h 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 zd+p+XrjZ%ld%`!rAaDQx000000000000000000000000000000000000000000000 N0000000000001vH6o&u+ literal 52226 zcmb4qGq5lWtn9J%9ox2T+qP}nwr$(CZQHhu`@iOOx43DNVrMdwCOeyrqJ*gE=M(^d znuwshsysXX?SD1GBv1|@B|b0`5O0ofj$|ciDG_J%~-pAU9-!fnN@5fiuFYsB~ zJ^bgl!nfHAuZbV`H{{pd-R|CB(O=WA*C<~c-?d-NE9m#qC;YeGo$n-{$zRhCxaaT0 z@6ey$=iXEA0q&fS-yhqDou*&;-`KC%3f}Txzu)E`&Tr8%_($5C-?wh3-|XMUk;hxy z3*MLCnm3@I&>!Gm)^}YK_#fY04~lQg@7n9xKG!GT``sVkl~4QM-{1Fpz}L!uS#6l_ zHtp}J%f`M~0)IR7ymj+HJW-$ncEP4)Fo8J85vy>^Duhr1?3hiYbqz{55q8`*%BB`M zf*31)2X#xE0#TgxVbkGacd9N#aF>T`!{xqQYpl$RwigB3{rS#hZLq)&H|M&QS1p>8 z4ODn=4E%D1=)*TYosaSZpsApdAi8H?oZnq<|e^Rxxv0>Nyp?i) z`)O1n=TqY3Wc)UxI*zJ!Sc0SslD#a5{f^sro$f-J5aKVwYJfw&bF5WZ58XKQX3LkO z7LdOm$qV|PD6Pp3leWhrX-H1{+7i-tOh&58*pR17Uxo-MFn|sjj-=dE4oTq`TcD^aAfw8Bt7xOrM%fWIfyn_3} zBR6>3z>k#oGnerGKYg*8VO`DOo-+P1MrjoM@EOZsYOcU%Z{S^0&6RRaq zJ(ZM_C_kUxbO?L%pUCC+iI4AX@XR|s-_b&aCX1;X zF$~fv9}da-gJ$#vh|V>gg@IosT@JTJ+i6;d!e*B;jy_}V88KW=lzTjP3M&H|a=n2h zd#$6{3BRFqT4zli_mgm{bWX;*f7p0-LsN3%X(R|W;(AE^40v4sd@w)1;%6gEB#j=}ncUnA*e&DF?PV{Eit*-fAbNg`hujrHNP0BBE2t((c6z9F-a#aZ z(QLJmVO=)#q;(o0O`LqAEsdM%WN@bxo*}w9gw0Oztypg;c&rA{-nIG`&9HQW+X{~c z_H9(@X5~q%X}`b}d+E0bBJtO3h|&H8fRE-76wzFG84&w}{2PsK+c^B|C9oo+=5hiX z$A$H^j%gsnEpII$^#kUXa7=*ru7}vl^^XB_wu>NSGpfCXJE5!juq>}?^qA`+T*NxC z+Fv`;uOZHDi*I8U+CKl{+Ob9=NsDSt=y>{_jOekQ9{t2pWO$fmg-ZA{!6A$P4d6U~ zQbe{*5uGgy8ov(SA1R!(2^;a1aFf$xO?CRJK6be%+{k*vbs04Q(8{9{6*XC|1@NJN ztUlfG+;O1ke{=eR%jEu(qA0;|{cl9S{N}oV-HJDlJyYUpkAI~Ru#cH=_<6E9%Q1fk zaE#220T3L2lX36H(a@=CgU%+>o#p<=Gc!+_E~vkmrr`796H#CPel;-?CXteep(k3I zOS7tbJUq(=6w&M@ox~Z0z5eIxpLrB3z_+(c_mW%d<{Pa;=efTEt>FmD-yYD6!_WG7bb)I&y(g;tcpMcui>+ zH_nR36#jYC-JI)M@G8Xz)q5B028rbhDogtgZE(h<&SEe{sbLuZ-Hn`i<&${JCi{*}HI@j$ERUP&*0^`Z(fxiHqwn(ISOHw?e7X=oj} zPxNr^tqv@<)x$@6v8KL+XBxjqTjSVJs?-Lm-%NstOZSn{y*R<6I%S#J4fNo$c}tjm|) z?F>(Ae^{d|^HQM-;4NUSB=aOyH6RbILiW)21B|InLw}S3ahNN5YJ=s2D1eWo`OlzI z&=~uLZMaTnYQ@LRN9S;6Mg9Ykd0&ZS4%_1SU}8~$w#7C<$O86hFZl&N$~h@QT}P)c zFRI+}f@_jY;I_-x!dwpfMlYgO7>)dhE}S;di>#aN(VeY=I>Vg5;@A>X7uhP&vsebn z#|@@gv9@uSpiSgJU0ND&;K>7%N(f$AcW%QB?^$t;E3*>O{c3#u$!#(RNOMt^adt}r zpF03=y5IvhJQOCrw56e<#={iL-~L_ULx)o?Sj$bV9zUAxUJE$iZ`tt zg{zeDFa(>?UUV`(SI@2ml-{7Op4fZ~x?V5IFvp`$s)S|?@6;epB%&BJy&>1!qX;?H|* zdom7Z&Yvt$wSdeTdd!P-OyTRPdnXR^(%~Eg%gA(ma(?1R5D&6rj?L*EK?YE7=Yo3t z)v8;r>^Gi$7@g}U;T6TVQ2Idu+X_l}avtp3iJP63N@# zC>b!AJw~p6;~1%us*nuPj7i+l9Ok>W7}&))!De-!tfd=*)E#|ZM@ZibJl1i>tnB2^ znYx?%6+2Q3pfht6+#w=GzcaR+>uD+Fv9H!c&4hPACSc1l7|WT@&9D^bMprl+K;pQj zGPs=WbLr*P73aVXIz~7Ar-{plxh0H_k>@4(ICV(hX1l#R$-UI)~y=zbbORBYsrG5 zv{3UN>*y>#44YYC%^Sw1V6aQ3TQzvXKFOlIQt*;e=}H=uA_e8Akv``%h_+#Yy#~_* znSy8C%!j7unm-3YQif+K-qIi0LeC6n>r~&{>RC z1LgO));I4bLKG%_*StqTS*Fx08fFmWCTT*>yN;zybbiydehbkMP=P6-WhwwC$25{fCH2p917q6{ue(oB744B9kpv97Q= z8^m=VA&Pu4!m!TthTmIdk7vu@uS~x*;kwk>9hwCmZv3*D|LXi$0eT^1QjMDoqs~?; z@GDKx^Y4&>%4L|L)9^QtTdZLtDMr7=Z|19vcw%!zrEpg$50=P%0{7HHt4!rA z6;MxrpTjh_&yw~)wEbSRVS3+QWm$W_0$c9zt;(pJkTO4;s8m!)gFS41#^kDxUo?FI z!d)UQZZ*76O7?Mwzb1Bj7jXo*x?&k6V&ULx9K0vUI8&G>jpFdeOKzbnsZxa?ZJ2P} zeP=WE4GIo<*Mq5_zqj0PiJ2w=j0eveF;98^ru?SC!TMc7steFYLdU)w^5db0AN1nf z(mE{;A+x}pDEFfurCedfKQj{yQNk-R*lm-{F(ya(pGc^Zr<|%-o{a~ z#?59%I+VIKsMX5jGzHnPRzoQjD15)gDF#}@R2X#wNZt6mNID;Y11A`XWwchS-92D5 zQ7k?ddzz*jfwDPB6s_52*Y6z{GVAp(F*eOFkG&R?YLn9qiQvwjzCDE*uCfB40@qjS zm8MvG>W-#ZT+w#EEkNAEoq&3tPAk9uwmhsr7R7vCs=wgm*zvvlv$HP#i{;TBIdIHiYk=_>}yPB{%_9d=*l{rcV`E)0n2`l;#%! zl+&=Qff>U7gsiWG68x~-wy{fy^t&sZsKfac{zSMI^KFzU?n6S2iOYiJqNqmi;V->b zrT9lg_&n9EWcz+&JoSd|+RVQN9R`~)b~?P32aAq(t?ESfdZUyv5~*)u5@Vba>Oh?yfJJb;^<|dX#9Vpbug%(OOMZKdxE|%2~FiyF+!AL z`e8!r4Q`>jLJ$}Xt}VSSPI`4pA!D|vrMqU+Y$fDV_45-?HOM)n>*(t^s18FOFagaB z(g#iv_ZqZ=qunqsNk)!0hFVzNsdafVtV5?uo%LVU)dSP61L~TNKie z<8Vy6p3pT<+m%nc{AE4q()Qa2#mkmx^qs;e*}~)TzQSIGbV>)>*~m)bF>udAw?1sB@cwG$aG(XKsjSvmJHm zz#u`13gM*b%;tB?Dt)IwxH9Px>2xViQ+dy>b#OiedV{^v{RJ(_AOuDQ=t@_7{C1OX z@Mjzy-#9HhXXFBRg4g7ib>x4HclUhQr=g3(Ry|lYI76bytM|`6CfZFFoaeEGkd?L( z@S$7x1-eaOMXgMe4tm&EcvS`K1G+9@XvSbP>97IvTQLeFbg*F$z7+}IXIG-yl6IZ7 zm~$qHr!H;8p5Fu;u`D&+=~sd>E-E&T3u9LPBYP{1vhi(A+_lV7Q=X;IyrN(z-96tSpFfz%TpyJL;NA zkC;m!+ncS%i#*^~R|6Y)3O{`p`|r|P>Q#vf04r{Evi>zxjLYEQs^h7kfvFEH{9VH`RUcH#->8fz zr7qX8hYMd04?CU8biteJ2&sOWq^ z`LiXrhC%GQm4{UdN?7=PQ!iqkN&2rOU{7506R-CJMb?}1z|ewqo{tgdq|Tg9b2Ty& zCnR{~MOt@psg^&I@qcGcyNu#)co?0W5p25C9)PwoGj8h^=!!Z$v*B8$*%!$itEO17 zrlTg1Rt4!Qwelk8rw12HJdWd9)P5Mj5`Y%qz@fA>%Z9P8jTZAtn11n%m3{U_!&P0& z_c503V5M2}?W8n1<%a%12ddKIv`znoG&STRMXu6e$Zl5qVN6C&EWh(0RK3Q_>Lb?U zbzzzRRlA%&U;9O2uO-w};(pxq3{Ll(q^*0dt?5jcNOB7-JmBfh!e6Df%I$Uerl7HH zh8IGC>-;vcMW-)3WXlppx_T9|Kh2IU@Hnz$>!a!^ES)P4)>!PfzEC`NR-DCs;bOK_ zz$cNeF<;-`?iNEIVHM<0ci!V}zUc|v45E_#`om+q3>4$F{!^+pLRol%jVHzb=F%d$ zg^K?yeH1rj(q7x*OEaOGb)Lb*6vNr@!@zQ$uYVY zUnpfV%>6=KzTH}jv_AQ;x)gFenHVJ`FHY0S^N$=V8jkw3tergC-J>{Zt^Uj(-viIW z=RFm|I~Rt6>X1?-g6wNSb8R$@9#v)i;pnlYor0GK`^YPIrpdUE-$yi+(_k&*feSZdW z@XDhjrQgs0QQ~AH=%i_FS0u&<_FdP7dx^<5YyP>>bPN|HHt?O#i-m*}9VC zWT)P|t!7Q41Xhb6CG{ISjHXDghO4Jd@M&!r;v^|q3CgI=x6@A{w)^fp4Kbxok*S^J z4`z|>*Xuw^yuW%@aM8RmHD2DE4{4jt8~qrOr;qP$Hz>paB(1^^1+f(mQ(1o`+41++ z2!2R@` z556BgNAr``PTuW4NEl|&BjB96Z_l&dem5lJUL?Lj5>Xh5vrtk3PgkRCLd!U{LkHnQ z$7=0;M=6S5LstF;%9tZcLE2;aj6lA}L_icvHl_{{HA|q(Ud%Ulx3rSLNe-cn#8EXP z8dHR>KlP18->N24P3XS=A&$1KIjlQ)ttq&s_;Z~J@!Ycg*^B?%*GD|DHeh+NiX>yA z;YzXB=ex~KQ%g2NT7QYW__V`{Ee%87bt<-4E_gITDq?VW44$%zon-l_RQ_5oVHEUl z)S5%@`$z1CG`{0LmS$5S1|<65GGxYbHxWs_uH48)Q!77G>F5zk3Vo_kD7+QoH`KEG zk4gb)$CNtcnOZ(Oxvv)5xS0JUtL1MLRUKEVbi!2aycHR((&VHMlq;KxlT z?0i^RGfln|BZR>aH<=y*N^71iA%TgwB|C+)#nT_GisZLk04~w{AjDJ{z2^EN`vPU^ zO^kUY`#bxGjQ}PXm&X$cY2>`~=MrQmh?9U~IDU^8K=^&D!)tGBBd*eP_{4ZSMf=#@ zoYJlAol{e=8HkGW^~(7o*QgOd&qAajG#T#DszBoR(lnSi>aJI8_KTNuVGlUbV9=dfQWt(8G&;)qXYg8g{R?to4y$7*4abry$$kteB9h+^&6Y8V5lY& z+Ol&%h$(TZXsg36MglrdC3yQf<78cI#Yq1chsNvdwu)dkNzTmvN5MZ0ua(L)etyJ; zU8Ad@xNR?@#WwoNxzj!cwF2B=gkofsR^GVVmP@ zf1lcKR+1o}Y~iMK;BWPPNVt_G(#2KQXdE^-$pZ4C2VGn=7Xca>dihUk3yRztnrzrF zySOAv7n(%{D?=2_ucjIWcHEaQ@{c`jtB3iMCVAFm_foW>;pv0D5r z2rPpaEcx!MN0cHy?*$K>=in?#p3E4bM>j&{Z(f8q+pbkMcwKLlOB{` z5W$s=#dxS4GcJ#=J|1i;t6<5`Fel8tiGUg+WH2p_c__N-dnxOgNDvL&&18o1T)pbwTX)oit86am zNjXBYRQ#Fkxg31UI} z#f%?59G`$V&U$@Wq?@%JJRlui&j`*!@11kI2R6p{-!hQR#ek8Ved!kO!{=#XxN!u6 zC|wzPfPLlFKglP_`stZo18y$?G*?kfXZNp^I!y}lWbjOg^NZi9D~2m7Wv z#U$8Xu*V;YAX$bJ)n7s1$zp%IAbkP>pdh|*-S9!KE2ine5wTuG{;te6o<3pN(R_sK zHsZ=NkfNej%f3xq*2T}6ZG+4xo(;|jrD36NVt#GDyL_?gkF;^~#M6po!B@al2&T!p zTe06N%y*YX9`sOS&?PGq0|9SQt)m7}$=?_axos=~)*qIb;j6un4pG-AkSoYlN8P+~ zy%o~h4RfAdAy+)}!*%);Ftc6tb1Qn56XNS_2q@HQ1FtI zHL{OqS z+Mu|6A4y3%yv3EPKvOJgjjP%JKxsRvN(!ZIFJFp*{&0*8Nko@Ik!S>^hb#1h6u55~1kMTdPctiI%Wgb? zOikJ|>t*!sj36u{38v&$0mv%QCz%Y|eEUXt*eH*ByE>I3=z*7-&kVv@>Q*Q732TBe z3UrzGd48JIf^eA5(0z^Sdqcd>4A_x3(9i*eD#Rd{_thi7IGWWS^;i~&{ecl5pH|Ss z`vHknILA|mg`5{UeQY~Z9JQJM-{OY0X-s<;Y74~3N^C-RK0mgA+N{OXR~wo}a8HW~ z2WVxk5?z&;{2PuPLV8G^%h}HAdTw4jwv-`TGsWQjDEH&JxqLagSCj(4{*na{s5$~4 zaHi)}?{cNcS?v(Hv}!h^@#22|ynBBjn${`#u2b8*TQEzA$5>=!br?(+h%>v0q|3qi z>FWS02fg5<&Bg450Z-cC+=0MQHOj%wt2+`7CQ{qeL3Oi*BsSQ?3b8V8=kTrZ0B?>< zf}qzcadII-5!)%W8RaYo0Kpsb2OL%&r$idZ_RAgZRsmzUHUj@Yj|=YWzG2CJR48a; z=<|HQuqx%j@1qnbBhZHt3Zn7eI*95BJfbNoe-)6;&@$1e3oNQ%(jZ%v{$}}eJmXn9 zE{SbzB1z$QyK2geF6ifFYCu=I5$LFMhsyz&g@+Yr)ewaDxtDdt! zx8b;oBhc4mf9aWA-L08P{um2lWy|-lHfionN^emS@8LpKMA|_&X~FVthlPwEsnUr9 zv_~FFHNmA`AMWWxbVoH`{MX7QyxZQl4tQX`w1o~l#nKr1u1zYXJInYTnVzxDp+*2m zrn#$0`R*Tf+Sk_v%ROPh2tOM@Cv8IYCXQ+KKuKxLjNcP6nfD>^;!nG6xrRNoyx9uN ziM~Q$1ZiSdxY*u-Fd!QznSCoPkveL8Y0mjG58 zsn)#n5AIcQyi3zmjW}H^BTID{?F`g6`)s)jfxP z=Y7fC7yz`|bf5q)yF`8@HS=fZtGh{H>YDRvxy4q@WTbw3tX--L8RKQzEM}kO(gaTw z-x)4~eks$1%g+334VgHSlP3Il>Md}ked_+X2x{NbW*X^D4$ZR=YC3I4)8nd$b{7Ta?}nK9gf+W!rNA7)sDw z(p+1mA3!4Q;u=_z#`K23{HWIYaHw5{4=v+YoMf?Tz^*5UbCYn0I3;O1v?)sz*Q0k~ zgyIAE!ur`=uTv?72=dz%o7$LFs1^y78R;$ZK$r~&3r-~UR)jhBX{uk7p;iDkNTV6R zT4Dz{ns1MXRhixQP&^epyzk|KDtRRuTw6K-%o^6^SVkXmrej;f5WJa@o0gwYt1L* zms^SVi!3LR?2sYo3KTM?Q;X&GnJb{_sh4Z&Cd?*0K0rVLrPC7mPjp>O-W}zMxOVd3 z5je}9G3D&>JC|B;^QmA@?m(W z?a2J(-g0840qUAlYlQ>E@UolS`UFw5$xe$pl03B>tM)9*;7=V$)V1(C36V?*sT+U$ z;9GH%>Ops|z57Kn0eZ48*#UujrsIBA^FF3Q1vB609tkag0T}G~vcd}g7O2ey!vJam zf(2G`Dh&-4Bj)JDg1M2N)eYECz*-eKUxk)tt(1K_XA>j`ubgz-OI@b46Gtl;F<#$^ zpk(2YiJzY;&r=~JgdaKVZz!BOqB_b?*rE4Zx0==rt4;rihwm+pz__wHIEz5N*hIH~ zXy!^g9;-)8F*ZfvO~-i1z)A+@yTuFZ*F8!B$*0+J3GCp(n)x0!g*tj-Wr;tQa#+*v zP{MEhgkwDs@cls*7Tb$m89!7+I1g(wRKzsBmv{6;Hho}onS+CDm}N4g@jV==kcZg? z9x->=c=SI-IOP?ngRTRq2ZwG`B?i#M6|A2}wmgk$)O$Ocf7HF6uAf+cSJ$y_65ZvW z3|e6#-mOw|GFSnF6|C6AS0e9}u^1R!Ea9QY%+FW9q5z$jn{T;Nq0Nz4wZN!2-?CKs z7ywlaaJDtZx<4xLK=oHU!eu#!88}Cbow)h>N=uzd=)%0`@|Bo}gF`>k8PK#)VzMlI zT|lK^Brv8ySOipxOoWJHX?Vix$il!_N5*iyB|mH?Q-pI16bfOLxSMloi5>KB+<2Hy zBidfjB<|PL#2=Y+$8am9c2e>BEx>G~ zaGgPUM`)Nd?t?n zRUeHK+YO-i-=YK% z63L7wA{|5wK>L5-EGci+@Dv4D9jTsajfVX!?|D)Y(u*}M5%aA+@#@LLxv49wEHJdd zkV-Ju14Y@%zil;`F2q@S9v5qrTII{iQ%awRJ^}Kzp-6f{6awPw=M-%yCCmf1NU4^G zDQ#7(iE$PeIU7uDr`-HdAc1rnib~4ZFz$47Og%?%@)mTtNx7qMzpb=^r^oN5_t4^ZVPrH z?^E&^@n219yLKJ{D_TF9<2qbj^KwMxif~YHS)7<-*KBSGSzgF{u77JTwckFW>^w-r zSCQKSB0|eC4~pQS1wREq4rg<={ngmIr6a}GFH?bZuZ5Hj&x8{cCbVqyk$P*NDEYF*ApSrDnu^l)>py7P zU6+`{i*A|uFebt&ni0bRmHZ6Jv{y=YCzivApR61wbvO=BIb0!RWiagl02>j*_!0!& zM1*w#C&#r7bT5hu{1x#uq(*dG;}JS%;j=v@*>Ep-o>{1EV*%)+mLlVuVxlGV6*TOV zh5PxauY0##JWEnCe3=#QZDi(|_PJ^Y4(lU?5_0jzpkgpv@EIv;?tL?_TO#8yjv0t9 z%Gw|9XB)O9x67!c`FFxP`=7cFvAcUx?V&1s)AW(=e(+Zs<%B>G7tjto-DqsN!iczr z462%npB;~LPaTdnZlJqOt_dVlArvYGjZv?O6x;f5`rSNax(J#E35mez`kMVYSf7HK zqX;p_H&z}i#$Jr5Ou)F5Ih6LNl-ZK1dHNHG>Zk*RokmqZXV7-Qc@Yvo^@{5!+XeaWE%9R&C33|f z&1_1P8)Hvz_oPomZroQrcpKf5+CF@KmE3w?E8u0g1mfY`Ko5tywFkfZH$&vo&MVpo0}N@g z*(;yZpA6zSB>P6NvxIWDEQiH|F=)kZvmF?65;k2l>RY$Pswx|85~=A94p7~&N8B=HY2n?AKI~y5wRA*>BHq6r`Plu^ME@_NQ zIKs0ODgX2x3dnpG}L5BLN2^n)+%^n}|>L1|&H%|4xZjVpbZKWd5;)pGmr2mRYstS=IL{s?i-VBnNiI=AnM zZh20a^Z{Imk!&!mw-=HWtj2A`wDMTk>iON+B-C@bemC z1^|E7`*!G~{pneaDfpgz2FLKe_RR9)8=a0?{}j%cTo)z%I6D;-G|{ty?&mE4ddmOH z_i^DbmCwt;KvnL_u8@bzL8p~IYEc-tAtSWm{iozLFgYJAz$@ zgh1=hW_Rl_AK^~@9@2?Q2P$OFUXqK z{^W6%lk@z~R{+bcjNEOK-7jCm5+him=Iz}czyhOo;?0T{1 zL#3#eMTsgN#cJy=V+id;eeEyHl|CB!;~}I0W4!l^N6nfa8xH(^mb>ewJjoR&^NHfV z2Y-ynxAINlHG;cy(iNMwdn{|=uLPt(Wz2=-Y0TrOn?TMtv74X?1%}m{WPGCax8@Oj zc4wrs;602fU!8oEZ^rE!QhI)Ljj=7UMjuL1Pbx~31aO$`y5FxC+>(%*4LYpiH7p@X6}ci69YXNaO)oXHf@t(P5vC;MSLo7 z+;yaf>VL8^=gK7Aumb12&<7&bWsU}ro8Tp=9#L>1bK%6y@w=D5O7nC}?sh%x$ zdTGoR+)GiOmSfi!w4AL{M!_)i_Hb@Xv%PnjC;Oi!bo-+sWz^hyu0Vq=mRLQ~1$7w( zMUv`j%?lG++yo$JR0vRion-lb8j+m1x94bJ`XErEZ#6DxdRjVQL(<)n?fcMYN$f-H zP7{6x96zvC=u$~C!KQ)uocjT*L*p}eaC%^H1txMA>vo}Y<3V_im{>BnB9O*-feQeCEVl#4rUk?Ee;N1zaEM~5dhGOAGqJn-E?Akn&K)e;Hu3)VZbdF>j++N|d6 zeTTEFmH9W)N}InCdye>ECpes6gRZ{;6uF7(iI)lCD!&07;i}vNFj%=y5)E(Ksg6yy zGb)n?AaE!$_AQ=$X6`Aztl9fK5UeReL-K8RqiO*4f{NF4^m%K8O=ABsJ)m zx$KiR^TEM-F1C5>M4Yf}wNq|C6Cz_$?%R-_dDs?$qpE{PuvPZ5A`P};3+YDTn=L?!T z*tL9y{*a(|11y!z3E|F0Zx{^%8(-kxkB&yt;jU-5N5m1-(+R0O(cZIud9~&J-v{1y zf@JSkmF`kiqO7>|x?3Ak7%i^pf3ixvRh2KfJqau6X;bP|HhvhO@`7?5T6@Vct;-rT z(fw5Tf2D+2^+mK;{#hH*XKc_e4^0?SsIhm;S&q;lHR)}|BKX_oCht zK9=fLlIkU^(3fUsCBMvXfJX;uT(VK{2BJ3eZqw4DEV(G{;_ZYEvT zmt&0JLv=oTbf{~83wqx!+%fjyHPmo}{5gZtVyAB0D0nhhcIXJp5Lr@vC#eESFb&WI zZL*GqQCCIvt{3qPWnml*uD!GoFR-q<3jy#K_iS~#zpQ4y~$ z7j+C7YmAxPPl9h;Y4YvSCm~THOqb*(oVqa+nZ!0M16roKAO5-`dY2xRuiZ*v@c8WmI15RMM=@k?IkrzjR5zZNyZ}bdZ zO+b;bYXVg2Y_d#ZDUh@DM=Zn8;P}eq?`0d6CHHXBBxxz7mrH{XA{ah58c|j{f9gq8 zoZ0{ zgS-181!y1dX+x!*Whpoxe{3%Q`7^;ZkYbJGs)LXEi4(Io7hXQkprxgm7*^r4(3<-9 zDz-EGK4+oxy|M1qOrIPu!mXL^4mQHo10FnDEJzK0rK)sLeatrFgYs{5+T+jv{-A6v z$s_zAtW1+Kv?p-Q>Q-%`Nfs@Fo1|#lv@H(PRpm?PFaJP4e5t{_Re%7m_#Xf6C~|Lu z2$5$RE9CsNq3cccLZ9i?7-M=Q39tu8QARQTLe-+#LrTwPe)r%x`mXGB*9=<>ALzi} zVBpm|Vf^tN=${=$?}nmh2PH=DS9x3ATLI{t9EJwcQ!$(G*l#Q+$OVj!c5=IMgtmu9 z!riR;MB!ob(c#Ig&DoGY#0QceAWm@mj|OPA7U0U(F?1Pdciy~aD@D|*;K^bZ`D{6n zxt9<7%3VvWt>Q<5hr6Vhr$>yRN{Q0p4=2OD(ICuyVeFzRnpIDnqa*l?)T*a8(DaDP z=3^_+iBjXZB6cqXBJ~m|_^RRCgWU(>9bc5thcZys95pDQ^v7pNiV%*lemHrz!>@7* zmc!L+Axu?rJMp{o9o}CiUg$u0YE$HxUA^FP5@j9Hw$tCdtML*=kEPDpEb5sl`ZirS z5zlEcXwr;w`vCTi`kZ*WW1?a0yM8~3L!!F_$b%X-ixWrae-`+Qa(*5aZ2M~P2V(%N zlVISNPL|2Trv#_{kf;`b!SBVmyNZOA46GxTh_0XL#43!~#94ap+GcKE-#Q)2u+`^iImdvN-d?kDY?#r87X{KwD~A#OG7jQDo9h;bGeu&0CYiN+ zQ*U!z=060(`wsFE0ik|GMG~>->SD&gC9CTV5>6{`ipYtP>M!A7|807QBe zXz7Y+mRK=%l!9KkynhkDF#1Fxyg!=wh}BU`Qz7m667W|tFQ2u7evpLC&j1md&8g<| z@!!3{){7~J)oV1y`=~)bj;K-33aNT1$h?M*(VUre43-IJ-<&q zk7Fr`34&_2ZYny)VejYHY2DYM8CCKlbQkQPsfpl@yh%T3>#}At*_FdZWKkrW+6{v{ z7U1D)=ymGv@&h}oi3@dlvk8_YuI@~MS9iuWY4}8E-}>_an8`l{s!x#0Y1d+WKDv}A zmD5{Goq3h~OQU>O2!Uw>tIhoiw~^U z*-(&sV4d+AEUP*ZfY>3aTfikXVuR>iFbBp-mBlGgZBP~Xi;3YHt2$8&RO*(0yU+QJ zIGG>#26`A%Dc?KC&7R}UVs}cb>5pyVWCx$MIAixAXCTOfmfY!&^ ziOK(=11s#3(f>TP?V;s}V5|twux2o! z6UNP`Lmof6qiwNGGjtdWn&PDJuXeU$N&Rq2wWSGN1p2Idr z>IZ0}ynvkhGqqO>mryxblUlm3kP1ZZH_$(Z9euCP_oKnn6~WlmMpgLfBajAsGstUQ zeOA27$rdT6;kXQm3wrhgWhj{}o312_JxR*xx1(-E2dpYK%`F9Lr~}0LVn;XfpwQ1= zAA$Dh0(6$_UK9kL^pE$%PP~RYbttka$pq;tXQ5lm9fnNKl8XcPF!38r#~*2bPV7IP z&Ll+)yS=WUiSzQ{G+q4F!!1P_C#Fxsb=a0ALkPl)T|j~H_tzDG&n z1qaJyp%aXMK&=LMH|>)S69uOuKh-X?Xi%44pYXi^NK+$ol81pTUy4CUtb$-Bh!ioO z=cT54()#Lr+fTZC8q~rvtcT|Kx9As`-V78O%WpA9w^3!Q%HIZxCe_RUm5HZ}9Hk3{ z$k_@$w%14V_9ve&-g+ea8RQNbMb^)jl0w%OlefBrVGBh4=%sMy;cheB6y~i$C5Q9m zOPR2?;<75|w}fIu!8a1tAiw~`1=BC_p5Ah#bKMGSg2JA((;pBv32pq6enbEz^i~E0 z?GS%9f(1V%6wEsCeHe;!$&3 zAi#Ux`+PN@8hg|9wq00|8thC8n8$Y{>OqgO`xA_=clM%E1n9x4n}*#6LO5>Fz){^^ zep->;MaG1_>}iT*{k_?_mfTprYN~n9u-;2sU#b#nQ#WNX){ui_2Xq(4iyYZz@imk7 zXbOE9sH>;{+&cKxwnr1=RKklX51&4H;|a^Wsm!VOKL9I0)W2P$L6a>7y|B1miLTS1 zh9`V?uK*`M=k_qYsC&JX^O`I}5`lzdRClj#veIEdtJx7q-%4Gk-h_W+V%-yS5U9C5 z$_9BaeCwC600FBN1Bpw_aE;IG(ZzqqZKEOKG#!l{fWug z?!MSfO+5;mt8J#*J0 zSbHA|anNfKfV0>nnxQT)U0q03wG;R#Lf!f75F!aE-+9gu6Woz+j(-<5jkB2m5GWe# z)v_Xk*${UCiTI*=7+^(M-GA(RIZW;kBR5wg{?M6TI1b*qxx=b|lgqrqeE^$IDy}QL z2v1Xf*sy}v;hldPj?JCGMoh_VT9-dg6)pP0A{4iHxKw=kG z(OQ+91Ytv69ymd2RDlt!<=9gUxZ>HOlcThMqx*HYS|%=i3!|s-@wR?iNhOclT*F#N z$-`C2VV4nZ=W^g*Kj$qwlj&~C`Uo8Il+U&~*0Y(la~R$z4qW&xqk2l{sI43O9x%lJ z9D_i+2e&c`Q66NhT%-cI=D?uE7aM{n>lm;c!?btY#85S`#azXI?7oq1XSKXtuHx)f zox&HOj$4oJ&GiX9*2}GRXsLr_^R<(RjSvZ%MRiwyr`@> z9k2>fABq-c)kf6>gE$xfZAXdsoWNFm`R{!DT^>c{_VVqEq^IrZKuGUbY5a-=?QTQRLIjrTQ}K-8CAVKuka$vd?ED%W*B%ggmX4P z``l7TDMq-88kM|m)hQ7a%_Va!KrHNHYlEsIQ}Tz0uU!kE-ERDCOGx`e8ZniM%@$HZ z;rUY$IMdU2hbdYm67#M#WH>Cc(b-$k`KU-puZ{2bS~>IKZ|I0JF1ztUdBxopOHrkb zkE7!!DLEPVi!Q!6LY8%9r)|x_JYN?X@M^fK? zRAYcE$}UanD(Tn#(dJc$wVBA^y<7ZDUX@Yx;H(@_10=VaD9>>Xa&^zwSPU}q zcb1|tgD7B!L}3qRwRj(8VMKnYKnHfI=rX84|6>o3(=J_qBM3G|C#n^X%EvY=!1T=N zW-PTUV#xj1u12JfGe;O7?>@y=%K{Xhka$xEVxIX3jpJIQ;@GRFJG?3XQOZBv#AU6n z{9#-|doP-cpfJszq9mPM!)3p6!8r=D7fls{3b)@*GT)&ih)Ul+5 z3>EYRF#6u)cmeapqvE=47)Ef3-t&W@k*Eo>fj+bveKdy+UY{MRDbfdALB8#!w-+^Ci-+_35mE+e{eX_#>TT?Qr`_VveS;IZcFNxL z(PmsIm7YkB>G&}7gq>eX2Z!G`|R-YcO>e8Aj;lOh>RDtTq7@^ zI7ub+yWowYvZEag!l&UFc-+h!Q3eQ zlmUwcg`sn>hC+i0e*h4lyu0z6b&$cKrTXf62rA0S5qK)abFwqAkFMln_!0M5NAi8s<{Y zCJ0R##+Z5UV8cZJX6{Z+w{{#2fI`qKWsGvSMv|@UANv74KxUt(hqydVdS1AANbAE6 zO40eOF}FROBj7b?N_|sccxa+BM6K;QM7VZw#hm-TcB*3NsiQKDs@=Hys4_0?vpIIv zBPrI7|ILQt)OT#6%kRYs#zN!XsJNO#2cNMjPg_~|@{EF(ZWMq<@H?#C3op&GAG%y4L;!+Ku{qT`744xM!MvzoZ@Te9~C@7po+%N8lNdRAR6vb!^b95^UpOzDyI2CUK~pDxB=R zoUfVN=XpV*U8ws6-V>f)Kz%j49VCw;h1PDvthKsuLn@_phrEgvC^1pR`$JhQII28; z>>%a=YS^@FMOZRut(w|r{L;$7(lX-jSVvVAMwR-*JV764WFiCZpik3-umG6}nF#0k z36GD>kvTzZGA(3zH4t=b2=4%lo|2z`ni&1sU$e?=fm*0sPq>LW_Z~GAh zKGu?eW`Q$M{>n41DyXKr!{{uDtCg>k{0t|-E}I7-SbwM`tSwN*Gb*uagx1~)2dBY)3pGKAwQ{$ z)H3bA=l?g9Xa5!-;OM+sG?_+_QW-0g6zb=#K9l-%rswDaA^(|Jeue1wHmS@Zx%jMc zXG?y-(9U(Ow)@qNgS~Gjy&Fj%iaj(27h|2zV&&`w^x6Q@5^Z|$D+PgA3wuU4Xk6DQ zzcq}68I`joa9sc)zB>}!z+2Ye&0&wT7-lJ`kV-n&p4`KB`jRI)CJ-v&9D3OC0`~q) ze0|YO2A0Ai%v2&-@WwYWd4s{yM<37aekX;{?_zU?xHI`Ac0OFp662A9dsfY`cU*q9 zU%Z7TwgJkSEU;hqw9H1VCjJLK#IfmNE8+nG7-Q>P#a%&o|6FAGX+G4Kw)6{LeW%@B zZ=AbX$Po{7a-Yo!VJnyO;m{Kz3kXuBf)F8dQI)rU#lTH@pwfqWA#o=RmlNOp>R6ZK zJM;lgwQvXw#^QQCRWT4%w57CNA*xP~a1@|INLH~0Kb(AGojxSO>5$WVlX|Pil!PV) z|My#5e;N0FC;JX5T6DMyya5p5Yx|$Ah8w$^Wpo?iWdaEY0x_&nr1Qq+69od2QcK;P zI*yTR>8DAWl4E+KisA3SRRjCL+parL&YvzQ{~}h4R*vt7xxu@bv(&vs2`-OA37Whc zPI{D)k)u&q?C{C{K;Zk1dO&&`&37E4Bb)l=SB!Zm5#xB0KY#zzAz`bqNo+VN{H9{1 z2I%uW4&XR?3Dj#s0`Bv=8L`BP0CHRf%Fp#&reYN<9YRj*%7n^_y8?v@l%=Bj=G#U3 zpX`*bIB<=?|I0j=AAC&Au4dnZ6lw9eh*QzKV9Sz^BC#+<~y*EMh&m=S}@5W@TTc_!GM*J z?QXW|!_|Etfx>lmuEIA6e1Shap?)z_ zM$_B#H(=^Nny}~*t!rx+$pzNxQ-~CS_ocXWFZkW?Wa&PH{xJF3j&D@C%T;pZ`K65S_ds=Lv&QCS>A0Gv!U~R30 zItl68$UJ+VlnCoNt;gr>C7)#Uw_ol!h4*CohZbyw!@&i!^(REx6Cvl?`8}_9E$*s< ze8n*@VTJC73Wwv!@35$$cV#x$QvhGV16p_SU5u*b)^b*nO;)rbft9_t3_;XdWo%x2 z-Zwp;;Nv8*c+UUbGD!Scs3~*G-T+lSkjI-U#_tQ$_)%uoF~4FM{>1hqS$O2JDN;3mh6{~9AW zi63y>o=H(2w*p@`wXmH;C&3|`@>Nm+rn$^v0Mb7FPrV>)h8h5-s%iJ4DdZ^F^Mq?d^|GYb?Ip=Qlj zC?Np!3b+8ECrtc4Q@z?%qYOtIyK`b9MRD!Yf~k*Ctl);`m5b#;WFcNDv)DrPWWZc< z+Bs>uioI$PHRjB`ydSq^>Zo5u>{Bm5^g|(q124CcXBWW=-ZKrbbE8uTBSiIZ%u-w! z?Ny+O^5G({1o8e45SyQS30750)ExctDh3EzGIe@K8gcU6YX7Zq(erQ+fnQJ^2oq>q zY))`UU(Ot>#XweJRJ*Ws_R73e-LfL1`!UM1r3Dr5V6v+~T=Ui2?Wfsfisg*CzG-H` zWbbN@PZmf${!H(9iM}BAqxFSb={2;9v7Ux4$ckOU6V3v5!BW6Z>_O+37d_PNH}hA$ zB0YTp6c~_r$pL?vNupx6{4hlwDyCLFW~i9GUF#v7^|?Zx^SFW$(uXFrk|8|qV&u>C*AW1Bm z(RSeD5iSFXj# z-6Yn?g*qFOB3_&r&^`_!i~mBDR#z)rQQXo>cXVvPl~W>pU7VQ18JyF)r1pxig7|6@ z7{ya$@_$uoq=uS9iz_GKOy~Kx`1Ea@l^#1@np&bxapOZqW zrM9h^axirhD;h4Y@0h5&Q~3`e$lR6K|MVjS3B<2mdtFLAIS!dW8>8ay7?Ab_B=(dW z-KVK3bG+~CdGV|9@`+!^bV*9K@Ed<#Ly`0ATzhEm=mg+7W4zJDE{eJV>m*+>YpF3r`5I2EzbKmVOGR+q_xD)^ef$S^w|DHwFjucixM^sT5Y@ej6c-?ONG@b`3(N6n0WFt~mUzPB`!}UKiW96bhIR z_P%(`PoV%SIGU==t_Ie;Ou^n62k`d^N&&pDz@-eGSpH|Z2`QKd(JN-pdW$X1uD%#C z61tTKGy3>U>Cqn23<_;5_GpEXV zCFNPsN`6@WgSwX(hw9Ropg)PyfE`(}jbKnmN2R*ykDhUCt|62c>!IW&dMs>A_4rpq zw*ml2GpApH#sF9FwJ6}acTtAGRM~^Pz+{?%`;M!l%63PYgfNn5j!tfOvR^rV&P2e5 z*>7D}%uSDWBh9e5Z9$8~SkmVE8XUA#i;WkGDv#J zR|9!~u$e0{n@2tceDV$wzo{dFi+P7*BpSCh7{JaPp6~10&{F96v1@D&(a*erFAr<9 zuQ!&)3Xe$#Wju`sOiCyRa`k-b%X-!*vNU(RK7ft7Mm5;@j3@npx!iw5O>$;>8yLiLyZ==6BBt%qsl;DJ_S8g=e=Z_Ys^ zK9o>=>t`Naf6g2KmSF8WPRSJkDYQeL`#Kfg;e*2oK1MI4BEw>^-hta%g21}#kMEpm zFiV&O{5&glYg^z1r63R?UV(*wJb6G&4#Su`9dW%mEJX*OR_^Ub81juCdMTT>KEXk{Q}bZRIM27vfWB}|wIhsyD}P(w>tr10i$PzzF)}yK?<%|^q|z;IfG~d9bpeKR@73Exm`Y{ z^VNq&X4egCmqpIQW>ydzO?;bg^j2BjiWU-DJ=1WemM^1|5<^1_orqCcp&sL9R>gO^ zj);!l%HH=D0C(5yB(ht<2TqLmeB$$3L1b;6r6yQM?zX^m^DiY)kI!_Wj(iniY)h&g zz+N4YRNtnk^^Po+_k7~(c567wR0Sv^VGEl3KI;pkP%BPro>~eSwz27~4>A-Rh=z{r ziKD~X6i@zGbko>griqHPE%3^c>?VYP2q3i^$No4tq4WFK*Lf!XT*g75Fs0q`0iihO zZH%vfdcFr;`DmaKLXt1>3$iUnWDBxN+Vi`SzJKD)pl_6*_YNP&Ay+uSkkRL-B(xLi z%_AER^O&p~M{QuysAubXc3O+Yr7fa3FBEyfrq$ZCeVm0=w4YbZx0m(bgHQ{hPo()>#6F0k<)L}uqHR2pTl<;sO)eItNdh6?J2_yPpF^+B}jnq@V1 zYTezfCC`wyddv4sG}yL$@8zNO%@}QLm0pTlphHYyC4=}^Nh&_d+4<>{*FM7sYHYMu zF`JPu^#6O283FAWl?U?f{V6aRB;H<8_v2~eBpE!=$Iw*plwWOU6HSmS>*+>7^80mZ zx0Ym|aLu|IdfD=6|ElNmC_>#D&wiK4H}gTs;8y%&b_zPw*t_=;=;=(;l!O& zYjGjkgp5addKZb;;cN$PUJ%lw3Oz81Nw4_KfG)|A*(jElAww|At`*H#3)V5LH%6t9 zm+}+hAnM%Y)RQXBbPzLYnN4|)9n`7r_)%v&=VQr$u`vyv@r#!|ak#mX{(U-TY0;Gw zg_v>Z#~3u@39z+WaqW$_7)QL=MUa3E`-D|pAI za690mOj%eiS%Fw@YjhaY}0H6ekC-@y*perpwk@0gXa=mHPi;;mZMVC&4!&_1Z> z|00TJzz2HS8g_yL%5)Zm2ShJo@nuDskX2*dAFg{(c8jY+fp2h2{WR^s1hBf6$v_l7`5_=qh z=pkt(j2&_~ndF@p2y^x4cCA9b;v-E|2IiI*5p38W6Y#25lN`v0kum3xGm1&X2;Kz4 zpkL&4-o1%U6qD9BTtO1}b>G{Acy+2*(dq%md7Id`D8ZpN}@g^KsUGCZ}!YUYANE|7tGsnO8Gfb zFMO9KH>_HX<6AZgdHr)vuijN2RHrX5C+P*FA27-5- z&%85&X1W&yNycg_nLs}c0Bm`!`2|LgT<~m^*wwdj=$4eCBdmf*t7e=hFQ{LOq}JnJ zuii1sy8!zrKwV#>Q2DFbo_*)E5SvI807F}8#=*u7e;7t{DeY8Pt!Jx4`|zlC;Q`L9 zn^RS6)zr1QePZDx*H@QY^~-eMuK$p5Sgz} zZ`L5@S$uz9W9Vhpy99Gg?9SbK)E;1qVc~F$Ni=$Gp~^6-q8# zc`_0EtavB|uc}T?eNx9{jc&GDa88{u_FdI?HZ)xhx53rhOo-PdCJkvBVL4y0i6Xco z-nvx_`x{vq_^dyd5lS7WKx1=!-+F0h)Ajy+ZeeGF9iX_9n5BF?Dto>*5J$Oa)MKfO zP;%|EP*N|xc(`2Ch(+D-L`pkPD`e~ZVTH8)JaV)H+;w8fwc%$wwyzp^6VeAQ;FX4x zEFLS&$3B2LLCC~qkrzD*D>!=aiR*BXt@QDuZE1$onMT`j-vGTB4mhD=8ZlEI-^=DE zn=Nh8UGa{Ui~uG!Cov^qXYNVIhP&c^#sE#530?ZhjbvEIzKLQhG?no=>Oc!2&@uy< z`ISDj{oXWkGT||<@Lb2%PWlbAP;Q-)NhB_qjf-Pa!Ol1W9S5HrVhSh?|31KfN-3+; zknonZVaSB{7tYLY95y(`w1l4V!yRI{NDb%P9B%V-)!uWsjIg1u*nP7F7hRWzI1OnOFa+3F$crvc2Mo5E|K5d#YXPqY%9iCRct`N&SRIb^&N zu?VK1v6w)_KmSh_Yz}0AFM3Hu%K~+g<%pvDI!hVa)mjiUBqK5UgdYVY2Z}Q}Dw$c< z``^Le7^KYG^_$%PkT7PN>oe3idS=LPg*;Ma&AsUd)<{QOqP&N<>Wk9I((qZlPeVV3%}Su^8^pDc8jdKa+4<*iEf9I*WjJ7GNRu zqPqA-pX;FSiW<^(sV&d0F6UDGw%+bDb6N63V_MgnSULv=XwAj{k#SUyK4j5xw{eSh zrSIXC0@d1mK!yE`)|V1W-F7-NOr@;IpP8jH>Rh1YV`~RH7u7{|85~O=EqK96(7iLc zz!}afKBk5JPMt&GFGD~7So?|z_M-1vKN@FT(5aFI-vCROv7D73#ODb*El39%b z{cv?@{H5;4yTgDju#B{djXP8+x*U>Jh|3$v`G;rmA{J*_ZcyG%J^4!e;IEscz}O|; z)6iFsleWRwK-h%nP;NZpR--&U+9EaY{IFk@rFB@Mx)tD%3qA1J2Fv! z61>d35vYTtIu2%TnhS5#ukgHyy=q@?=OuzSIu-hQYqI0}jsKCqz>}+ghFZU@&W|t* zKKG^ScBT^3HoNFZ%`@KrE{aL!OJimrd4-h;6E9k8o?;ykI}de3 zLX(O+^g4xUs5k+_oC(4#4vMTNJ}oUE`jOteK^1hjc&DoYMH_kIe`w$FM(^yKysUjsrg8Gx{?PvJv9Qv zNcT5gHd|{i+^POi!QI9%cpKG4gAZa=%$VH>+tx}Hv7gyOn z>eV(3u$1ZTORt;*NyjQSyi}f6*?Akjv1K3X%I@ymgAraXJY5Nyw&`1i(i9iMYz=Er zc$@8jjp~i&?Q`(P+dl}cR6(#3V+0)wjSVP0#4Df-a~d)`H#WHntNH05Y+ZYxOvvG* z0jQYJjOaAd{J?q$g;50vl~MOSj&~A29>SI+ChzcQz;C4azVxFPfe4Pq-(Z@z|D9*7 z)^I@NC$gZ|B3=cR(eTv9CdL=I*38DpH*{?A!zv3pEvjAlaZYkcz&a)aBt^;6!El2E zXlRR|>>`#W$gD!$PH|m>aY9MeVp0gBgb#v*%B`xXcYAAa6pLLhd+wd3^+I7EnMvt> z$l&tboJ&XHi-=8nytzLFO^)eL*TzNb2&Ef2NK0@hB)plL<^T4&NA|bEGlUX#qEJ%f ztNT`a2({7|^B3!!GO?@*y+&TyCQYU;q%C8RrUYAT)8j~z{s{27$2@dOBxKpTPzgjz z%QqQPFXO%3QWkb9IgM#Si&L&TEhLpZL}V`O&&-VeNbML=6MU2^Ed;>_Z@lR8>1f&Z zZ(!V-XL`vre)?;mXt#zYk*s3#Lb2-XLQNL+P{tLsHk>G6qKpOmh6r~!e-MVvkY%Zr z*}IjIedtfUVAN*yf}c+VuQ7NrzyH6kav7RA^_3A4!bu=5`J`E|GsdA$qxpr76N!ZpJrO;yktW3ks zyR);v>TEi$DgTP2FEsGkgsXa>S*1c@RdgVe6kx|wZ-miIDH(ph@!0);)im+}1PY5y zB(>KTLN`LF=C|n`RvmbV%U4Azyxu?t0nPYeMiI$pWe>`9x802ID1N5U2)1~V!er7F z;f5F#=0scssp51ze+|RLw6OO!CU~!F$1bw9!l86}h&)nSu(4I}at>$xqWhhAsBvIz zLtxaGpUt>$^R98Bld1IA){u&Q`Q+;_i(%F3lPy2O;?P<6=`aRcCh<1Po&vZE{xa8< ziCO$NxQcWGK~Aa3GA_oq@?HMCxHWdU*Q?C9)KnnoBF6&AQ0vHyQqOfkO|1woBD9pG zqN^L!+}KW>6FIs#8GGY_8RbX$ytePp-%#9toZ-uBq{d`yoBS+-Nay4+*Gpq)J5QYc zfAi1znEu_8{_JV^zuTU)qgUNv5u!1qyt(BvA^h<}4!qWVsqA>sVs0Rdj&BIPVoVVr ze|ZlF`nY!G@gB;rOxj2xrATO-b#~KUTwxFFqhdYDRHP=O8!PUcTQkx-6r~<_Is^ax zN+r4MKgx2(EIb-&G=L+Nl_o;`bl}9yX{|K&!%_r?Ju4=@(OezYC?4$-r1hV9F}y=cq-VE(ce9_DZyioXrGT?C z0B3`jDGNo84G4SIK^KMnq_ekQuv^PW0;A>Vur7fdT|^QHvJIBa5q`c48aO&d*E6p& z2k{*=v#}v~ym!P}xVkFTN!HlgWeseKVoz7u`9l9QxlhOC7=oi{(zT>jQMTmB|{fr~TQ+lz?F;(FwxG zs@zt`-|A$I7ETQl8%xqj&axA{^ejF4~Ybjht z+;BQU+1XpcO@Gi{OcxHS$768h^4^Cb-O$QKy=$HIN2K~lHsbq!KPgwjkkHOtX&$f$ zE)%le=o6>y0ecvSP9mRx3ttJ2ix9u95G#v+Iv-O}uq-Ugz)(u!lz<`Txn)4hZ_wma zUxDQ#6?KC(<1sGik}!QiS@^7B&{6WT$HtM#d?nH-*eOu-ASo2tyjCi6Q#UGc8#g!J zbcogf=e-ChC#)rd%g>+FgCq`AATKXgmNtc4OTXF*eDkPU3OBW@BU2-mVZAVxZz)do ztm#fj(npiY|C*0#SUP_IJw+qzk|sw9X&I!B*SHxsGYmu2S=n|L)*s`0zFtJ2cMm#N zuhIg|N&T__k#3}u8RMJf*ARF`<{y81-J-@`HTo!Ea(o=L;PN!H=`q-xfx2@MN71lx z*T%qFeGTK(R-#&z`C>X$L^%_N?g#k~Gec*?teu|s%4GAdW_3g71$DijGEav{26DiFapCBq}-%6gWlCWRbFaerRD87(<}cK8?jI&G@XUJ3@Fu=iojw zp{5V@%A(fv+6&|dU+&RU{FzDKk0r&W_!?6Q9hk{Ps>epvFoHtVM=y=7i|yoswN2pX zP}k7z7T-qcO<2R|nTV{K9-q4s#p~9TQCZlSh`Yz)TMpNTQAMSzcR7z1u@>y}X`I|s z(iWs=pQBwBP)bYEAF$%k4Y~3&Wv%>WKZ5KZI`eU19P-Qrj#T){$tG$EYNFN!yDT7( zBoW}l43BG6(}7P~Hll(FP-}+|wztBPAurl<5wuI2e=L+I9*W#a8>-$Lq{%eKfq5|uPF=A_Zof*0 z-c?G;=g8Heqg<3k?8?+>L2UGzq(kbq)M-txe6t?gcYYQc%F;9ZzAvKzxxuF@Q}dRN?@9UKOF< zV5#|?gHS=~QhkL~TEsM>AW6k*QV*5$Kp?zjGqANu$1ZJlE!F=u)|iX*9rPYdn%(K(e=6I#4HIqFKf*yX6a36_q- z4D|(Ka5E3Ds#)+La~Ket6t49}|?}OlMSn%W^9G{1HiBZX}P8NsTwpW0gb7PN`%|2F_ zX+nDFa%QYB;3QY%_i0${)cA$_R1-9m644LfD%BFw3y%zv(zv}jK5s~;u*u6s%oYM~ zr{jrFZ~||W^$aQNliKIr3{WFE$bRS)X=z}no)N>A%cF;olOyxbMBi5)CBc$maq|k` zitljhJiO3}135{7b+c``Jc|+AV(5)#3PsEs88vJxo76JBtO9Wu6}@I6hpaM6xKe4P z>{2ZpC_G#&n_PQH=eGt^tg@ozXqT!%QgFhdV%^QkmMh7HQ$@0$|hgN?uZOO}m zU4uyAdB>SJH+Vv&k_V$V_{%dS`)M|kk&{`3j`cz+fLI7l2+T)V+b1Dp`N`d39}B?a zW5t|#)gNv4_*jwZ{9biFBzFahTbg;fa1!*4n1q_oO_LvW^`o9WWKuyBBtYo4=D%?( z>vin-1)v&TlyM~DUib;}^H$G>yQ&B5PZ^btZDJyq8-DP0`)b97h5ZltvFCLM!HVxK zg}dZ{Lsn1&`)ZLjvhwcAi2g+(aq<$T6ug_*!_zYS9VnoHkbLjDkxqP?${UdL3{<6e zIQ7<%nW$hpJ+>ZedYd}QO(C=aAZCXI z-*Pi4%Wfl4m9)|!Ji9xly|yIo)C#r2*}N0^V%ZwhOJK%A@1^(k_<6+DR#UN9kl@;iB@SFAN9Ld+u3CfV8VHB~E_vp9?$3>drbS!XgjC4Hevakf5Z z4KBs$Vi18vpc3*cF6jPF86XX5{MaSEg0>O?N}i4h193p@^Jpp&5S{{|LI{L}0Wz3$ zW*guTFc<`*SW?$zE;8VF(~h3BHHX5wOp3UI@um%9$PRTJvYdoLLb8xs18DRv)F&b^GtX6VX}8K;B#OE@$sY6#((~VF19z>67zH@NN$d^70c`#l z2Z|nW{NTuHaFf0URoE?m8(`ZQMY0&yifk#yIB=-+&vP5Gy^L4AKc|X=_;5c-a>E|& zp-2T`_hE7m<{%li$g(Ch?haI}TP9hA3e?Qc-H7CW#)8A^b^cCH+Zh1R0Hj@;RX!xE zLZ~7m8h!5B6ct>Gu8?w`0~UU?ZWA&Ptb)nrg!w?N1K{rP{sz_V3>+np8sYr&-&id^ z7p+$t2tSF({3aW@bv$3BDY3?XdL|#{$}t~LA8ZcC*m{nOLN66tYr|kzbZUM`CT*K- zgPb)EA>IaZv^Z!(VGayM*?}sF3AB1cbsC^$V9F()$BT}$KuV66d17Zho~r1TbESiH zx&UQ`zTo$fYd{M-Dh*ngvmrpoIvVTt>VB)hR?QT_pgKzaq^OHRbVO1Ku%XaqM-?e= zh6ysZ?#-jm54jmWoPQ%wBDjIN&6L8h7#KJY-w#LHg2aGd@VTVKC%tJh2f3!8ffQzq z35fMzm^gO8H|z9trtGw4$lZLoo@`NZ(DP}EwW08={T&3L8J<*f)44zUa@L`~Io#f{!PoGwx|;q;IM2T4`Kk zvmFxR5L3d<0uc`$g(vK63+(=Oi3nwAH=U2(xOaXNG^(lZX5GmB45II%|<(+5`nxg0jZyCEDFz#pZVzE23 zr^w;`x&GAJu@>Mc#zbKsd7dX4^?!(AMv||kWM3CGMU(oQ>`Wa zz>g>rFb7aQQ7)MF(l0AE{(`Qk^?F9)_+0rSqjboZdD%u`xUoSIEW; zrcE~CR@6EvIa~#KU%P3jkJma`cn%E25s4G;i!+IhELVf_l7iDSKgDSs#gta?sbSgN zMk&e?Yy*L~n~aDJBXNYvfmLWNaw6Ab@_=Rb==bix1Mw@`nG$X@jZSs#sSM#W?(qIv z6R6E(1AL|4qTHu1$Xx|{uoFM`*AG(v?J^is<#;urFtSG$Q=!u>hf-b&@+(!D!|&MiNYN|>Hi|UL?YQMd;(R*q$C(>nGIJ2@T)2(xwRtW8AlhbYK(*H zfewZliNqt7Q;siK{DovLfB_9Cd!US=HiBgoSOXqYSg?Q8N3>D+{1yxwjT=D@1y4T7 z=*NMD@;04oIY#^#>Y&{Ls3TFE5`=^3j{R;;s>ni@fxY{IbZ1|A29XSvIc0#S08;2Z z>(3BLDNH6^w|)<~L_-*8rr6*?jijV9K<1e^5Gy5ZkcH)I#ztk&mC;lTyJ~y*!pAa_ z?xi#6)9NEbayQ`IkoM~-U(?Hhx;0HWvSN!(Fp=xx48M0p@L;@6)(sAw`9p|LrA>u^ z-44n*was`@i}0bE;EbyhTM~(qggvWtiJQss!Y=12kY2ei)>=+exTm|OHd-&kZ*piz zQUnaoP{zvS%vv6&TmytBCST!;F8)V4`|OVu1@}gdv(0_}q}x4KL@8Pb1PwUOsjdxEr32=?{0T#5hbU81V7ovD+198P zIJ@W3C8)fqWRwD&0(|XP2(q-abkB5FUEOQWDl=}j70+(R3nRfOM5g)f6zTsepS4KV z4+@x3BgFsza}5GS30g*ZKu`BSBLiAza*IjEGly*Thxs;D$nP``&C-kTjm|ts`7)|` z#@x}Zij@_nNl>a-1SO&&LXG+@RnAfYT6h$QfUdw`^#DOYzP~-~hEp({5JYlC&aOTg z>VwXo73a&V0sjmf41qWp>0hkNnP`-dN?h9hy^nC)oKPOj9z9uUczB3r*p93=(d>ed z#wJK4b!k&a>>0da_-l8MkR+#wuF$SleDQ8&>27Juj-F1>RGiDxsf)Q>iA(iL)RDO& z<4bL{R?!3aye`6#%;(B*!Ft^b#O;6Y+Bhif0YF%|1!Hr5ueEnmu9DwOV7AOZy&`QS zX=i^As6ZO5%ZCP$n3w`$9~L}kBc=8A#Xp{j&`%LvgCgsn^ScjjDwDQOKMBHC<-px2 zPTe{4o+ve+2(q7}M-&ii>4Iw5nW6l=*ZR_hCVY{J6=7qC6Z>E<%z@G2_Mvl z7Z@pR-y^>YiozeCg4D!EsTmv{9yZM1^S4kl;`gu7Z1EmrpD)!Qwh!8{3YZx#-LN#u z3gsv~rEU(+Nyk2njKaTZH090EKMo)^g{|J%6_@=Lri?fci|wM2fT zziFp59x|W&DX6InG(w|}ng_ew+9SCDDXH~WM?K;H?P);S6Nf6%sgY`?MYNyFpxvU1 zsoeU=%+Ki*bMZ&5{KuyWjBgz6si3(rUNq!UGEmw8jwJG5$`&;Q_IL2bbZ)jwIZtL; z@?pK#cUP;(6F6JdA+Dm8fwn-Z`S*d7-n=?7|2N8Ay5?CX^Q_O$Q&j@&>Q=M)$#`~1 zCu}t(TO;sDP=b&nSAjAnM8*LmE=~F;Td?TfTRiYcvPW^T0M0MTo66+wt|!S-IJo$) zcWZTlSZ^a^fYB3>1y>CVf|0p zm+bU(^;H3Oeh2_?dU(SeB_CCOs#36mQE=Z~nnQNU9w!pf(T zK2EWlclfY8ok+j4nPbdIG1Pgb&!A<6%e*!!TE$7*;!qrDiGLq*&`sSto&55y45X~d zPapU_QcjYVX*juCu1zbP2jGI2{j!IQ!vBQFrpWp2VlCr&pQIzjhqRxn}q(yo$3AYuna@AdUtpt8`r1hOD@=Ig05tb|9K3_np{xg?z! zMqZg77-vA-A17oatI4OiL4}jX&Qi^>x~2P(eU7y^M2t@Eb-6M6ub)4jX@WdMnYJP* z+k>rsQ-DTGL>L5w{Uak0HT{$*3~H0`M?m;Q z@aR5C+cU#Qz3mRyQ$GoB<1xA<=nNFX69`U(<(FznLH?0OH9zP5_Jdd1zMPNOqY+Eq z@zaL@%jjPO7w_|8Y>*k5ry*p^<3EG`9q4G-pIsl@wK9F?~!;tRt^Em@*g; z+LNuGrmoItrh$7EaMm8RzaS`#%*m?(cTj1UGb!u6WUevu`|G}#d}_LO!O?$)OY!Er z00T6%nx`S-ZF&`PCN#&5>a+I?b@mpsOWEOwnI5X-=7xW*F{A&I5En2A#SrhmwL;3` zX|vTRw%{UWPBpHV(>CDLRcOz2X>^9Tmp2oRJg>Hlj&%HW%1)!V8%8VRdVQc6xy$Hs z(FA1<3Qw=(PTZW|jvFmX(S+A@{Aw-HuN(%Z_c^BUed)oU)Cj~f*FCX< z`sb7Hz*u9o331~F#6xvZjHb?P+bE)Tir^kLZ0V<^dBJPxc>TVcz_Vfe$f3{2AgR-a zZro+_mgT-E%uCLad5fK4R$>X&mRAwTSg&@tRvF#!82cVKlVN?H|M9K9zrTGou}GnS zLhx~V&p#sUBhapzRhX17bwZZ8ORZZ~ksB?DvMnhfCe0mdvrMk1d992Vws%lHN5F(q zy4?PG;Yik1k-TvDwKL{{+^#lUjhqA2#vW2q3O=%Z9Jqag*KW~Yl{866f77U#0ap|R z1nB<8s<^Uj%)UetfIFwV3OymuQI?gFHNmMu7!>iE7FA&b4Nt3y`Cer5INdyGNCjkf z3E4gU=u({xcxElze$AP6P-b%Z6q0aUDokqy#x2UhD(RKCvHIT0a~u$a-0sYpzfeO+ zaNO?=FFy`#H`{csyV*#RW}#nv=r;ioHQR1^+{LNd3pYOkJRhjbALCOLlq&$y0(NxW z2w#9$#N(AYzNN8dM4vc;X^~GPi-MjUakO;)zm>HkG1ci4yPS#sy;j^EH@3kddYXQM z6Ws3Zd*Xz86c!Bj{vuop zyOJ94O$LzT1$N=JqO9ixe;Wi?AA;p7F5ThR%0v7$-R(xi$Xw1sT>K` z!my3u@LdEuQCfpSCsNtgfJuZ-N@s99cE2QGILYhDX=a-JH+a{C41XjHB<4Mmfh7G` z>f6EQ8_a5AJB60+g}EGle%%Cg;I2AxIMGT2?;Sw-5Am1imcGM91C2KqxdU0YEt3ZV zLSPoVpq-dv?=q!pZpLmKg$W(iu!$$Whhja@8Vg zo|*>b;N2P%yOLFGB~GUN26Flk>O;HK!zJ3o1Xl=cmAqG@{O>BXg`H^(JnL@W%Pj?K z8@zN?O4PbiL6EN%;8;Jc;MahZ@2-acWZ4XocsQK?$|(F`4Shk;-ez1nn%IO%&VVtA zx~o(x+)y6il9Kr{6WR85RwpE zZ;8D5UkNA5iLWnObKPHZ>1aHOIZ!?AA0rt=&(GsE>~9;iQ!ybl6&*31PuRen*f!!9 zLu0ncin8JUm|L<05eOOQ(?D-MoZ0#1w(rX~akyPZF-PZ@z9lW`IX9fc0K*(>iomiR zE1J=DQS9YO0szdnT~A1Qxqk_sFaD8AB2J*6=%D9GoYb6AY%9Pa^RlDhPOg@&v!Vh# z=e&B#f=L%7oFsY;ecLbJn&HHLqYw=J>p@$J9#zHr1O0_nLd@%!kBL7hqr*+sM->uo z_8<*Q5qLU<`#Am+5?{JpJ_r#&i(sWKLPzq6bu&^O!G3i+8!I4m zn-*k@DaX5)sM_ko80TUORADHLq;Q$cjhELA$=;sJm0ucjYJCHHF}eUwPYTp;(3ARW zMKWgsx;{BA-Z$^g=w5WFL1cm>Wjmcs=#fbR_&JjzHbp@{S08DjNTtT~6K0>z^D8MTs z&RH(&+~}IJHEl*ez9v=}qhBQ^`xc+W*qUaOP4jBvQaL;4j2^i8s_sT zJ_Ow-Qc~S)fB{T|A7J<}33pv%N`Eb>O8}q4hfMF^d=0fB~V z=K=>-W$sc0Nx=7r{=}{tW=xfi@p=r~$}L$pz$fAWYmMQ!7P^rnUfO zgW4&a7hQPcW{ze@qU%2X%9$X2k(h_5#t{)TG!}D0&sZ-hLJc1$MC#mvEzk(#CXJF5 zV&a?>xXTxc`J_dnkjaBqf<}Otf0E}t#LuP}r>oOlgpTC>dg>gs6r)0Qw^e4K;qCc` zv8uKL%BK(UstUiZgEg@sHXqHiW-N^wrs;NfuljcM(586^WRd_*R z%ImO|P%*+%N|E{U5VktOoHVRkd{t$cd$uY`$bK)OxlMBn2o|X zf>dHGUe>W1LyPn{aWgx-JS*hXRiDdqKVB-G(M=oxPwxWA+Q+?7oOkQa2uMtwz0gSP z@r2S^ATJ$WfB)=F*ua5{r=L|m^DHuA7VR3LGay%oX8i5OVYDSvRnU{thk`CjpHZ-$%U8FnO_-Qo+C5N-Z7R z8~8CT6w(?A{0g_#+ij+^aMhDY1xHwJH@YRw9Y z{{_lA)}pQ~e$1C*kX{1pbw;Z5B(|4s9knX@XT4I6K#3mTCc=(m#?P5Z?x)*d#G)9( z=0>Yy)zOSK2*XjWoWG{&dBgVebp-qf)r!YCh_|^29TjG zEl>T*pS8o=>@xNi2b;Esk$m23P;FGZs)7&(i76|?D}|P?tA;$*xp&>&3liniSxY~E zTevM0e6+475SQ)sU1d{9FBdp*{Q?i$aBAU|p*z!~&M@fQ=Gl^wk7}AXCPZr#3EUq= zP)2$r^N(1p2h&5FpvVJ#pc6-c+%uWFjktqwoE0=>CH7XxLq6?sBIAYcSAAKNL)>BB zoHFm+kIJ2p84fCBbZfEC?9mi~uq&rwV@(x0mMu7J?{DOWps!q3 z+ql|fxut>w3^aaL0Ljhy{EHVS?oQ9iKGAz34woM29GJ&C$qFU4G%m*z z#@awE!6XQ)sEa1$_gtOA22Vm^Vk!6!g#OvD9gD0aUgP zPCWIdlPfcb%O>gFJGf)$xn7yr5sjjc%}sG?@(bK5txgEABOyd<=Xcyse0%xdgD#u8 zRB4!O@W$`68{XvK;3#{1@Zo{pk=ig^xCkRl1A?8Cabwxn@`d3E>cIy z?K_$;u?`I~l*S1Q6Oe>++MAa&8JN$5map>{MCs-G^H3H*Sj=(dU4b)zJ2Qn3$b*Kk zsfb6M+BVbp(Gl+9oUnEx{TQ@@K}_)fDAZU707`2Z6mUxA{X*Bhce= zb8$1`-fLt1i{HpRVC-STR7k6esM*}Qn3ZzDOyn{8=|~P^^CIqcRpFkj0C4p@O<#`~M4_G!5DaH(5wS3>Ths>@&$UD*m@BorJRM~tC*@Ikd>_Z zWrOd}lpkG*`qrglLek#Uq%|sj?IG=-ub`zqpg;nu{{TLgI*S$K58A3$p} z|8rviZxcdh+)^l89TC~n<8fE&o6Himq{4l8UM#sUB+-HPqoK$;gF!}DiLU&`hDEH0AFPKqg5lCX@Qo{5PY<{0_k8^#!$ zZXHq45@t{JZrV^mY>V*nR(m3(b;1*&fC3^vp*k6r_ZbB|a@jI0ZTU*QFCGmsC?+Yz z3H`8xG$*^KZLRLSdGhy-(=&AAxr3eet4}yAN(-s zO2-}tj?#VZumEtC?cK?8o`i0_U-Y@(P!W#u1n1lopCpSh4340$tW)|e$QHlItVB0g zVn@888GVAsE@oRH34kzEOt>gjSD-Gp{&;32Zr+sR`{q> zh%?EmOG8|F?_4xXyhmgfkfqynM4PDy+^7MvCoiQEZ!#`VLysTF0ev2#LuAOpv)b<0HZ9y4x(cR&F>Qo6=%0*gEuQmiqLY*+j9t6tSJ}VC`n(L zG19CV22xmEVR9TXI*QpqTYxseZI*3g#R_foFaNC$pJ};;Z6*i%C>DwY&OBcRk8fb1 zj$TK^WP)bwDIy7sl#jxa;LwH4MU8%@`<0N7_6GJ6n$7QugD+X^#x4)MvrvJC#2_T* z8qij9uWeeo8HxWMuWi*shI!M6drnai6&({X5Yqqgnb5aF2mMBA!#jJ`{Q&?T-7dxz zlM%*08nLIQwm5@ZEEo}{_Kw6Z5nkINm`V}1>+Egyv?*1%l%;U_T2 z${pr~*yfX>g^WTDeZ-{{APm$%(pVBTl0@fLjaAcqBU&QQ28RTrbp^cC6?i)*>SStB zkW5~gJAe;6ttWTyvs`SKZggDR<$PRHSiOaO#!sM0rvoF)lMroGd0I@_{77XOTSZ5? z-@n=k6zx=szGl8P_;Ae5Px7!yf<4w~CA5IbLO$dGb3WjQ-?~i;9~j%Sq#@V}W|w5W zXFsKdgbqNWz$uPajXJ6DZ#LTWUYdsMP=dp>1(A`O*aZoqKCi&b19l;OmN_FFuO61r zUub$^{MQxeYn0sI>47c%!w?Qaw8CxTorYW?k(p-d{v&i*R9&wxz8pie(w|Pvn2KvcZ;5piUgALCYe-^$< z&6K>f8Gvp@1A%~aCo)u+oh^{I&u zh~M%@#TT4z^-@i-VtuY<@&!cM1)jM^p4LSE#&P|+Ny2opL)7sni_AF1&fO5?fnV}0 z&qc{ULPXeogAIV}p))Ukvp4;U`HmTy3=aJFULUg_(z=P1`GMqu&a6*CwB#okLgh#J z5ezb+B0oH&fq81Fg#V-2b)gb#=DRKb%2yQxW-mZL;rfi^Xttn4!Vl7kiN8g?mSF5R z2ItU)qLnA<1M_gJM;?l{Zdt8tZ?m<)d%gbvLxG(|SIZmHxAUaSlRO43$iSgl4s_xyv27&_C>Q8WqyQwT%xw`J z)RVnu=e{_L+6CH63MM;FL1k~^u9J1kD8Xfc(Z;<2OjlYpq!*8^vaycZ`*cjDU*U+2 z-J47(?Rqq)o)jg%Z|*7<4!@Wu`mp5oNU1p!j;(?|^~ zjc?2n1H|hL+E<1o6>Seq6JkR?3-iP<5I04pE-{65sexE-l1%fMVAE)Ti2%@MRLzBs zXDIMQ_Q}YgpDcWtXcy@CeG~*cz#XxOu~N zRSU6h7Lmv9QbO)-lftdlI75#LucI@K016-Ch%1nN!K?Ui<;!r*RKXdjFp4X{!V{g? zTAu{!|EF|Xxd>N_p4n31b_LT$p58$3+NX^6+-C}@&Md@vJM)osb+Ls1>uprWq0>HX zZ4CI^0Fw_*f6;gXYp(%j6dkd!406UOAnH={bv}AIJn5qgZz;9e4xBI{5dFE1vm7;d z%qMSLAzoq<{{LNI8d{&>y6f%)2x3hhi3IvG2KI;)goB#`;0|^LV{^D}rMdoenBjvfX?;5mnca@feyg^)(zL-7-`ELW8zZ+8&&#@Xo zBCa$u6>Ntu*+(liLy(AAM5v>W!yVd>%SVA3>cY2dvJ`IeD|^X$H%8zQK!H$+cg-!YquY4W?l zcuDvNF>f?Bx15Y)$jI387Y>~TJRZzG^~S(Jq$q8ZR)l`}*5}AFlynIdsl?zPAVI;H zgI!vSmmCqR=Ux%>l~{jDO1obLqt!nE6#r>sn`^rS`Lziz(v@_n#?Tg6;w*LEosVS8 zbOOq*OQofF9y;-)7r71w0)UW{jCi`1?}_euS@NdvaYjIX7*R~iSSe7D0pg$7ZYZ)x zO6=t?isVmJPD2sdFV2W(L+2g14r)qezv+Ob_Y47t1YiMRjRO#dHa+5SK4XVRN5ru% zUagw30fsm-bSz+o6<@k3A;NqnS>_NHvtDo(GlFL|Xf%t$l+wk#0}oke1!*ni<&5Cx znY8(g9=*aRS)7Cg$AeQwWp5Ua>yJEpCky(pk>wA_GZo+*YieMwTMdoCgbtdyEhN7X zS`R{s_+9+XtRsTkp*9(KQy4{x4G_XL&~lBY)ew_vjzof}zJjzHTLv-$wnWCLDFoQy z1W@cw?h$U3cOB@)z9t_Sb z=CPBF(uh$A-ILL;+Dl=3K%#@l1ZEAit&|{yRJV=DjaF3hy|B<5$c}#ZF^j!`4GV4? zcijAkOZdYojWKcVVk_1>;)(d3Ax7s*+BvW0xRU{rpBK=-F-L7zHH^W_DkA!8UBTiB zp^ZIk}>>;8}R~Z-n_4 zrHV+C+|1<40RbAZosjAPT`8m@5^p*+dP-bC+fcypdnl2jVS(wni+;a_q1h9uS0^5D zBYq+>AaaZShKD)sp9tyxn*?>Z$0~oWfNG&+eM|Bfu`|OQ!Bhx>5#onmy0q;p_Oid5 zfvF80Mv#_50yp85SIRw+H)}=CH4e49oF|N%9hDHxX3}ORz&2P_y@ByKgU3CG$S*{P zZ$BK!O5w@CV2A)E>@r%Wr`zu^CeHv_{bNC{zQenEmMcpLx70?{EasGKKiN~)PVkUJ zuZ!L zH{iE0TI+L_EUV3q;z=tajK$isAr3+NR37n2_G;2%f}za_t}I|svKt&LUU~$?$0Aiw zvV^@Nq)OlKBA|Gq=F&W_*`}YTD*)$DY4%8G2WW*K)0UhYV6-MczYLWx+GEs$eF?wj z29jfbiDO>Oc@Tooh$EfgqpXu%kH<2(P&vo*y;3|zPd^EsU=PI)d#$_zZqYTbwg3 z;+wI*e;`nDbRNRw(6iReO=2MsD zGGoGkMuD#;mG$N_UplsS^mz(C9S0b(S22zoux2PbFH|=0Fp`X>TTX-p7)u ziwwlF?1!rQ3%)M@e@89}%VaP~hv$FVm_O3OBu|cc=PrRXCT@P+<3ZY})ex5S=D-O; z>#x;IPvQuc=4{go%ybZYV#eCY-jCRZ z+`ZcgIq!OOZN!Fh59~zX(l1+!4MkT&UK^-$`E$qh2HtJe*cHYo%?HBEmm3_&t zu;U@WSRl2}10*@&zHY;Z+2W1R*XYx3}c=Y^)%)$ay8b&ks571W=Dj)DowE55Y0l}1owd7E%cree9 zzib(^3C~Y^;uB3PiJEWgutu>)*4VsN3eFz(L(`MN(lw>I8cE2CHsNc`+Ee2XNxkmu z!N+ZeD~I6$*DTy7y64LvXwpggcy85|FW zi4r0`jCo6uSx~0Rn_@u&=1(YqV?oHcM}R)@c|+>0w%PAAR!L{tY%m_ZE{v(Xhh+de z!f{8Gvt#&Xwdg_X8$8&>s=_o(q!~GMb(QlMh(^c&tQKL7k03dBL&4L9Ww}8zH@i!^ z|5|k&vyl5A=mUhp6C*~%WjmuC43xQ8Qm#$AgBv~12+$E+~*^V3; z=7)rkCao0n23$}FW9jl{yuGYm{=J$(d8jz1y_$h>>o(Xwz2zKZ^YZ?*p+h*zayE0L zf%Zv~RaI-~e$3N=ft`rCS&&mF#nZpVZ3U;J7-G~Q^mh^zFS|Bn%mTWdg*DCr6Gi<6 zu}G~vj^IfVClGnr&dnC61FXz`sJB{&i-B zPu)6l(G-{sS?c_e15mCS9bc?oj$@F!S*p3$3()j}Tmhk4qmA*VX5+wG=xhKsCSg!H?c{~dH z%GNE#(r2y2^rSomTuA2WrdZzbm<`6{n_u3|tEkhu8GOny0j$r}BOAzd?&HwSjfe7= zPUi`Ytr6d*R7Lei>S)&Iba=&erl`9py^eqZ3LW=}w!IzV9Xob0NFP_dgPaqCDk&19 zl45A`ne!BO%;`YT4RKFWGl)hwqiK_&AGWHD9sfvR>;TAm>EWjr)t{Z2z!t-8m;6H| zo2cBt>hNV|+~a$q$#Ea;YYt&k>8%s+u*tN!qa}prtT$;J%mON-*z&*KApJYpzwjED z0g?Bz=FkuqC7@?=jCa5*3qMnVs95WjwRcs=+gJ-yUYd;~)RtI=q&{|}5qR1ZxPa;RYDH)}EVyzHEwix~bEa3BfGmyK?kjDvlDL7zNnN8JS z-u7|vDEAxpv{-x&jSoPXAStJ(J!(tGCxni!JzZ#Q;bK zBP)0*CvHKJHo$1iq2J~VmBS}HuI&RjJAT6>)X#^_TI7~CtjS?r@K5St4kZpPv~7Ip zbxWqiOL3(bK-u=aB_WEip*;pOI}3PEW81V|E@V5gDAM!iW)__p?E~s=ACYoDIS}#Z z3#(>;2n`Y`gOnuMX;yqiW2aCU+2^d|45m)kc(`Ey2|VI91t_6(wQ@*m2CZ`LZz38Z zVSj$%Fv?>bVujQL8D4WP)lJ9+N>j@|Z%7@DBP3{R0l5I7Rh5ruBpTF#b-tp2wAW3< zYplkDg3(cS=LYM>hOr$^e&cZN5@^I@8RqRKAeAoDHl2z^}BLxYq zC1bwMr;mZJ72A4nf-L5sg!o|PT4SfZUxQ#b)h&~IBSQjc<^*NgR3r317>f9`N+odx zNblbvq*T&{AD~tEt$?iCg<4=#GCQf`>H0>y7BlSP@g-Aq$?DNJ3^LkBaZn85>SSh4 z;xvk63W@2}-PAMOa}^_wJ4Yo0y-1Er?mK7b9%h+1ZR z7`-g=%9Nu5^%l8imM^p+AAE?!XxWF-N8pKDAWkhPu49Fm5ZQft$t}>s%22Z*SnLcp zm*o&Q!V#-eV`Zv8vhSs~9T`d|zqe=~a&($&dBoA}8^Zy=BG~u>9 zX*J;Ca;_BjGwE|F86Ut$i0IlQa@`@ehRR#1^2+yg%`5eDApp>penD{7@Gr`c6FXCYn6XAmHw;MYSL=pe+jBT)eZhNkMEj? z5vP-UCGxQIs8kcsFim^(?0nLapqPGcLMeKTe))I4zyq!*T#Dq{u23V2B;TUjJLB+BGR^s zupI*R_wU|QS{-y~Pnbf)35KX5)NrrVC#pY`usoCko5_N<>11BXH7W)lEtQIZgKWy~ zKTL_PJemJ&-Z+*Ce#@|HHm^8YU@+I5j5=NlmcojxS~7jCg88* z?DKZT(YoNw{siz1AM?2SlytyLb)qqP}5_>i7WY)Tyo*3lQJ8Nu+yO0hd1hF*7EFQnjK5R&*me zNH8>Hjh?tyFhRnv=TkTHG-BUb1)e;hse#a%Z<3O{ZlfDc2=`lAw)XC3d7M`nj zoz}2V(C+39yAF@>r33PN=49T|g<%np1(WZ&XeH64EkHYRI1&LDDE{_0cf$>O+ty42 z$kJ|myHJ{t4(tJ=`RdVL#rK~3p)zYYS?tGl?{_|ZYXIwGmd;5x8xBs?;W{#9uTC0y zqPGL7gsP&p4ZVCdSU7+{;#E6aqX2L8N9@?4t_@rY>n+WfHqNiSOObSJD=&oKYu>ph zT0T;G2xXDgOUbQZk(3aMd#L%eQiss`(;^8ABu|jjSv=T7BSz`+d#}h#;uz4W)&-c@ zPL-80T1)S&TZnJPEN(4To@-ROWa}`0kHehFouGHD;tnZiOr6Xy>${GMUgH*Kp{WP& zh|U1KpZvzDVrYI$#_z5Bm0~@rV)eceXTkr2l3a!nAzaj>KGFWMQjFD3=E}LNPrK8C z7tvr*m7tWyy$x~wVS{mf!P22?cO39w)i)1=H7I|+nQyAN-(&V?H84MCP06VY*TS#` z5z5P*cpaqVbmGB>cMdae-3=O5tV1E~pu0b#=6Ee%)coMT5wpyylW^l;n1dvTw63fsd3o@Sk4X1~Ay_YL}rcfEeZcDDBVeY`Jcxahw zNLx8|T@(mn9_z}2vzaKI!b_|V#h(W4324s%PsSN$6c;au)G06MqAg}Qvp*bOT%~q- z3umsnWQy=i3Fq*WHk&&UQT&+#qYf1EdmOwYMn^8+LcN2@;hA4Qxejs_nmKS1)uHl9 zRSEOwZ^gKbDE#BeA{A4*JLhdxlE2DzCkB-`n(}XzrJH<^gA#&%NF^!IgG?Z|(Bcli zFF|JFP^^?Igwp;qcQuCs%D%L;b_WW(BhB-&4NoRY2I)gU>*cfaj8TDyS=}4K-!+Xme43cTMZ|m z5EvFU${Q{E(xmm2Tp_@D%|I%DSPo7ffJphCaSLVhFo4dY+(Jz;<$*Fx}# zyV}`c&OB2qFcfBeW2!1kT1S+hMAR*lcBfCV-;mB18W}yxarosf#KwbCWqcEy5^R;8 z;#fesATXmzYDUTH8A0$YLLsFjT|<}Vaq)smCRWSZfeBKb0D@Q285Crfl>!j!P~$%g zoQ)ZmSC=*rj?|5y!pr0HX#UkiTQ+Ej{=AN5Y)&(!BRKh1?XnYn(%Bl&4nIVv!sX~l z>NRx`e;t~h*s}fcT^8HLUx9Rc`fS$-bMQ-M_r%MZopv3k9 zTf1;h0G-Z~C$`Ch-y`y3E|&&20Z>p=ePoVe3tC}4 z#Q*-0H)3AKz`vUb+$aLFRw&?N-1YxY!B%?OBm}f`z`2UBAyzI;#JiySAQg1&Fmjl7 zbE#*O*$B~ztYqWg124brMw>D779#pHb~FuiyW;oeA39GGy8`loDO1QUX2omu~QwbXyRTZgE{6o3(x!m6D$QZFv$tgYI&bw}fnm z*#y4XQi=k+{{*kuPg8Qv>vl;l#_jGs!DYr0wR|&=p17?_-%_V_bJjKkPBKpS6MJMYh>Ty8&>f zjHm6TQifM7gWyrYVLpvriWZq`mgWSs>t1dzU9=RIFX7$6kG%dbWq*7f_vus2_kJd9pqAyqLTr z#nV_j`zrX@_O$%MDBd+Xj+SyQ(`kItnmHJ%yInZhl8bz*(}t3)+pJ}`k7)gS4~rCy zXUZi4@iq16`t(bXrf7J;jYCib&*;)1hv0yTeEqjckQF;A|z>n4i?Nl6WbO< z)IbB3Icq_L#8?loXo_XgVO^2>Oq#3k?_Z-l-k^9!ZJ{Ia4^wl$fwlI@ffN1+N{{(0 z@?Kfzm5LmlOBr>)CW_5pUj!nFpGlIH7ur$f9=Rp6VyuSrqaZ4lb*tsfJz*GCEx|SE zc)wJL;~kJMsKu0+E=jtV7RX!a(x+wjCq+&kng5c|1ll-3wLT!jZk3$H)-bJ9ozp1N z@jL%gAb*@&mYA>q; z!S=H7_I ztMchsXT~{)2$%ADl3uqvNmXW|b&m|iveO2)cX*b0*#74Am2|-><+uZPZDx2DMA{Mjm2u>2_%0o8brCv0yAGyVL`=}^*>Ptyt#1eq-5HV|2B&=Q;dpc+&-3)9sjrC`W%Y)3ihJyAhDr77EXo|5`tEWzg~>ifWe82rQ6 zylQWh6p=)Q_jE4Q3F=Ii5Awcwj!12lyTh*Mh@LUmE&A%;_+~S|AbYfmp-o>8iRU(r z?7hy9i5gFi;|GDFCr~5OkyHtNS6^|7V=9 z8$d^SIq&G0`W+|!(9U8JI@G?s`6Wmidx9X;LcyCCmbj-^i$02)SwY)Xp%fYtB>b_5 zGO6+Ix%9G*TroG*RE4hl+bheB5@Ij$A;jRBcm784tab~mV2;pc&NJU{ENJKJGxx6e z@=~nFZejLd5&oJgtG~vL4|JWn_Zid8FzP^@3C|7Cp76%e%9M`ijoz?>ER&GW*p-R% z;D;q8o{`{t>dXG)Ic_x~KTVvXKv7c?b$#bu7^ zsswcJy*7mX)YvJUAakdyN}X2n+fQzCZ(8$8oQ=}hf<`8^D2_cCt!+{zKZL3LcbgD7 zIN2@+V*s@72>lJ2j)n@ZD+kWz!M_Fwo`P5dDQ|7Z%rO zu6-6f~0|yo6W%M zUU9fz^EKN8DzGnps#H8EN#{d$XxUSQ68A}YieIplfzbV*8I{YdTu>*+i(Jj)89Qog zOoDW$i3e|0AC@T^;}C3CwrSX1}`rV!yFf5ZR*J=lslbl0JLxhx_Px|6`tohU!I|2Dp`AlS|hYGj5`g8YMqKRat6Rf zgqC9gD+|>0ld}>$$&fucRtv1??@hLPylLIp+DiS=XL2Pj9vLh}_j_4v;n$`oLZVR zR&M^L)7qP55OTlOt?ohOyUS01wr$B0B)O~A(w4vAjKjNCwWvWUb--SGcQh+AS0deI zGJ)KW2sH)pIH1trsnc=I!~+GWPQ-j#y!wM!ESY9_f>L6~@<2_+dcA>U8I4?RAQ6o<1?)&`OV118pTdTZ<=1JF_@souO{9EVwtWoHN}X=H$iPmiqZN zsTJ~l%p+$|jkW3(4#CdM7tVjZ@&Ae2=@*{3k8sZbF^JW(zygf@9pHeAn=&Qr#bg$} zt@pD&X9ljlXJQ2!v_sl2egssFKy<}(;$j8{i9mOQ#tjVs=RYUWL46;5?h*%DhYrVI z-%+)lLuC|8J~{5Jg%SF;pm~P5U%)dX1lvP!Jh9eBchS?1nHuB1T_e1GBF}vB$l({l zoWhm1h_!nCp_zmRP$O9hHuK_0uwMx#>y(TRtBc3csYAut90+VdmR!koP$R%S3peb8 z6Pd0Bk$nMe6Fv}Vs8SYw+>t+`>+hkurhI#A{7vE7rIXh%JtXhZE{E4c99o);ZEh0i}(iOz!13dq!*yO&8 zr4&EWd|^$+*0i7zW;bv=P+Zvr#EJt9nDP*{;X;-ZYJ#pZ;MacNxW85^RE0XE43na* zDhlAyLafljN=!DgytL$|CHzqtaEVHD?w5L!ta`z2Ufbjg(giY#U-ppy<)*vM59EDsa`_R#p5flF#fk+W3s;2YcTpC z^K2RGLY&-S)uG=qxn+RTE!z8@=>ZNJqD~mzU9`j?uGe*x#7i4OEGfUa=2_7_SOUBS zv%y;=Y!&N+7cg`7Iy7FWZ|-_=WFXkUglZh+y(+O(D>))th{U?NApr}-!^N`V78=>f z|9CKmobPZk(a~sfrv^UlA$>e#w-2Y!o^-UqjA+$9= zE?+QJv8nh((Lh}oOD(qt0vT8q{^-i3+ElX0^?0(VTNRfE2aCBQfkWV_3u}gx&ZXi@;2{!%pLTcwOsa4^_J33*QwmX)fHuMa*1IiQPL_@i?qcKJmn zbElaoGqlKDoyqB2Op{FU2@Pr|@15=1bJz2=lGIn^*4C=J!7l~Pa$`#)>Ki|bdo3!7 zO^bXvAqByyEYe-CEkdbxti2^Aw9-fU0X_kP+~U?9dF>jmTPUZvIRLW)Vkg~1yVkp- zj5!*hU%~!v9rY)k%Hy2rDQavcBP1!x0t?|lBJ9a0@eeBkZEF8fz1>W3j(4>9IgDve zC_v(@SbR3y)?jTFYu5c_+iZ8<=(T@=if-J zx;Gp73MML}Z4W-}560y3;nc?CBM#oR^y?KY0)eh=!k-LEs%Ja9iXPm)u2LsJT&C%i zeGS4z7nPW7ac>{Ur3;#9o>rPeO?{abxPo#vJ4u)FuYBPfDI0%Yg(hAj^ZRf%j}^>4 zT{g&`S93hnos0}+99m)3e*GJmCu{^D@gy&XGv*p$0E}oldav8dcHCa;;!65Y3=K4* z02HgSf~ z*A(1wZ1e(uwK-c=4B9Mi#GLYG;imP(oPs9wPrQ_7S2~oEHVHuR6iOi2)$bEVHR4BH zfQ+|zYVwFMJMHg%&4*Qs!%MhO$pNDqpsm0zKM>duuGPA2j-beR(7!Spp56&lBC_|4 z{woLxEvviHq{}@$;lPAUny1IOP#4O%F9Pc$mY#9PSk%^_JE4;T{duhQc=CwuL7I<0 z=~KFOL`)Qh3w$|+nVPs(~qHthi4g%?0C|k<@#v@p+E`6+aw~D zm#GD31Q8jCf)Ar^ClSsjb#n854};t>0e{D6DLAG#8XLXKS~n0MFu)cj*~dr5MY3m| zAjaei@OMB6u+>FaFUOCs#)6tVE&Q8ZMzmKLd&FxnOe)gTh35<1--BwVGjoiC=C^md zXXv-BHTxRVi#y-NU|Z-@Z*-WG)g6`qx0{$DjzGVRid)t^1}gkU0U^R%R*}P3-sEHA z7)ZtXiVvaWPGITu!~?zHMCttrw^Doo1{RwbE2GU zr3r`3at_?~(Wd)`v-V`er@8*`Jn1gnBw)JM;0GXs5?_QT5ooC@*khk&>WC{zs7Bv@ zt69iJEyT|_5Ptu55C8xG000000000000000000000000000000000000000000000 K000000002Zz@}dS diff --git a/boards/infineon/cyw920829m2evk_02/doc/index.rst b/boards/infineon/cyw920829m2evk_02/doc/index.rst index fbb6e02439261..cac878c01a595 100644 --- a/boards/infineon/cyw920829m2evk_02/doc/index.rst +++ b/boards/infineon/cyw920829m2evk_02/doc/index.rst @@ -19,9 +19,8 @@ Hardware For more information about the CYW20829 SoC and CYW920829M2EVK-02 board: -- `CYW920829M2EVK-02 Website`_ -- `CYW920829M2EVK-02 BT User Guide`_ - +- `CYW20829 SoC Website`_ +- `CYW920829M2EVK-02 Board Website`_ Kit Features: ============= @@ -86,51 +85,76 @@ To fetch Binary Blobs: Build blinking led sample ************************* -Here is an example for the :zephyr:code-sample:`blinky` application. +Here is an example for building the :zephyr:code-sample:`blinky` sample application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky :board: cyw920829m2evk_02 - :goals: build flash + :goals: build -OpenOCD Installation -==================== +Programming and Debugging +************************* -To get the OpenOCD package, it is required that you +The CYW920829M2EVK-02 includes an onboard programmer/debugger (`KitProg3`_) to provide debugging, flash programming, and serial communication over USB. Flash and debug commands use OpenOCD and require a custom Infineon OpenOCD version, that supports KitProg3, to be installed. -1. Download and install the `ModusToolbox`_ software. -2. After the installation, add the directory containing the OpenOCD scripts to your environment's PATH variable. +Infineon OpenOCD Installation +============================= +Both the full `ModusToolbox`_ and the `ModusToolbox Programming Tools`_ packages include Infineon OpenOCD. Installing either of these packages will also install Infineon OpenOCD. If neither package is installed, a minimal installation can be done by downloading the `Infineon OpenOCD`_ release for your system and manually extract the files to a location of your choice. -Programming and Debugging -************************* +.. note:: Linux requires device access rights to be set up for KitProg3. This is handled automatically by the ModusToolbox and ModusToolbox Programming Tools installations. When doing a minimal installation, this can be done manually by executing the script ``openocd/udev_rules/install_rules.sh``. + +West Commands +============= -The CYW920829M2EVK-02 includes an onboard programmer/debugger (KitProg3) to provide debugging, flash programming, and serial communication over USB. Flash and debug commands must be pointed to the Cypress OpenOCD you downloaded above. +The path to the installed Infineon OpenOCD executable must be available to the ``west`` tool commands. There are multiple ways of doing this. The example below uses a permanent CMake argument to set the CMake variable ``OPENOCD``. -On Windows: + .. tabs:: + .. group-tab:: Windows -.. code-block:: shell + .. code-block:: shell - west flash --openocd path/to/infineon/openocd/bin/openocd.exe - west debug --openocd path/to/infineon/openocd/bin/openocd.exe + # Run west config once to set permanent CMake argument + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd.exe -On Linux: + # Do a pristine build once after setting CMake argument + west build -b cyw920829m2evk_02 -p always samples/basic/blinky -.. code-block:: shell + west flash + west debug - west flash --openocd path/to/infineon/openocd/bin/openocd - west debug --openocd path/to/infineon/openocd/bin/openocd + .. group-tab:: Linux + + .. code-block:: shell + + # Run west config once to set permanent CMake argument + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd + + # Do a pristine build once after setting CMake argument + west build -b cyw920829m2evk_02 -p always samples/basic/blinky + + west flash + west debug Once the gdb console starts after executing the west debug command, you may now set breakpoints and perform other standard GDB debugging on the CYW20829 CM33 core. -.. _CYW920829M2EVK-02 Website: +.. _CYW20829 SoC Website: https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-bluetooth-le-bluetooth-multiprotocol/airoc-bluetooth-le/cyw20829/ +.. _CYW920829M2EVK-02 Board Website: + https://www.infineon.com/cms/en/product/evaluation-boards/cyw920829m2evk-02/ + .. _CYW920829M2EVK-02 BT User Guide: https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-bluetooth-le-bluetooth-multiprotocol/airoc-bluetooth-le/cyw20829/#!?fileId=8ac78c8c8929aa4d018a16f726c46b26 .. _ModusToolbox: https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolbox +.. _ModusToolbox Programming Tools: + https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolboxprogtools + .. _Infineon OpenOCD: - https://github.com/infineon/openocd/releases/tag/release-v4.3.0 + https://github.com/Infineon/openocd/releases/latest + +.. _KitProg3: + https://github.com/Infineon/KitProg3 From f67b24327d5649fc24e523e3c51ca1bc7b8391c3 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Wed, 26 Jun 2024 00:35:10 +0700 Subject: [PATCH 117/187] lib: smf: use `while (true)` in `get_child_of` for better clarity Replace the condition-less `for` loop (`;;`) in `get_child_of` with a `while (true)` loop and remove the redundant `return NULL;` at the end, which is never reached. This change aims to enhance readability since `while (true)` is better suited for this scenario. Signed-off-by: Pisit Sawangvonganan --- lib/smf/smf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/smf/smf.c b/lib/smf/smf.c index 0d7ac258fc1f4..2c050526a5662 100644 --- a/lib/smf/smf.c +++ b/lib/smf/smf.c @@ -36,7 +36,9 @@ static bool share_paren(const struct smf_state *test_state, const struct smf_sta static const struct smf_state *get_child_of(const struct smf_state *states, const struct smf_state *parent) { - for (const struct smf_state *tmp = states;; tmp = tmp->parent) { + const struct smf_state *tmp = states; + + while (true) { if (tmp->parent == parent) { return tmp; } @@ -44,9 +46,9 @@ static const struct smf_state *get_child_of(const struct smf_state *states, if (tmp->parent == NULL) { return NULL; } - } - return NULL; + tmp = tmp->parent; + } } static const struct smf_state *get_last_of(const struct smf_state *states) From d9abc19bc9368c63dd723c7415b42b4c357ea7c2 Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Fri, 21 Jun 2024 15:41:55 -0400 Subject: [PATCH 118/187] drivers: serial: pl011: add support for hardware flow control Flow control will be enabled for UART if hw-flow-control is set. Signed-off-by: Xudong Zheng <7pkvm5aw@slicealias.com> --- drivers/serial/uart_pl011.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c index 54bebac9dd815..799e8c55ae232 100644 --- a/drivers/serial/uart_pl011.c +++ b/drivers/serial/uart_pl011.c @@ -88,6 +88,20 @@ static void pl011_disable_fifo(const struct device *dev) get_uart(dev)->lcr_h &= ~PL011_LCRH_FEN; } +static void pl011_set_flow_control(const struct device *dev, bool rts, bool cts) +{ + if (rts) { + get_uart(dev)->cr |= PL011_CR_RTSEn; + } else { + get_uart(dev)->cr &= ~PL011_CR_RTSEn; + } + if (cts) { + get_uart(dev)->cr |= PL011_CR_CTSEn; + } else { + get_uart(dev)->cr &= ~PL011_CR_CTSEn; + } +} + static int pl011_set_baudrate(const struct device *dev, uint32_t clk, uint32_t baudrate) { @@ -240,6 +254,10 @@ static int pl011_runtime_configure_internal(const struct device *dev, switch (cfg->flow_ctrl) { case UART_CFG_FLOW_CTRL_NONE: + pl011_set_flow_control(dev, false, false); + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + pl011_set_flow_control(dev, true, true); break; default: goto enable; @@ -506,7 +524,7 @@ static int pl011_init(const struct device *dev) if (!data->sbsa) { get_uart(dev)->dmacr = 0U; barrier_isync_fence_full(); - get_uart(dev)->cr &= ~(BIT(14) | BIT(15) | BIT(1)); + get_uart(dev)->cr &= ~PL011_CR_SIREN; get_uart(dev)->cr |= PL011_CR_RXE | PL011_CR_TXE; barrier_isync_fence_full(); } @@ -641,7 +659,9 @@ void pl011_isr(const struct device *dev) .parity = UART_CFG_PARITY_NONE, \ .stop_bits = UART_CFG_STOP_BITS_1, \ .data_bits = UART_CFG_DATA_BITS_8, \ - .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, \ + .flow_ctrl = DT_INST_PROP(n, hw_flow_control) \ + ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ }, \ .clk_freq = COND_CODE_1( \ DT_NODE_HAS_COMPAT(DT_INST_CLOCKS_CTLR(n), fixed_clock), \ From ffba53f686862c09cf2c1b4fdd9a96179425201e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 21 Jun 2024 15:31:43 +0200 Subject: [PATCH 119/187] soc: nordic: common: dmm: Fix memory utilization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DMM was enforcing cache line alignment all memory regions, including those which were not cacheable. Fixing it by using memory attribute from the device tree to determine if alignment needs to be applied. Because of that memory usage was significantly increased because even 1 byte buffers (e.g. for uart_poll_out) was consuming 32 bytes (cache line size). Signed-off-by: Krzysztof Chruściński --- soc/nordic/common/dmm.c | 10 ++++++---- soc/nordic/common/dmm.h | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/soc/nordic/common/dmm.c b/soc/nordic/common/dmm.c index 85f18dfa7e8e8..4206870d79475 100644 --- a/soc/nordic/common/dmm.c +++ b/soc/nordic/common/dmm.c @@ -23,6 +23,7 @@ {.dt_addr = DT_REG_ADDR(node_id), \ .dt_size = DT_REG_SIZE(node_id), \ .dt_attr = DT_PROP(node_id, zephyr_memory_attr), \ + .dt_align = DMM_ALIGN_SIZE(node_id), \ .dt_allc = &_BUILD_LINKER_END_VAR(node_id)}, /* Generate declarations of linker variables used to determine size of preallocated variables @@ -36,6 +37,7 @@ struct dmm_region { uintptr_t dt_addr; size_t dt_size; uint32_t dt_attr; + uint32_t dt_align; void *dt_allc; }; @@ -91,7 +93,7 @@ static bool is_user_buffer_correctly_preallocated(void const *user_buffer, size_ return true; } - if (IS_ALIGNED(addr, DMM_DCACHE_LINE_SIZE)) { + if (IS_ALIGNED(addr, region->dt_align)) { /* If buffer is in cacheable region it must be aligned to data cache line size. */ return true; } @@ -101,7 +103,7 @@ static bool is_user_buffer_correctly_preallocated(void const *user_buffer, size_ static size_t dmm_heap_start_get(struct dmm_heap *dh) { - return ROUND_UP(dh->region->dt_allc, DMM_DCACHE_LINE_SIZE); + return ROUND_UP(dh->region->dt_allc, dh->region->dt_align); } static size_t dmm_heap_size_get(struct dmm_heap *dh) @@ -111,8 +113,8 @@ static size_t dmm_heap_size_get(struct dmm_heap *dh) static void *dmm_buffer_alloc(struct dmm_heap *dh, size_t length) { - length = ROUND_UP(length, DMM_DCACHE_LINE_SIZE); - return sys_heap_aligned_alloc(&dh->heap, DMM_DCACHE_LINE_SIZE, length); + length = ROUND_UP(length, dh->region->dt_align); + return sys_heap_aligned_alloc(&dh->heap, dh->region->dt_align, length); } static void dmm_buffer_free(struct dmm_heap *dh, void *buffer) diff --git a/soc/nordic/common/dmm.h b/soc/nordic/common/dmm.h index 03780f37239d0..a1a17e599ea8b 100644 --- a/soc/nordic/common/dmm.h +++ b/soc/nordic/common/dmm.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -22,8 +23,18 @@ extern "C" { /** @cond INTERNAL_HIDDEN */ -#define DMM_DCACHE_LINE_SIZE \ - COND_CODE_1(IS_ENABLED(CONFIG_DCACHE), (CONFIG_DCACHE_LINE_SIZE), (sizeof(uint8_t))) +/* Determine if memory region for the peripheral is cacheable. */ +#define DMM_IS_REG_CACHEABLE(node_id) \ + COND_CODE_1(CONFIG_DCACHE, \ + (COND_CODE_1(DT_NODE_HAS_PROP(DT_PHANDLE(node_id, memory_regions), zephyr_memory_attr), \ + (DT_PROP(DT_PHANDLE(node_id, memory_regions), zephyr_memory_attr) & DT_MEM_CACHEABLE), \ + (0))), (0)) + +/* Determine required alignment of the static buffers in memory regions. Cache line alignment is + * required if region is cacheable and data cache is enabled. + */ +#define DMM_ALIGN_SIZE(node_id) \ + (DMM_IS_REG_CACHEABLE(node_id) ? CONFIG_DCACHE_LINE_SIZE : sizeof(uint8_t)) /** * @brief Get reference to memory region associated with the specified device node @@ -35,7 +46,6 @@ extern "C" { #define DMM_DEV_TO_REG(node_id) \ COND_CODE_1(DT_NODE_HAS_PROP(node_id, memory_regions), \ ((void *)DT_REG_ADDR(DT_PHANDLE(node_id, memory_regions))), (NULL)) - /** * @brief Preallocate buffer in memory region associated with the specified device node * @@ -45,7 +55,7 @@ extern "C" { COND_CODE_1(DT_NODE_HAS_PROP(node_id, memory_regions), \ (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \ DT_PHANDLE(node_id, memory_regions))))) \ - __aligned(DMM_DCACHE_LINE_SIZE)), \ + __aligned(DMM_ALIGN_SIZE(node_id))), \ ()) #ifdef CONFIG_HAS_NORDIC_DMM From ff8c6b432fcdc304a16fc77a0c1c95db66496e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 21 Jun 2024 15:40:46 +0200 Subject: [PATCH 120/187] tests: boards: nrf: dmm: Adjust test to dmm changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After changing dmm to not apply data cache line alignment for all regions test needs to be aligned. Signed-off-by: Krzysztof Chruściński --- tests/boards/nrf/dmm/src/main.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/boards/nrf/dmm/src/main.c b/tests/boards/nrf/dmm/src/main.c index 5ddbebfb83823..b21eeb97e02e1 100644 --- a/tests/boards/nrf/dmm/src/main.c +++ b/tests/boards/nrf/dmm/src/main.c @@ -74,7 +74,7 @@ static bool dmm_buffer_in_region_check(struct dmm_test_region *dtr, void *buf, s } static void dmm_check_output_buffer(struct dmm_test_region *dtr, uint32_t *fill_value, - void *data, size_t size, bool was_prealloc) + void *data, size_t size, bool was_prealloc, bool is_cached) { void *buf; int retval; @@ -82,7 +82,9 @@ static void dmm_check_output_buffer(struct dmm_test_region *dtr, uint32_t *fill_ memset(data, (*fill_value)++, size); retval = dmm_buffer_out_prepare(dtr->mem_reg, data, size, &buf); zassert_ok(retval); - zassert_true(IS_ALIGNED(buf, DMM_DCACHE_LINE_SIZE)); + if (IS_ENABLED(CONFIG_DCACHE) && is_cached) { + zassert_true(IS_ALIGNED(buf, CONFIG_DCACHE_LINE_SIZE)); + } if (IS_ENABLED(CONFIG_HAS_NORDIC_DMM)) { if (was_prealloc) { @@ -112,7 +114,9 @@ static void dmm_check_input_buffer(struct dmm_test_region *dtr, uint32_t *fill_v retval = dmm_buffer_in_prepare(dtr->mem_reg, data, size, &buf); zassert_ok(retval); - zassert_true(IS_ALIGNED(buf, DMM_DCACHE_LINE_SIZE)); + if (IS_ENABLED(CONFIG_DCACHE) && is_cached) { + zassert_true(IS_ALIGNED(buf, CONFIG_DCACHE_LINE_SIZE)); + } if (IS_ENABLED(CONFIG_HAS_NORDIC_DMM)) { if (was_prealloc) { @@ -162,7 +166,7 @@ ZTEST_USER_F(dmm, test_check_dev_cache_out_allocate) uint8_t user_data[16]; dmm_check_output_buffer(&fixture->regions[DMM_TEST_REGION_CACHE], &fixture->fill_value, - user_data, sizeof(user_data), false); + user_data, sizeof(user_data), false, true); } ZTEST_USER_F(dmm, test_check_dev_cache_out_preallocate) @@ -170,7 +174,7 @@ ZTEST_USER_F(dmm, test_check_dev_cache_out_preallocate) static uint8_t user_data[16] DMM_MEMORY_SECTION(DUT_CACHE); dmm_check_output_buffer(&fixture->regions[DMM_TEST_REGION_CACHE], &fixture->fill_value, - user_data, sizeof(user_data), true); + user_data, sizeof(user_data), true, true); } ZTEST_USER_F(dmm, test_check_dev_nocache_in_allocate) @@ -194,7 +198,7 @@ ZTEST_USER_F(dmm, test_check_dev_nocache_out_allocate) uint8_t user_data[16]; dmm_check_output_buffer(&fixture->regions[DMM_TEST_REGION_NOCACHE], &fixture->fill_value, - user_data, sizeof(user_data), false); + user_data, sizeof(user_data), false, false); } ZTEST_USER_F(dmm, test_check_dev_nocache_out_preallocate) @@ -202,7 +206,7 @@ ZTEST_USER_F(dmm, test_check_dev_nocache_out_preallocate) static uint8_t user_data[16] DMM_MEMORY_SECTION(DUT_NOCACHE); dmm_check_output_buffer(&fixture->regions[DMM_TEST_REGION_NOCACHE], &fixture->fill_value, - user_data, sizeof(user_data), true); + user_data, sizeof(user_data), true, false); } ZTEST_SUITE(dmm, NULL, test_setup, NULL, test_cleanup, NULL); From 925b4caf4c25ad53605cd85e03e520da2922acf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 26 Jun 2024 15:39:56 +0200 Subject: [PATCH 121/187] soc: nordic: nrf54h: DMM shall be applied only to rad&app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpuppr can only use slow peripherals and uses RAM3 as RAM so it does not need to use DMM. Signed-off-by: Krzysztof Chruściński --- soc/nordic/nrf54h/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 35017812d695b..338b51238eeed 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -7,7 +7,6 @@ config SOC_SERIES_NRF54HX select HAS_NRFS select HAS_NRFX select HAS_NORDIC_DRIVERS - select HAS_NORDIC_DMM config SOC_NRF54H20_CPUAPP select ARM @@ -19,6 +18,7 @@ config SOC_NRF54H20_CPUAPP select CPU_HAS_ICACHE select CPU_HAS_FPU select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS + select HAS_NORDIC_DMM select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRFS_HAS_CLOCK_SERVICE select NRFS_HAS_DVFS_SERVICE @@ -40,6 +40,7 @@ config SOC_NRF54H20_CPURAD select NRFS_HAS_CLOCK_SERVICE select NRFS_HAS_MRAM_SERVICE select NRFS_HAS_TEMP_SERVICE + select HAS_NORDIC_DMM config SOC_NRF54H20_CPUPPR depends on RISCV_CORE_NORDIC_VPR From 788db34418beee5160e4febc68c59ed5e293c7db Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Wed, 19 Jun 2024 21:00:58 +0200 Subject: [PATCH 122/187] scripts: west robot & simulation: Fix OOT The current version of scipts do not consider OOT boards use cases and the tests with robot now are strict to only one robot file, which is not realistic for real environment. This address those issues and allow multiple testsuits at command line and lists at tests entries. It add another test parameter to allow configure robotframework options. Fixes: #74563 Signed-off-by: Gerson Fernando Budke --- doc/develop/test/twister.rst | 35 +++++++++++++++++-- samples/subsys/shell/shell_module/sample.yaml | 2 +- scripts/pylib/twister/twisterlib/handlers.py | 7 +++- scripts/pylib/twister/twisterlib/harness.py | 22 ++++++++++-- scripts/schemas/twister/testsuite-schema.yaml | 7 ++-- scripts/tests/twister/test_harness.py | 6 +++- scripts/west_commands/runners/renode-robot.py | 5 ++- .../console/line_splitting/testcase.yaml | 6 +++- 8 files changed, 78 insertions(+), 12 deletions(-) diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index e6d347a90f6d8..a95a0b509dc6a 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -615,8 +615,11 @@ harness_config: If the scope is set to ``function``, DUT is launched for every test case in python script. For ``session`` scope, DUT is launched only once. - robot_test_path: (default empty) - Specify a path to a file containing a Robot Framework test suite to be run. + robot_testsuite: (default empty) + Specify one or more paths to a file containing a Robot Framework test suite to be run. + + robot_option: (default empty) + One or more options to be send to robotframework. bsim_exe_name: If provided, the executable filename when copying to BabbleSim's bin @@ -673,7 +676,33 @@ harness_config: robot.example: harness: robot harness_config: - robot_test_path: [robot file path] + robot_testsuite: [robot file path] + + It can be more than one test suite using a list. + + .. code-block:: yaml + + tests: + robot.example: + harness: robot + harness_config: + robot_testsuite: + - [robot file path 1] + - [robot file path 2] + - [robot file path n] + + One or more options can be passed to robotframework. + + .. code-block:: yaml + + tests: + robot.example: + harness: robot + harness_config: + robot_testsuite: [robot file path] + robot_option: + - --exclude tag + - --stop-on-error filter: Filter whether the test scenario should be run by evaluating an expression diff --git a/samples/subsys/shell/shell_module/sample.yaml b/samples/subsys/shell/shell_module/sample.yaml index 482e4a37875fa..62f9b30af0f40 100644 --- a/samples/subsys/shell/shell_module/sample.yaml +++ b/samples/subsys/shell/shell_module/sample.yaml @@ -75,4 +75,4 @@ tests: sample.shell.shell_module.robot: harness: robot harness_config: - robot_test_path: shell_module.robot + robot_testsuite: shell_module.robot diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index f832425245002..c4d9919de8026 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -18,6 +18,7 @@ import threading import time +from pathlib import Path from queue import Queue, Empty from twisterlib.environment import ZEPHYR_BASE, strip_ansi_sequences from twisterlib.error import TwisterException @@ -241,7 +242,11 @@ def _create_command(self, robot_test): # os.path.join cannot be used on a Mock object, so we are # explicitly checking the type if isinstance(self.instance.platform, Platform): - resc = os.path.join(self.options.coverage_basedir, self.instance.platform.resc) + for board_dir in self.options.board_root: + path = os.path.join(Path(board_dir).parent, self.instance.platform.resc) + if os.path.exists(path): + resc = path + break uart = self.instance.platform.uart command = ["renode-test", "--variable", "KEYWORDS:" + keywords, diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 7af7867b3e30d..c25b7fcf421ab 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -160,7 +160,8 @@ def configure(self, instance): config = instance.testsuite.harness_config if config: - self.path = config.get('robot_test_path', None) + self.path = config.get('robot_testsuite', None) + self.option = config.get('robot_option', None) def handle(self, line): ''' Test cases that make use of this harness care about results given @@ -176,7 +177,24 @@ def run_robot_test(self, command, handler): start_time = time.time() env = os.environ.copy() - command.append(os.path.join(handler.sourcedir, self.path)) + if self.option: + if isinstance(self.option, list): + for option in self.option: + for v in str(option).split(): + command.append(f'{v}') + else: + for v in str(self.option).split(): + command.append(f'{v}') + + if self.path is None: + raise PytestHarnessException(f'The parameter robot_testsuite is mandatory') + + if isinstance(self.path, list): + for suite in self.path: + command.append(os.path.join(handler.sourcedir, suite)) + else: + command.append(os.path.join(handler.sourcedir, self.path)) + with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.instance.build_dir, env=env) as renode_test_proc: out, _ = renode_test_proc.communicate() diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 28b7e730edbe5..4cb81431d86b8 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -120,8 +120,11 @@ schema;scenario-schema: required: false sequence: - type: str - "robot_test_path": - type: str + "robot_testsuite": + type: any + required: false + "robot_option": + type: any required: false "record": type: map diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index 2e0028b234a9c..57e68f9deb70b 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -133,7 +133,8 @@ def test_robot_configure(tmp_path): instance = TestInstance(testsuite=mock_testsuite, platform=mock_platform, outdir=outdir) instance.testsuite.harness_config = { - 'robot_test_path': '/path/to/robot/test' + 'robot_testsuite': '/path/to/robot/test', + 'robot_option': 'test_option' } robot_harness = Robot() @@ -143,6 +144,7 @@ def test_robot_configure(tmp_path): #Assert assert robot_harness.instance == instance assert robot_harness.path == '/path/to/robot/test' + assert robot_harness.option == 'test_option' def test_robot_handle(tmp_path): @@ -190,6 +192,7 @@ def test_robot_run_robot_test(tmp_path, caplog, exp_out, returncode, expected_st handler.log = "handler.log" path = "path" + option = "option" mock_platform = mock.Mock() mock_platform.name = "mock_platform" @@ -209,6 +212,7 @@ def test_robot_run_robot_test(tmp_path, caplog, exp_out, returncode, expected_st robot = Robot() robot.path = path + robot.option = option robot.instance = instance proc_mock = mock.Mock( returncode = returncode, diff --git a/scripts/west_commands/runners/renode-robot.py b/scripts/west_commands/runners/renode-robot.py index 3a5c87ad7d0ea..68fe453b8ac96 100644 --- a/scripts/west_commands/runners/renode-robot.py +++ b/scripts/west_commands/runners/renode-robot.py @@ -28,6 +28,8 @@ def capabilities(cls): @classmethod def do_add_parser(cls, parser): parser.add_argument('--testsuite', + metavar='SUITE', + action='append', help='path to Robot test suite') parser.add_argument('--renode-robot-arg', metavar='ARG', @@ -54,7 +56,8 @@ def run_test(self, **kwargs): for arg in self.renode_robot_arg: cmd.append(arg) if self.testsuite is not None: - cmd.append(self.testsuite) + for suite in self.testsuite: + cmd.append(suite) else: self.logger.error("No Robot testsuite passed to renode-test! Use the `--testsuite` argument to provide one.") subprocess.run(cmd, check=True) diff --git a/tests/drivers/console/line_splitting/testcase.yaml b/tests/drivers/console/line_splitting/testcase.yaml index a7c0f1b8e6771..05567a76c344b 100644 --- a/tests/drivers/console/line_splitting/testcase.yaml +++ b/tests/drivers/console/line_splitting/testcase.yaml @@ -8,4 +8,8 @@ common: tests: drivers.console.line_splitting: harness_config: - robot_test_path: line_splitting.robot + robot_testsuite: line_splitting.robot + drivers.console.line_splitting.plus.some_option: + harness_config: + robot_testsuite: line_splitting.robot + robot_option: --exclude some_flag From 439f69c397c3abbed2212ac017c0b0bad582642c Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Mon, 1 Jul 2024 14:30:42 -0500 Subject: [PATCH 123/187] tests: arm_irq_vector_table: Fix RT/WXXX Fix preprocessor expression for custom vector table due to OS timer isr being needed. The parentheses are missing. Also add RW6xx to the list which has the same isr needed for ostimer. Signed-off-by: Declan Snyder --- tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c index eaf9ddd2a6d44..c8da69982a961 100644 --- a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c +++ b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c @@ -184,7 +184,8 @@ vth __irq_vector_table _irq_vector_table[] = { isr0, isr1, isr2, 0, rtc_isr }; -#elif defined(CONFIG_SOC_SERIES_IMXRT6XX) || defined(CONFIG_SOC_SERIES_IMXRT5XX) && \ +#elif (defined(CONFIG_SOC_SERIES_IMXRT6XX) || defined(CONFIG_SOC_SERIES_IMXRT5XX) || \ + defined(CONFIG_SOC_SERIES_RW6XX)) && \ defined(CONFIG_MCUX_OS_TIMER) /* MXRT685 employs a OS Event timer to implement the Kernel system * timer, instead of the ARM Cortex-M SysTick. Therefore, a pointer to From 45f16fb6638eb49f4a4858e3e0798110e5be85a1 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 1 Jul 2024 11:18:20 +0200 Subject: [PATCH 124/187] west: commands: runners: canopen: increase default SDO timeout Increase the default SDO timeout for the CANopen program download west runner from 0.3 seconds to 1 second. Depending on the flash size and speed, a full erase may take slightly longer than 300 ms. The timeout can be customized by using the --sdo-timeout runner parameter. Fixes: #73987 Signed-off-by: Henrik Brix Andersen --- scripts/west_commands/runners/canopen_program.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/runners/canopen_program.py b/scripts/west_commands/runners/canopen_program.py index 74fdf38e95ea9..c51f07891a2e3 100644 --- a/scripts/west_commands/runners/canopen_program.py +++ b/scripts/west_commands/runners/canopen_program.py @@ -31,7 +31,7 @@ # Default timeouts and retries DEFAULT_TIMEOUT = 10.0 # seconds -DEFAULT_SDO_TIMEOUT = 0.3 # seconds +DEFAULT_SDO_TIMEOUT = 1 # seconds DEFAULT_SDO_RETRIES = 1 # Object dictionary indexes From df852db020e60474069163ea790e8b818dc05d37 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 28 Jun 2024 13:53:30 +0800 Subject: [PATCH 125/187] soc: nordic: vpr: select INCLUDE_RESET_VECTOR for default implementation For SOCs that do not implement a custom `__reset` function, select `INCLUDE_RESET_VECTOR` so that Zephyr provides a default implementation that simply jumps to `__initialize` Signed-off-by: Yong Cong Sin --- soc/nordic/common/vpr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/nordic/common/vpr/Kconfig b/soc/nordic/common/vpr/Kconfig index c2abfbb18b1f0..0c60b8a8b1c86 100644 --- a/soc/nordic/common/vpr/Kconfig +++ b/soc/nordic/common/vpr/Kconfig @@ -18,5 +18,6 @@ config RISCV_CORE_NORDIC_VPR select RISCV_SOC_CONTEXT_SAVE select HAS_FLASH_LOAD_OFFSET select ARCH_CPU_IDLE_CUSTOM + select INCLUDE_RESET_VECTOR help Enable support for the RISC-V Nordic VPR core. From 0fc320f3ddf946d52613c9722f6bcdd6bada94b7 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 28 Jun 2024 13:47:31 +0800 Subject: [PATCH 126/187] Revert "soc: riscv-privileged: support SoCs without reset vector" This reverts commit 75f5d98002f1ae0b12f57e4ba77468fb18453b4d. Signed-off-by: Yong Cong Sin --- soc/common/riscv-privileged/vector.S | 5 ----- 1 file changed, 5 deletions(-) diff --git a/soc/common/riscv-privileged/vector.S b/soc/common/riscv-privileged/vector.S index 73e41000f150b..7230561a340d1 100644 --- a/soc/common/riscv-privileged/vector.S +++ b/soc/common/riscv-privileged/vector.S @@ -103,10 +103,5 @@ SECTION_FUNC(vectors, __start) #endif /* CONFIG_RISCV_VECTORED_MODE */ -#if CONFIG_INCLUDE_RESET_VECTOR /* Jump to __reset */ tail __reset -#else - /* Jump to __initialize */ - tail __initialize -#endif From 43fe35571d6c2908a5be4dc4622fdd33b994c7fa Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 28 Jun 2024 14:02:27 +0800 Subject: [PATCH 127/187] arch: riscv: update the description of INCLUDE_RESET_VECTOR Kconfig Update the description of the `INCLUDE_RESET_VECTOR` Kconfig so that it is more clear to the user what it does. Signed-off-by: Yong Cong Sin --- arch/riscv/Kconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 76ea74026ac3d..f25b1ca7c950d 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -48,10 +48,11 @@ config RISCV_EXCEPTION_STACK_TRACE menu "RISCV Processor Options" config INCLUDE_RESET_VECTOR - bool "Include Reset vector" + bool "Jumps to __initialize directly" help - Include the reset vector stub, which initializes the stack and - prepares for running C code. + Select 'y' here to use the Zephyr provided default implementation that + jumps to `__initialize` directly. Otherwise a SOC needs to provide its + custom `__reset` routine. config RISCV_PRIVILEGED bool From ae0140e6d7c5d3d94e721a9cb62831823790e5a1 Mon Sep 17 00:00:00 2001 From: Sreeram Tatapudi Date: Fri, 28 Jun 2024 10:03:01 -0700 Subject: [PATCH 128/187] samples: bluetooth: Update samples to support cyw920829m2evk_02 Update bluetooth projects to support cyw920829m2evk_02 platform Signed-off-by: Sreeram Tatapudi --- samples/bluetooth/beacon/sample.yaml | 1 + samples/bluetooth/broadcaster/sample.yaml | 1 + samples/bluetooth/central/sample.yaml | 1 + samples/bluetooth/observer/sample.yaml | 1 + samples/bluetooth/periodic_adv/sample.yaml | 1 + samples/bluetooth/peripheral_dis/sample.yaml | 1 + samples/bluetooth/scan_adv/sample.yaml | 1 + 7 files changed, 7 insertions(+) diff --git a/samples/bluetooth/beacon/sample.yaml b/samples/bluetooth/beacon/sample.yaml index d76a16eb566f0..6c450c27f90f3 100644 --- a/samples/bluetooth/beacon/sample.yaml +++ b/samples/bluetooth/beacon/sample.yaml @@ -9,6 +9,7 @@ tests: - nrf51dk/nrf51822 - nrf52dk/nrf52832 - nrf54l15pdk/nrf54l15/cpuapp + - cyw920829m2evk_02 tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/broadcaster/sample.yaml b/samples/bluetooth/broadcaster/sample.yaml index 7556e2aba7f57..46eeed2e9b148 100644 --- a/samples/bluetooth/broadcaster/sample.yaml +++ b/samples/bluetooth/broadcaster/sample.yaml @@ -8,6 +8,7 @@ tests: - qemu_x86 - nrf51dk/nrf51822 - nrf52dk/nrf52832 + - cyw920829m2evk_02 tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/central/sample.yaml b/samples/bluetooth/central/sample.yaml index 973b48c7c0bb5..e108b68a834d6 100644 --- a/samples/bluetooth/central/sample.yaml +++ b/samples/bluetooth/central/sample.yaml @@ -6,6 +6,7 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - cyw920829m2evk_02 tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/observer/sample.yaml b/samples/bluetooth/observer/sample.yaml index b60ccc9fe8ed3..0b701bec4c686 100644 --- a/samples/bluetooth/observer/sample.yaml +++ b/samples/bluetooth/observer/sample.yaml @@ -7,6 +7,7 @@ tests: - qemu_cortex_m3 - qemu_x86 - nrf52840dk/nrf52840 + - cyw920829m2evk_02 integration_platforms: - qemu_cortex_m3 tags: bluetooth diff --git a/samples/bluetooth/periodic_adv/sample.yaml b/samples/bluetooth/periodic_adv/sample.yaml index f9018ff09ef32..7002a4a5fb338 100644 --- a/samples/bluetooth/periodic_adv/sample.yaml +++ b/samples/bluetooth/periodic_adv/sample.yaml @@ -8,6 +8,7 @@ tests: - qemu_x86 - nrf52_bsim - nrf52dk/nrf52832 + - cyw920829m2evk_02 tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/peripheral_dis/sample.yaml b/samples/bluetooth/peripheral_dis/sample.yaml index 0521956f6e13d..a5853fd52ded2 100644 --- a/samples/bluetooth/peripheral_dis/sample.yaml +++ b/samples/bluetooth/peripheral_dis/sample.yaml @@ -7,6 +7,7 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - cyw920829m2evk_02 tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/scan_adv/sample.yaml b/samples/bluetooth/scan_adv/sample.yaml index 52ec407b0a72e..c7ef734b4ea1a 100644 --- a/samples/bluetooth/scan_adv/sample.yaml +++ b/samples/bluetooth/scan_adv/sample.yaml @@ -7,6 +7,7 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - cyw920829m2evk_02 tags: bluetooth integration_platforms: - qemu_cortex_m3 From 763454f1ec76b66219ff7f5bef84de3df89a23f2 Mon Sep 17 00:00:00 2001 From: Sreeram Tatapudi Date: Thu, 27 Jun 2024 23:09:15 -0700 Subject: [PATCH 129/187] soc: infineon: cyw20829: Updates linker script Add missed #include in linker script to fix build error with samples/subsys/bindesc/hello_bindesc Signed-off-by: Sreeram Tatapudi --- soc/infineon/cat1b/cyw20829/linker.ld | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/infineon/cat1b/cyw20829/linker.ld b/soc/infineon/cat1b/cyw20829/linker.ld index efe1dffa603fa..bcbf53c63994c 100644 --- a/soc/infineon/cat1b/cyw20829/linker.ld +++ b/soc/infineon/cat1b/cyw20829/linker.ld @@ -13,6 +13,7 @@ #include #include +#include #include #include From f15296942e6ff324d2e67c461ce9ef48e512920a Mon Sep 17 00:00:00 2001 From: Sreeram Tatapudi Date: Thu, 27 Jun 2024 23:16:14 -0700 Subject: [PATCH 130/187] tests: bluetooth: shell: Enable flow control Enabling UART flow control for CYW20829 Signed-off-by: Sreeram Tatapudi --- tests/bluetooth/shell/boards/cyw920829m2evk_02.overlay | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/bluetooth/shell/boards/cyw920829m2evk_02.overlay diff --git a/tests/bluetooth/shell/boards/cyw920829m2evk_02.overlay b/tests/bluetooth/shell/boards/cyw920829m2evk_02.overlay new file mode 100644 index 0000000000000..0622b29e2a658 --- /dev/null +++ b/tests/bluetooth/shell/boards/cyw920829m2evk_02.overlay @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +uart2: &scb2 { + hw-flow-control; + pinctrl-0 = <&p3_3_scb2_uart_tx &p3_2_scb2_uart_rx &p3_1_scb2_uart_rts &p3_0_scb2_uart_cts>; +}; From 1fcfce8b7fbbcf3e1c877ac67f53d14ce5b224a5 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 2 Jul 2024 08:17:05 +0300 Subject: [PATCH 131/187] net: dns: Avoid superfluous error message If we have configured the DNS dispatcher to be only as a responder but receive a query response, or if we are only as a resolver but receive a query, then the dispatcher just ignores the packet and returns -ENOENT. Unfortunately we print an error message in this case [00:10:18.818,000] net_dns_dispatcher: DNS recv error (-2) which is totally unnecessary and causes confusion so do not print an error message in this case. Signed-off-by: Jukka Rissanen --- subsys/net/lib/dns/dispatcher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/dns/dispatcher.c b/subsys/net/lib/dns/dispatcher.c index e4e6a7b569a8f..0e7e1ac39eb07 100644 --- a/subsys/net/lib/dns/dispatcher.c +++ b/subsys/net/lib/dns/dispatcher.c @@ -161,7 +161,7 @@ void dns_dispatcher_svc_handler(struct k_work *work) int ret; ret = recv_data(pev); - if (ret < 0 && ret != DNS_EAI_ALLDONE) { + if (ret < 0 && ret != DNS_EAI_ALLDONE && ret != -ENOENT) { NET_ERR("DNS recv error (%d)", ret); } } From 58ee5e39f4599e1111ec10f0f67658068356d21e Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 2 Jul 2024 12:57:29 +0800 Subject: [PATCH 132/187] arch: riscv: irq: include `util_macro.h` for the macros Macros like `BIT()` & `BIT64()` from the `util_macro.h` are used, include their header to compile properly. Signed-off-by: Yong Cong Sin --- include/zephyr/arch/riscv/irq.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/arch/riscv/irq.h b/include/zephyr/arch/riscv/irq.h index 3d81415e0d767..1cebd2ae94a27 100644 --- a/include/zephyr/arch/riscv/irq.h +++ b/include/zephyr/arch/riscv/irq.h @@ -18,6 +18,8 @@ extern "C" { #endif +#include + #ifndef _ASMLANGUAGE #include #include From b527e45586792bccd01a878382db7a6df987cfcf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 28 Jun 2024 12:12:58 +0200 Subject: [PATCH 133/187] samples: net: dhcpv4_client: Replace example DHCP server with kea Currently used DHCP server in the sample, dhcpd, is no longer maintained and reached EOL. Therefore, update the sample's readme file with a sample configuration for its successor, kea. Signed-off-by: Robert Lubos --- samples/net/dhcpv4_client/README.rst | 110 +++++++++++++++++++-------- 1 file changed, 77 insertions(+), 33 deletions(-) diff --git a/samples/net/dhcpv4_client/README.rst b/samples/net/dhcpv4_client/README.rst index e8c232a7e94be..43d95479b9e51 100644 --- a/samples/net/dhcpv4_client/README.rst +++ b/samples/net/dhcpv4_client/README.rst @@ -23,30 +23,51 @@ Running DHCPv4 client in Linux Host =================================== These are instructions for how to use this sample application using -QEMU on a Linux host to negotiate IP address from DHCPv4 server running +QEMU on a Linux host to negotiate IP address from DHCPv4 server (kea) running on Linux host. To use QEMU for testing, follow the :ref:`networking_with_qemu` guide. -Here's a sample server configuration file '/etc/dhcp/dhcpd.conf' +Here's a sample server configuration file '/etc/kea/kea-dhcp4.conf' used to configure the DHCPv4 server: .. code-block:: console - log-facility local7; - default-lease-time 600; - max-lease-time 7200; - - subnet 192.0.2.0 netmask 255.255.255.0 { - range 192.0.2.10 192.0.2.100; - } + { + "Dhcp4": { + "interfaces-config": { + "interfaces": [ "tap0" ], + "dhcp-socket-type": "raw" + }, + + "valid-lifetime": 7200, + + "subnet4": [ + { + "id": 1, + "subnet": "192.0.2.0/24", + "pools": [ { "pool": "192.0.2.10 - 192.0.2.100" } ], + "option-data": [ + { + "name": "routers", + "data": "192.0.2.2" + }, + { + "name": "domain-name-servers", + "data": "8.8.8.8" + } + ] + } + ] + } + } Use another terminal window to start up a DHCPv4 server on the Linux host, using this conf file: .. code-block:: console - $ sudo dhcpd -d -4 -cf /etc/dhcp/dhcpd.conf -lf /var/lib/dhcp/dhcpd.leases tap0 + $ sudo kea-dhcp4 -c /etc/kea/kea-dhcp4.conf Run Zephyr samples/net/dhcpv4_client application in QEMU: @@ -62,12 +83,13 @@ are shown like this: .. code-block:: console - [dhcpv4] [INF] main: In main - [dhcpv4] [INF] main_thread: Run dhcpv4 client - [dhcpv4] [INF] handler: Your address: 192.0.2.10 - [dhcpv4] [INF] handler: Lease time: 600 - [dhcpv4] [INF] handler: Subnet: 255.255.255.0 - [dhcpv4] [INF] handler: Router: 0.0.0.0 + [00:00:00.000,000] net_dhcpv4_client_sample: Run dhcpv4 client + [00:00:00.000,000] net_dhcpv4_client_sample: Start on slip: index=1 + [00:00:07.080,000] net_dhcpv4: Received: 192.0.2.10 + [00:00:07.080,000] net_dhcpv4_client_sample: Address[1]: 192.0.2.10 + [00:00:07.080,000] net_dhcpv4_client_sample: Subnet[1]: 255.255.255.0 + [00:00:07.080,000] net_dhcpv4_client_sample: Router[1]: 192.0.2.2 + [00:00:07.080,000] net_dhcpv4_client_sample: Lease time[1]: 7200 seconds To verify the Zephyr application client is running and has received an ip address by typing: @@ -81,8 +103,8 @@ FRDM_K64F ========= These are instructions for how to use this sample application running on -:ref:`frdm_k64f` board to negotiate IP address from DHCPv4 server running on -Linux host. +:ref:`frdm_k64f` board to negotiate IP address from DHCPv4 server (kea) running +on Linux host. Connect ethernet cable from :ref:`Freedom-K64F board ` to Linux host machine and check for new interfaces: @@ -98,25 +120,46 @@ Add ip address and routing information to interface: $ sudo ip addr add 192.0.2.2 dev eth1 $ sudo ip route add 192.0.2.0/24 dev eth1 -Here's a sample server configuration file '/etc/dhcpd/dhcp.conf' +Here's a sample server configuration file '/etc/kea/kea-dhcp4.conf' used to configure the DHCPv4 server: .. code-block:: console - log-facility local7; - default-lease-time 600; - max-lease-time 7200; - - subnet 192.0.2.0 netmask 255.255.255.0 { - range 192.0.2.10 192.0.2.100; - } + { + "Dhcp4": { + "interfaces-config": { + "interfaces": [ "eth1" ], + "dhcp-socket-type": "raw" + }, + + "valid-lifetime": 7200, + + "subnet4": [ + { + "id": 1, + "subnet": "192.0.2.0/24", + "pools": [ { "pool": "192.0.2.10 - 192.0.2.100" } ], + "option-data": [ + { + "name": "routers", + "data": "192.0.2.2" + }, + { + "name": "domain-name-servers", + "data": "8.8.8.8" + } + ] + } + ] + } + } Use another terminal window to start up a DHCPv4 server on the Linux host, using this conf file: .. code-block:: console - $ sudo dhcpd -d -4 -cf /etc/dhcp/dhcpd.conf -lf /var/lib/dhcp/dhcpd.leases eth1 + $ sudo kea-dhcp4 -c /etc/kea/kea-dhcp4.conf Build Zephyr samples/net/dhcpv4_client application: @@ -133,12 +176,13 @@ are shown like this: .. code-block:: console $ sudo screen /dev/ttyACM0 115200 - [dhcpv4] [INF] main: In main - [dhcpv4] [INF] main_thread: Run dhcpv4 client - [dhcpv4] [INF] handler: Your address: 192.0.2.10 - [dhcpv4] [INF] handler: Lease time: 600 - [dhcpv4] [INF] handler: Subnet: 255.255.255.0 - [dhcpv4] [INF] handler: Router: 0.0.0.0 + [00:00:00.000,000] net_dhcpv4_client_sample: Run dhcpv4 client + [00:00:00.000,000] net_dhcpv4_client_sample: Start on ethernet: index=1 + [00:00:07.080,000] net_dhcpv4: Received: 192.0.2.10 + [00:00:07.080,000] net_dhcpv4_client_sample: Address[1]: 192.0.2.10 + [00:00:07.080,000] net_dhcpv4_client_sample: Subnet[1]: 255.255.255.0 + [00:00:07.080,000] net_dhcpv4_client_sample: Router[1]: 192.0.2.2 + [00:00:07.080,000] net_dhcpv4_client_sample: Lease time[1]: 7200 seconds To verify the Zephyr application client is running and has received an ip address by typing: From 1df1b9c05d9e583cae3a40766c4c3ea96922b6c1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 28 Jun 2024 12:14:30 +0200 Subject: [PATCH 134/187] samples: net: dhcpv4_client: Enable DNS in the sample The DHCP server can distribute DNS addresses, hence enable DNS resolver in the sample to show this functionality. Signed-off-by: Robert Lubos --- samples/net/dhcpv4_client/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/net/dhcpv4_client/prj.conf b/samples/net/dhcpv4_client/prj.conf index 7f76396d518e3..0b93365f11342 100644 --- a/samples/net/dhcpv4_client/prj.conf +++ b/samples/net/dhcpv4_client/prj.conf @@ -5,6 +5,7 @@ CONFIG_NET_ARP=y CONFIG_NET_UDP=y CONFIG_NET_DHCPV4=y CONFIG_NET_DHCPV4_OPTION_CALLBACKS=y +CONFIG_DNS_RESOLVER=y CONFIG_TEST_RANDOM_GENERATOR=y From aec0910a12e1654d6ad7456c6e143d5e3cbaf558 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Fri, 28 Jun 2024 09:15:35 +0200 Subject: [PATCH 135/187] Bluetooth: host: ensure ownership of conn on TX path This is a bug-fix: When upper layers want to send something, they add a `conn` object to a list. They do so by adding a node on `struct conn` rather than the object itself. We forgot to increase the reference count of the connection object when doing so. This means that there can be a scenario where the conn object is destroyed and re-used while still being on the TX list/queue. This is bad for obvious reasons. This patch fixes that by: - increasing the refcount when putting on the TX list - decreasing the refcount *only* when popping off the TX list - passing a new reference from `get_conn_ready` into `bt_conn_tx_processor` Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/conn.c | 36 +++++++++++++++++++++++---- subsys/bluetooth/host/conn_internal.h | 6 +++++ subsys/bluetooth/host/hci_core.h | 2 ++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 419be99fc9f5e..a5f81fbea2c32 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -773,6 +773,10 @@ static bool should_stop_tx(struct bt_conn *conn) { LOG_DBG("%p", conn); + if (conn->state != BT_CONN_CONNECTED) { + return true; + } + /* TODO: This function should be overridable by the application: they * should be able to provide their own heuristic. */ @@ -804,6 +808,12 @@ void bt_conn_data_ready(struct bt_conn *conn) /* The TX processor will call the `pull_cb` to get the buf */ if (!atomic_set(&conn->_conn_ready_lock, 1)) { + /* Attach a reference to the `bt_dev.le.conn_ready` list. + * + * This reference will be consumed when the conn is popped off + * the list (in `get_conn_ready`). + */ + bt_conn_ref(conn); sys_slist_append(&bt_dev.le.conn_ready, &conn->_conn_ready); LOG_DBG("raised"); @@ -857,6 +867,12 @@ struct bt_conn *get_conn_ready(void) return NULL; } + /* `conn` borrows from the list node. That node is _not_ popped yet. + * + * If we end up not popping that conn off the list, we have to make sure + * to increase the refcount before returning a pointer to that + * connection out of this function. + */ struct bt_conn *conn = CONTAINER_OF(node, struct bt_conn, _conn_ready); if (dont_have_viewbufs()) { @@ -887,6 +903,7 @@ struct bt_conn *get_conn_ready(void) } if (should_stop_tx(conn)) { + /* Move reference off the list and into the `conn` variable. */ __maybe_unused sys_snode_t *s = sys_slist_get(&bt_dev.le.conn_ready); __ASSERT_NO_MSG(s == node); @@ -902,9 +919,11 @@ struct bt_conn *get_conn_ready(void) LOG_DBG("appending %p to back of TX queue", conn); bt_conn_data_ready(conn); } + + return conn; } - return conn; + return bt_conn_ref(conn); } /* Crazy that this file is compiled even if this is not true, but here we are. */ @@ -985,7 +1004,8 @@ void bt_conn_tx_processor(void) LOG_DBG("processing conn %p", conn); if (conn->state != BT_CONN_CONNECTED) { - LOG_ERR("conn %p: not connected", conn); + LOG_WRN("conn %p: not connected", conn); + /* Call the user callbacks & destroy (final-unref) the buffers * we were supposed to send. */ @@ -994,7 +1014,8 @@ void bt_conn_tx_processor(void) destroy_and_callback(conn, buf, cb, ud); buf = conn->tx_data_pull(conn, SIZE_MAX, &buf_len); } - return; + + goto exit; } /* now that we are guaranteed resources, we can pull data from the upper @@ -1008,7 +1029,8 @@ void bt_conn_tx_processor(void) * the upper layer when it has more data. */ LOG_DBG("no buf returned"); - return; + + goto exit; } bool last_buf = conn_mtu(conn) >= buf_len; @@ -1044,13 +1066,17 @@ void bt_conn_tx_processor(void) destroy_and_callback(conn, buf, cb, ud); bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - return; + goto exit; } /* Always kick the TX work. It will self-suspend if it doesn't get * resources or there is nothing left to send. */ bt_tx_irq_raise(); + +exit: + /* Give back the ref that `get_conn_ready()` gave us */ + bt_conn_unref(conn); } static void process_unack_tx(struct bt_conn *conn) diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 039a252b0c316..38be652cc7156 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -547,5 +547,11 @@ void bt_conn_tx_processor(void); /* To be called by upper layers when they want to send something. * Functions just like an IRQ. + * + * Note: This fn will take and hold a reference to `conn` until the IRQ for that + * conn is serviced. + * For the current implementation, that means: + * - ref the conn when putting on an "conn-ready" slist + * - unref the conn when popping the conn from the slist */ void bt_conn_data_ready(struct bt_conn *conn); diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index d92f0e931ad4b..323b448323bfb 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -311,6 +311,8 @@ struct bt_dev_le { #endif /* CONFIG_BT_SMP */ /* List of `struct bt_conn` that have either pending data to send, or * something to process (e.g. a disconnection event). + * + * Each element in this list contains a reference to its `conn` object. */ sys_slist_t conn_ready; }; From d13198adaa6b8555347247f61a8e63a8b4477100 Mon Sep 17 00:00:00 2001 From: Benjamin Bigler Date: Thu, 27 Jun 2024 16:00:16 +0200 Subject: [PATCH 136/187] drivers: ethernet: phy_mii: check if there is a mdio config In fixed-link mode, mdio remains unconfigured. This results in a null pointer dereference, triggering a bus fault Signed-off-by: Benjamin Bigler --- drivers/ethernet/phy/phy_mii.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ethernet/phy/phy_mii.c b/drivers/ethernet/phy/phy_mii.c index 041be3dafaa32..9b11e6517a6b6 100644 --- a/drivers/ethernet/phy/phy_mii.c +++ b/drivers/ethernet/phy/phy_mii.c @@ -49,6 +49,10 @@ static inline int reg_read(const struct device *dev, uint16_t reg_addr, { const struct phy_mii_dev_config *const cfg = dev->config; + /* if there is no mdio (fixed-link) it is not supported to read */ + if (cfg->mdio == NULL) { + return -ENOTSUP; + } return mdio_read(cfg->mdio, cfg->phy_addr, reg_addr, value); } @@ -57,6 +61,10 @@ static inline int reg_write(const struct device *dev, uint16_t reg_addr, { const struct phy_mii_dev_config *const cfg = dev->config; + /* if there is no mdio (fixed-link) it is not supported to write */ + if (cfg->mdio == NULL) { + return -ENOTSUP; + } return mdio_write(cfg->mdio, cfg->phy_addr, reg_addr, value); } From f38c4331e53ed0e5bc50af9880971c44d91aa534 Mon Sep 17 00:00:00 2001 From: Eve Redero Date: Fri, 28 Jun 2024 11:24:59 +0200 Subject: [PATCH 137/187] doc: detail how to find the drop-down version selector Adding more guidance in the documentation website top banner Signed-off-by: Eve Redero --- doc/_templates/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html index 6d58c015548a5..2420dad6f7f31 100644 --- a/doc/_templates/layout.html +++ b/doc/_templates/layout.html @@ -9,7 +9,7 @@
This is the documentation for the latest (main) development branch of Zephyr. If you are looking for the documentation of previous releases, use - the drop-down menu on the left and select the desired version. + the drop-down list at the bottom of the left panel and select the desired version.
{% endif %} {{ super() }} From d57879341780ef4a3c0dac71a2bfc5f6f896e6b2 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 1 Jul 2024 11:03:50 +0200 Subject: [PATCH 138/187] west.yml: hal_stm32: Remove autoconf.h Sync with hal_stm32 PR Signed-off-by: Erwan Gouriou --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b056124c50db6..0d4a3b6a29670 100644 --- a/west.yml +++ b/west.yml @@ -234,7 +234,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: d12e21e35d8d33c5fdf711d1a1c07f38c9295f70 + revision: 2d9f67657064e91865fa6a08ac17868572ff2e3d path: modules/hal/stm32 groups: - hal From f61058b37dab64d89821ab940e73226094ad6706 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 2 Jul 2024 09:28:40 +0100 Subject: [PATCH 139/187] drivers: udc_stm32: only check for HS_SPEED if defined Seems like not all stm32 devices define USBD_HS_SPEED in the HAL, only check for USBD_HS_SPEED if defined. Fixes a build failure with the new stack on F1 MCUs. Signed-off-by: Fabio Baltieri --- drivers/usb/udc/udc_stm32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 39a795c984098..7eae1a1810d9d 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -789,9 +789,11 @@ static enum udc_bus_speed udc_stm32_device_speed(const struct device *dev) { struct udc_stm32_data *priv = udc_get_private(dev); +#ifdef USBD_HS_SPEED if (priv->pcd.Init.speed == USBD_HS_SPEED) { return UDC_BUS_SPEED_HS; } +#endif if (priv->pcd.Init.speed == USBD_FS_SPEED) { return UDC_BUS_SPEED_FS; From 2ca5300052cc8550bf010c04128c01249b1a7fba Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Thu, 27 Jun 2024 14:39:22 +0300 Subject: [PATCH 140/187] tests: drivers: i2c: i2c_target_api: Support 16-bit word addresses Existing tests fail when 16-bit address width is used. Adjust the code to support 16-bit addresses as well. Signed-off-by: Tahsin Mutlugun --- tests/drivers/i2c/i2c_target_api/src/main.c | 68 ++++++++++++++++----- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/tests/drivers/i2c/i2c_target_api/src/main.c b/tests/drivers/i2c/i2c_target_api/src/main.c index e07ab6d33db6c..5c1540e3e79ae 100644 --- a/tests/drivers/i2c/i2c_target_api/src/main.c +++ b/tests/drivers/i2c/i2c_target_api/src/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -43,15 +44,17 @@ static void to_display_format(const uint8_t *src, size_t size, char *dst) } static int run_full_read(const struct device *i2c, uint8_t addr, - const uint8_t *comp_buffer) + uint8_t addr_width, const uint8_t *comp_buffer) { int ret; + uint8_t start_addr[2]; TC_PRINT("Testing full read: Master: %s, address: 0x%x\n", i2c->name, addr); /* Read EEPROM from I2C Master requests, then compare */ - ret = i2c_burst_read(i2c, addr, 0, i2c_buffer, TEST_DATA_SIZE); + memset(start_addr, 0, sizeof(start_addr)); + ret = i2c_write_read(i2c, addr, start_addr, (addr_width >> 3), i2c_buffer, TEST_DATA_SIZE); zassert_equal(ret, 0, "Failed to read EEPROM"); if (memcmp(i2c_buffer, comp_buffer, TEST_DATA_SIZE)) { @@ -70,15 +73,27 @@ static int run_full_read(const struct device *i2c, uint8_t addr, } static int run_partial_read(const struct device *i2c, uint8_t addr, - const uint8_t *comp_buffer, unsigned int offset) + uint8_t addr_width, const uint8_t *comp_buffer, unsigned int offset) { int ret; + uint8_t start_addr[2]; TC_PRINT("Testing partial read. Master: %s, address: 0x%x, off=%d\n", i2c->name, addr, offset); - ret = i2c_burst_read(i2c, addr, - offset, i2c_buffer, TEST_DATA_SIZE-offset); + switch (addr_width) { + case 8: + start_addr[0] = (uint8_t) (offset & 0xFF); + break; + case 16: + sys_put_be16((uint16_t)(offset & 0xFFFF), start_addr); + break; + default: + return -EINVAL; + } + + ret = i2c_write_read(i2c, addr, + start_addr, (addr_width >> 3), i2c_buffer, TEST_DATA_SIZE-offset); zassert_equal(ret, 0, "Failed to read EEPROM"); if (memcmp(i2c_buffer, &comp_buffer[offset], TEST_DATA_SIZE-offset)) { @@ -97,9 +112,11 @@ static int run_partial_read(const struct device *i2c, uint8_t addr, } static int run_program_read(const struct device *i2c, uint8_t addr, - unsigned int offset) + uint8_t addr_width, unsigned int offset) { int ret, i; + uint8_t start_addr[2]; + struct i2c_msg msg[2]; TC_PRINT("Testing program. Master: %s, address: 0x%x, off=%d\n", i2c->name, addr, offset); @@ -108,15 +125,32 @@ static int run_program_read(const struct device *i2c, uint8_t addr, i2c_buffer[i] = i; } - ret = i2c_burst_write(i2c, addr, - offset, i2c_buffer, TEST_DATA_SIZE-offset); + switch (addr_width) { + case 8: + start_addr[0] = (uint8_t) (offset & 0xFF); + break; + case 16: + sys_put_be16((uint16_t)(offset & 0xFFFF), start_addr); + break; + default: + return -EINVAL; + } + + msg[0].buf = start_addr; + msg[0].len = (addr_width >> 3); + msg[0].flags = I2C_MSG_WRITE; + msg[1].buf = &i2c_buffer[0]; + msg[1].len = TEST_DATA_SIZE; + msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP; + + ret = i2c_transfer(i2c, &msg[0], 2, addr); zassert_equal(ret, 0, "Failed to write EEPROM"); (void)memset(i2c_buffer, 0xFF, TEST_DATA_SIZE); /* Read back EEPROM from I2C Master requests, then compare */ - ret = i2c_burst_read(i2c, addr, - offset, i2c_buffer, TEST_DATA_SIZE-offset); + ret = i2c_write_read(i2c, addr, + start_addr, (addr_width >> 3), i2c_buffer, TEST_DATA_SIZE-offset); zassert_equal(ret, 0, "Failed to read EEPROM"); for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { @@ -137,9 +171,11 @@ ZTEST(i2c_eeprom_target, test_eeprom_target) const struct device *const eeprom_0 = DEVICE_DT_GET(NODE_EP0); const struct device *const i2c_0 = DEVICE_DT_GET(DT_BUS(NODE_EP0)); int addr_0 = DT_REG_ADDR(NODE_EP0); + uint8_t addr_0_width = DT_PROP_OR(NODE_EP0, address_width, 8); const struct device *const eeprom_1 = DEVICE_DT_GET(NODE_EP1); const struct device *const i2c_1 = DEVICE_DT_GET(DT_BUS(NODE_EP1)); int addr_1 = DT_REG_ADDR(NODE_EP1); + uint8_t addr_1_width = DT_PROP_OR(NODE_EP1, address_width, 8); int ret, offset; zassert_not_null(i2c_0, "EEPROM 0 - I2C bus not found"); @@ -194,21 +230,22 @@ ZTEST(i2c_eeprom_target, test_eeprom_target) * Similarly validation of EP1 uses i2c_0 as a master with addr_1 and * eeprom_1_data for validation. */ - ret = run_full_read(i2c_1, addr_0, eeprom_0_data); + ret = run_full_read(i2c_1, addr_0, addr_0_width, eeprom_0_data); zassert_equal(ret, 0, "Full I2C read from EP0 failed"); if (IS_ENABLED(CONFIG_APP_DUAL_ROLE_I2C)) { - ret = run_full_read(i2c_0, addr_1, eeprom_1_data); + ret = run_full_read(i2c_0, addr_1, addr_1_width, eeprom_1_data); zassert_equal(ret, 0, "Full I2C read from EP1 failed"); } for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) { zassert_equal(0, run_partial_read(i2c_1, addr_0, - eeprom_0_data, offset), + addr_0_width, eeprom_0_data, offset), "Partial I2C read EP0 failed"); if (IS_ENABLED(CONFIG_APP_DUAL_ROLE_I2C)) { zassert_equal(0, run_partial_read(i2c_0, addr_1, + addr_1_width, eeprom_1_data, offset), "Partial I2C read EP1 failed"); @@ -216,11 +253,12 @@ ZTEST(i2c_eeprom_target, test_eeprom_target) } for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) { - zassert_equal(0, run_program_read(i2c_1, addr_0, offset), + zassert_equal(0, run_program_read(i2c_1, addr_0, + addr_0_width, offset), "Program I2C read EP0 failed"); if (IS_ENABLED(CONFIG_APP_DUAL_ROLE_I2C)) { zassert_equal(0, run_program_read(i2c_0, addr_1, - offset), + addr_1_width, offset), "Program I2C read EP1 failed"); } } From 0318adead9498dc3b3784990f80a981196b9ca64 Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Thu, 27 Jun 2024 14:54:54 +0300 Subject: [PATCH 141/187] tests: drivers: i2c: i2c_target_api: Use address-width property Boards that use 1024 byte EEPROM buffers need 16-bit address widths otherwise eeprom_target driver will cause build failure. Signed-off-by: Tahsin Mutlugun --- .../i2c/i2c_target_api/boards/max32690evkit_max32690_m4.overlay | 2 ++ .../i2c/i2c_target_api/boards/mec1501modular_assy6885.overlay | 2 ++ tests/drivers/i2c/i2c_target_api/boards/npcx9m6f_evb.overlay | 2 ++ tests/drivers/i2c/i2c_target_api/boards/nucleo_h563zi.overlay | 2 ++ tests/drivers/i2c/i2c_target_api/boards/nucleo_l476rg.overlay | 2 ++ tests/drivers/i2c/i2c_target_api/boards/numaker_m2l31ki.overlay | 2 ++ .../drivers/i2c/i2c_target_api/boards/numaker_pfm_m467.overlay | 2 ++ 7 files changed, 14 insertions(+) diff --git a/tests/drivers/i2c/i2c_target_api/boards/max32690evkit_max32690_m4.overlay b/tests/drivers/i2c/i2c_target_api/boards/max32690evkit_max32690_m4.overlay index dc62f0be0d217..ac616bf26a2df 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/max32690evkit_max32690_m4.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/max32690evkit_max32690_m4.overlay @@ -12,6 +12,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -24,6 +25,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; diff --git a/tests/drivers/i2c/i2c_target_api/boards/mec1501modular_assy6885.overlay b/tests/drivers/i2c/i2c_target_api/boards/mec1501modular_assy6885.overlay index f9a8aca95cffa..17ae7f879a65f 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/mec1501modular_assy6885.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/mec1501modular_assy6885.overlay @@ -8,6 +8,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -17,6 +18,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; diff --git a/tests/drivers/i2c/i2c_target_api/boards/npcx9m6f_evb.overlay b/tests/drivers/i2c/i2c_target_api/boards/npcx9m6f_evb.overlay index c0ecd39418f5f..b870b6eae2ee6 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/npcx9m6f_evb.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/npcx9m6f_evb.overlay @@ -10,6 +10,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -23,6 +24,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_h563zi.overlay b/tests/drivers/i2c/i2c_target_api/boards/nucleo_h563zi.overlay index 02574be9b3e1f..bbb37fc8935f6 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/nucleo_h563zi.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_h563zi.overlay @@ -20,6 +20,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -31,6 +32,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_l476rg.overlay b/tests/drivers/i2c/i2c_target_api/boards/nucleo_l476rg.overlay index 98cd20632b596..e21e19aeeb462 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/nucleo_l476rg.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_l476rg.overlay @@ -17,6 +17,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -25,6 +26,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; diff --git a/tests/drivers/i2c/i2c_target_api/boards/numaker_m2l31ki.overlay b/tests/drivers/i2c/i2c_target_api/boards/numaker_m2l31ki.overlay index 2b621b51a2ff7..f0d07272d3a1f 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/numaker_m2l31ki.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/numaker_m2l31ki.overlay @@ -24,6 +24,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -36,6 +37,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; diff --git a/tests/drivers/i2c/i2c_target_api/boards/numaker_pfm_m467.overlay b/tests/drivers/i2c/i2c_target_api/boards/numaker_pfm_m467.overlay index a5cd026c7ebae..bcf3c2ca0c3d4 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/numaker_pfm_m467.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/numaker_pfm_m467.overlay @@ -24,6 +24,7 @@ eeprom0: eeprom@54 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x54>; + address-width = <16>; size = <1024>; }; }; @@ -36,6 +37,7 @@ eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; + address-width = <16>; size = <1024>; }; }; From 8ff3604c131782e8e64688d7dc280d1e224f03ef Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 2 Jul 2024 14:31:26 +0200 Subject: [PATCH 142/187] west.yml: TF-M: Fix 2 issues preventing usage on STM32 targets Points to the updated T-FM Signed-off-by: Erwan Gouriou --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 0d4a3b6a29670..5f96e1de78456 100644 --- a/west.yml +++ b/west.yml @@ -327,7 +327,7 @@ manifest: groups: - crypto - name: trusted-firmware-m - revision: 8df9cc8baf46252fd188bba1d87333a8daa9a5e8 + revision: f8d3a903578192d226ac1552f383d95b94ee8780 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From c50beadc5d688575c52dd7fcceaf0c06cd828581 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 18 Jun 2024 11:40:43 -0700 Subject: [PATCH 143/187] doc: doxygen: provide a way to override configs locally This allows specifying the environment variable ZEPHYR_DOXYGEN_OVERLAY pointing to a overlay file for doxygen to override configs in the base zephyr.doxyfile.in for local document builds. Signed-off-by: Daniel Leung --- doc/CMakeLists.txt | 10 ++++++++++ doc/zephyr.doxyfile.in | 2 ++ 2 files changed, 12 insertions(+) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index e72b7ac229861..4a9861f7a1d3a 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -47,6 +47,16 @@ set(SPHINX_ENV DOT_EXECUTABLE=${DOXYGEN_DOT_EXECUTABLE} ) +if(DEFINED ENV{ZEPHYR_DOXYGEN_OVERLAY}) + if(EXISTS $ENV{ZEPHYR_DOXYGEN_OVERLAY}) + set(INCLUDE_CUSTOM_FILE "@INCLUDE = $ENV{ZEPHYR_DOXYGEN_OVERLAY}") + else() + message(FATAL_ERROR "Zephyr Doxygen overlay $ENV{ZEPHYR_DOXYGEN_OVERLAY} does not exist!") + endif() +else() + set(INCLUDE_CUSTOM_FILE "") +endif() + set(DOCS_CFG_DIR ${CMAKE_CURRENT_LIST_DIR}) set(DOCS_DOCTREE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doctrees) set(DOCS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 268f2337802a2..df01f7954c79a 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -2816,3 +2816,5 @@ GENERATE_LEGEND = YES # The default value is: YES. DOT_CLEANUP = YES + +@INCLUDE_CUSTOM_FILE@ From 4189a9c0d73bad1d54a2b592151755d5bfb25885 Mon Sep 17 00:00:00 2001 From: Peter Gielda Date: Sun, 30 Jun 2024 13:42:21 +0200 Subject: [PATCH 144/187] dts: riscv: Fix incorrect plic size Fix wrong size of the plic node dts entry. Signed-off-by: Peter Gielda --- dts/riscv/efinix/sapphire_soc.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/riscv/efinix/sapphire_soc.dtsi b/dts/riscv/efinix/sapphire_soc.dtsi index b83c9bc1b0f35..72092a4bc9300 100644 --- a/dts/riscv/efinix/sapphire_soc.dtsi +++ b/dts/riscv/efinix/sapphire_soc.dtsi @@ -54,7 +54,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = <0xf8c00000 0x04000000>; + reg = <0xf8c00000 0x0400000>; riscv,max-priority = <3>; riscv,ndev = <32>; }; From 648d65bd660c820278d5afb9176320f97fa2c0ca Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 1 Jul 2024 08:07:10 +0300 Subject: [PATCH 145/187] doc: net: Add info about misc network config options Add information about these missing Kconfig options: CONFIG_NET_CONFIG_MY_IPV6_ADDR CONFIG_NET_CONFIG_PEER_IPV6_ADDR CONFIG_NET_CONFIG_MY_IPV4_ADDR CONFIG_NET_CONFIG_MY_IPV4_NETMASK CONFIG_NET_CONFIG_MY_IPV4_GW CONFIG_NET_CONFIG_PEER_IPV4_ADDR Fixes #75211 Signed-off-by: Jukka Rissanen --- doc/connectivity/networking/api/net_config.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/connectivity/networking/api/net_config.rst b/doc/connectivity/networking/api/net_config.rst index 85103ec11aebf..9c6ea17b98113 100644 --- a/doc/connectivity/networking/api/net_config.rst +++ b/doc/connectivity/networking/api/net_config.rst @@ -50,6 +50,18 @@ setup the system: this option tells that the network application needs IPv6 router to exists before continuing. This means in practice that the application wants to wait until it receives IPv6 router advertisement message before continuing." + ":kconfig:option:`CONFIG_NET_CONFIG_MY_IPV6_ADDR`","Local static IPv6 address assigned to + the default network interface." + ":kconfig:option:`CONFIG_NET_CONFIG_PEER_IPV6_ADDR`","Peer static IPv6 address. This is mainly + useful in testing setups where the application can connect to a pre-defined host." + ":kconfig:option:`CONFIG_NET_CONFIG_MY_IPV4_ADDR`","Local static IPv4 address assigned to + the default network interface." + ":kconfig:option:`CONFIG_NET_CONFIG_MY_IPV4_NETMASK`","Static IPv4 netmask assigned to the IPv4 + address." + ":kconfig:option:`CONFIG_NET_CONFIG_MY_IPV4_GW`","Static IPv4 gateway address assigned to the + default network interface." + ":kconfig:option:`CONFIG_NET_CONFIG_PEER_IPV4_ADDR`","Peer static IPv4 address. This is mainly + useful in testing setups where the application can connect to a pre-defined host." Sample usage ************ From 052acf13c74a54217a1ebc36332c8b5858be17a8 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Mon, 1 Jul 2024 00:34:45 -0600 Subject: [PATCH 146/187] twister: Fix gTest harness The gTest harness asssumed that the lines end with the test name, but some gTest implementations include the test duration in the line. Update both the tests and regex to allow this and also avoid capturing characters into the `test_name` that cannot be valid test name chars. Fixes #72318 Signed-off-by: Yuval Peress --- scripts/pylib/twister/twisterlib/harness.py | 10 +++++----- scripts/tests/twister/test_harness.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index c25b7fcf421ab..6c132a10d4e95 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -570,11 +570,11 @@ def _parse_report_file(self, report): class Gtest(Harness): ANSI_ESCAPE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') - TEST_START_PATTERN = r".*\[ RUN \] (?P.*)\.(?P.*)$" - TEST_PASS_PATTERN = r".*\[ OK \] (?P.*)\.(?P.*)$" - TEST_SKIP_PATTERN = r".*\[ DISABLED \] (?P.*)\.(?P.*)$" - TEST_FAIL_PATTERN = r".*\[ FAILED \] (?P.*)\.(?P.*)$" - FINISHED_PATTERN = r".*\[==========\] Done running all tests\.$" + TEST_START_PATTERN = r".*\[ RUN \] (?P[a-zA-Z_][a-zA-Z0-9_]*)\.(?P[a-zA-Z_][a-zA-Z0-9_]*)" + TEST_PASS_PATTERN = r".*\[ OK \] (?P[a-zA-Z_][a-zA-Z0-9_]*)\.(?P[a-zA-Z_][a-zA-Z0-9_]*)" + TEST_SKIP_PATTERN = r".*\[ DISABLED \] (?P[a-zA-Z_][a-zA-Z0-9_]*)\.(?P[a-zA-Z_][a-zA-Z0-9_]*)" + TEST_FAIL_PATTERN = r".*\[ FAILED \] (?P[a-zA-Z_][a-zA-Z0-9_]*)\.(?P[a-zA-Z_][a-zA-Z0-9_]*)" + FINISHED_PATTERN = r".*\[==========\] Done running all tests\." def __init__(self): super().__init__() diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index 57e68f9deb70b..116d4bf50fb3d 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -33,7 +33,7 @@ SAMPLE_GTEST_START = ( "[00:00:00.000,000]  label: [==========] Running all tests." ) -SAMPLE_GTEST_FMT = "[00:00:00.000,000]  label: [{state}] {suite}.{test}" +SAMPLE_GTEST_FMT = "[00:00:00.000,000]  label: [{state}] {suite}.{test} (0ms)" SAMPLE_GTEST_END = ( "[00:00:00.000,000]  label: [==========] Done running all tests." ) From 44db32c8e91a115af80879a795c922e65144ed9c Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 26 Jun 2024 15:58:44 -0500 Subject: [PATCH 147/187] docs: Add icm42688 changes to migration guide Adds the icm42688 devicetree binding changes to the migration guide noting that the previous bindings were not at all in use. Signed-off-by: Tom Burdick --- doc/releases/migration-guide-3.7.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/releases/migration-guide-3.7.rst b/doc/releases/migration-guide-3.7.rst index 1fcf5f50a85fc..6321d5fed3acc 100644 --- a/doc/releases/migration-guide-3.7.rst +++ b/doc/releases/migration-guide-3.7.rst @@ -238,6 +238,27 @@ Device Drivers and Devicetree }; }; +* The driver for :dtcompatible:`invensense,icm42688` now correctly supports device + tree configuration(:github:`74267`). Prior devicetrees may have tried to use + the bindings to set sample rate and scale for the accel/gyro without any + effect. The devicetree usage should now use the provided defines and include + file along with new bindings which take these values. + + For example: + + .. code-block:: devicetree + + #include + + icm42688: icm42688@0 { + accel-pwr-mode = ; + accel-fs = ; + accel-odr = ; + gyro-pwr-mode= ; + gyro-fs = ; + gyro-odr = ; + }; + * `st,lis2mdl` property `spi-full-duplex` changed to `duplex = SPI_FULL_DUPLEX`. Full duplex is now the default. From 27ece7626fbcaf42c55828f34c9cc0bd2c24ce37 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 1 Jul 2024 11:35:20 +0800 Subject: [PATCH 148/187] doc: modules: fix indentation Fix the indentation of `bar` in the code block. Signed-off-by: Yong Cong Sin --- doc/develop/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/modules.rst b/doc/develop/modules.rst index 0369a0e670c1f..8188e12bc00a8 100644 --- a/doc/develop/modules.rst +++ b/doc/develop/modules.rst @@ -785,7 +785,7 @@ module ``bar`` to be present in the build system: name: foo build: depends: - - bar + - bar This example will ensure that ``bar`` is present when ``foo`` is included into the build system, and it will also ensure that ``bar`` is processed before From 664b6c20e0280ac65703749a287a0fe117824507 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Wed, 3 Jul 2024 09:08:21 +0200 Subject: [PATCH 149/187] samples: modules: canopennode: add bootloader argument The README "Testing CANopen Program Download" section needs a sysbuild MCUboot option. Otherwise only the application is built and the test will fail. This has probably been missing since commit 238d113185c041e951c7f3636b5cdc98cbf2d9d9. Signed-off-by: Jeppe Odgaard --- samples/modules/canopennode/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/modules/canopennode/README.rst b/samples/modules/canopennode/README.rst index 4b735f9b5d7b7..8a7a067c0d4c5 100644 --- a/samples/modules/canopennode/README.rst +++ b/samples/modules/canopennode/README.rst @@ -409,7 +409,7 @@ for the FRDM-K64F as follows: :board: frdm_k64f :goals: build :west-args: --sysbuild - :gen-args: -Dcanopennode_CONF_FILE=prj_img_mgmt.conf + :gen-args: -Dcanopennode_CONF_FILE=prj_img_mgmt.conf -DSB_CONFIG_BOOTLOADER_MCUBOOT=y :compact: #. Flash the newly built MCUboot and CANopen sample binaries using west: From 4bc0653822d7e1a80a11529b094fa255185c8138 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 1 Jul 2024 15:54:06 +0300 Subject: [PATCH 150/187] net: ipv6-pe: Verify that hmac calculation was ok Make sure to check return values of mbedtls hmac APIs so that the digest is calculated properly. Fixes #75259 Fixes #75260 Fixes #75261 Coverity-CID: 366271 Coverity-CID: 366277 Coverify-CID: 366279 Signed-off-by: Jukka Rissanen --- subsys/net/ip/ipv6_pe.c | 72 ++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/subsys/net/ip/ipv6_pe.c b/subsys/net/ip/ipv6_pe.c index 77fa2a1424efe..798a2f26b9737 100644 --- a/subsys/net/ip/ipv6_pe.c +++ b/subsys/net/ip/ipv6_pe.c @@ -216,16 +216,17 @@ static bool ipv6_pe_prefix_update_lifetimes(struct net_if_ipv6 *ipv6, } /* RFC 8981 ch 3.3.2 */ -static void gen_temporary_iid(struct net_if *iface, - const struct in6_addr *prefix, - uint8_t *network_id, size_t network_id_len, - uint8_t dad_counter, - uint8_t *temporary_iid, - size_t temporary_iid_len) +static int gen_temporary_iid(struct net_if *iface, + const struct in6_addr *prefix, + uint8_t *network_id, size_t network_id_len, + uint8_t dad_counter, + uint8_t *temporary_iid, + size_t temporary_iid_len) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); mbedtls_md_context_t ctx; uint8_t digest[32]; + int ret; static bool once; static uint8_t secret_key[16]; /* Min 128 bits, RFC 8981 ch 3.3.2 */ struct { @@ -256,12 +257,30 @@ static void gen_temporary_iid(struct net_if *iface, mbedtls_md_init(&ctx); mbedtls_md_setup(&ctx, md_info, true); - mbedtls_md_hmac_starts(&ctx, secret_key, sizeof(secret_key)); - mbedtls_md_hmac_update(&ctx, (uint8_t *)&buf, sizeof(buf)); - mbedtls_md_hmac_finish(&ctx, digest); - mbedtls_md_free(&ctx); + ret = mbedtls_md_hmac_starts(&ctx, secret_key, sizeof(secret_key)); + if (ret != 0) { + NET_DBG("Cannot %s hmac (%d)", "start", ret); + goto err; + } + + ret = mbedtls_md_hmac_update(&ctx, (uint8_t *)&buf, sizeof(buf)); + if (ret != 0) { + NET_DBG("Cannot %s hmac (%d)", "update", ret); + goto err; + } + + ret = mbedtls_md_hmac_finish(&ctx, digest); + if (ret != 0) { + NET_DBG("Cannot %s hmac (%d)", "finish", ret); + goto err; + } memcpy(temporary_iid, digest, MIN(sizeof(digest), temporary_iid_len)); + +err: + mbedtls_md_free(&ctx); + + return ret; } void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix, @@ -272,7 +291,7 @@ void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix, struct in6_addr addr; k_ticks_t remaining; k_timeout_t vlifetimeout; - int i, dad_count = 1; + int i, ret, dad_count = 1; int32_t lifetime; bool valid = false; @@ -328,21 +347,22 @@ void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix, net_ipaddr_copy(&addr, prefix); do { - gen_temporary_iid(iface, prefix, - COND_CODE_1(CONFIG_NET_INTERFACE_NAME, - (iface->config.name, - sizeof(iface->config.name)), - (net_if_get_device(iface)->name, - strlen(net_if_get_device(iface)->name))), - dad_count, - &addr.s6_addr[8], 8U); - - ifaddr = net_if_ipv6_addr_lookup(&addr, NULL); - if (ifaddr == NULL && !net_ipv6_is_addr_unspecified(&addr) && - memcmp(&addr, &reserved_anycast_subnet, - sizeof(struct in6_addr)) != 0) { - valid = true; - break; + ret = gen_temporary_iid(iface, prefix, + COND_CODE_1(CONFIG_NET_INTERFACE_NAME, + (iface->config.name, + sizeof(iface->config.name)), + (net_if_get_device(iface)->name, + strlen(net_if_get_device(iface)->name))), + dad_count, + &addr.s6_addr[8], 8U); + if (ret == 0) { + ifaddr = net_if_ipv6_addr_lookup(&addr, NULL); + if (ifaddr == NULL && !net_ipv6_is_addr_unspecified(&addr) && + memcmp(&addr, &reserved_anycast_subnet, + sizeof(struct in6_addr)) != 0) { + valid = true; + break; + } } } while (dad_count++ < TEMP_IDGEN_RETRIES); From c724af7dc1e15b3ec072f436bcab8cf1f7027de6 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Mon, 1 Jul 2024 12:16:31 +0200 Subject: [PATCH 151/187] tests: dma/chan_blen_transfer: place TX buf in RAM This commit removes the const qualifier from TX (source) buffer of the chan_blen_transfer DMA test to ensure it gets placed in RAM rather than flash. This ensures the test can pass on hardware where the DMA controller is unable to access flash. Fixes #75125. Signed-off-by: Mathieu Choplain --- tests/drivers/dma/chan_blen_transfer/src/test_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/dma/chan_blen_transfer/src/test_dma.c b/tests/drivers/dma/chan_blen_transfer/src/test_dma.c index 2b7f83d5fb1e8..054bb6b89b9e9 100644 --- a/tests/drivers/dma/chan_blen_transfer/src/test_dma.c +++ b/tests/drivers/dma/chan_blen_transfer/src/test_dma.c @@ -22,7 +22,7 @@ #define RX_BUFF_SIZE (48) -static __aligned(32) const char tx_data[] = "It is harder to be kind than to be wise........"; +static __aligned(32) char tx_data[] = "It is harder to be kind than to be wise........"; static __aligned(32) char rx_data[RX_BUFF_SIZE] = { 0 }; static void test_done(const struct device *dma_dev, void *arg, From 35d47b311c2ae65192b9ad83b52d33e6b689f50a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 1 Jul 2024 10:53:58 +0200 Subject: [PATCH 152/187] Bluetooth: BAP: Broadcast: Fix state checks The existing state checks for both the broadcast sink and broadcast source only ever checked the first BIS. This sort of made sense, since they are all linked by HCI (i.e. they share the same state), but there is a race condition in the ISO and BAP callbacks that could allow applications to delete sinks and sources before all the ISO callbacks had been handled. By treating the sink and source states as the highest value of the BIS, then we better treat all BIS the same. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_sink.c | 81 +++++++++---------- subsys/bluetooth/audio/bap_broadcast_source.c | 29 +++---- 2 files changed, 50 insertions(+), 60 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index d554d0f1ef633..7f2ef7adbeb2e 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -299,6 +299,33 @@ static void broadcast_sink_iso_recv(struct bt_iso_chan *chan, } } +/** Gets the "highest" state of all BIS in the broadcast sink */ +static enum bt_bap_ep_state broadcast_sink_get_state(struct bt_bap_broadcast_sink *sink) +{ + enum bt_bap_ep_state state = BT_BAP_EP_STATE_IDLE; + struct bt_bap_stream *stream; + + if (sink == NULL) { + LOG_DBG("sink is NULL"); + + return state; + } + + if (sys_slist_is_empty(&sink->streams)) { + LOG_DBG("Sink does not have any streams"); + + return state; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&sink->streams, stream, _node) { + if (stream->ep != NULL) { + state = MAX(state, stream->ep->status.state); + } + } + + return state; +} + static void broadcast_sink_iso_connected(struct bt_iso_chan *chan) { struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan); @@ -306,7 +333,6 @@ static void broadcast_sink_iso_connected(struct bt_iso_chan *chan) struct bt_bap_broadcast_sink *sink; struct bt_bap_stream *stream; struct bt_bap_ep *ep = iso->rx.ep; - bool all_connected; if (ep == NULL) { LOG_ERR("iso %p not bound with ep", chan); @@ -340,17 +366,7 @@ static void broadcast_sink_iso_connected(struct bt_iso_chan *chan) LOG_WRN("No callback for started set"); } - all_connected = true; - SYS_SLIST_FOR_EACH_CONTAINER(&sink->streams, stream, _node) { - __ASSERT(stream->ep, "Endpoint is NULL"); - - if (stream->ep->status.state != BT_BAP_EP_STATE_STREAMING) { - all_connected = false; - break; - } - } - - if (all_connected) { + if (broadcast_sink_get_state(sink) != BT_BAP_EP_STATE_STREAMING) { update_recv_state_big_synced(sink); } } @@ -1278,8 +1294,7 @@ int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t inde int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink) { - struct bt_bap_stream *stream; - sys_snode_t *head_node; + enum bt_bap_ep_state state; int err; CHECKIF(sink == NULL) { @@ -1292,21 +1307,9 @@ int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink) return -EALREADY; } - head_node = sys_slist_peek_head(&sink->streams); - stream = CONTAINER_OF(head_node, struct bt_bap_stream, _node); - - /* All streams in a broadcast source is in the same state, - * so we can just check the first stream - */ - if (stream->ep == NULL) { - LOG_DBG("stream->ep is NULL"); - return -EINVAL; - } - - if (stream->ep->status.state != BT_BAP_EP_STATE_STREAMING && - stream->ep->status.state != BT_BAP_EP_STATE_QOS_CONFIGURED) { - LOG_DBG("Broadcast sink stream %p invalid state: %u", stream, - stream->ep->status.state); + state = broadcast_sink_get_state(sink); + if (state != BT_BAP_EP_STATE_STREAMING && state != BT_BAP_EP_STATE_QOS_CONFIGURED) { + LOG_DBG("Broadcast sink %p invalid state: %u", sink, state); return -EBADMSG; } @@ -1324,25 +1327,17 @@ int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink) int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink) { + enum bt_bap_ep_state state; + CHECKIF(sink == NULL) { LOG_DBG("sink is NULL"); return -EINVAL; } - if (!sys_slist_is_empty(&sink->streams)) { - struct bt_bap_stream *stream; - sys_snode_t *head_node; - - head_node = sys_slist_peek_head(&sink->streams); - stream = CONTAINER_OF(head_node, struct bt_bap_stream, _node); - - /* All streams in a broadcast source is in the same state, - * so we can just check the first stream - */ - if (stream->ep != NULL) { - LOG_DBG("Sink is not stopped"); - return -EBADMSG; - } + state = broadcast_sink_get_state(sink); + if (state != BT_BAP_EP_STATE_IDLE) { + LOG_DBG("Broadcast sink %p invalid state: %u", sink, state); + return -EBADMSG; } /* Reset the broadcast sink */ diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index c8547e13ae711..4f11e247ceb90 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -624,38 +624,33 @@ static bool valid_broadcast_source_param(const struct bt_bap_broadcast_source_pa return true; } +/** Gets the "highest" state of all BIS in the broadcast source */ static enum bt_bap_ep_state broadcast_source_get_state(struct bt_bap_broadcast_source *source) { + enum bt_bap_ep_state state = BT_BAP_EP_STATE_IDLE; struct bt_bap_broadcast_subgroup *subgroup; - struct bt_bap_stream *stream; - sys_snode_t *head_node; if (source == NULL) { LOG_DBG("source is NULL"); - return BT_BAP_EP_STATE_IDLE; + return state; } if (sys_slist_is_empty(&source->subgroups)) { LOG_DBG("Source does not have any streams"); - return BT_BAP_EP_STATE_IDLE; + return state; } - /* Get the first stream */ - head_node = sys_slist_peek_head(&source->subgroups); - subgroup = CONTAINER_OF(head_node, struct bt_bap_broadcast_subgroup, _node); - - head_node = sys_slist_peek_head(&subgroup->streams); - stream = CONTAINER_OF(head_node, struct bt_bap_stream, _node); + SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) { + struct bt_bap_stream *stream; - /* All streams in a broadcast source is in the same state, - * so we can just check the first stream - */ - if (stream->ep == NULL) { - LOG_DBG("stream->ep is NULL"); - return BT_BAP_EP_STATE_IDLE; + SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) { + if (stream->ep != NULL) { + state = MAX(state, stream->ep->status.state); + } + } } - return stream->ep->status.state; + return state; } static bool merge_bis_and_subgroup_data_cb(struct bt_data *data, void *user_data) From daff18fea5bc878c5ebe51b91798825a11a70851 Mon Sep 17 00:00:00 2001 From: Jared Kangas Date: Sat, 29 Jun 2024 07:11:48 -0700 Subject: [PATCH 153/187] drivers: adc: lmp90xxx: fix checksum mismatch return value During channel reads, zero is returned on CRC mismatches: the returned error variable is not written to after a previous non-zero check. Return -EIO to mirror other drivers' checksum validation behaviors. Signed-off-by: Jared Kangas --- drivers/adc/adc_lmp90xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/adc/adc_lmp90xxx.c b/drivers/adc/adc_lmp90xxx.c index d47789333c41a..f71d6f4fa3879 100644 --- a/drivers/adc/adc_lmp90xxx.c +++ b/drivers/adc/adc_lmp90xxx.c @@ -639,7 +639,7 @@ static int lmp90xxx_adc_read_channel(const struct device *dev, if (buf[3] != crc) { LOG_ERR("CRC mismatch (0x%02x vs. 0x%02x)", buf[3], crc); - return err; + return -EIO; } } From 2a0f3f52f61f35e4f8bd9b6089f7c8e2e3c59414 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 27 Jun 2024 15:38:30 +0200 Subject: [PATCH 154/187] intel_adsp/ace: power: fix firmware panic on MTL The power_down() function attempts to lock the hpsram_mask on-stack variable in data cache, which causes an exception. Moving it to .bss by making it static fixes it. Signed-off-by: Guennadi Liakhovetski --- soc/intel/intel_adsp/ace/power.c | 3 ++- soc/intel/intel_adsp/ace/power_down.S | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/soc/intel/intel_adsp/ace/power.c b/soc/intel/intel_adsp/ace/power.c index 20efc8e6f97f4..4d856af4584a9 100644 --- a/soc/intel/intel_adsp/ace/power.c +++ b/soc/intel/intel_adsp/ace/power.c @@ -339,7 +339,8 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) (void *)rom_entry; sys_cache_data_flush_range((void *)imr_layout, sizeof(*imr_layout)); #endif /* CONFIG_ADSP_IMR_CONTEXT_SAVE */ - uint32_t hpsram_mask = 0; + /* This assumes a single HPSRAM segment */ + static uint32_t hpsram_mask; #ifdef CONFIG_ADSP_POWER_DOWN_HPSRAM /* turn off all HPSRAM banks - get a full bitmap */ uint32_t ebb_banks = ace_hpsram_get_bank_count(); diff --git a/soc/intel/intel_adsp/ace/power_down.S b/soc/intel/intel_adsp/ace/power_down.S index 1b9f7792ac815..c93e56286566f 100644 --- a/soc/intel/intel_adsp/ace/power_down.S +++ b/soc/intel/intel_adsp/ace/power_down.S @@ -60,6 +60,10 @@ power_down: ipfl pfl_reg, 128 ipfl pfl_reg, 192 + /* + * This assumes a single HPSRAM segment although the code below is + * generic and uses MAX_MEMORY_SEGMENTS for their number + */ mov pfl_reg, pu32_hpsram_mask dpfl pfl_reg, 0 /* move some values to registries before switching off whole memory */ From 102764bd4622de27f166a467f652a06d2a8e1c1b Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 1 Jul 2024 14:03:01 +0100 Subject: [PATCH 155/187] soc: nordic: Fix run once regex issue and add missing entries Fixes an issue whereby multiple boards would be grouped when using a regex to group them, and adds missing nRF91 entries to the list Signed-off-by: Jamie McCrae --- soc/nordic/soc.yml | 75 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/soc/nordic/soc.yml b/soc/nordic/soc.yml index 73e4aea0474b4..0bce815b9dc95 100644 --- a/soc/nordic/soc.yml +++ b/soc/nordic/soc.yml @@ -52,16 +52,37 @@ runners: run: first groups: - qualifiers: - - nrf51([0-9]{3})((.+)?) + - nrf51822 - qualifiers: - - nrf52([0-9]{3})((.+)?) + - nrf52805 + - qualifiers: + - nrf52810 + - qualifiers: + - nrf52811 + - qualifiers: + - nrf52820 + - qualifiers: + - nrf52832 + - qualifiers: + - nrf52833 + - qualifiers: + - nrf52840 - qualifiers: - nrf5340/cpunet - nrf5340/cpuapp - nrf5340/cpuapp/ns + - qualifiers: + - nrf9131 + - nrf9131/ns + - qualifiers: + - nrf9151 + - nrf9151/ns - qualifiers: - nrf9160 - nrf9160/ns + - qualifiers: + - nrf9161 + - nrf9161/ns - qualifiers: - nrf54l15/cpuapp - nrf54l15/cpuflpr @@ -77,17 +98,38 @@ runners: run: first groups: - qualifiers: - - nrf51([0-9]{3})((.+)?) + - nrf51822 + - qualifiers: + - nrf52805 + - qualifiers: + - nrf52810 + - qualifiers: + - nrf52811 + - qualifiers: + - nrf52820 + - qualifiers: + - nrf52832 - qualifiers: - - nrf52([0-9]{3})((.+)?) + - nrf52833 + - qualifiers: + - nrf52840 - qualifiers: - nrf5340/cpunet - qualifiers: - nrf5340/cpuapp - nrf5340/cpuapp/ns + - qualifiers: + - nrf9131 + - nrf9131/ns + - qualifiers: + - nrf9151 + - nrf9151/ns - qualifiers: - nrf9160 - nrf9160/ns + - qualifiers: + - nrf9161 + - nrf9161/ns - qualifiers: - nrf54l15/cpuapp - nrf54l15/cpuflpr @@ -103,17 +145,38 @@ runners: run: last groups: - qualifiers: - - nrf51([0-9]{3})((.+)?) + - nrf51822 + - qualifiers: + - nrf52805 + - qualifiers: + - nrf52810 + - qualifiers: + - nrf52811 - qualifiers: - - nrf52([0-9]{3})((.+)?) + - nrf52820 + - qualifiers: + - nrf52832 + - qualifiers: + - nrf52833 + - qualifiers: + - nrf52840 - qualifiers: - nrf5340/cpunet - qualifiers: - nrf5340/cpuapp - nrf5340/cpuapp/ns + - qualifiers: + - nrf9131 + - nrf9131/ns + - qualifiers: + - nrf9151 + - nrf9151/ns - qualifiers: - nrf9160 - nrf9160/ns + - qualifiers: + - nrf9161 + - nrf9161/ns - qualifiers: - nrf54l15/cpuapp - nrf54l15/cpuflpr From 8fa418c7e1be07bb9f02afd905df5b9183276131 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 24 Jun 2024 20:53:15 +0530 Subject: [PATCH 156/187] modules: hostap: Fix MbedTLS TLS TLS is only for Enterprise, so, move to enterprise macro. Signed-off-by: Chaitanya Tata --- modules/hostap/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt index 543f13506fe96..026fcfb08cce9 100644 --- a/modules/hostap/CMakeLists.txt +++ b/modules/hostap/CMakeLists.txt @@ -417,7 +417,6 @@ zephyr_library_sources( ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-bignum.c ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-ec.c ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls.c - ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls.c ${HOSTAP_SRC_BASE}/crypto/aes-internal.c ${HOSTAP_SRC_BASE}/crypto/aes-wrap.c ${HOSTAP_SRC_BASE}/crypto/aes-unwrap.c @@ -439,6 +438,10 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPA3 ${HOSTAP_SRC_BASE}/crypto/sha256-kdf.c ) +zephyr_library_sources_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + ${HOSTAP_SRC_BASE}/crypto/tls_none.c +) + zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE # common ${HOSTAP_SRC_BASE}/crypto/sha384-tlsprf.c @@ -450,6 +453,7 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE # MD4 removed from MbedTLS ${HOSTAP_SRC_BASE}/crypto/md4-internal.c ${HOSTAP_SRC_BASE}/crypto/aes-encblock.c + ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls.c ) endif() From defae14f67ec513afbc9c38185fab0bf89bd6709 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 24 Jun 2024 20:53:47 +0530 Subject: [PATCH 157/187] modules: hostap: Fix MbedTLS config issue Fixes build issues when Wi-Fi security is enabled for default implementation, the alternative implementation is managed separately, and doesn't need these. Signed-off-by: Chaitanya Tata --- modules/hostap/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 1c8ebede91f3b..fade8953c4ae9 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -113,8 +113,11 @@ choice WIFI_NM_WPA_SUPPLICANT_CRYPTO_BACKEND config WIFI_NM_WPA_SUPPLICANT_CRYPTO bool "Crypto support for WiFi" select MBEDTLS + select MBEDTLS_SHA1 + select MBEDTLS_CIPHER select MBEDTLS_CIPHER_MODE_CTR_ENABLED select MBEDTLS_CIPHER_MODE_CBC_ENABLED + select MBEDTLS_CIPHER_AES_ENABLED select MBEDTLS_ECP_C select MBEDTLS_ECP_ALL_ENABLED select MBEDTLS_CMAC From c4760433dc99c56a4d85eb507fcc5a9e1b8a4227 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 24 Jun 2024 22:22:33 +0530 Subject: [PATCH 158/187] modules: hostap: Fix SoF Due to recent changes to hostap, the stack usage is increased, so, increase the stack size to fix SoF. Signed-off-by: Chaitanya Tata --- modules/hostap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index fade8953c4ae9..f74ec3510a56f 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -36,7 +36,7 @@ config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE int "Stack size for wpa_supplicant iface workqueue" - default 4096 + default 6144 config WIFI_NM_WPA_SUPPLICANT_WQ_PRIO int "Thread priority of wpa_supplicant iface workqueue" From b7a2526a1038d4c02943d33fc6e0d262f43dd367 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 24 Jun 2024 22:23:08 +0530 Subject: [PATCH 159/187] modules: hostap: Fix check for iface up We only need the interface to be administratively up, the operationl status is managed by the WPA supplicant. Signed-off-by: Chaitanya Tata --- modules/hostap/src/supp_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index fc5644a615d39..75946793e64ca 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -419,7 +419,7 @@ static void iface_cb(struct net_if *iface, void *user_data) return; } - if (!net_if_is_up(iface)) { + if (!net_if_is_admin_up(iface)) { return; } From a2657f28201f373eb21fc687f5664ccf32d73368 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:05:53 +0200 Subject: [PATCH 160/187] Revert "doc: posix: mark posis fd mgmt as supported" PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 This reverts commit e9b676a9ab4c4a977ec6507219dd983248ae630a. Signed-off-by: Alberto Escolar Piedras --- doc/services/portability/posix/aep/index.rst | 2 +- .../portability/posix/option_groups/index.rst | 28 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index 651bc43b0cf52..b1fe34ee0d986 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -101,7 +101,7 @@ The *Realtime Controller System Profile* (PSE52) includes all features from PSE5 :widths: 50, 10, 50 :ref:`POSIX_C_LANG_MATH `, yes, - :ref:`POSIX_FD_MGMT `, yes, :kconfig:option:`CONFIG_POSIX_FD_MGMT` + :ref:`POSIX_FD_MGMT `,, :kconfig:option:`CONFIG_POSIX_FD_MGMT` :ref:`POSIX_FILE_SYSTEM `,, :kconfig:option:`CONFIG_POSIX_FILE_SYSTEM` .. csv-table:: PSE52 Option Requirements diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index 08a4b3e68fcad..f8e32b125ef83 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -546,26 +546,24 @@ POSIX_TIMERS POSIX_FD_MGMT ============= -.. note:: - When using Newlib, Picolibc, or other C libraries conforming to the ISO C Standard, the - C89 components of the ``POSIX_FD_MGMT`` Option Group are considered supported. +This table lists service support status in Zephyr for `POSIX_FD_MGMT`: .. csv-table:: POSIX_FD_MGMT :header: API, Supported :widths: 50,10 - dup(), yes - dup2(), yes - fcntl(), yes - fgetpos(), yes - fseek(), yes - fseeko(), yes - fsetpos(), yes - ftell(), yes - ftello(), yes - ftruncate(), yes - lseek(), yes - rewind(), yes + dup(), + dup2(), + fcntl(), + fgetpos(), + fseek(), + fseeko(), + fsetpos(), + ftell(), + ftello(), + ftruncate(),yes + lseek(), + rewind(), .. _posix_option_group_file_locking: From 8cd88c861a23ef9f939133883a3b7844ec0bf7ef Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:06:47 +0200 Subject: [PATCH 161/187] Revert "posix: fd_mgmt: implement dup(), dup2(), fseeko(), and ftello()" This reverts commit b18cad15b9ea1b72436da4a96444012a360e5fc8. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 40 ------------------------------- lib/posix/options/Kconfig.fd_mgmt | 2 -- lib/posix/options/fd_mgmt.c | 37 ---------------------------- 3 files changed, 79 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 52f62f69cd0e9..0c9131d7c39d0 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -424,46 +424,6 @@ int zvfs_fileno(FILE *file) return (struct fd_entry *)file - fdtable; } -int zvfs_dup(int fd, int *newfd) -{ - int ret; - - if (_check_fd(fd) < 0) { - return -1; - } - - (void)k_mutex_lock(&fdtable_lock, K_FOREVER); - - if (newfd == NULL) { - /* dup() - just find lowest-numbered fd */ - ret = _find_fd_entry(); - } else { - /* dup2() - check if newfd is valid */ - if (_check_fd(*newfd) < 0) { - ret = -1; - } else { - if (fdtable[fd].vtable->close) { - (void)fdtable[fd].vtable->close(fdtable[fd].obj); - } - ret = *newfd; - } - } - - if (ret >= 0) { - /* Mark entry as used and initialize fields */ - if (newfd == NULL) { - (void)z_fd_ref(ret); - } - fdtable[ret] = fdtable[fd]; - k_mutex_init(&fdtable[ret].lock); - k_condvar_init(&fdtable[ret].cond); - } - - k_mutex_unlock(&fdtable_lock); - - return ret; -} - int zvfs_fstat(int fd, struct stat *buf) { if (_check_fd(fd) < 0) { diff --git a/lib/posix/options/Kconfig.fd_mgmt b/lib/posix/options/Kconfig.fd_mgmt index fee6f17848f65..329036ffbf891 100644 --- a/lib/posix/options/Kconfig.fd_mgmt +++ b/lib/posix/options/Kconfig.fd_mgmt @@ -5,8 +5,6 @@ menuconfig POSIX_FD_MGMT bool "POSIX file descriptor management [EXPERIMENTAL]" select EXPERIMENTAL - select FDTABLE - select REQUIRES_FULL_LIBC help Select 'y' here and Zephyr will provide implementations for the POSIX_FD_MGMT Option Group. This includes support for dup(), dup2(), fcntl(), fseeko(), ftello(), ftruncate(), diff --git a/lib/posix/options/fd_mgmt.c b/lib/posix/options/fd_mgmt.c index 923a133cf1f5a..c1f60aca8e490 100644 --- a/lib/posix/options/fd_mgmt.c +++ b/lib/posix/options/fd_mgmt.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -15,22 +14,10 @@ #include /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ -int zvfs_dup(int fd, int *newfd); int zvfs_fcntl(int fd, int cmd, va_list arg); -int zvfs_fileno(FILE *file); int zvfs_ftruncate(int fd, off_t length); off_t zvfs_lseek(int fd, off_t offset, int whence); -int dup(int fd) -{ - return zvfs_dup(fd, NULL); -} - -int dup2(int oldfd, int newfd) -{ - return zvfs_dup(oldfd, &newfd); -} - int fcntl(int fd, int cmd, ...) { int ret; @@ -46,30 +33,6 @@ int fcntl(int fd, int cmd, ...) FUNC_ALIAS(fcntl, _fcntl, int); #endif /* CONFIG_POSIX_FD_MGMT_ALIAS_FCNTL */ -int fseeko(FILE *file, off_t offset, int whence) -{ - int fd; - - fd = zvfs_fileno(file); - if (fd < 0) { - return -1; - } - - return zvfs_lseek(fd, offset, whence); -} - -off_t ftello(FILE *file) -{ - int fd; - - fd = zvfs_fileno(file); - if (fd < 0) { - return -1; - } - - return zvfs_lseek(fd, 0, SEEK_CUR); -} - int ftruncate(int fd, off_t length) { return zvfs_ftruncate(fd, length); From 1903cafbd595af5b032ad7064e29c09c199c38b3 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:06:52 +0200 Subject: [PATCH 162/187] Revert "doc: posix: mark posix signals supported with undefined behaviour" This reverts commit b10f1ca3a6faf58db10a57f2138802b2d7157f12. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- doc/services/portability/posix/aep/index.rst | 4 +-- .../portability/posix/option_groups/index.rst | 28 +++++++------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index b1fe34ee0d986..bfeb92853ed73 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -50,8 +50,8 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`POSIX_C_LANG_JUMP `, yes, :ref:`POSIX_C_LANG_SUPPORT `, yes, - :ref:`POSIX_DEVICE_IO `,yes, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` - :ref:`POSIX_SIGNALS `, yes, :kconfig:option:`CONFIG_POSIX_SIGNALS` :ref:`†` + :ref:`POSIX_DEVICE_IO `, yes, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` + :ref:`POSIX_SIGNALS `,, :kconfig:option:`CONFIG_POSIX_SIGNALS` :ref:`POSIX_SINGLE_PROCESS `, yes, :kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS` :ref:`XSI_THREADS_EXT `, yes, :kconfig:option:`CONFIG_XSI_THREADS_EXT` diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index f8e32b125ef83..cb7f7e64ce497 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -244,34 +244,26 @@ POSIX_SIGNALS Signal services are a basic mechanism within POSIX-based systems and are required for error and event handling. -.. note:: - As processes are not yet supported in Zephyr, the ISO C functions ``abort()``, ``signal()``, - and ``raise()``, as well as the other POSIX functions listed below, may exhibit undefined - behaviour. The POSIX functions ``kill()``, ``pause()``, ``sigaction()``, ``sigpending()``, - ``sigsuspend()``, and ``sigwait()`` are implemented to ensure that conformant applications can - link, but they are expected to fail, setting errno to ``ENOSYS`` - :ref:`†`. - .. csv-table:: POSIX_SIGNALS :header: API, Supported :widths: 50,10 - abort(),yes :ref:`†` - alarm(),yes :ref:`†` - kill(),yes :ref:`†` - pause(),yes :ref:`†` - raise(),yes :ref:`†` - sigaction(),yes :ref:`†` + abort(),yes + alarm(), + kill(), + pause(), + raise(), + sigaction(), sigaddset(),yes sigdelset(),yes sigemptyset(),yes sigfillset(),yes sigismember(),yes - signal(),yes :ref:`†` - sigpending(),yes :ref:`†` + signal(), + sigpending(), sigprocmask(),yes - sigsuspend(),yes :ref:`†` - sigwait(),yes :ref:`†` + sigsuspend(), + sigwait(), strsignal(),yes .. _posix_option_group_device_io: From 4742a5c929f3137c2898f28f45275b743a7ab6af Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:06:56 +0200 Subject: [PATCH 163/187] Revert "tests: posix: headers: add checks for posix signals option group" This reverts commit 308322e9b9a1430f334e074b335186db36a783ca. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- tests/posix/headers/src/signal_h.c | 65 +++++++++++++----------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/tests/posix/headers/src/signal_h.c b/tests/posix/headers/src/signal_h.c index 76cde3e592d91..35616e4a29e54 100644 --- a/tests/posix/headers/src/signal_h.c +++ b/tests/posix/headers/src/signal_h.c @@ -6,8 +6,6 @@ #include "_common.h" -#include - #ifdef CONFIG_POSIX_API #include #else @@ -21,17 +19,13 @@ */ ZTEST(posix_headers, test_signal_h) { - typedef void *(*my_sig_handler_t)(int signo); - - my_sig_handler_t handler; - - handler = SIG_DFL; - handler = SIG_ERR; - handler = SIG_IGN; + /* zassert_not_equal(-1, SIG_DFL); */ /* not implemented */ + /* zassert_not_equal(-1, SIG_ERR); */ /* not implemented */ /* zassert_not_equal(-1, SIG_HOLD); */ /* not implemented */ + /* zassert_not_equal(-1, SIG_IGN); */ /* not implemented */ zassert_not_equal((sig_atomic_t)-1, (sig_atomic_t)0); - zassert_not_equal((pid_t)-1, (pid_t)0); + /* zassert_not_equal((pid_t)-1, (pid_t)0); */ /* not implemented */ zassert_not_equal(-1, offsetof(struct sigevent, sigev_notify)); zassert_not_equal(-1, offsetof(struct sigevent, sigev_signo)); @@ -53,15 +47,6 @@ ZTEST(posix_headers, test_signal_h) zassert_not_equal(-1, SIG_UNBLOCK); zassert_not_equal(-1, SIG_SETMASK); - zassert_not_equal(-1, offsetof(struct sigaction, sa_handler)); - zassert_not_equal(-1, offsetof(struct sigaction, sa_mask)); - zassert_not_equal(-1, offsetof(struct sigaction, sa_flags)); - zassert_not_equal(-1, offsetof(struct sigaction, sa_sigaction)); - - zassert_not_equal(-1, offsetof(siginfo_t, si_signo)); - zassert_not_equal(-1, offsetof(siginfo_t, si_code)); - zassert_not_equal(-1, offsetof(siginfo_t, si_value)); - /* zassert_not_equal(-1, SA_NOCLDSTOP); */ /* not implemented */ /* zassert_not_equal(-1, SA_ONSTACK); */ /* not implemented */ /* zassert_not_equal(-1, SA_RESETHAND); */ /* not implemented */ @@ -132,11 +117,18 @@ ZTEST(posix_headers, test_signal_h) /* zassert_not_equal(-1, CLD_STOPPED); */ /* not implemented */ /* zassert_not_equal(-1, CLD_CONTINUED); */ /* not implemented */ - zassert_not_equal(-1, SI_USER); - zassert_not_equal(-1, SI_QUEUE); - zassert_not_equal(-1, SI_TIMER); - zassert_not_equal(-1, SI_ASYNCIO); - zassert_not_equal(-1, SI_MESGQ); + /* zassert_not_equal(-1, POLL_IN); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_OUT); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_MSG); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_ERR); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_PRI); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_HUP); */ /* not implemented */ + + /* zassert_not_equal(-1, SI_USER); */ /* not implemented */ + /* zassert_not_equal(-1, SI_QUEUE); */ /* not implemented */ + /* zassert_not_equal(-1, SI_TIMER); */ /* not implemented */ + /* zassert_not_equal(-1, SI_ASYNCIO); */ /* not implemented */ + /* zassert_not_equal(-1, SI_MESGQ); */ /* not implemented */ #ifdef CONFIG_POSIX_SIGNALS zassert_true(SIGRTMIN >= 0); @@ -166,40 +158,37 @@ ZTEST(posix_headers, test_signal_h) zassert_not_equal(-1, SIGXCPU); zassert_not_equal(-1, SIGXFSZ); zassert_not_equal(((sigset_t){.sig[0] = 0}).sig[0], ((sigset_t){.sig[0] = -1}).sig[0]); - zassert_not_null(abort); - zassert_not_null(alarm); - zassert_not_null(kill); - zassert_not_null(pause); - zassert_not_null(pthread_sigmask); - zassert_not_null(raise); - zassert_not_null(sigaction); - zassert_not_null(sigaddset); - zassert_not_null(sigdelset); zassert_not_null(sigemptyset); zassert_not_null(sigfillset); + zassert_not_null(sigaddset); + zassert_not_null(sigdelset); zassert_not_null(sigismember); - zassert_not_null(signal); - zassert_not_null(sigpending); - zassert_not_null(sigprocmask); - zassert_not_null(sigsuspend); - zassert_not_null(sigwait); zassert_not_null(strsignal); + zassert_not_null(sigprocmask); + zassert_not_null(pthread_sigmask); #endif /* CONFIG_POSIX_SIGNALS */ if (IS_ENABLED(CONFIG_POSIX_API)) { + /* zassert_not_null(kill); */ /* not implemented */ /* zassert_not_null(killpg); */ /* not implemented */ /* zassert_not_null(psiginfo); */ /* not implemented */ /* zassert_not_null(psignal); */ /* not implemented */ /* zassert_not_null(pthread_kill); */ /* not implemented */ + /* zassert_not_null(raise); */ /* not implemented */ + /* zassert_not_null(sigaction); */ /* not implemented */ /* zassert_not_null(sigaltstack); */ /* not implemented */ /* zassert_not_null(sighold); */ /* not implemented */ /* zassert_not_null(sigignore); */ /* not implemented */ /* zassert_not_null(siginterrupt); */ /* not implemented */ + /* zassert_not_null(signal); */ /* not implemented */ /* zassert_not_null(sigpause); */ /* not implemented */ + /* zassert_not_null(sigpending); */ /* not implemented */ /* zassert_not_null(sigqueue); */ /* not implemented */ /* zassert_not_null(sigrelse); */ /* not implemented */ /* zassert_not_null(sigset); */ /* not implemented */ + /* zassert_not_null(sigsuspend); */ /* not implemented */ /* zassert_not_null(sigtimedwait); */ /* not implemented */ + /* zassert_not_null(sigwait); */ /* not implemented */ /* zassert_not_null(sigwaitinfo); */ /* not implemented */ } } From 81f656bcb9fec459557226b4073b5a2eae692e39 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:00 +0200 Subject: [PATCH 164/187] Revert "posix: add stubs for signal.h functions that need process support" This reverts commit b2243af32d326fe641301063dc39e45258423299. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/posix/signal.h | 32 ----------------- lib/libc/Kconfig | 1 - lib/posix/options/Kconfig.signal | 7 ---- lib/posix/options/signal.c | 59 -------------------------------- 4 files changed, 99 deletions(-) diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 7a1efdbd449ce..165050f2ded92 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -77,16 +77,6 @@ typedef struct { #define SIG_UNBLOCK 2 #endif -#define SIG_DFL ((void *)0) -#define SIG_IGN ((void *)1) -#define SIG_ERR ((void *)-1) - -#define SI_USER 1 -#define SI_QUEUE 2 -#define SI_TIMER 3 -#define SI_ASYNCIO 4 -#define SI_MESGQ 5 - typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ union sigval { @@ -102,34 +92,12 @@ struct sigevent { int sigev_signo; }; -typedef struct { - int si_signo; - int si_code; - union sigval si_value; -} siginfo_t; - -struct sigaction { - void (*sa_handler)(int signno); - sigset_t sa_mask; - int sa_flags; - void (*sa_sigaction)(int signo, siginfo_t *info, void *context); -}; - -unsigned int alarm(unsigned int seconds); -int kill(pid_t pid, int sig); -int pause(void); -int raise(int signo); -int sigaction(int sig, const struct sigaction *ZRESTRICT act, struct sigaction *ZRESTRICT oact); -int sigpending(sigset_t *set); -int sigsuspend(const sigset_t *sigmask); -int sigwait(const sigset_t *ZRESTRICT set, int *ZRESTRICT signo); char *strsignal(int signum); int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); int sigismember(const sigset_t *set, int signo); -void (*signal(int signo, void (*)(int signo)))(int signo); int sigprocmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset); int pthread_sigmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset); diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 7a509fb06e594..6607f62c521f0 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -105,7 +105,6 @@ config NEWLIB_LIBC imply POSIX_FD_MGMT_ALIAS_LSEEK imply POSIX_FILE_SYSTEM_ALIAS_FSTAT imply POSIX_MULTI_PROCESS_ALIAS_GETPID - imply POSIX_SIGNALS_ALIAS_KILL help Build with newlib library. The newlib library is expected to be part of the SDK in this case. diff --git a/lib/posix/options/Kconfig.signal b/lib/posix/options/Kconfig.signal index 1e84a55de598d..4507302e3f32d 100644 --- a/lib/posix/options/Kconfig.signal +++ b/lib/posix/options/Kconfig.signal @@ -24,7 +24,6 @@ endif # POSIX_REALTIME_SIGNALS config POSIX_SIGNALS bool "POSIX signals [EXPERIMENTAL]" select EXPERIMENTAL - select POSIX_MULTI_PROCESS help Enable support for POSIX signals. @@ -37,12 +36,6 @@ config POSIX_SIGNAL_STRING_DESC Use full description for the strsignal API. Will use 256 bytes of ROM. -# These options are intended to be used for compatibility with external POSIX -# implementations such as those in Newlib or Picolibc. - -config POSIX_SIGNALS_ALIAS_KILL - bool - endif endmenu # "Signal support" diff --git a/lib/posix/options/signal.c b/lib/posix/options/signal.c index 84171fde0f07e..cb282f69bdc86 100644 --- a/lib/posix/options/signal.c +++ b/lib/posix/options/signal.c @@ -118,62 +118,3 @@ int sigprocmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset errno = ENOSYS; return -1; } - -/* - * The functions below are provided so that conformant POSIX applications and libraries can still - * link. - */ - -unsigned int alarm(unsigned int seconds) -{ - ARG_UNUSED(seconds); - return 0; -} - -int kill(pid_t pid, int sig) -{ - ARG_UNUSED(pid); - ARG_UNUSED(sig); - errno = ENOSYS; - return -1; -} -#ifdef CONFIG_POSIX_SIGNALS_ALIAS_KILL -FUNC_ALIAS(kill, _kill, int); -#endif /* CONFIG_POSIX_SIGNALS_ALIAS_KILL */ - -int pause(void) -{ - errno = ENOSYS; - return -1; -} - -int sigaction(int sig, const struct sigaction *ZRESTRICT act, struct sigaction *ZRESTRICT oact) -{ - ARG_UNUSED(sig); - ARG_UNUSED(act); - ARG_UNUSED(oact); - errno = ENOSYS; - return -1; -} - -int sigpending(sigset_t *set) -{ - ARG_UNUSED(set); - errno = ENOSYS; - return -1; -} - -int sigsuspend(const sigset_t *sigmask) -{ - ARG_UNUSED(sigmask); - errno = ENOSYS; - return -1; -} - -int sigwait(const sigset_t *ZRESTRICT set, int *ZRESTRICT sig) -{ - ARG_UNUSED(set); - ARG_UNUSED(sig); - errno = ENOSYS; - return -1; -} From 6638a95922a008f66f871144566143854a0d1867 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:06 +0200 Subject: [PATCH 165/187] Revert "posix: procN: add missing alias for getpid()" This reverts commit be086f174c9bd8c0b62d48e5ff08b2a483b2985d. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/posix/options/multi_process.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/posix/options/multi_process.c b/lib/posix/options/multi_process.c index ab697a66c0c72..221dc04ae1ad9 100644 --- a/lib/posix/options/multi_process.c +++ b/lib/posix/options/multi_process.c @@ -21,6 +21,3 @@ pid_t getpid(void) return 42; } -#ifdef CONFIG_POSIX_MULTI_PROCESS_ALIAS_GETPID -FUNC_ALIAS(getpid, _getpid, pid_t); -#endif /* CONFIG_POSIX_MULTI_PROCESS_ALIAS_GETPID */ From 5851d20509dd8cef65deefc2632367db3e835050 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:10 +0200 Subject: [PATCH 166/187] Revert "posix: kconfig: remove select y from non-user-selectable help" This reverts commit b82b5b0734c30490368e21627423f10036487343. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/posix/options/Kconfig.device_io | 10 +++++----- lib/posix/options/Kconfig.fd_mgmt | 6 +++--- lib/posix/options/Kconfig.fs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index f50165bd330ea..80447326b375e 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -27,27 +27,27 @@ if POSIX_DEVICE_IO config POSIX_DEVICE_IO_ALIAS_CLOSE bool help - When selected via Kconfig, Zephyr will provide an alias for close() as _close(). + Select 'y' here and Zephyr will provide an alias for close() as _close(). config POSIX_DEVICE_IO_ALIAS_OPEN bool help - When selected via Kconfig, Zephyr will provide an alias for open() as _open(). + Select 'y' here and Zephyr will provide an alias for open() as _open(). config POSIX_DEVICE_IO_ALIAS_READ bool help - When selected via Kconfig, Zephyr will provide an alias for read() as _read(). + Select 'y' here and Zephyr will provide an alias for read() as _read(). config POSIX_DEVICE_IO_ALIAS_WRITE bool help - When selected via Kconfig, Zephyr will provide an alias for write() as _write(). + Select 'y' here and Zephyr will provide an alias for write() as _write(). config POSIX_DEVICE_IO_STDIN_STDOUT_STDERR bool help - When selected via Kconfig, Zephyr will provide the stdin, stdout, and stderr variables. + Select 'y' here and Zephyr will provide the stdin, stdout, and stderr variables. Some libc's that implement the POSIX API may already have declared these variables. However, it should be noted that they are a part of POSIX and not a part of ISO C. diff --git a/lib/posix/options/Kconfig.fd_mgmt b/lib/posix/options/Kconfig.fd_mgmt index 329036ffbf891..ca16539560148 100644 --- a/lib/posix/options/Kconfig.fd_mgmt +++ b/lib/posix/options/Kconfig.fd_mgmt @@ -21,16 +21,16 @@ if POSIX_FD_MGMT config POSIX_FD_MGMT_ALIAS_FCNTL bool help - When selected via Kconfig, Zephyr will provide an alias for fcntl() as _fcntl(). + Select 'y' here and Zephyr will provide an alias for fcntl() as _fcntl(). config POSIX_FD_MGMT_ALIAS_FTRUNCATE bool help - When selected via Kconfig, Zephyr will provide an alias for ftruncate() as _ftruncate(). + Select 'y' here and Zephyr will provide an alias for ftruncate() as _ftruncate(). config POSIX_FD_MGMT_ALIAS_LSEEK bool help - When selected via Kconfig, Zephyr will provide an alias for lseek() as _lseek(). + Select 'y' here and Zephyr will provide an alias for lseek() as _lseek(). endif # POSIX_FD_MGMT diff --git a/lib/posix/options/Kconfig.fs b/lib/posix/options/Kconfig.fs index bc492e5dc7a03..663d706e3fb80 100644 --- a/lib/posix/options/Kconfig.fs +++ b/lib/posix/options/Kconfig.fs @@ -15,6 +15,6 @@ if POSIX_FILE_SYSTEM config POSIX_FILE_SYSTEM_ALIAS_FSTAT bool help - When selected via Kconfig, Zephyr will provide an alias for fstat() as _fstat(). + Select 'y' here and Zephyr will provide an alias for fstat() as _fstat(). endif # POSIX_FILE_SYSTEM From e4788dd7f131375dc115fa16783ae7a4fd74775c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:14 +0200 Subject: [PATCH 167/187] Revert "doc: posix: mark posix device io as complete" This reverts commit d9855da483226348a76dc4f0461fd9c9738c098d. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- doc/services/portability/posix/aep/index.rst | 2 +- .../portability/posix/option_groups/index.rst | 58 +++++++++---------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index bfeb92853ed73..aeb591f2ab0a4 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -50,7 +50,7 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`POSIX_C_LANG_JUMP `, yes, :ref:`POSIX_C_LANG_SUPPORT `, yes, - :ref:`POSIX_DEVICE_IO `, yes, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` + :ref:`POSIX_DEVICE_IO `,, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` :ref:`POSIX_SIGNALS `,, :kconfig:option:`CONFIG_POSIX_SIGNALS` :ref:`POSIX_SINGLE_PROCESS `, yes, :kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS` :ref:`XSI_THREADS_EXT `, yes, :kconfig:option:`CONFIG_XSI_THREADS_EXT` diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index cb7f7e64ce497..e67523ae3d7c5 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -271,10 +271,6 @@ required for error and event handling. POSIX_DEVICE_IO =============== -.. note:: - When using Newlib, Picolibc, or other C libraries conforming to the ISO C Standard, the - C89 components of the ``POSIX_DEVICE_IO`` Option Group are considered supported. - .. csv-table:: POSIX_DEVICE_IO :header: API, Supported :widths: 50,10 @@ -285,48 +281,48 @@ POSIX_DEVICE_IO FD_ZERO(),yes clearerr(),yes close(),yes - fclose(),yes - fdopen(), yes - feof(),yes - ferror(),yes - fflush(),yes - fgetc(),yes - fgets(),yes - fileno(), yes - fopen(),yes + fclose(), + fdopen(), + feof(), + ferror(), + fflush(), + fgetc(), + fgets(), + fileno(), + fopen(), fprintf(),yes fputc(),yes fputs(),yes - fread(),yes - freopen(),yes - fscanf(),yes + fread(), + freopen(), + fscanf(), fwrite(),yes - getc(),yes - getchar(),yes - gets(),yes + getc(), + getchar(), + gets(), open(),yes perror(),yes poll(),yes printf(),yes - pread(),yes - pselect(),yes + pread(), + pselect(), putc(),yes putchar(),yes puts(),yes - pwrite(),yes + pwrite(), read(),yes - scanf(),yes + scanf(), select(),yes - setbuf(),yes - setvbuf(),yes - stderr,yes - stdin,yes - stdout,yes - ungetc(),yes + setbuf(), + setvbuf(), + stderr, + stdin, + stdout, + ungetc(), vfprintf(),yes - vfscanf(),yes + vfscanf(), vprintf(),yes - vscanf(),yes + vscanf(), write(),yes .. _posix_option_group_barriers: From 0584df3dbd97ae6a149891f82236b0c062601ada Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:18 +0200 Subject: [PATCH 168/187] Revert "posix: device_io: use mode argument correctly in open()" This reverts commit 499a6339764b51f2ebde2081c33fc1936be9b8dd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/posix/fcntl.h | 9 +-- lib/posix/options/device_io.c | 23 +++----- lib/posix/options/fs.c | 75 ++++++++++++------------- tests/posix/fs/src/test_fs_dir.c | 2 +- tests/posix/fs/src/test_fs_file.c | 2 +- tests/posix/fs/src/test_fs_open_flags.c | 4 +- tests/posix/fs/src/test_fs_stat.c | 2 +- 7 files changed, 50 insertions(+), 67 deletions(-) diff --git a/include/zephyr/posix/fcntl.h b/include/zephyr/posix/fcntl.h index 9aeef0caa6fbc..9689d1ae8c3fb 100644 --- a/include/zephyr/posix/fcntl.h +++ b/include/zephyr/posix/fcntl.h @@ -8,13 +8,9 @@ #define ZEPHYR_POSIX_FCNTL_H_ #ifdef CONFIG_PICOLIBC -#define O_CREAT 0x0040 -#define O_TRUNC 0x0200 -#define O_APPEND 0x0400 +#define O_CREAT 0x0040 #else -#define O_APPEND 0x0008 -#define O_CREAT 0x0200 -#define O_TRUNC 0x0400 +#define O_CREAT 0x0200 #endif #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) @@ -23,6 +19,7 @@ #define O_WRONLY 01 #define O_RDWR 02 +#define O_APPEND 0x0400 #define O_EXCL 0x0800 #define O_NONBLOCK 0x4000 diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index 6fea22d01545d..a504545ba0346 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -17,28 +16,28 @@ int zvfs_close(int fd); FILE *zvfs_fdopen(int fd, const char *mode); int zvfs_fileno(FILE *file); -int zvfs_open(const char *name, int flags, int mode); +int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); void FD_CLR(int fd, struct zvfs_fd_set *fdset) { - return ZVFS_FD_CLR(fd, fdset); + return ZVFS_FD_CLR(fd, (struct zvfs_fd_set *)fdset); } int FD_ISSET(int fd, struct zvfs_fd_set *fdset) { - return ZVFS_FD_ISSET(fd, fdset); + return ZVFS_FD_ISSET(fd, (struct zvfs_fd_set *)fdset); } void FD_SET(int fd, struct zvfs_fd_set *fdset) { - ZVFS_FD_SET(fd, fdset); + ZVFS_FD_SET(fd, (struct zvfs_fd_set *)fdset); } void FD_ZERO(fd_set *fdset) { - ZVFS_FD_ZERO(fdset); + ZVFS_FD_ZERO((struct zvfs_fd_set *)fdset); } int close(int fd) @@ -61,16 +60,8 @@ int fileno(FILE *file) int open(const char *name, int flags, ...) { - int mode = 0; - va_list args; - - if ((flags & O_CREAT) != 0) { - va_start(args, flags); - mode = va_arg(args, int); - va_end(args); - } - - return zvfs_open(name, flags, mode); + /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ + return zvfs_open(name, flags); } #ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN FUNC_ALIAS(open, _open, int); diff --git a/lib/posix/options/fs.c b/lib/posix/options/fs.c index a9d07b73293b2..a8bf1fb620fcd 100644 --- a/lib/posix/options/fs.c +++ b/lib/posix/options/fs.c @@ -59,22 +59,37 @@ static inline void posix_fs_free_obj(struct posix_fs_desc *ptr) ptr->used = false; } -int zvfs_open(const char *name, int flags, int mode) +static int posix_mode_to_zephyr(int mf) +{ + int mode = (mf & O_CREAT) ? FS_O_CREATE : 0; + + mode |= (mf & O_APPEND) ? FS_O_APPEND : 0; + + switch (mf & O_ACCMODE) { + case O_RDONLY: + mode |= FS_O_READ; + break; + case O_WRONLY: + mode |= FS_O_WRITE; + break; + case O_RDWR: + mode |= FS_O_RDWR; + break; + default: + break; + } + + return mode; +} + +int zvfs_open(const char *name, int flags) { int rc, fd; struct posix_fs_desc *ptr = NULL; - int zflags = 0; - - if ((flags & O_ACCMODE) == O_RDONLY) { - zflags |= FS_O_READ; - } else if ((flags & O_ACCMODE) == O_WRONLY) { - zflags |= FS_O_WRITE; - } else if ((flags & O_ACCMODE) == O_RDWR) { - zflags |= FS_O_RDWR; - } + int zmode = posix_mode_to_zephyr(flags); - if ((flags & O_APPEND) != 0) { - zflags |= FS_O_APPEND; + if (zmode < 0) { + return zmode; } fd = zvfs_reserve_fd(); @@ -84,44 +99,24 @@ int zvfs_open(const char *name, int flags, int mode) ptr = posix_fs_alloc_obj(false); if (ptr == NULL) { - rc = -EMFILE; - goto out_err; + zvfs_free_fd(fd); + errno = EMFILE; + return -1; } fs_file_t_init(&ptr->file); - if (flags & O_CREAT) { - flags &= ~O_CREAT; + rc = fs_open(&ptr->file, name, zmode); - rc = fs_open(&ptr->file, name, FS_O_CREATE | (mode & O_ACCMODE)); - if (rc < 0) { - goto out_err; - } - rc = fs_close(&ptr->file); - if (rc < 0) { - goto out_err; - } - } - - rc = fs_open(&ptr->file, name, zflags); if (rc < 0) { - goto out_err; - } - - zvfs_finalize_fd(fd, ptr, &fs_fd_op_vtable); - - goto out; - -out_err: - if (ptr != NULL) { posix_fs_free_obj(ptr); + zvfs_free_fd(fd); + errno = -rc; + return -1; } - zvfs_free_fd(fd); - errno = -rc; - return -1; + zvfs_finalize_fd(fd, ptr, &fs_fd_op_vtable); -out: return fd; } diff --git a/tests/posix/fs/src/test_fs_dir.c b/tests/posix/fs/src/test_fs_dir.c index dd3a89c6dc577..b0908cb1586cb 100644 --- a/tests/posix/fs/src/test_fs_dir.c +++ b/tests/posix/fs/src/test_fs_dir.c @@ -27,7 +27,7 @@ static int test_mkdir(void) return res; } - res = open(TEST_DIR_FILE, O_CREAT | O_RDWR, 0770); + res = open(TEST_DIR_FILE, O_CREAT | O_RDWR); if (res < 0) { TC_PRINT("Failed opening file [%d]\n", res); diff --git a/tests/posix/fs/src/test_fs_file.c b/tests/posix/fs/src/test_fs_file.c index c6f2edd66895c..9614412a07a58 100644 --- a/tests/posix/fs/src/test_fs_file.c +++ b/tests/posix/fs/src/test_fs_file.c @@ -16,7 +16,7 @@ static int test_file_open(void) { int res; - res = open(TEST_FILE, O_CREAT | O_RDWR, 0660); + res = open(TEST_FILE, O_CREAT | O_RDWR); if (res < 0) { TC_ERROR("Failed opening file: %d, errno=%d\n", res, errno); /* FIXME: restructure tests as per #46897 */ diff --git a/tests/posix/fs/src/test_fs_open_flags.c b/tests/posix/fs/src/test_fs_open_flags.c index 7c35145343b75..1187b1c3e5757 100644 --- a/tests/posix/fs/src/test_fs_open_flags.c +++ b/tests/posix/fs/src/test_fs_open_flags.c @@ -60,7 +60,7 @@ static int test_file_open_flags(void) /* 2 Create file for read only, attempt to read, attempt to write */ TC_PRINT("Open on non-existent file, flags = O_CREAT | O_WRONLY\n"); - fd = open(THE_FILE, O_CREAT | O_WRONLY, 0440); + fd = open(THE_FILE, O_CREAT | O_WRONLY); if (fd < 0) { TC_PRINT("Expected success; fd = %d, errno = %d\n", fd, errno); return TC_FAIL; @@ -236,7 +236,7 @@ static int test_file_open_flags(void) TC_PRINT("Attempt write to file opened with O_APPEND | O_RDWR\n"); /* Clean start */ unlink(THE_FILE); - fd = open(THE_FILE, O_CREAT | O_WRONLY, 0440); + fd = open(THE_FILE, O_CREAT | O_WRONLY); if (fd < 0) { TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno); return TC_FAIL; diff --git a/tests/posix/fs/src/test_fs_stat.c b/tests/posix/fs/src/test_fs_stat.c index 0031596dcef15..14167d3f7756c 100644 --- a/tests/posix/fs/src/test_fs_stat.c +++ b/tests/posix/fs/src/test_fs_stat.c @@ -21,7 +21,7 @@ static void create_file(const char *filename, uint32_t size) { int fh; - fh = open(filename, O_CREAT | O_WRONLY, 0440); + fh = open(filename, O_CREAT | O_WRONLY); zassert(fh >= 0, "Failed creating test file"); uint8_t filling[FILL_SIZE]; From cfa37f4c18383edc1f62a64ac16610895591a045 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:21 +0200 Subject: [PATCH 169/187] Revert "posix: device_io: implement fileno()" This reverts commit 48dff5562cc62e2bdeb048ed777321cc8a42df2d. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 10 ---------- lib/posix/options/device_io.c | 6 ------ 2 files changed, 16 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 0c9131d7c39d0..acf1cf75a92b9 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -414,16 +414,6 @@ FILE *zvfs_fdopen(int fd, const char *mode) return (FILE *)&fdtable[fd]; } -int zvfs_fileno(FILE *file) -{ - if (!IS_ARRAY_ELEMENT(fdtable, file)) { - errno = EBADF; - return -1; - } - - return (struct fd_entry *)file - fdtable; -} - int zvfs_fstat(int fd, struct stat *buf) { if (_check_fd(fd) < 0) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index a504545ba0346..0de6293ca8469 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -15,7 +15,6 @@ /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); FILE *zvfs_fdopen(int fd, const char *mode); -int zvfs_fileno(FILE *file); int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); @@ -53,11 +52,6 @@ FILE *fdopen(int fd, const char *mode) return zvfs_fdopen(fd, mode); } -int fileno(FILE *file) -{ - return zvfs_fileno(file); -} - int open(const char *name, int flags, ...) { /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ From bd58694436944934bf993eb3c114d4a4c87266e9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:24 +0200 Subject: [PATCH 170/187] Revert "posix: device_io: implement fdopen()" This reverts commit 581a0f56e6f0b3d41b5eee5c165c657b3e95c4d2. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 11 ----------- lib/posix/options/device_io.c | 7 ------- 2 files changed, 18 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index acf1cf75a92b9..6edf98066e19c 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -403,17 +403,6 @@ int zvfs_close(int fd) return res; } -FILE *zvfs_fdopen(int fd, const char *mode) -{ - ARG_UNUSED(mode); - - if (_check_fd(fd) < 0) { - return NULL; - } - - return (FILE *)&fdtable[fd]; -} - int zvfs_fstat(int fd, struct stat *buf) { if (_check_fd(fd) < 0) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index 0de6293ca8469..d15b5da2a91ac 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -5,7 +5,6 @@ */ #include -#include #include #include @@ -14,7 +13,6 @@ /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); -FILE *zvfs_fdopen(int fd, const char *mode); int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); @@ -47,11 +45,6 @@ int close(int fd) FUNC_ALIAS(close, _close, int); #endif -FILE *fdopen(int fd, const char *mode) -{ - return zvfs_fdopen(fd, mode); -} - int open(const char *name, int flags, ...) { /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ From bb51dfe6a0a3df61d265f3e36896e904800f846a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:30 +0200 Subject: [PATCH 171/187] Revert "posix: device_io: implement pselect()" This reverts commit 305ec62a6b1fc2aee8ecb1a8c34f09492114ba28. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/socket_select.h | 7 ++----- include/zephyr/posix/sys/select.h | 2 -- include/zephyr/sys/fdtable.h | 2 +- lib/os/zvfs/zvfs_select.c | 12 +++++------- lib/posix/options/device_io.c | 13 +------------ tests/posix/headers/src/sys_select_h.c | 2 +- 6 files changed, 10 insertions(+), 28 deletions(-) diff --git a/include/zephyr/net/socket_select.h b/include/zephyr/net/socket_select.h index 3eaa9aacfcfe8..877bd863a6b82 100644 --- a/include/zephyr/net/socket_select.h +++ b/include/zephyr/net/socket_select.h @@ -51,12 +51,9 @@ typedef struct zvfs_fd_set zsock_fd_set; static inline int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds, zsock_fd_set *exceptfds, struct zsock_timeval *timeout) { - struct timespec to = { - .tv_sec = (timeout == NULL) ? 0 : timeout->tv_sec, - .tv_nsec = (long)((timeout == NULL) ? 0 : timeout->tv_usec * NSEC_PER_USEC)}; + struct timeval; - return zvfs_select(nfds, (struct zvfs_fd_set *)readfds, (struct zvfs_fd_set *)writefds, - (struct zvfs_fd_set *)exceptfds, (timeout == NULL) ? NULL : &to, NULL); + return zvfs_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout); } /** Number of file descriptors which can be added to zsock_fd_set */ diff --git a/include/zephyr/posix/sys/select.h b/include/zephyr/posix/sys/select.h index 78d900f5316b2..e10eeb237ee0d 100644 --- a/include/zephyr/posix/sys/select.h +++ b/include/zephyr/posix/sys/select.h @@ -20,8 +20,6 @@ extern "C" { struct timeval; -int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - const struct timespec *timeout, const void *sigmask); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *fdset); int FD_ISSET(int fd, fd_set *fdset); diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index 37b25d57c75eb..f9f48d9b55b71 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -223,7 +223,7 @@ struct timespec; __syscall int zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, struct zvfs_fd_set *ZRESTRICT writefds, struct zvfs_fd_set *ZRESTRICT errorfds, - const struct timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask); + const struct timeval *ZRESTRICT timeout); /** * Request codes for fd_op_vtable.ioctl(). diff --git a/lib/os/zvfs/zvfs_select.c b/lib/os/zvfs/zvfs_select.c index 2788e3c9318ff..36a8457db0fc8 100644 --- a/lib/os/zvfs/zvfs_select.c +++ b/lib/os/zvfs/zvfs_select.c @@ -77,7 +77,7 @@ void ZVFS_FD_SET(int fd, struct zvfs_fd_set *set) int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, struct zvfs_fd_set *ZRESTRICT writefds, struct zvfs_fd_set *ZRESTRICT exceptfds, - const struct timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask) + const struct timeval *ZRESTRICT timeout) { struct zvfs_pollfd pfds[CONFIG_ZVFS_POLL_MAX]; k_timeout_t poll_timeout; @@ -142,8 +142,7 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, if (timeout == NULL) { poll_timeout = K_FOREVER; } else { - poll_timeout = - K_USEC(timeout->tv_sec * USEC_PER_SEC + timeout->tv_nsec / NSEC_PER_USEC); + poll_timeout = K_USEC(timeout->tv_sec * USEC_PER_SEC + timeout->tv_usec); } res = zvfs_poll_internal(pfds, num_pfds, poll_timeout); @@ -221,11 +220,10 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, struct zvfs_fd_set *ZRESTRICT writefds, struct zvfs_fd_set *ZRESTRICT exceptfds, - const struct timespec *ZRESTRICT timeout, - const void *ZRESTRICT sigmask) + const struct timeval *ZRESTRICT timeout) { struct zvfs_fd_set *readfds_copy = NULL, *writefds_copy = NULL, *exceptfds_copy = NULL; - struct timespec *to = NULL; + struct timeval *to = NULL; int ret = -1; if (readfds) { @@ -263,7 +261,7 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } } - ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to, sigmask); + ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to); if (ret >= 0) { if (readfds_copy) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index d15b5da2a91ac..eaae1c69c79e1 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -71,12 +71,6 @@ ssize_t pread(int fd, void *buf, size_t count, off_t offset) return zvfs_read(fd, buf, count, (size_t *)&off); } -int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - const struct timespec *timeout, const void *sigmask) -{ - return zvfs_select(nfds, readfds, writefds, exceptfds, timeout, sigmask); -} - ssize_t pwrite(int fd, void *buf, size_t count, off_t offset) { size_t off = (size_t)offset; @@ -99,12 +93,7 @@ FUNC_ALIAS(read, _read, ssize_t); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - struct timespec to = { - .tv_sec = (timeout == NULL) ? 0 : timeout->tv_sec, - .tv_nsec = (long)((timeout == NULL) ? 0 : timeout->tv_usec * NSEC_PER_USEC)}; - - return zvfs_select(nfds, readfds, writefds, exceptfds, (timeout == NULL) ? NULL : &to, - NULL); + return zvfs_select(nfds, readfds, writefds, exceptfds, timeout); } ssize_t write(int fd, const void *buf, size_t sz) diff --git a/tests/posix/headers/src/sys_select_h.c b/tests/posix/headers/src/sys_select_h.c index ad1014c5b446d..49fd4dc8ed5f8 100644 --- a/tests/posix/headers/src/sys_select_h.c +++ b/tests/posix/headers/src/sys_select_h.c @@ -30,7 +30,7 @@ ZTEST(posix_headers, test_sys_select_h) FD_SET(0, &fds); FD_ZERO(&fds); - zassert_not_null(pselect); + /* zassert_not_null(pselect); */ /* not implemented */ zassert_not_null(select); } } From d1e52275b62bca3e43dce77735681fa9ecc8128f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:33 +0200 Subject: [PATCH 172/187] Revert "net: sockets: move select() implementation to zvfs" This reverts commit 49ac1912b29d858af6059901c2eb291e17e34a49. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/socket_select.h | 42 +++---- include/zephyr/posix/sys/select.h | 14 +-- include/zephyr/sys/fdtable.h | 19 +-- lib/os/zvfs/CMakeLists.txt | 1 - lib/os/zvfs/Kconfig | 5 - lib/posix/options/Kconfig.device_io | 1 - lib/posix/options/device_io.c | 24 +--- subsys/net/lib/sockets/CMakeLists.txt | 2 + subsys/net/lib/sockets/Kconfig | 1 - .../net/lib/sockets/sockets_select.c | 108 +++++++++--------- tests/posix/headers/prj.conf | 1 - tests/posix/headers/src/sys_select_h.c | 10 +- 12 files changed, 82 insertions(+), 146 deletions(-) rename lib/os/zvfs/zvfs_select.c => subsys/net/lib/sockets/sockets_select.c (60%) diff --git a/include/zephyr/net/socket_select.h b/include/zephyr/net/socket_select.h index 877bd863a6b82..5fca2950d6a59 100644 --- a/include/zephyr/net/socket_select.h +++ b/include/zephyr/net/socket_select.h @@ -19,18 +19,17 @@ * @{ */ -#include - #include #include -#include #ifdef __cplusplus extern "C" { #endif /** Socket file descriptor set. */ -typedef struct zvfs_fd_set zsock_fd_set; +typedef struct zsock_fd_set { + uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; +} zsock_fd_set; /** * @brief Legacy function to poll multiple sockets for events @@ -48,16 +47,13 @@ typedef struct zvfs_fd_set zsock_fd_set; * it may conflict with generic POSIX ``select()`` function). * @endrst */ -static inline int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds, - zsock_fd_set *exceptfds, struct zsock_timeval *timeout) -{ - struct timeval; - - return zvfs_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout); -} +__syscall int zsock_select(int nfds, zsock_fd_set *readfds, + zsock_fd_set *writefds, + zsock_fd_set *exceptfds, + struct zsock_timeval *timeout); /** Number of file descriptors which can be added to zsock_fd_set */ -#define ZSOCK_FD_SETSIZE ZVFS_FD_SETSIZE +#define ZSOCK_FD_SETSIZE (sizeof(((zsock_fd_set *)0)->bitset) * 8) /** * @brief Initialize (clear) fd_set @@ -71,10 +67,7 @@ static inline int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *wr * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline void ZSOCK_FD_ZERO(zsock_fd_set *set) -{ - ZVFS_FD_ZERO(set); -} +void ZSOCK_FD_ZERO(zsock_fd_set *set); /** * @brief Check whether socket is a member of fd_set @@ -88,10 +81,7 @@ static inline void ZSOCK_FD_ZERO(zsock_fd_set *set) * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set) -{ - return ZVFS_FD_ISSET(fd, set); -} +int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set); /** * @brief Remove socket from fd_set @@ -105,10 +95,7 @@ static inline int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set) * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline void ZSOCK_FD_CLR(int fd, zsock_fd_set *set) -{ - ZVFS_FD_CLR(fd, set); -} +void ZSOCK_FD_CLR(int fd, zsock_fd_set *set); /** * @brief Add socket to fd_set @@ -122,10 +109,7 @@ static inline void ZSOCK_FD_CLR(int fd, zsock_fd_set *set) * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline void ZSOCK_FD_SET(int fd, zsock_fd_set *set) -{ - ZVFS_FD_SET(fd, set); -} +void ZSOCK_FD_SET(int fd, zsock_fd_set *set); /** @cond INTERNAL_HIDDEN */ @@ -169,6 +153,8 @@ static inline void FD_SET(int fd, zsock_fd_set *set) } #endif +#include + /** * @} */ diff --git a/include/zephyr/posix/sys/select.h b/include/zephyr/posix/sys/select.h index e10eeb237ee0d..fc61c018e249f 100644 --- a/include/zephyr/posix/sys/select.h +++ b/include/zephyr/posix/sys/select.h @@ -13,18 +13,16 @@ extern "C" { #endif -#undef fd_set #define fd_set zsock_fd_set - -#define FD_SETSIZE ZVFS_FD_SETSIZE +#define FD_SETSIZE ZSOCK_FD_SETSIZE +#define FD_ZERO ZSOCK_FD_ZERO +#define FD_SET ZSOCK_FD_SET +#define FD_CLR ZSOCK_FD_CLR +#define FD_ISSET ZSOCK_FD_ISSET struct timeval; -int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); -void FD_CLR(int fd, fd_set *fdset); -int FD_ISSET(int fd, fd_set *fdset); -void FD_SET(int fd, fd_set *fdset); -void FD_ZERO(fd_set *fdset); +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); #ifdef __cplusplus } diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index f9f48d9b55b71..c2a6705ca9518 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -8,7 +8,6 @@ #include #include - /* FIXME: For native_posix ssize_t, off_t. */ #include #include @@ -208,23 +207,9 @@ struct zvfs_pollfd { __syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout); -struct zvfs_fd_set { +struct zsock_fd_set { uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; }; - -#define ZVFS_FD_SETSIZE (sizeof(((struct zvfs_fd_set *)0)->bitset) * 8) - -void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *fdset); -int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *fdset); -void ZVFS_FD_SET(int fd, struct zvfs_fd_set *fdset); -void ZVFS_FD_ZERO(struct zvfs_fd_set *fdset); - -struct timespec; -__syscall int zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, - struct zvfs_fd_set *ZRESTRICT writefds, - struct zvfs_fd_set *ZRESTRICT errorfds, - const struct timeval *ZRESTRICT timeout); - /** * Request codes for fd_op_vtable.ioctl(). * @@ -254,6 +239,4 @@ enum { } #endif -#include - #endif /* ZEPHYR_INCLUDE_SYS_FDTABLE_H_ */ diff --git a/lib/os/zvfs/CMakeLists.txt b/lib/os/zvfs/CMakeLists.txt index d855d1005efc6..ef0dde4513bed 100644 --- a/lib/os/zvfs/CMakeLists.txt +++ b/lib/os/zvfs/CMakeLists.txt @@ -3,4 +3,3 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_ZVFS_EVENTFD zvfs_eventfd.c) zephyr_library_sources_ifdef(CONFIG_ZVFS_POLL zvfs_poll.c) -zephyr_library_sources_ifdef(CONFIG_ZVFS_SELECT zvfs_select.c) diff --git a/lib/os/zvfs/Kconfig b/lib/os/zvfs/Kconfig index df107c24c626d..40cba2cd9c9f4 100644 --- a/lib/os/zvfs/Kconfig +++ b/lib/os/zvfs/Kconfig @@ -49,11 +49,6 @@ config ZVFS_POLL_MAX help Maximum number of entries supported for poll() call. -config ZVFS_SELECT - bool "ZVFS select" - help - Enable support for zvfs_select(). - endif # ZVFS_POLL endif # ZVFS diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 80447326b375e..9a4bbd60f4591 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -10,7 +10,6 @@ config POSIX_DEVICE_IO select REQUIRES_FULL_LIBC select ZVFS select ZVFS_POLL - select ZVFS_SELECT help Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index eaae1c69c79e1..7b638c84976e7 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -10,6 +10,7 @@ #include #include #include +#include /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); @@ -17,26 +18,6 @@ int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); -void FD_CLR(int fd, struct zvfs_fd_set *fdset) -{ - return ZVFS_FD_CLR(fd, (struct zvfs_fd_set *)fdset); -} - -int FD_ISSET(int fd, struct zvfs_fd_set *fdset) -{ - return ZVFS_FD_ISSET(fd, (struct zvfs_fd_set *)fdset); -} - -void FD_SET(int fd, struct zvfs_fd_set *fdset) -{ - ZVFS_FD_SET(fd, (struct zvfs_fd_set *)fdset); -} - -void FD_ZERO(fd_set *fdset) -{ - ZVFS_FD_ZERO((struct zvfs_fd_set *)fdset); -} - int close(int fd) { return zvfs_close(fd); @@ -93,7 +74,8 @@ FUNC_ALIAS(read, _read, ssize_t); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - return zvfs_select(nfds, readfds, writefds, exceptfds, timeout); + /* TODO: create zvfs_select() and dispatch to subsystems based on file type */ + return zsock_select(nfds, readfds, writefds, exceptfds, (struct zsock_timeval *)timeout); } ssize_t write(int fd, const void *buf, size_t sz) diff --git a/subsys/net/lib/sockets/CMakeLists.txt b/subsys/net/lib/sockets/CMakeLists.txt index 8e8b156260222..253cb4a182f8c 100644 --- a/subsys/net/lib/sockets/CMakeLists.txt +++ b/subsys/net/lib/sockets/CMakeLists.txt @@ -2,6 +2,7 @@ zephyr_syscall_header( ${ZEPHYR_BASE}/include/zephyr/net/socket.h + ${ZEPHYR_BASE}/include/zephyr/net/socket_select.h ) zephyr_library_include_directories(.) @@ -9,6 +10,7 @@ zephyr_library_include_directories(.) zephyr_library_sources( getaddrinfo.c sockets.c + sockets_select.c ) if(NOT CONFIG_NET_SOCKETS_OFFLOAD) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 43331d7141390..b767a05cba5ed 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -7,7 +7,6 @@ menuconfig NET_SOCKETS bool "BSD Sockets compatible API" select ZVFS select ZVFS_POLL - select ZVFS_SELECT help Provide BSD Sockets like API on top of native Zephyr networking API. diff --git a/lib/os/zvfs/zvfs_select.c b/subsys/net/lib/sockets/sockets_select.c similarity index 60% rename from lib/os/zvfs/zvfs_select.c rename to subsys/net/lib/sockets/sockets_select.c index 36a8457db0fc8..49d61a2d28c65 100644 --- a/lib/os/zvfs/zvfs_select.c +++ b/subsys/net/lib/sockets/sockets_select.c @@ -4,12 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include #include #include +#include "sockets_internal.h" /* Get size, in elements, of an array within a struct. */ #define STRUCT_MEMBER_ARRAY_SIZE(type, field) ARRAY_SIZE(((type *)0)->field) @@ -21,12 +20,7 @@ bit_mask = 1 << b_idx; \ } -/** Number of file descriptors which can be added to zsock_fd_set */ -#define ZVFS_FD_SETSIZE (sizeof(((struct zvfs_fd_set *)0)->bitset) * 8) - -int zvfs_poll_internal(struct zvfs_pollfd *fds, int nfds, k_timeout_t timeout); - -void ZVFS_FD_ZERO(struct zvfs_fd_set *set) +void ZSOCK_FD_ZERO(zsock_fd_set *set) { int i; @@ -35,11 +29,11 @@ void ZVFS_FD_ZERO(struct zvfs_fd_set *set) } } -int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *set) +int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set) { uint32_t word_idx, bit_mask; - if (fd < 0 || fd >= ZVFS_FD_SETSIZE) { + if (fd < 0 || fd >= ZSOCK_FD_SETSIZE) { return 0; } @@ -48,11 +42,11 @@ int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *set) return (set->bitset[word_idx] & bit_mask) != 0U; } -void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *set) +void ZSOCK_FD_CLR(int fd, zsock_fd_set *set) { uint32_t word_idx, bit_mask; - if (fd < 0 || fd >= ZVFS_FD_SETSIZE) { + if (fd < 0 || fd >= ZSOCK_FD_SETSIZE) { return; } @@ -61,11 +55,11 @@ void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *set) set->bitset[word_idx] &= ~bit_mask; } -void ZVFS_FD_SET(int fd, struct zvfs_fd_set *set) +void ZSOCK_FD_SET(int fd, zsock_fd_set *set) { uint32_t word_idx, bit_mask; - if (fd < 0 || fd >= ZVFS_FD_SETSIZE) { + if (fd < 0 || fd >= ZSOCK_FD_SETSIZE) { return; } @@ -74,19 +68,17 @@ void ZVFS_FD_SET(int fd, struct zvfs_fd_set *set) set->bitset[word_idx] |= bit_mask; } -int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, - struct zvfs_fd_set *ZRESTRICT writefds, - struct zvfs_fd_set *ZRESTRICT exceptfds, - const struct timeval *ZRESTRICT timeout) +int z_impl_zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds, + zsock_fd_set *exceptfds, struct zsock_timeval *timeout) { - struct zvfs_pollfd pfds[CONFIG_ZVFS_POLL_MAX]; + struct zsock_pollfd pfds[CONFIG_NET_SOCKETS_POLL_MAX]; k_timeout_t poll_timeout; int i, res; int num_pfds = 0; int num_selects = 0; int fd_no = 0; - for (i = 0; i < STRUCT_MEMBER_ARRAY_SIZE(struct zvfs_fd_set, bitset); i++) { + for (i = 0; i < STRUCT_MEMBER_ARRAY_SIZE(zsock_fd_set, bitset); i++) { uint32_t bit_mask = 1U; uint32_t read_mask = 0U, write_mask = 0U, except_mask = 0U; uint32_t ored_mask; @@ -119,15 +111,15 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (read_mask & bit_mask) { - events |= ZVFS_POLLIN; + events |= ZSOCK_POLLIN; } if (write_mask & bit_mask) { - events |= ZVFS_POLLOUT; + events |= ZSOCK_POLLOUT; } if (except_mask & bit_mask) { - events |= ZVFS_POLLPRI; + events |= ZSOCK_POLLPRI; } pfds[num_pfds].fd = fd_no; @@ -142,24 +134,25 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, if (timeout == NULL) { poll_timeout = K_FOREVER; } else { - poll_timeout = K_USEC(timeout->tv_sec * USEC_PER_SEC + timeout->tv_usec); + poll_timeout = + K_USEC(timeout->tv_sec * 1000000UL + timeout->tv_usec); } - res = zvfs_poll_internal(pfds, num_pfds, poll_timeout); + res = zsock_poll_internal(pfds, num_pfds, poll_timeout); if (res == -1) { return -1; } if (readfds != NULL) { - ZVFS_FD_ZERO(readfds); + ZSOCK_FD_ZERO(readfds); } if (writefds != NULL) { - ZVFS_FD_ZERO(writefds); + ZSOCK_FD_ZERO(writefds); } if (exceptfds != NULL) { - ZVFS_FD_ZERO(exceptfds); + ZSOCK_FD_ZERO(exceptfds); } for (i = 0; i < num_pfds && res > 0; i++) { @@ -176,21 +169,21 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, * So, unlike poll(), a single invalid fd aborts the entire * select(). */ - if (revents & ZVFS_POLLNVAL) { + if (revents & ZSOCK_POLLNVAL) { errno = EBADF; return -1; } - if (revents & ZVFS_POLLIN) { + if (revents & ZSOCK_POLLIN) { if (readfds != NULL) { - ZVFS_FD_SET(fd, readfds); + ZSOCK_FD_SET(fd, readfds); num_selects++; } } - if (revents & ZVFS_POLLOUT) { + if (revents & ZSOCK_POLLOUT) { if (writefds != NULL) { - ZVFS_FD_SET(fd, writefds); + ZSOCK_FD_SET(fd, writefds); num_selects++; } } @@ -198,14 +191,14 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, /* It's unclear if HUP/ERR belong here. At least not ignore * them. Zephyr doesn't use HUP and barely use ERR so far. */ - if (revents & (ZVFS_POLLPRI | ZVFS_POLLHUP | ZVFS_POLLERR)) { + if (revents & (ZSOCK_POLLPRI | ZSOCK_POLLHUP | ZSOCK_POLLERR)) { if (exceptfds != NULL) { - ZVFS_FD_SET(fd, exceptfds); + ZSOCK_FD_SET(fd, exceptfds); num_selects++; } if (writefds != NULL) { - ZVFS_FD_SET(fd, writefds); + ZSOCK_FD_SET(fd, writefds); num_selects++; } } @@ -217,18 +210,19 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } #ifdef CONFIG_USERSPACE -static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, - struct zvfs_fd_set *ZRESTRICT writefds, - struct zvfs_fd_set *ZRESTRICT exceptfds, - const struct timeval *ZRESTRICT timeout) +static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, + zsock_fd_set *writefds, + zsock_fd_set *exceptfds, + struct zsock_timeval *timeout) { - struct zvfs_fd_set *readfds_copy = NULL, *writefds_copy = NULL, *exceptfds_copy = NULL; - struct timeval *to = NULL; + zsock_fd_set *readfds_copy = NULL, *writefds_copy = NULL, + *exceptfds_copy = NULL; + struct zsock_timeval *timeval = NULL; int ret = -1; if (readfds) { - readfds_copy = - k_usermode_alloc_from_copy((void *)readfds, sizeof(struct zvfs_fd_set)); + readfds_copy = k_usermode_alloc_from_copy((void *)readfds, + sizeof(zsock_fd_set)); if (!readfds_copy) { errno = ENOMEM; goto out; @@ -236,8 +230,8 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (writefds) { - writefds_copy = - k_usermode_alloc_from_copy((void *)writefds, sizeof(struct zvfs_fd_set)); + writefds_copy = k_usermode_alloc_from_copy((void *)writefds, + sizeof(zsock_fd_set)); if (!writefds_copy) { errno = ENOMEM; goto out; @@ -245,8 +239,8 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (exceptfds) { - exceptfds_copy = - k_usermode_alloc_from_copy((void *)exceptfds, sizeof(struct zvfs_fd_set)); + exceptfds_copy = k_usermode_alloc_from_copy((void *)exceptfds, + sizeof(zsock_fd_set)); if (!exceptfds_copy) { errno = ENOMEM; goto out; @@ -254,39 +248,41 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (timeout) { - to = k_usermode_alloc_from_copy((void *)timeout, sizeof(*to)); - if (!to) { + timeval = k_usermode_alloc_from_copy((void *)timeout, + sizeof(struct zsock_timeval)); + if (!timeval) { errno = ENOMEM; goto out; } } - ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to); + ret = z_impl_zsock_select(nfds, readfds_copy, writefds_copy, + exceptfds_copy, timeval); if (ret >= 0) { if (readfds_copy) { k_usermode_to_copy((void *)readfds, readfds_copy, - sizeof(struct zvfs_fd_set)); + sizeof(zsock_fd_set)); } if (writefds_copy) { k_usermode_to_copy((void *)writefds, writefds_copy, - sizeof(struct zvfs_fd_set)); + sizeof(zsock_fd_set)); } if (exceptfds_copy) { k_usermode_to_copy((void *)exceptfds, exceptfds_copy, - sizeof(struct zvfs_fd_set)); + sizeof(zsock_fd_set)); } } out: - k_free(to); + k_free(timeval); k_free(readfds_copy); k_free(writefds_copy); k_free(exceptfds_copy); return ret; } -#include +#include #endif diff --git a/tests/posix/headers/prj.conf b/tests/posix/headers/prj.conf index e5c34983aeaf2..374baf4cbdfa6 100644 --- a/tests/posix/headers/prj.conf +++ b/tests/posix/headers/prj.conf @@ -22,4 +22,3 @@ CONFIG_POSIX_TIMERS=y CONFIG_POSIX_MESSAGE_PASSING=y CONFIG_EVENTFD=y CONFIG_POSIX_C_LIB_EXT=y -CONFIG_POSIX_DEVICE_IO=y diff --git a/tests/posix/headers/src/sys_select_h.c b/tests/posix/headers/src/sys_select_h.c index 49fd4dc8ed5f8..5cca45419712d 100644 --- a/tests/posix/headers/src/sys_select_h.c +++ b/tests/posix/headers/src/sys_select_h.c @@ -22,14 +22,12 @@ ZTEST(posix_headers, test_sys_select_h) fd_set fds = {0}; zassert_not_equal(-1, FD_SETSIZE); + FD_CLR(0, &fds); + FD_ISSET(0, &fds); + FD_SET(0, &fds); + FD_ZERO(&fds); if (IS_ENABLED(CONFIG_POSIX_DEVICE_IO)) { - - FD_CLR(0, &fds); - FD_ISSET(0, &fds); - FD_SET(0, &fds); - FD_ZERO(&fds); - /* zassert_not_null(pselect); */ /* not implemented */ zassert_not_null(select); } From 4e3b1a076e88890abec7565832410ce089089eea Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:33 +0200 Subject: [PATCH 173/187] Revert "net: sockets: move poll implementation to zvfs" This reverts commit 93973e2ead9bc1e8e1bcf05d46cc292a05b49fdd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/socket.h | 5 +- include/zephyr/net/socket_poll.h | 8 +- include/zephyr/sys/fdtable.h | 18 -- lib/os/CMakeLists.txt | 3 - lib/os/zvfs/CMakeLists.txt | 1 - lib/os/zvfs/Kconfig | 20 +- lib/os/zvfs/zvfs_poll.c | 212 ------------------ lib/posix/options/Kconfig.device_io | 3 +- lib/posix/options/device_io.c | 3 +- subsys/net/lib/sockets/Kconfig | 7 +- subsys/net/lib/sockets/sockets.c | 218 +++++++++++++++++++ subsys/tracing/ctf/tracing_ctf.h | 6 +- tests/net/lib/coap_client/src/stubs.c | 4 +- tests/net/lib/lwm2m/lwm2m_engine/prj.conf | 2 - tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c | 4 +- 15 files changed, 239 insertions(+), 275 deletions(-) delete mode 100644 lib/os/zvfs/zvfs_poll.c diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index a1df517d0f2eb..9af729faecd85 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -625,10 +625,7 @@ static inline int zsock_ioctl_wrapper(int sock, unsigned long request, ...) * it may conflict with generic POSIX ``poll()`` function). * @endrst */ -static inline int zsock_poll(struct zsock_pollfd *fds, int nfds, int timeout) -{ - return zvfs_poll(fds, nfds, timeout); -} +__syscall int zsock_poll(struct zsock_pollfd *fds, int nfds, int timeout); /** * @brief Get various socket options diff --git a/include/zephyr/net/socket_poll.h b/include/zephyr/net/socket_poll.h index 934ca3ce6f162..97e03804311ab 100644 --- a/include/zephyr/net/socket_poll.h +++ b/include/zephyr/net/socket_poll.h @@ -7,8 +7,6 @@ #ifndef ZEPHYR_INCLUDE_NET_SOCKET_POLL_H_ #define ZEPHYR_INCLUDE_NET_SOCKET_POLL_H_ -#include - /* Setting for pollfd to avoid circular inclusion */ /** @@ -27,7 +25,11 @@ extern "C" { * * An array of these descriptors is passed as an argument to poll(). */ -#define zsock_pollfd zvfs_pollfd +struct zsock_pollfd { + int fd; /**< Socket descriptor */ + short events; /**< Requested events */ + short revents; /**< Returned events */ +}; #ifdef __cplusplus } diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index c2a6705ca9518..785df8d42e0fc 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -27,13 +27,6 @@ #define ZVFS_MODE_IFLNK 0120000 #define ZVFS_MODE_IFSOCK 0140000 -#define ZVFS_POLLIN BIT(0) -#define ZVFS_POLLPRI BIT(1) -#define ZVFS_POLLOUT BIT(2) -#define ZVFS_POLLERR BIT(3) -#define ZVFS_POLLHUP BIT(4) -#define ZVFS_POLLNVAL BIT(5) - #ifdef __cplusplus extern "C" { #endif @@ -199,17 +192,6 @@ static inline int zvfs_fdtable_call_ioctl(const struct fd_op_vtable *vtable, voi return res; } -struct zvfs_pollfd { - int fd; - short events; - short revents; -}; - -__syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout); - -struct zsock_fd_set { - uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; -}; /** * Request codes for fd_op_vtable.ioctl(). * diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index 80f5f16f5d791..4ce50ad418292 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -12,9 +12,6 @@ zephyr_sources( ) zephyr_sources_ifdef(CONFIG_FDTABLE fdtable.c) -zephyr_syscall_header_ifdef(CONFIG_FDTABLE - ${ZEPHYR_BASE}/include/zephyr/sys/fdtable.h -) zephyr_sources_ifdef(CONFIG_CBPRINTF_COMPLETE cbprintf_complete.c) zephyr_sources_ifdef(CONFIG_CBPRINTF_NANO cbprintf_nano.c) diff --git a/lib/os/zvfs/CMakeLists.txt b/lib/os/zvfs/CMakeLists.txt index ef0dde4513bed..ca191a4d3ad7a 100644 --- a/lib/os/zvfs/CMakeLists.txt +++ b/lib/os/zvfs/CMakeLists.txt @@ -2,4 +2,3 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_ZVFS_EVENTFD zvfs_eventfd.c) -zephyr_library_sources_ifdef(CONFIG_ZVFS_POLL zvfs_poll.c) diff --git a/lib/os/zvfs/Kconfig b/lib/os/zvfs/Kconfig index 40cba2cd9c9f4..7f50ff52befc2 100644 --- a/lib/os/zvfs/Kconfig +++ b/lib/os/zvfs/Kconfig @@ -16,7 +16,7 @@ if ZVFS config ZVFS_EVENTFD bool "ZVFS event file descriptor support" - imply ZVFS_POLL + select POLL help Enable support for ZVFS event file descriptors. An eventfd can be used as an event wait/notify mechanism together with POSIX calls @@ -33,22 +33,4 @@ config ZVFS_EVENTFD_MAX endif # ZVFS_EVENTFD -config ZVFS_POLL - bool "ZVFS poll" - select POLL - help - Enable support for zvfs_poll(). - -if ZVFS_POLL - -config ZVFS_POLL_MAX - int "Max number of supported zvfs_poll() entries" - default 6 if WIFI_NM_WPA_SUPPLICANT - default 4 if SHELL_BACKEND_TELNET - default 3 - help - Maximum number of entries supported for poll() call. - -endif # ZVFS_POLL - endif # ZVFS diff --git a/lib/os/zvfs/zvfs_poll.c b/lib/os/zvfs/zvfs_poll.c deleted file mode 100644 index 45aec5cfb8d24..0000000000000 --- a/lib/os/zvfs/zvfs_poll.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2017-2018 Linaro Limited - * Copyright (c) 2021 Nordic Semiconductor - * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) -bool net_socket_is_tls(void *obj); -#else -#define net_socket_is_tls(obj) false -#endif - -int zvfs_poll_internal(struct zvfs_pollfd *fds, int nfds, k_timeout_t timeout) -{ - bool retry; - int ret = 0; - int i; - struct zvfs_pollfd *pfd; - struct k_poll_event poll_events[CONFIG_ZVFS_POLL_MAX]; - struct k_poll_event *pev; - struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); - const struct fd_op_vtable *vtable; - struct k_mutex *lock; - k_timepoint_t end; - bool offload = false; - const struct fd_op_vtable *offl_vtable = NULL; - void *offl_ctx = NULL; - - end = sys_timepoint_calc(timeout); - - pev = poll_events; - for (pfd = fds, i = nfds; i--; pfd++) { - void *ctx; - int result; - - /* Per POSIX, negative fd's are just ignored */ - if (pfd->fd < 0) { - continue; - } - - ctx = zvfs_get_fd_obj_and_vtable(pfd->fd, &vtable, &lock); - if (ctx == NULL) { - /* Will set POLLNVAL in return loop */ - continue; - } - - (void)k_mutex_lock(lock, K_FOREVER); - - result = zvfs_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_PREPARE, pfd, &pev, - pev_end); - if (result == -EALREADY) { - /* If POLL_PREPARE returned with EALREADY, it means - * it already detected that some socket is ready. In - * this case, we still perform a k_poll to pick up - * as many events as possible, but without any wait. - */ - timeout = K_NO_WAIT; - end = sys_timepoint_calc(timeout); - result = 0; - } else if (result == -EXDEV) { - /* If POLL_PREPARE returned EXDEV, it means - * it detected an offloaded socket. - * If offloaded socket is used with native TLS, the TLS - * wrapper for the offloaded poll will be used. - * In case the fds array contains a mixup of offloaded - * and non-offloaded sockets, the offloaded poll handler - * shall return an error. - */ - offload = true; - if (offl_vtable == NULL || net_socket_is_tls(ctx)) { - offl_vtable = vtable; - offl_ctx = ctx; - } - - result = 0; - } - - k_mutex_unlock(lock); - - if (result < 0) { - errno = -result; - return -1; - } - } - - if (offload) { - int poll_timeout; - - if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { - poll_timeout = SYS_FOREVER_MS; - } else { - poll_timeout = k_ticks_to_ms_floor32(timeout.ticks); - } - - return zvfs_fdtable_call_ioctl(offl_vtable, offl_ctx, ZFD_IOCTL_POLL_OFFLOAD, fds, - nfds, poll_timeout); - } - - timeout = sys_timepoint_timeout(end); - - do { - ret = k_poll(poll_events, pev - poll_events, timeout); - /* EAGAIN when timeout expired, EINTR when cancelled (i.e. EOF) */ - if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { - errno = -ret; - return -1; - } - - retry = false; - ret = 0; - - pev = poll_events; - for (pfd = fds, i = nfds; i--; pfd++) { - void *ctx; - int result; - - pfd->revents = 0; - - if (pfd->fd < 0) { - continue; - } - - ctx = zvfs_get_fd_obj_and_vtable(pfd->fd, &vtable, &lock); - if (ctx == NULL) { - pfd->revents = ZVFS_POLLNVAL; - ret++; - continue; - } - - (void)k_mutex_lock(lock, K_FOREVER); - - result = zvfs_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_UPDATE, pfd, - &pev); - k_mutex_unlock(lock); - - if (result == -EAGAIN) { - retry = true; - continue; - } else if (result != 0) { - errno = -result; - return -1; - } - - if (pfd->revents != 0) { - ret++; - } - } - - if (retry) { - if (ret > 0) { - break; - } - - timeout = sys_timepoint_timeout(end); - - if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { - break; - } - } - } while (retry); - - return ret; -} - -int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) -{ - k_timeout_t timeout; - - if (poll_timeout < 0) { - timeout = K_FOREVER; - } else { - timeout = K_MSEC(poll_timeout); - } - - return zvfs_poll_internal(fds, nfds, timeout); -} - -#ifdef CONFIG_USERSPACE -static inline int z_vrfy_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int timeout) -{ - struct zvfs_pollfd *fds_copy; - size_t fds_size; - int ret; - - /* Copy fds array from user mode */ - if (size_mul_overflow(nfds, sizeof(struct zvfs_pollfd), &fds_size)) { - errno = EFAULT; - return -1; - } - fds_copy = k_usermode_alloc_from_copy((void *)fds, fds_size); - if (!fds_copy) { - errno = ENOMEM; - return -1; - } - - ret = z_impl_zvfs_poll(fds_copy, nfds, timeout); - - if (ret >= 0) { - k_usermode_to_copy((void *)fds, fds_copy, fds_size); - } - k_free(fds_copy); - - return ret; -} -#include -#endif diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 9a4bbd60f4591..11a611691c945 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -6,10 +6,9 @@ menu "POSIX device I/O" config POSIX_DEVICE_IO bool "POSIX device I/O [EXPERIMENTAL]" + select FDTABLE select EXPERIMENTAL select REQUIRES_FULL_LIBC - select ZVFS - select ZVFS_POLL help Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index 7b638c84976e7..e2c7510d7ad87 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -37,7 +37,8 @@ FUNC_ALIAS(open, _open, int); int poll(struct pollfd *fds, int nfds, int timeout) { - return zvfs_poll(fds, nfds, timeout); + /* TODO: create zvfs_poll() and dispatch to subsystems based on file type */ + return zsock_poll(fds, nfds, timeout); } ssize_t pread(int fd, void *buf, size_t count, off_t offset) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index b767a05cba5ed..2fe534678fa1c 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -5,8 +5,7 @@ menuconfig NET_SOCKETS bool "BSD Sockets compatible API" - select ZVFS - select ZVFS_POLL + select FDTABLE help Provide BSD Sockets like API on top of native Zephyr networking API. @@ -48,7 +47,9 @@ config NET_SOCKETS_POSIX_NAMES config NET_SOCKETS_POLL_MAX int "Max number of supported poll() entries" - default ZVFS_POLL_MAX + default 6 if WIFI_NM_WPA_SUPPLICANT + default 4 if SHELL_BACKEND_TELNET + default 3 help Maximum number of entries supported for poll() call. diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index b78e1479222a2..88d8a3d091706 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2306,6 +2306,224 @@ static int zsock_poll_update_ctx(struct net_context *ctx, return 0; } +static inline int time_left(uint32_t start, uint32_t timeout) +{ + uint32_t elapsed = k_uptime_get_32() - start; + + return timeout - elapsed; +} + +int zsock_poll_internal(struct zsock_pollfd *fds, int nfds, k_timeout_t timeout) +{ + bool retry; + int ret = 0; + int i; + struct zsock_pollfd *pfd; + struct k_poll_event poll_events[CONFIG_NET_SOCKETS_POLL_MAX]; + struct k_poll_event *pev; + struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); + const struct fd_op_vtable *vtable; + struct k_mutex *lock; + k_timepoint_t end; + bool offload = false; + const struct fd_op_vtable *offl_vtable = NULL; + void *offl_ctx = NULL; + + end = sys_timepoint_calc(timeout); + + pev = poll_events; + for (pfd = fds, i = nfds; i--; pfd++) { + void *ctx; + int result; + + /* Per POSIX, negative fd's are just ignored */ + if (pfd->fd < 0) { + continue; + } + + ctx = get_sock_vtable(pfd->fd, + (const struct socket_op_vtable **)&vtable, + &lock); + if (ctx == NULL) { + /* Will set POLLNVAL in return loop */ + continue; + } + + (void)k_mutex_lock(lock, K_FOREVER); + + result = zvfs_fdtable_call_ioctl(vtable, ctx, + ZFD_IOCTL_POLL_PREPARE, + pfd, &pev, pev_end); + if (result == -EALREADY) { + /* If POLL_PREPARE returned with EALREADY, it means + * it already detected that some socket is ready. In + * this case, we still perform a k_poll to pick up + * as many events as possible, but without any wait. + */ + timeout = K_NO_WAIT; + end = sys_timepoint_calc(timeout); + result = 0; + } else if (result == -EXDEV) { + /* If POLL_PREPARE returned EXDEV, it means + * it detected an offloaded socket. + * If offloaded socket is used with native TLS, the TLS + * wrapper for the offloaded poll will be used. + * In case the fds array contains a mixup of offloaded + * and non-offloaded sockets, the offloaded poll handler + * shall return an error. + */ + offload = true; + if (offl_vtable == NULL || net_socket_is_tls(ctx)) { + offl_vtable = vtable; + offl_ctx = ctx; + } + + result = 0; + } + + k_mutex_unlock(lock); + + if (result < 0) { + errno = -result; + return -1; + } + } + + if (offload) { + int poll_timeout; + + if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { + poll_timeout = SYS_FOREVER_MS; + } else { + poll_timeout = k_ticks_to_ms_floor32(timeout.ticks); + } + + return zvfs_fdtable_call_ioctl(offl_vtable, offl_ctx, + ZFD_IOCTL_POLL_OFFLOAD, + fds, nfds, poll_timeout); + } + + timeout = sys_timepoint_timeout(end); + + do { + ret = k_poll(poll_events, pev - poll_events, timeout); + /* EAGAIN when timeout expired, EINTR when cancelled (i.e. EOF) */ + if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { + errno = -ret; + return -1; + } + + retry = false; + ret = 0; + + pev = poll_events; + for (pfd = fds, i = nfds; i--; pfd++) { + void *ctx; + int result; + + pfd->revents = 0; + + if (pfd->fd < 0) { + continue; + } + + ctx = get_sock_vtable( + pfd->fd, + (const struct socket_op_vtable **)&vtable, + &lock); + if (ctx == NULL) { + pfd->revents = ZSOCK_POLLNVAL; + ret++; + continue; + } + + (void)k_mutex_lock(lock, K_FOREVER); + + result = zvfs_fdtable_call_ioctl(vtable, ctx, + ZFD_IOCTL_POLL_UPDATE, + pfd, &pev); + k_mutex_unlock(lock); + + if (result == -EAGAIN) { + retry = true; + continue; + } else if (result != 0) { + errno = -result; + return -1; + } + + if (pfd->revents != 0) { + ret++; + } + } + + if (retry) { + if (ret > 0) { + break; + } + + timeout = sys_timepoint_timeout(end); + + if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { + break; + } + } + } while (retry); + + return ret; +} + +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) +{ + k_timeout_t timeout; + int ret; + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(socket, poll, fds, nfds, poll_timeout); + + if (poll_timeout < 0) { + timeout = K_FOREVER; + } else { + timeout = K_MSEC(poll_timeout); + } + + ret = zsock_poll_internal(fds, nfds, timeout); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(socket, poll, fds, nfds, + ret < 0 ? -errno : ret); + return ret; +} + +#ifdef CONFIG_USERSPACE +static inline int z_vrfy_zsock_poll(struct zsock_pollfd *fds, + int nfds, int timeout) +{ + struct zsock_pollfd *fds_copy; + size_t fds_size; + int ret; + + /* Copy fds array from user mode */ + if (size_mul_overflow(nfds, sizeof(struct zsock_pollfd), &fds_size)) { + errno = EFAULT; + return -1; + } + fds_copy = k_usermode_alloc_from_copy((void *)fds, fds_size); + if (!fds_copy) { + errno = ENOMEM; + return -1; + } + + ret = z_impl_zsock_poll(fds_copy, nfds, timeout); + + if (ret >= 0) { + k_usermode_to_copy((void *)fds, fds_copy, fds_size); + } + k_free(fds_copy); + + return ret; +} +#include +#endif + int z_impl_zsock_inet_pton(sa_family_t family, const char *src, void *dst) { if (net_addr_pton(family, src, dst) == 0) { diff --git a/subsys/tracing/ctf/tracing_ctf.h b/subsys/tracing/ctf/tracing_ctf.h index 53eb097d07921..2756e6e8f5d1b 100644 --- a/subsys/tracing/ctf/tracing_ctf.h +++ b/subsys/tracing/ctf/tracing_ctf.h @@ -521,7 +521,7 @@ void sys_trace_k_event_init(struct k_event *event); */ struct sockaddr; struct msghdr; -struct zvfs_pollfd; +struct zsock_pollfd; void sys_trace_socket_init(int sock, int family, int type, int proto); void sys_trace_socket_close_enter(int sock); @@ -552,8 +552,8 @@ void sys_trace_socket_fcntl_enter(int sock, int cmd, int flags); void sys_trace_socket_fcntl_exit(int sock, int ret); void sys_trace_socket_ioctl_enter(int sock, int req); void sys_trace_socket_ioctl_exit(int sock, int ret); -void sys_trace_socket_poll_enter(const struct zvfs_pollfd *fds, int nfds, int timeout); -void sys_trace_socket_poll_exit(const struct zvfs_pollfd *fds, int nfds, int ret); +void sys_trace_socket_poll_enter(const struct zsock_pollfd *fds, int nfds, int timeout); +void sys_trace_socket_poll_exit(const struct zsock_pollfd *fds, int nfds, int ret); void sys_trace_socket_getsockopt_enter(int sock, int level, int optname); void sys_trace_socket_getsockopt_exit(int sock, int level, int optname, void *optval, size_t optlen, int ret); diff --git a/tests/net/lib/coap_client/src/stubs.c b/tests/net/lib/coap_client/src/stubs.c index 8fd41ef7e7258..13effd8f91b91 100644 --- a/tests/net/lib/coap_client/src/stubs.c +++ b/tests/net/lib/coap_client/src/stubs.c @@ -16,7 +16,7 @@ DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, const struct sockaddr *, socklen_t); -struct zvfs_pollfd { +struct zsock_pollfd { int fd; short events; short revents; @@ -39,7 +39,7 @@ int z_impl_zsock_socket(int family, int type, int proto) return 0; } -int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) { LOG_INF("Polling, events %d", my_events); k_sleep(K_MSEC(10)); diff --git a/tests/net/lib/lwm2m/lwm2m_engine/prj.conf b/tests/net/lib/lwm2m/lwm2m_engine/prj.conf index 4dd0a80c1f2d2..5d331d20c3312 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_engine/prj.conf @@ -1,5 +1,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=5120 CONFIG_MP_MAX_NUM_CPUS=1 - -CONFIG_ZVFS=y diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 953d4b72f2577..13b0e38e8e6e0 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -54,7 +54,7 @@ sys_slist_t *lwm2m_obs_obj_path_list(void) static sys_slist_t engine_obj_inst_list = SYS_SLIST_STATIC_INIT(&engine_obj_inst_list); sys_slist_t *lwm2m_engine_obj_inst_list(void) { return &engine_obj_inst_list; } -struct zvfs_pollfd { +struct zsock_pollfd { int fd; short events; short revents; @@ -123,7 +123,7 @@ ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, return -1; } -int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) { k_sleep(K_MSEC(1)); fds->revents = my_events; From 432e3b8e98705a4f31ff5a05a40700ea0069e2e1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:40 +0200 Subject: [PATCH 174/187] Revert "posix: device_io: implement pread() and pwrite()" This reverts commit 2d729665162a21cf0bb5e5dc2f6ab36880e09ddd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 54 +++++++++-------------------------- lib/posix/options/device_io.c | 32 +++------------------ 2 files changed, 17 insertions(+), 69 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 6edf98066e19c..f65b7dc1ae294 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -308,21 +308,9 @@ int zvfs_alloc_fd(void *obj, const struct fd_op_vtable *vtable) return fd; } -static bool supports_pread_pwrite(uint32_t mode) +static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write) { - switch (mode & ZVFS_MODE_IFMT) { - case ZVFS_MODE_IFSHM: - return true; - default: - return false; - } -} - -static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write, const size_t *from_offset) -{ - bool prw; ssize_t res; - const size_t *off; if (_check_fd(fd) < 0) { return -1; @@ -330,40 +318,24 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write, const size_t (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); - prw = supports_pread_pwrite(fdtable[fd].mode); - if (from_offset != NULL && !prw) { - /* - * Seekable file types should support pread() / pwrite() and per-fd offset passing. - * Otherwise, it's a bug. - */ - errno = ENOTSUP; - res = -1; - goto unlock; - } - - /* If there is no specified from_offset, then use the current offset of the fd */ - off = (from_offset == NULL) ? &fdtable[fd].offset : from_offset; - if (is_write) { - if (fdtable[fd].vtable->write_offs == NULL) { + if (fdtable[fd].vtable->write_offset == NULL) { res = -1; errno = EIO; } else { - res = fdtable[fd].vtable->write_offs(fdtable[fd].obj, buf, sz, *off); + res = fdtable[fd].vtable->write_offset(fdtable[fd].obj, buf, sz, + fdtable[fd].offset); } } else { - if (fdtable[fd].vtable->read_offs == NULL) { + if (fdtable[fd].vtable->read == NULL) { res = -1; errno = EIO; } else { - res = fdtable[fd].vtable->read_offs(fdtable[fd].obj, buf, sz, *off); + res = fdtable[fd].vtable->read_offset(fdtable[fd].obj, buf, sz, + fdtable[fd].offset); } } - if (res > 0 && prw && from_offset == NULL) { - /* - * only update the fd offset when from_offset is not specified - * See pread() / pwrite() - */ + if (res > 0) { fdtable[fd].offset += res; } @@ -373,14 +345,14 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write, const size_t return res; } -ssize_t zvfs_read(int fd, void *buf, size_t sz, const size_t *from_offset) +ssize_t zvfs_read(int fd, void *buf, size_t sz) { - return zvfs_rw(fd, buf, sz, false, from_offset); + return zvfs_rw(fd, buf, sz, false); } -ssize_t zvfs_write(int fd, const void *buf, size_t sz, const size_t *from_offset) +ssize_t zvfs_write(int fd, const void *buf, size_t sz) { - return zvfs_rw(fd, (void *)buf, sz, true, from_offset); + return zvfs_rw(fd, (void *)buf, sz, true); } int zvfs_close(int fd) @@ -522,7 +494,7 @@ static ssize_t stdinout_read_vmeth(void *obj, void *buffer, size_t count) static ssize_t stdinout_write_vmeth(void *obj, const void *buffer, size_t count) { #if defined(CONFIG_BOARD_NATIVE_POSIX) - return zvfs_write(1, buffer, count, NULL); + return zvfs_write(1, buffer, count); #elif defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_ARCMWDT_LIBC) return z_impl_zephyr_write_stdout(buffer, count); #else diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index e2c7510d7ad87..585dc7000c2be 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -15,8 +15,8 @@ /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); int zvfs_open(const char *name, int flags); -ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); -ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); +ssize_t zvfs_read(int fd, void *buf, size_t sz); +ssize_t zvfs_write(int fd, const void *buf, size_t sz); int close(int fd) { @@ -41,33 +41,9 @@ int poll(struct pollfd *fds, int nfds, int timeout) return zsock_poll(fds, nfds, timeout); } -ssize_t pread(int fd, void *buf, size_t count, off_t offset) -{ - size_t off = (size_t)offset; - - if (offset < 0) { - errno = EINVAL; - return -1; - } - - return zvfs_read(fd, buf, count, (size_t *)&off); -} - -ssize_t pwrite(int fd, void *buf, size_t count, off_t offset) -{ - size_t off = (size_t)offset; - - if (offset < 0) { - errno = EINVAL; - return -1; - } - - return zvfs_write(fd, buf, count, (size_t *)&off); -} - ssize_t read(int fd, void *buf, size_t sz) { - return zvfs_read(fd, buf, sz, NULL); + return zvfs_read(fd, buf, sz); } #ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_READ FUNC_ALIAS(read, _read, ssize_t); @@ -81,7 +57,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc ssize_t write(int fd, const void *buf, size_t sz) { - return zvfs_write(fd, buf, sz, NULL); + return zvfs_write(fd, buf, sz); } #ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE FUNC_ALIAS(write, _write, ssize_t); From 16c5b8d2edea7133b65840310157ad2822a14701 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:44 +0200 Subject: [PATCH 175/187] Revert "posix: device_io: provide stdin, stdout, stderr variables" This reverts commit 86b92934cc6c06a4080c6422269b815ac74c0aea. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 7 ------- lib/posix/options/Kconfig.device_io | 8 -------- 2 files changed, 15 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index f65b7dc1ae294..3bd22413c8e4a 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -14,7 +14,6 @@ */ #include -#include #include #include @@ -73,12 +72,6 @@ static struct fd_entry fdtable[CONFIG_ZVFS_OPEN_MAX] = { #endif }; -#ifdef CONFIG_POSIX_DEVICE_IO_STDIN_STDOUT_STDERR -FILE *stdin = &fdtable[0]; -FILE *stdout = &fdtable[1]; -FILE *stderr = &fdtable[2]; -#endif - static K_MUTEX_DEFINE(fdtable_lock); static int z_fd_ref(int fd) diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 11a611691c945..0999a4462e2d2 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -42,14 +42,6 @@ config POSIX_DEVICE_IO_ALIAS_WRITE help Select 'y' here and Zephyr will provide an alias for write() as _write(). -config POSIX_DEVICE_IO_STDIN_STDOUT_STDERR - bool - help - Select 'y' here and Zephyr will provide the stdin, stdout, and stderr variables. - - Some libc's that implement the POSIX API may already have declared these variables. - However, it should be noted that they are a part of POSIX and not a part of ISO C. - endif # POSIX_DEVICE_IO config POSIX_OPEN_MAX From 7acffbae1dcc5d99918140f9adde8e505c83592d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:47 +0200 Subject: [PATCH 176/187] Revert "posix: device_io: require a full libc for c89 functions" This reverts commit 6f62292d42883a221c717cdaf99f59efbe69fa52. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/posix/options/Kconfig.device_io | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 0999a4462e2d2..9cfbd453102bc 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -8,7 +8,6 @@ config POSIX_DEVICE_IO bool "POSIX device I/O [EXPERIMENTAL]" select FDTABLE select EXPERIMENTAL - select REQUIRES_FULL_LIBC help Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), From dd7409dc8d2d00dac5aee32b320d876bf2680e32 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:51 +0200 Subject: [PATCH 177/187] Revert "fdtable: read, write, close: only execute methods if non-NULL" This reverts commit a9a909c558c8c2069742aeee55aba831740826cd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 72 ++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 3bd22413c8e4a..9594afdd8cd6c 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -301,7 +301,7 @@ int zvfs_alloc_fd(void *obj, const struct fd_op_vtable *vtable) return fd; } -static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write) +ssize_t zvfs_read(int fd, void *buf, size_t sz) { ssize_t res; @@ -310,57 +310,63 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write) } (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); - - if (is_write) { - if (fdtable[fd].vtable->write_offset == NULL) { - res = -1; - errno = EIO; - } else { - res = fdtable[fd].vtable->write_offset(fdtable[fd].obj, buf, sz, - fdtable[fd].offset); - } - } else { - if (fdtable[fd].vtable->read == NULL) { - res = -1; - errno = EIO; - } else { - res = fdtable[fd].vtable->read_offset(fdtable[fd].obj, buf, sz, - fdtable[fd].offset); - } - } + res = fdtable[fd].vtable->read_offs(fdtable[fd].obj, buf, sz, fdtable[fd].offset); if (res > 0) { - fdtable[fd].offset += res; + switch (fdtable[fd].mode & ZVFS_MODE_IFMT) { + case ZVFS_MODE_IFDIR: + case ZVFS_MODE_IFBLK: + case ZVFS_MODE_IFSHM: + case ZVFS_MODE_IFREG: + fdtable[fd].offset += res; + break; + default: + break; + } } - -unlock: k_mutex_unlock(&fdtable[fd].lock); return res; } -ssize_t zvfs_read(int fd, void *buf, size_t sz) -{ - return zvfs_rw(fd, buf, sz, false); -} - ssize_t zvfs_write(int fd, const void *buf, size_t sz) { - return zvfs_rw(fd, (void *)buf, sz, true); + ssize_t res; + + if (_check_fd(fd) < 0) { + return -1; + } + + (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); + res = fdtable[fd].vtable->write_offs(fdtable[fd].obj, buf, sz, fdtable[fd].offset); + if (res > 0) { + switch (fdtable[fd].mode & ZVFS_MODE_IFMT) { + case ZVFS_MODE_IFDIR: + case ZVFS_MODE_IFBLK: + case ZVFS_MODE_IFSHM: + case ZVFS_MODE_IFREG: + fdtable[fd].offset += res; + break; + default: + break; + } + } + k_mutex_unlock(&fdtable[fd].lock); + + return res; } int zvfs_close(int fd) { - int res = 0; + int res; if (_check_fd(fd) < 0) { return -1; } (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); - if (fdtable[fd].vtable->close != NULL) { - /* close() is optional - e.g. stdinout_fd_op_vtable */ - res = fdtable[fd].vtable->close(fdtable[fd].obj); - } + + res = fdtable[fd].vtable->close(fdtable[fd].obj); + k_mutex_unlock(&fdtable[fd].lock); zvfs_free_fd(fd); From 3412cf1957a22db630bf04b550e67d0cb2c6df97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 1 Jul 2024 16:51:12 +0200 Subject: [PATCH 178/187] doc: release: Add highlights of Zephyr 3.7 release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces a high-level summary of the most notable changes in 3.7. This also tries to capture the most useful changes since previous LTS. Signed-off-by: Benjamin Cabé --- doc/releases/release-notes-3.7.rst | 57 ++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 44ba97740a98a..7646f82ec83f7 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -7,18 +7,69 @@ Zephyr 3.7.0 (Working Draft) We are pleased to announce the release of Zephyr version 3.7.0. +This release is the last non-maintenance 3.x release and, as such, will be the next +:ref:`Long Term Support (LTS) release `. + Major enhancements with this release include: -* A new, completely overhauled hardware model has been introduced. This changes - the way both SoCs and boards are named, defined and constructed in Zephyr. +* A new, completely overhauled hardware model has been introduced. This change the way both SoCs and + boards are named, defined and constructed in Zephyr. Additional information can be found in the :ref:`board_porting_guide`. -* Zephyr now requires Python 3.10 or higher +* A long-awaited HTTP server library, and associated service API, allow to easily implement HTTP/1.1 + and HTTP/2 servers in Zephyr. Resources can be registered statically or at runtime, and WebSocket + support is included. +* POSIX support has been extended, with all the Option Requirements of POSIX Subprofiling Option + Groups now being supported for PSE51, PSE52, and PSE53 profiles. +* Bluetooth Host has been extended with support for the Nordic UART Service (NUS), Hands-free Audio + Gateway (AG), Advanced Audio Distribution Profile (A2DP), and Audio/Video Distribution Transport + Protocol (AVDTP). +* Sensor abstraction model has been overhauled to adopt a read-then-decode approach that enables + more types of sensors and data flows than the previous fetch/get APIs. +* A new LLEXT Extension Development Kit (EDK) makes it easier to develop and integrate custom + extensions into Zephyr, including outside of the Zephyr tree. +* Native simulator now supports leveraging native host networking stack without having to rely on + complex setup of the host environment. * Trusted Firmware-M (TF-M) 2.1.0 and Mbed TLS 3.6.0 have been integrated into Zephyr. Both of these versions are LTS releases. +* New documentation pages have been introduced to help developers setup their local development + environment with Visual Studio Code and CLion. An overview of the changes required or recommended when migrating your application from Zephyr v3.6.0 to Zephyr v3.7.0 can be found in the separate :ref:`migration guide`. +While you may refer to release notes from previous 3.x releases for a full description, other major +enhancements and changes since previous LTS release, Zephyr 2.7.0, include: + +* Added support for Picolibc as the new default C library. +* Added support for the following types of hardware peripherals: + + * 1-Wire + * Battery Charger + * Cellular Modem + * Fuel Gauge + * GNSS + * Hardware Spinlock + * I3C + * RTC (Real Time Clock) + * SMBus + +* Added support for snippets. Snippets are common configuration settings that can be used across + platforms. +* Added support for Linkable Loadable Extensions (LLEXT). +* Summary of breaking changes (refer to release notes and migration guides from previous release + notes for more details): + + * All Zephyr public headers have been moved to :file:`include/zephyr`, meaning they need to be + prefixed with ```` when included. + * Pinmux API has been removed. Pin control needs to be used as its replacement, refer to + :ref:`pinctrl-guide` for more details. + + * The following deprecated or experimental features have been removed: + + * 6LoCAN + * civetweb module. See Zephyr 3.7's new HTTP server as a replacement. + * tinycbor module. You may use zcbor as a replacement. + The following sections provide detailed lists of changes by component. Security Vulnerability Related From cf0524fb7d9547376cbd9277e5b3d2ca8710b4db Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Mon, 1 Jul 2024 12:13:08 +0300 Subject: [PATCH 179/187] drivers: wifi/airoc: Update cb_search to check SSID length Issue: When there are two similar SSIDs (e.g. MySSID and MySSID_Guest), the current implementation may use the wrong (truncated) SSID for the connection. See issue#74910 for details. Fix: Updated airoc_wifi_scan_cb_search to filter all SSID where length is different than the user-entered SSID. Signed-off-by: Nazar Palamar --- drivers/wifi/infineon/airoc_wifi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/wifi/infineon/airoc_wifi.c b/drivers/wifi/infineon/airoc_wifi.c index 1b4ccaa1cf493..e3d8e6a3c7d3b 100644 --- a/drivers/wifi/infineon/airoc_wifi.c +++ b/drivers/wifi/infineon/airoc_wifi.c @@ -125,8 +125,7 @@ static void airoc_wifi_scan_cb_search(whd_scan_result_t **result_ptr, void *user if (status == WHD_SCAN_COMPLETED_SUCCESSFULLY) { k_sem_give(&airoc_wifi_data.sema_scan); } else if ((status == WHD_SCAN_INCOMPLETE) && (user_data != NULL) && - ((**result_ptr).SSID.length > 0)) { - + ((**result_ptr).SSID.length == ((whd_scan_result_t *)user_data)->SSID.length)) { if (strncmp(((whd_scan_result_t *)user_data)->SSID.value, (**result_ptr).SSID.value, (**result_ptr).SSID.length) == 0) { memcpy(user_data, *result_ptr, sizeof(whd_scan_result_t)); From 1f6174107f75764c9ac0305a0f3db41a284d6b16 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Mon, 1 Jul 2024 10:03:11 +0200 Subject: [PATCH 180/187] soc/openisa: enable the `C` extension According to the RV32M1 Series Manual, Rev 1.1 RV32M1 series supports the C extension, and doesn't support the A extension. Apply fixes accordingly. Signed-off-by: Filip Kokosinski --- dts/riscv/openisa/rv32m1.dtsi | 4 ++-- soc/openisa/rv32m1/Kconfig | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dts/riscv/openisa/rv32m1.dtsi b/dts/riscv/openisa/rv32m1.dtsi index cb234eba99827..d514cf946420b 100644 --- a/dts/riscv/openisa/rv32m1.dtsi +++ b/dts/riscv/openisa/rv32m1.dtsi @@ -23,14 +23,14 @@ cpu@0 { device_type = "cpu"; compatible = "openisa,ri5cy", "riscv"; - riscv,isa = "rv32ima_zicsr_zifencei"; + riscv,isa = "rv32imc_zicsr_zifencei"; reg = <0>; }; cpu@1 { device_type = "cpu"; compatible = "openisa,zero-ri5cy", "riscv"; - riscv,isa = "rv32ima_zicsr_zifencei"; + riscv,isa = "rv32imc_zicsr_zifencei"; reg = <1>; }; }; diff --git a/soc/openisa/rv32m1/Kconfig b/soc/openisa/rv32m1/Kconfig index 21fe5d9297d94..199d13ba74426 100644 --- a/soc/openisa/rv32m1/Kconfig +++ b/soc/openisa/rv32m1/Kconfig @@ -17,6 +17,6 @@ config SOC_OPENISA_RV32M1 select BUILD_OUTPUT_HEX select RISCV_ISA_RV32I select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI From 61e3e6f8d46f66b7272d066654ee39dd4993f0df Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Mon, 1 Jul 2024 10:12:44 +0200 Subject: [PATCH 181/187] soc/openisa: rely on the `CONFIG_RISCV_ISA_EXT_*` options for arch string This commit makes the RV32M1 SoC rely on the default behavior of relying on the `CONFIG_RISCV_ISA_EXT_*` config options, and removes the `zephyr_compile_options` override when the standard toolchain is used. Signed-off-by: Filip Kokosinski --- soc/openisa/rv32m1/CMakeLists.txt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/soc/openisa/rv32m1/CMakeLists.txt b/soc/openisa/rv32m1/CMakeLists.txt index cd65ea9d62868..fcfda5f17eda8 100644 --- a/soc/openisa/rv32m1/CMakeLists.txt +++ b/soc/openisa/rv32m1/CMakeLists.txt @@ -2,14 +2,10 @@ # # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_SOC_OPENISA_RV32M1_RI5CY) - if (CONFIG_RISCV_GENERIC_TOOLCHAIN) - zephyr_compile_options(-march=rv32imc_zicsr_zifencei) - else() - zephyr_compile_options(-march=rv32imcxpulpv2) - endif() -elseif(CONFIG_SOC_OPENISA_RV32M1_ZERO_RISCY) - zephyr_compile_options(-march=rv32imc_zicsr_zifencei) +# Let's rely on `-march` being generated by the CMake script based on which `CONFIG_RISCV_ISA_EXT_*` +# options are y-selected; provide full arch string with the custom extension otherwise. +if(CONFIG_SOC_OPENISA_RV32M1_RI5CY AND NOT CONFIG_RISCV_GENERIC_TOOLCHAIN) + zephyr_compile_options(-march=rv32imcxpulpv2) endif() zephyr_sources( From a764b46acea41a830fa618aea8e8c9f7e4e1085b Mon Sep 17 00:00:00 2001 From: Alessandro Manganaro Date: Fri, 28 Jun 2024 17:12:42 +0200 Subject: [PATCH 182/187] drivers: bluetooth: hci: Kconfig Enabling BT_HCI_SET_PUBLIC_ADDR option for STM32WBA BLE HCI driver Signed-off-by: Alessandro Manganaro --- drivers/bluetooth/hci/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 5e2a4f5ae2b7c..e6adca872e54b 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -71,6 +71,7 @@ config BT_STM32WBA default y depends on DT_HAS_ST_HCI_STM32WBA_ENABLED select HAS_STM32LIB + select BT_HCI_SET_PUBLIC_ADDR help ST STM32WBA HCI Bluetooth interface From ed7c63e982b2147d24dfe21c682b23c8df575bbf Mon Sep 17 00:00:00 2001 From: Alessandro Manganaro Date: Fri, 28 Jun 2024 17:15:17 +0200 Subject: [PATCH 183/187] drivers: bluetooth: hci: hci_stm32wba.c Providing setup implementation for STM32WBA BLE HCI driver Signed-off-by: Alessandro Manganaro --- drivers/bluetooth/hci/hci_stm32wba.c | 97 ++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index 34e2385b2414d..490f2b7258b55 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -52,6 +52,20 @@ static K_SEM_DEFINE(hci_sem, 1, 1); #define DIVC(x, y) (((x)+(y)-1)/(y)) +#if defined(CONFIG_BT_HCI_SETUP) +/* Bluetooth LE public STM32WBA default device address (if udn not available) */ +static bt_addr_t bd_addr_dflt = {{0x65, 0x43, 0x21, 0x1E, 0x08, 0x00}}; + +#define ACI_HAL_WRITE_CONFIG_DATA BT_OP(BT_OGF_VS, 0xFC0C) +#define HCI_CONFIG_DATA_PUBADDR_OFFSET 0 +static bt_addr_t bd_addr_udn; +struct aci_set_ble_addr { + uint8_t config_offset; + uint8_t length; + uint8_t value[6]; +} __packed; +#endif + static uint32_t __noinit buffer[DIVC(BLE_DYN_ALLOC_SIZE, 4)]; static uint32_t __noinit gatt_buffer[DIVC(BLE_GATT_BUF_SIZE, 4)]; @@ -380,7 +394,90 @@ static int bt_hci_stm32wba_open(const struct device *dev, bt_hci_recv_t recv) return ret; } +#if defined(CONFIG_BT_HCI_SETUP) + +bt_addr_t *bt_get_ble_addr(void) +{ + bt_addr_t *bd_addr; + uint32_t udn; + uint32_t company_id; + uint32_t device_id; + + /* Get the 64 bit Unique Device Number UID */ + /* The UID is used by firmware to derive */ + /* 48-bit Device Address EUI-48 */ + udn = LL_FLASH_GetUDN(); + + if (udn != 0xFFFFFFFF) { + /* Get the ST Company ID */ + company_id = LL_FLASH_GetSTCompanyID(); + /* Get the STM32 Device ID */ + device_id = LL_FLASH_GetDeviceID(); + + /* + * Public Address with the ST company ID + * bit[47:24] : 24bits (OUI) equal to the company ID + * bit[23:16] : Device ID. + * bit[15:0] : The last 16bits from the UDN + * Note: In order to use the Public Address in a final product, a dedicated + * 24bits company ID (OUI) shall be bought. + */ + + bd_addr_udn.val[0] = (uint8_t)(udn & 0x000000FF); + bd_addr_udn.val[1] = (uint8_t)((udn & 0x0000FF00) >> 8); + bd_addr_udn.val[2] = (uint8_t)device_id; + bd_addr_udn.val[3] = (uint8_t)(company_id & 0x000000FF); + bd_addr_udn.val[4] = (uint8_t)((company_id & 0x0000FF00) >> 8); + bd_addr_udn.val[5] = (uint8_t)((company_id & 0x00FF0000) >> 16); + bd_addr = &bd_addr_udn; + } else { + bd_addr = &bd_addr_dflt; + } + + return bd_addr; +} + +static int bt_hci_stm32wba_setup(const struct device *dev, + const struct bt_hci_setup_params *params) +{ + bt_addr_t *uid_addr; + struct aci_set_ble_addr *param; + struct net_buf *buf; + int err; + + uid_addr = bt_get_ble_addr(); + if (!uid_addr) { + return -ENOMSG; + } + + buf = bt_hci_cmd_create(ACI_HAL_WRITE_CONFIG_DATA, sizeof(*param)); + if (!buf) { + return -ENOBUFS; + } + + param = net_buf_add(buf, sizeof(*param)); + param->config_offset = HCI_CONFIG_DATA_PUBADDR_OFFSET; + param->length = 6; + + if (bt_addr_eq(¶ms->public_addr, BT_ADDR_ANY)) { + bt_addr_copy((bt_addr_t *)param->value, uid_addr); + } else { + bt_addr_copy((bt_addr_t *)param->value, &(params->public_addr)); + } + + err = bt_hci_cmd_send_sync(ACI_HAL_WRITE_CONFIG_DATA, buf, NULL); + if (err) { + return err; + } + + return 0; +} +#endif /* CONFIG_BT_HCI_SETUP */ + static const struct bt_hci_driver_api drv = { +#if defined(CONFIG_BT_HCI_SETUP) + .setup = bt_hci_stm32wba_setup, +#endif .open = bt_hci_stm32wba_open, .send = bt_hci_stm32wba_send, }; From 3239f54b61fd56e884dc7bfda0ccf9d8a5217790 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 27 Jun 2024 21:34:31 -0400 Subject: [PATCH 184/187] demand_paging: LRU eviction: remove restriction on PF index 0 The first page frame index was reserved for head and tail ^pointers. However there are cases where the first frame is actually made evictable and would trigger the assertion guarding against that. Fix this by applying an offset to actual frame indexes. Signed-off-by: Nicolas Pitre --- subsys/demand_paging/eviction/lru.c | 31 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/subsys/demand_paging/eviction/lru.c b/subsys/demand_paging/eviction/lru.c index 4130fbf19da68..2dd4a32891160 100644 --- a/subsys/demand_paging/eviction/lru.c +++ b/subsys/demand_paging/eviction/lru.c @@ -49,8 +49,9 @@ /* * Number of bits needed to store a page frame index. Rounded up to a byte * boundary for best compromize between code performance and space saving. + * The extra entry is used to store head and tail indexes. */ -#define PF_IDX_BITS ROUND_UP(LOG2CEIL(K_MEM_NUM_PAGE_FRAMES), 8) +#define PF_IDX_BITS ROUND_UP(LOG2CEIL(K_MEM_NUM_PAGE_FRAMES + 1), 8) /* For each page frame, track the previous and next page frame in the queue. */ struct lru_pf_idx { @@ -58,13 +59,23 @@ struct lru_pf_idx { uint32_t prev : PF_IDX_BITS; } __packed; -static struct lru_pf_idx lru_pf_queue[K_MEM_NUM_PAGE_FRAMES]; +static struct lru_pf_idx lru_pf_queue[K_MEM_NUM_PAGE_FRAMES + 1]; static struct k_spinlock lru_lock; -/* Slot 0 is for head and tail indexes (assuming actual PF #0 won't be used) */ +/* Slot 0 is for head and tail indexes (actual indexes are offset by 1) */ #define LRU_PF_HEAD lru_pf_queue[0].next #define LRU_PF_TAIL lru_pf_queue[0].prev +static inline uint32_t pf_to_idx(struct k_mem_page_frame *pf) +{ + return (pf - k_mem_page_frames) + 1; +} + +static inline struct k_mem_page_frame *idx_to_pf(uint32_t idx) +{ + return &k_mem_page_frames[idx - 1]; +} + static inline void lru_pf_append(uint32_t pf_idx) { lru_pf_queue[pf_idx].next = 0; @@ -102,7 +113,7 @@ static void lru_pf_remove(uint32_t pf_idx) if (was_head && (LRU_PF_HEAD != 0)) { /* make new head PF unaccessible */ - struct k_mem_page_frame *pf = &k_mem_page_frames[LRU_PF_HEAD]; + struct k_mem_page_frame *pf = idx_to_pf(LRU_PF_HEAD); uintptr_t flags = arch_page_info_get(k_mem_page_frame_to_virt(pf), NULL, true); /* clearing the accessed flag expected only on loaded pages */ @@ -113,11 +124,10 @@ static void lru_pf_remove(uint32_t pf_idx) void k_mem_paging_eviction_add(struct k_mem_page_frame *pf) { - uint32_t pf_idx = pf - k_mem_page_frames; + uint32_t pf_idx = pf_to_idx(pf); k_spinlock_key_t key = k_spin_lock(&lru_lock); __ASSERT(k_mem_page_frame_is_evictable(pf), ""); - __ASSERT(pf_idx != 0, "page frame 0 not expected to be used here"); __ASSERT(!lru_pf_in_queue(pf_idx), ""); lru_pf_append(pf_idx); k_spin_unlock(&lru_lock, key); @@ -125,10 +135,9 @@ void k_mem_paging_eviction_add(struct k_mem_page_frame *pf) void k_mem_paging_eviction_remove(struct k_mem_page_frame *pf) { - uint32_t pf_idx = pf - k_mem_page_frames; + uint32_t pf_idx = pf_to_idx(pf); k_spinlock_key_t key = k_spin_lock(&lru_lock); - __ASSERT(pf_idx != 0, "page frame 0 not expected to be used here"); __ASSERT(lru_pf_in_queue(pf_idx), ""); lru_pf_remove(pf_idx); k_spin_unlock(&lru_lock, key); @@ -137,10 +146,10 @@ void k_mem_paging_eviction_remove(struct k_mem_page_frame *pf) void k_mem_paging_eviction_accessed(uintptr_t phys) { struct k_mem_page_frame *pf = k_mem_phys_to_page_frame(phys); - uint32_t pf_idx = pf - k_mem_page_frames; + uint32_t pf_idx = pf_to_idx(pf); k_spinlock_key_t key = k_spin_lock(&lru_lock); - if (pf_idx != 0 && lru_pf_in_queue(pf_idx)) { + if (lru_pf_in_queue(pf_idx)) { lru_pf_remove(pf_idx); lru_pf_append(pf_idx); } @@ -155,7 +164,7 @@ struct k_mem_page_frame *k_mem_paging_eviction_select(bool *dirty_ptr) return NULL; } - struct k_mem_page_frame *pf = &k_mem_page_frames[head_pf_idx]; + struct k_mem_page_frame *pf = idx_to_pf(head_pf_idx); uintptr_t flags = arch_page_info_get(k_mem_page_frame_to_virt(pf), NULL, false); __ASSERT(k_mem_page_frame_is_evictable(pf), ""); From 11699fa79ea7adbbcff21999c4ea34cbec3578cc Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Wed, 3 Jul 2024 16:50:57 +0200 Subject: [PATCH 185/187] drivers: nsos: add missing 'break' in switch statements There are 2-level switch statements (one switch inside another) which were not properly terminated with 'break' statements, leading to implicit fallthrough. Fix that. Signed-off-by: Marcin Niestroj --- drivers/net/nsos_adapt.c | 6 ++++++ drivers/net/nsos_sockets.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/net/nsos_adapt.c b/drivers/net/nsos_adapt.c index 91be0b4cf5b48..44310253f1243 100644 --- a/drivers/net/nsos_adapt.c +++ b/drivers/net/nsos_adapt.c @@ -625,6 +625,7 @@ int nsos_adapt_getsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_KEEPALIVE, nsos_mid_optval, nsos_mid_optlen); } + break; case NSOS_MID_IPPROTO_TCP: switch (nsos_mid_optname) { @@ -641,6 +642,7 @@ int nsos_adapt_getsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return nsos_adapt_getsockopt_int(fd, IPPROTO_TCP, TCP_KEEPCNT, nsos_mid_optval, nsos_mid_optlen); } + break; case NSOS_MID_IPPROTO_IPV6: switch (nsos_mid_optname) { @@ -648,6 +650,7 @@ int nsos_adapt_getsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return nsos_adapt_getsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, nsos_mid_optval, nsos_mid_optlen); } + break; } return -NSOS_MID_EOPNOTSUPP; @@ -727,6 +730,7 @@ int nsos_adapt_setsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_KEEPALIVE, nsos_mid_optval, nsos_mid_optlen); } + break; case NSOS_MID_IPPROTO_TCP: switch (nsos_mid_optname) { @@ -743,6 +747,7 @@ int nsos_adapt_setsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return nsos_adapt_setsockopt_int(fd, IPPROTO_TCP, TCP_KEEPCNT, nsos_mid_optval, nsos_mid_optlen); } + break; case NSOS_MID_IPPROTO_IPV6: switch (nsos_mid_optname) { @@ -750,6 +755,7 @@ int nsos_adapt_setsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return nsos_adapt_setsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, nsos_mid_optval, nsos_mid_optlen); } + break; } return -NSOS_MID_EOPNOTSUPP; diff --git a/drivers/net/nsos_sockets.c b/drivers/net/nsos_sockets.c index 7991cf683da65..ac82e1ad52591 100644 --- a/drivers/net/nsos_sockets.c +++ b/drivers/net/nsos_sockets.c @@ -1095,6 +1095,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_KEEPALIVE, optval, optlen); } + break; case IPPROTO_TCP: switch (optname) { @@ -1115,6 +1116,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, NSOS_MID_IPPROTO_TCP, NSOS_MID_TCP_KEEPCNT, optval, optlen); } + break; case IPPROTO_IPV6: switch (optname) { @@ -1123,6 +1125,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, NSOS_MID_IPPROTO_IPV6, NSOS_MID_IPV6_V6ONLY, optval, optlen); } + break; } errno = EOPNOTSUPP; @@ -1261,6 +1264,7 @@ static int nsos_setsockopt(void *obj, int level, int optname, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_KEEPALIVE, optval, optlen); } + break; case IPPROTO_TCP: switch (optname) { @@ -1281,6 +1285,7 @@ static int nsos_setsockopt(void *obj, int level, int optname, NSOS_MID_IPPROTO_TCP, NSOS_MID_TCP_KEEPCNT, optval, optlen); } + break; case IPPROTO_IPV6: switch (optname) { @@ -1289,6 +1294,7 @@ static int nsos_setsockopt(void *obj, int level, int optname, NSOS_MID_IPPROTO_IPV6, NSOS_MID_IPV6_V6ONLY, optval, optlen); } + break; } errno = EOPNOTSUPP; From 7645667303e6c2051d4482b6c71772ce9c602d23 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 1 Jul 2024 15:47:16 +0100 Subject: [PATCH 186/187] github: hello_world_multiplatform: upgrade from macos-12 to macos-13 Upgrade the CI image for x86 macos from 12 to 13, this is apparently the latest "free" x86 macos runner that will be supported, let's switch to it until it gets deprecated. Signed-off-by: Fabio Baltieri --- .github/workflows/hello_world_multiplatform.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hello_world_multiplatform.yaml b/.github/workflows/hello_world_multiplatform.yaml index bcd11ee3ecc37..bbcce51d9e570 100644 --- a/.github/workflows/hello_world_multiplatform.yaml +++ b/.github/workflows/hello_world_multiplatform.yaml @@ -26,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, macos-12, macos-14, windows-2022] + os: [ubuntu-22.04, macos-13, macos-14, windows-2022] runs-on: ${{ matrix.os }} steps: - name: Checkout From 95cadc1cfb64ac21def4a3dbb9a731178d57ca52 Mon Sep 17 00:00:00 2001 From: Riaz Khan Date: Thu, 15 Aug 2024 13:20:39 -0700 Subject: [PATCH 187/187] @FIR-65: tsvbootloader changes --- CMakeLists.txt | 4 +- scripts/build/tsvbootloader.hex | 4050 +++++++++++++++---------------- 2 files changed, 2027 insertions(+), 2027 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1078ff4a52e5f..d856841eaedaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2067,9 +2067,9 @@ set(TSVIMAGELOADER_NAME IMAGE0_testfile.hex) add_custom_command( OUTPUT ${STRIPPED_KERNEL_HEX_NAME} COMMAND ${TAIL_EXECUTABLE} -n +2 ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} >> ${PROJECT_BINARY_DIR}/${STRIPPED_HEX_NAME} - COMMAND ${HEAD_EXECUTABLE} -n +65 ${ZEPHYR_BASE}/${TSVBOOTLOADER_NAME} >> ${PROJECT_BINARY_DIR}/${TSVIMAGELOADER_NAME} + COMMAND ${HEAD_EXECUTABLE} -n +48 ${ZEPHYR_BASE}/${TSVBOOTLOADER_NAME} >> ${PROJECT_BINARY_DIR}/${TSVIMAGELOADER_NAME} COMMAND ${HEAD_EXECUTABLE} -n +1 ${PROJECT_BINARY_DIR}/${STRIPPED_HEX_NAME} >> ${PROJECT_BINARY_DIR}/${TSVIMAGELOADER_NAME} - COMMAND ${TAIL_EXECUTABLE} -n +67 ${ZEPHYR_BASE}/${TSVBOOTLOADER_NAME} >> ${PROJECT_BINARY_DIR}/${TSVIMAGELOADER_NAME} + COMMAND ${TAIL_EXECUTABLE} -n +50 ${ZEPHYR_BASE}/${TSVBOOTLOADER_NAME} >> ${PROJECT_BINARY_DIR}/${TSVIMAGELOADER_NAME} COMMAND ${TAIL_EXECUTABLE} -n +1 ${PROJECT_BINARY_DIR}/${STRIPPED_HEX_NAME} >> ${PROJECT_BINARY_DIR}/${TSVIMAGELOADER_NAME} DEPENDS ${MERGED_KERNEL_HEX_NAME} ) diff --git a/scripts/build/tsvbootloader.hex b/scripts/build/tsvbootloader.hex index 1c3cff9c85d1c..55e84f7516820 100644 --- a/scripts/build/tsvbootloader.hex +++ b/scripts/build/tsvbootloader.hex @@ -1,5 +1,5 @@ 10000000000000000 -0000000c160001100 +0000000c160000068 00000000000000000 00000000000000000 00000000000000000 @@ -23,2027 +23,2027 @@ 0000000c5000000c5 0000000c5000000c5 0000000c5000000c5 -0f7ffbf3047004802 -0000001ad0000bffd -0f804f0008000f3af -0bd10b510bd1fb51f -0f7ff4611f818f000 -0f000f85af000fff7 -0fff2f7ffb403f806 -0b510f80ff000bc03 -046208000f3af4604 -0bff1f7ff4010e8bd -04603460a47702000 -064adf64d00004770 -0bf0464adf6cd2800 -0040df2c9040df249 -01044f240f816f000 -0bf0060040000f2c8 -05014f64e0000e7fe -0f44168010000f2ce -08f4ff3bf60013140 -0000047708f6ff3bf -00001f2ce0000f24e -060010104f0416801 -08f6ff3bf8f4ff3bf -0f64db51000004770 -064adf6cd280064ad -0f2c9040df249bf04 -0f240ffe5f7ff040d -060040000f2c81044 -0f2c60c01f240bd10 -00000f04f47600c00 -04604460346024601 -04680460746064605 -04684468346824681 -0bf182800480b4686 -0bf182800480a4780 -04c09d024f8df4780 -0429abf6ff7ff47a0 -0f8420b04f851bf3c -000004770d3f80b04 -00000000000000000 -06000024160040000 -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff -0ffffffffffffffff +0f7ffbf3047004812 +0f851bf3c429abffd +0d3f80b04f8420b04 +0f4416801480d4770 +0f04f480b60013140 +0490b480a60010100 +06001490b480b6001 +060010104f04f480b +060010105f04f480a +00000013100004770 +0e000ed98e000ed14 +080000003e000ed9c +09ffffff1e000eda0 +0e000ed94e000edc0 +0460246010000f04f +04606460546044603 +04682468146804607 +04808468646844683 +048074780bf182800 +0f8df4780bf182800 +0f7ff47a04c06d018 +08000f3afbf00bfad +00000000000000000 +06000abc160006600 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000 +00000000000000000