diff --git a/.cyignore b/.cyignore new file mode 100644 index 0000000..a6bb694 --- /dev/null +++ b/.cyignore @@ -0,0 +1,13 @@ +build +configs +deps +docs +doxygen +devops_scripts +images +template_linkers +scripts +snippets +ota_bootloader_abstraction_doxy.h +README.md +RELEASE.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b3f8090 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.sh text eol=lf + +*.bash text eol=lf +*.py text eol=lf + +*.bin binary +*.exe binary diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..01d5e58 --- /dev/null +++ b/LICENSE @@ -0,0 +1,211 @@ +CYPRESS (AN INFINEON COMPANY) END USER LICENSE AGREEMENT + +PLEASE READ THIS END USER LICENSE AGREEMENT ("Agreement") CAREFULLY BEFORE +DOWNLOADING, INSTALLING, COPYING, OR USING THIS SOFTWARE AND ACCOMPANYING +DOCUMENTATION. BY DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE, +YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL +OF THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN AND DO NOT USE THE SOFTWARE. +IF YOU HAVE PURCHASED THIS LICENSE TO THE SOFTWARE, YOUR RIGHT TO RETURN THE +SOFTWARE EXPIRES 30 DAYS AFTER YOUR PURCHASE AND APPLIES ONLY TO THE ORIGINAL +PURCHASER. + +1. Definitions. + + "Software" means this software and any accompanying documentation, + including any upgrades, updates, bug fixes or modified versions provided + to you by Cypress. + + "Source Code" means software in human-readable form. + + "Binary Code" means the software in binary code form such as object code or + an executable. + + "Development Tools" means software that is intended to be installed on a + personal computer and used to create programming code for Firmware, + Drivers, or Host Applications. Examples of Development Tools are + Cypress's PSoC Creator software, Cypress's AIROC SDKs, and Cypress's + ModusToolbox software. + + "Firmware" means software that executes on a Cypress hardware product. + + "Driver" means software that enables the use of a Cypress hardware product + on a particular host operating system such as GNU/Linux, Windows, MacOS, + Android, and iOS. + + "Host Application" means software that executes on a device other than a + Cypress hardware product in order to program, control, or communicate + with a Cypress hardware product. + + "inf File" means a hardware setup information file (.inf file) created by + the Software to allow a Microsoft Windows operating system to install + the driver for a Cypress hardware product. + +2. License. Subject to the terms and conditions of this Agreement, Cypress +Semiconductor Corporation ("Cypress") and its suppliers grant to you a +non-exclusive, non-transferable license under their copyright rights: + + a. to use the Development Tools in object code form solely for the purpose + of creating Firmware, Drivers, Host Applications, and inf Files for + Cypress hardware products; and + + b. (i) if provided in Source Code form, to copy, modify, and compile the + Firmware Source Code to create Firmware for execution on a Cypress + hardware product, and + (ii) to distribute Firmware in binary code form only, only when + installed onto a Cypress hardware product; and + + c. (i) if provided in Source Code form, to copy, modify, and compile the + Driver Source Code to create one or more Drivers to enable the use + of a Cypress hardware product on a particular host operating + system, and + (ii) to distribute the Driver, in binary code form only, only when + installed on a device that includes the Cypress hardware product + that the Driver is intended to enable; and + + d. (i) if provided in Source Code form, to copy, modify, and compile the + Host Application Source Code to create one or more Host + Applications to program, control, or communicate with a Cypress + hardware product, and + (ii) to distribute Host Applications, in binary code form only, only + when installed on a device that includes a Cypress hardware product + that the Host Application is intended to program, control, or + communicate with; and + + e. to freely distribute any inf File. + +Any distribution of Software permitted under this Agreement must be made +pursuant to your standard end user license agreement used for your proprietary +(closed source) software products, such end user license agreement to include, +at a minimum, provisions limiting your licensors' liability and prohibiting +reverse engineering of the Software, consistent with such provisions in this +Agreement. + +3. Free and Open Source Software. Portions of the Software may be licensed +under free and/or open source licenses such as the GNU General Public License +or other licenses from third parties ("Third Party Software"). Third Party +Software is subject to the applicable license agreement and not this +Agreement. If you are entitled to receive the source code from Cypress for +any Third Party Software included with the Software, either the source code +will be included with the Software or you may obtain the source code at no +charge from +. +The applicable license terms will accompany each source code package. To +review the license terms applicable to any Third Party Software for which +Cypress is not required to provide you with source code, please see the +Software's installation directory on your computer. + +4. Proprietary Rights; Ownership. The Software, including all intellectual +property rights therein, is and will remain the sole and exclusive property of +Cypress or its suppliers. Cypress retains ownership of the Source Code and +any compiled version thereof. Subject to Cypress' ownership of the underlying +Software (including Source Code), you retain ownership of any modifications +you make to the Source Code. You agree not to remove any Cypress copyright or +other notices from the Source Code and any modifications thereof. You agree +to keep the Source Code confidential. Any reproduction, modification, +translation, compilation, or representation of the Source Code except as +permitted in Section 2 ("License") is prohibited without the express written +permission of Cypress. Except as otherwise expressly provided in this +Agreement, you may not: + (i) modify, adapt, or create derivative works based upon the Software; + (ii) copy the Software; + (iii) except and only to the extent explicitly permitted by applicable + law despite this limitation, decompile, translate, reverse engineer, + disassemble or otherwise reduce the Software to human-readable form; + or + (iv) use the Software or any sample code other than for the Purpose. +You hereby covenant that you will not assert any claim that the Software, or +derivative works thereof created by or for Cypress, infringe any intellectual +property right owned or controlled by you + +5. No Support. Cypress may, but is not required to, provide technical support +for the Software. + +6. Term and Termination. This Agreement is effective until terminated, and +either party may terminate this Agreement at any time with or without cause. +This Agreement and your license rights under this Agreement will terminate +immediately without notice from Cypress if you fail to comply with any +provision of this Agreement. Upon termination, you must destroy all copies of +Software in your possession or control. The following paragraphs shall +survive any termination of this Agreement: "Free and Open Source Software," +"Proprietary Rights; Ownership," "Compliance With Law," "Disclaimer," +"Limitation of Liability," and "General." + +7. Compliance With Law. Each party agrees to comply with all applicable laws, +rules and regulations in connection with its activities under this Agreement. +Without limiting the foregoing, the Software may be subject to export control +laws and regulations of the United States and other countries. You agree to +comply strictly with all such laws and regulations and acknowledge that you +have the responsibility to obtain licenses to export, re-export, or import the +Software. + +8. Disclaimer. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS +MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THE +SOFTWARE, INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +reserves the right to make changes to the Software without notice. Cypress +does not assume any liability arising out of the application or use of +Software or any product or circuit described in the Software. It is the +responsibility of the user of the Software to properly design, program, and +test the functionality and safety of any application made of the Software and +any resulting product. Cypress does not authorize its Software or products +for use in any products where a malfunction or failure of the Software or +Cypress product may reasonably be expected to result in significant property +damage, injury or death ("High Risk Product"). If you include any Software or +Cypress product in a High Risk Product, you assume all risk of such use and +agree to indemnify Cypress and its suppliers against all liability. No +computing device can be absolutely secure. Therefore, despite security +measures implemented in Cypress hardware or software products, Cypress does +not assume any liability arising out of any security breach, such as +unauthorized access to or use of a Cypress product. + +9. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE +LAW, IN NO EVENT WILL CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS BE +LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, +CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS +OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR +INABILITY TO USE THE SOFTWARE EVEN IF CYPRESS OR ITS SUPPLIERS, RESELLERS, OR +DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO +EVENT SHALL CYPRESS' OR ITS SUPPLIERS', RESELLERS', OR DISTRIBUTORS' TOTAL +LIABILITY TO YOU, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR +OTHERWISE, EXCEED THE GREATER OF US$500 OR THE PRICE PAID BY YOU FOR THE +SOFTWARE. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED +WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS +DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, +ALL OR PORTIONS OF THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +10. Restricted Rights. The Software is commercial computer software as that +term is described in 48 C.F.R. 252.227-7014(a)(1). If the Software is being +acquired by or on behalf of the U.S. Government or by a U.S. Government prime +contractor or subcontractor (at any tier), then the Government's rights in +Software shall be only those set forth in this Agreement. + +11. Personal Information. You agree that information you provide through your +registration on Cypress IoT Community Forum or other Cypress websites, +including contact information or other personal information, may be collected +and used by Cypress consistent with its Data Privacy Policy +(https://www.infineon.com/cms/en/about-infineon/privacy-policy/), as updated +or revised from time to time, and may be provided to its third party sales +representatives, distributors and other entities conducting sales activities +for Cypress for sales-related and other business purposes. + +12. General. This Agreement will bind and inure to the benefit of each +party's successors and assigns, provided that you may not assign or transfer +this Agreement, in whole or in part, without Cypress' written consent. This +Agreement shall be governed by and construed in accordance with the laws of +the State of California, United States of America, as if performed wholly +within the state and without giving effect to the principles of conflict of +law. The parties consent to personal and exclusive jurisdiction of and venue +in, the state and federal courts within Santa Clara County, California; +provided however, that nothing in this Agreement will limit Cypress' right to +bring legal action in any venue in order to protect or enforce its +intellectual property rights. No failure of either party to exercise or +enforce any of its rights under this Agreement will act as a waiver of such +rights. If any portion of this Agreement is found to be void or +unenforceable, the remaining provisions of this Agreement shall remain in full +force and effect. This Agreement is the complete and exclusive agreement +between the parties with respect to the subject matter hereof, superseding and +replacing any and all prior agreements, communications, and understandings +(both written and oral) regarding such subject matter. Any notice to Cypress +will be deemed effective when actually received and must be sent to Cypress +Semiconductor Corporation, ATTN: Chief Legal Officer, 198 Champion Court, San +Jose, CA 95134 USA. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5114930 --- /dev/null +++ b/README.md @@ -0,0 +1,315 @@ +# Over-the-Air (OTA) Bootloader Abstraction Middleware Library + +The OTA Bootloader Abstraction library has implementation for bootloader specific storage interface APIs for handling OTA upgrade images. +This library is expected to work only with the Infineon [ota-update](https://github.com/Infineon/ota-update/) library which downloads OTA upgrade images on PSoC6, 20829, and XMC7200 platforms. +Application should not directly call the bootloader-specific storage interface APIs. Rather, during Infineon OTA Agent initialization, the application needs to register these bootloader-specific storage interface APIs as callback APIs. +See the [ota-update](https://github.com/Infineon/ota-update/) library documentation for more details. + +## Library Versions + +| Library Version | Supported MTB version | Remarks | +|---------------------------------| -------------------------|-------------------------------------------| +| ota-bootloader-abstraction v1.0.0 | ModusToolbox 3.1 | cysecuretools v5.0 or greater is required | + +## 1. Bootloader Support +To add different bootloader support on Infineon connectivity-enabled MCU platforms, [ota-update](https://github.com/Infineon/ota-update/) library offloads bootloader specific storage interface APIs using callback mechanism. +To handle downloaded OTA upgrade images *ota-update* library calls registered bootloader-specific storage interface callbacks. +The ota-bootloader-abstraction library includes an implementation of bootloader-specific storage interface APIs for various bootloaders. Additionally, it provides the necessary build environment to create BOOT and UPGRADE images for OTA applications. + + 1.1 OTA storage interface callback APIs structure
+OTA storage interface callback APIs structure and callback APIs syntax are defined in *ota-update* library. +Refer [ota-update library API header file](https://github.com/Infineon/ota-update/blob/master/include/cy_ota_api.h) for details. + +``` +typedef struct cy_ota_storage_interface_s +{ + cy_ota_file_open ota_file_open; /**< Creates and open new receive file for the data chunks as they come in. */ + cy_ota_file_read ota_file_read; /**< Reads the flash data starting from the given offset. */ + cy_ota_file_write ota_file_write; /**< Write a data to the flash at the given offset. */ + cy_ota_file_close ota_file_close; /**< Close the underlying receive file in the specified OTA context. */ + cy_ota_file_verify ota_file_verify; /**< Authenticate received OTA update file specified in the OTA context. */ + cy_ota_file_validate ota_file_validate; /**< The application has validated the new OTA image. */ + cy_ota_file_get_app_info ota_file_get_app_info; /**< Get Application info like Application version and Application ID. */ +} cy_ota_storage_interface_t; +``` +
+ + 1.2 OTA storage interface APIs implementation
+ +| Storage operation callback | Bootloader | API | Remarks | +|----------------------------| ---------------|----------------------------------|------------------| +| ota_file_open | MCUBootloader | cy_ota_storage_open() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | +| ota_file_read | MCUBootloader | cy_ota_storage_read() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | +| ota_file_write | MCUBootloader | cy_ota_storage_write() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | +| ota_file_close | MCUBootloader | cy_ota_storage_close() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | +| ota_file_verify | MCUBootloader | cy_ota_storage_verify() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | +| ota_file_validate | MCUBootloader | cy_ota_storage_image_validate() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | +| ota_file_get_app_info | MCUBootloader | cy_ota_storage_get_app_info() | Available in source/COMPONENT_MCUBOOT/cy_ota_storage_api.c | + +NOTE: The current version of ota-bootloader-abstraction library implements only storage interface APIs for MCUBootloader based OTA. + +## 2. MCUBootloader Support + +*ota-bootloader-abstraction* library has below support for MCUBootloader based OTA on PSoC6, 20829,and XMC7200 platforms. + +- Template flashmaps for PSoC6, 20829, and XMC7200 platforms. + +- Template linker files for GCC_ARM, ARM, and IAR toolchains. + +- Storage operation callback APIs to handle MCUBootloader based upgrade image. + +- Prebuild and Postbuild scripts for generating and signing MCUBootloader based BOOT and UPGRADE image of an OTA Application. + + Supported devices:
+- PSoC™ 6 MCU with + - AIROC™ CYW4343W + - CYW43012 Wi-Fi & Bluetooth® combo chip +- CYW920829M2EVK-02 evaluation board. +- CY8CKIT-062-BLE +- CY8CPROTO-063-BLE +- CYBLE-416045-EVAL +- KIT_XMC72_EVK + +The *ota-update* along with *ota-bootloader-abstraction* library works in concert with MCUBootloader to provide a no-fail solution to updating device software in the field. + +MCUBootloader is a secure bootloader application for 32-bit microcontrollers and users should build it outside of the user OTA application. It is programmed separately to the device before flashing the user OTA application and is not updated for the life of the device. + +User OTA application will include the *ota-update* library along with *ota-bootloader-abstraction* library, which will set the appropriate flags so that MCUBootloader knows when to perform an update of your application. The OTA library will download a new (updated) application, store it in flash, and set flags so that on the next reset, MCUBootloader will see there is an update available. + + The basic device boot sequence is as follows: +1. ROM boot will start MCUBootloader +2. If no update is downloaded, MCUBootloader starts the current application. +3. MCUBootloader determines if there is an update in the Secondary Slot +4. If there is an update available:
+ a. MCUBootloader verifies the update.
+ b. MCUBootloader SWAPs (or OVERWRITEs) the current with the update applications.
+ c. MCUBootloader starts the new (updated) application.
+ d. The updated application must call cy_ota_storage_image_validate() to validate the update.
+ e. For SWAP, if the new application does not call cy_ota_storage_image_validate(), MCUBootloader will REVERT on the next reset.
+ + NOTE: On secure MCUs such as PSoC™ 64, MCUBootloader is flashed as part of the provisioning step performed by the provisioning tools, and does not need to be built separately. For more information see [MCUBootloader App Information](./source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md#5-cysecuretools-for-psoc-64-and-cyw20829-devices).

+ + 2.1 Flash layout requirements
+ +MCUBootApp and the OTA enabled application must use the same flash layout. + +The flash is separated into sections also called slots. The current application occupies the Primary (BOOT) Slot. The update application (new version) will be downloaded into the Secondary (UPGRADE) Slot. +Besides primary and secondary slots, MCUBootApp has a code section, a section for a "Swap Buffer" and a section for "Status Info". + +| Section | Size | Description | +|-----------------| ---------------------|----------------------------| +| MCUBootApp | 0x00028000 | MCUBootApp code | +| Primary Slot | Varies by flash size | User Application (current) | +| Secondary Slot | Same size as Primary | Update Application (new) | +| Swap Buffer | Varies by flash size | Used by MCUBootApp for SWAP operation | +| Status | Varies by size of Slots | Used by MCUBootApp for update status | + +For more information, please see [OTA Flash Layout Information](./source/COMPONENT_MCUBOOT/MCUBOOT_OTA_FLASH_LAYOUT_README.md).

+ + 2.2 Target and Flashmap Use
+ +Template flashmaps for the supported targets as of v1.0.0 release. These flashmaps are available in [MCUBootloader based OTA Flashmap folder](./configs/COMPONENT_MCUBOOT/flashmap/). + +| Target | Internal
Flash size | OTA_PLATFORM | Flashmaps | +|-------------------|---------------------|----|------| +| CY8CPROTO-062-4343W
CY8CKIT-062S2-43012
CY8CPROTO-062-4343W
CY8CEVAL-062S2-LAI-4373M2
CY8CEVAL-062S2-MUR-43439M2| 2M | PSOC_062_2M | Default - psoc62_2m_ext_swap_single.json
psoc62_2m_ext_overwrite_single.json
psoc62_2m_int_overwrite_single.json
psoc62_2m_int_swap_single.json| +| CY8CKIT-062-BLE | 1M | PSOC_062_1M |Default - psoc62_1m_cm0_int_swap_single.json | +| CY8CPROTO-063-BLE
CYBLE-416045-EVAL | 1M | PSOC_063_1M | Default - psoc63_1m_cm0_int_swap_single.json | +| CY8CPROTO-062S3-4343W | 512K | PSOC_062_512K | Default - psoc62_512k_xip_swap_single.json
psoc62_512k_ext_overwrite_single.json
psoc62_512k_ext_swap_single.json | +| CY8CKIT-064B0S2-4343W | 2M | PSOC_064_2M | Default - policy_single_CM0_CM4_smif_swap.json | +| CYW920829M2EVK-02 | 0K | CYW20829 | Default - cyw20829_xip_swap_single.json
cyw20829_xip_overwrite_single.json | +| KIT_XMC72_EVK | 8MB | XMC7200 | Default - xmc7200_int_swap_single.json
xmc7200_int_overwrite_single.json | + +
+ +| 2M Internal Flash Maps | Memory Usage | +|--------------------------------|--------------| +| psoc62_2m_ext_overwrite_single.json | Internal primary, external secondary | +| psoc62_2m_ext_swap_single.json | Internal primary, external secondary | +| psoc62_2m_int_overwrite_single.json | Internal only (primary and secondary) | +| psoc62_2m_int_swap_single.json | Internal only (primary and secondary) | + +| 1M Internal Flash Maps | Memory Usage | +|--------------------------------|--------------| +| psoc62_1m_cm0_int_swap_single.json | Internal only (primary and secondary) | +| psoc63_1m_cm0_int_swap_single.json | Internal only (primary and secondary) | + + +| 512K Internal Flash Maps | Memory Usage | +|--------------------------------|--------------| +| psoc62_512k_ext_overwrite_single.json | Internal primary, external secondary | +| psoc62_512k_ext_swap_single.json | Internal primary, external secondary | +| psoc62_512k_xip_swap_single.json | External only (primary and secondary) | + + +| 0K Internal Flash Maps | Memory Usage | +|--------------------------------|--------------| +| cyw20829_xip_overwrite_single.json | External only (primary and secondary) | +| cyw20829_xip_swap_single.json | External only (primary and secondary) | +| cyw20829_xip_swap_single_psvp.json | External only (primary and secondary) | + + +| 8M Internal Flash Maps | Memory Usage | +|--------------------------------|--------------| +| xmc7200_int_swap_single.json | Internal only (primary and secondary) | +| xmc7200_int_overwrite_single.json | Internal only (primary and secondary) | + + 2.3 MCUBootApp Cloning and Building
+ +MCUBootloader Application i.e MCUBootApp is a standalone application. It is an open source software taken and customized in terms of Flash map and is built outside of ModusToolbox. MCUBootApp is programmed/flashed on the device one time, at manufacture (or for development). + +- MCUBootApp runs on the CM0+ CPU and starts any OTA enabled application on CM4 core in case of multicore Psoc6 devices and on CM7 core in case of XMC7200 devices. +- In case of 20829 devices, MCUBootApp runs on CM33 CPU along with the OTA enabled applications. + +MCUBoot itself is not OTA upgradable. + +For cloning and building MCUBootApp refer to [MCUBootApp README](./source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md). + +## 3. Enabling MCUBootloader based OTA in an Application + +- Before enabling MCUBootloader based OTA in an application, the user must build and program MCUBootApp on the chosen platform(s). Refer to refer to [MCUBootApp README](./source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md). + +- Create an *ota-bootloader-abstraction.mtb* file to pull *ota-bootloader-abstraction* library which has storage APIs to handle the MCUBootloader based OTA upgrade files. Place *ota-bootloader-abstraction.mtb* in the application *deps* folder. The contents of *ota-bootloader-abstraction.mtb* should be as follows: + ``` + https://github.com/Infineon/ota-bootloader-abstraction#latest-v1.X#$$ASSET_REPO$$/ota-bootloader-abstraction/latest-v1.X + ``` + +- After adding *ota-bootloader-abstraction.mtb* file to the *deps* folder of your application, Run the command 'make getlibs' to fetch *ota-bootloader-abstraction* library and its dependencies. + ``` + make getlibs + ``` + +- Update OTA Application makefile by referring [OTA Bootloader Abstraction Makefile Readme](./source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md). + +- Make sure that the Python module is installed on your computer, preferably Python version 3.8. Additionally, Application need to provide the path to the installed Python module by setting CY_PYTHON_PATH in the OTA Application makefile. The pre and post build scripts of the *ota-bootloader-abstraction* library use this Python module to parse memory configurations. + ``` + CY_PYTHON_PATH = + ``` + +- *ota-bootloader-abstraction* library has makefile *mcuboot_support.mk* located in [makefiles folder](./makefiles/mcuboot/) which has necessary pre and post build scripts for generating MCUBootloader based BOOT and UPGRADE images of OTA application. + +- Include *mcuboot_support.mk* which is located in [makefiles folder](./makefiles/mcuboot/) from OTA Application makefile. + ``` + include ../mtb_shared/ota-bootloader-abstraction//makefiles/mcuboot/mcuboot_support.mk + ``` + +- Configure OTA storage interface callback APIs in OTA application, And pass the same storage interface while starting OTA agent. + ``` + /* OTA storage interface callbacks */ + cy_ota_storage_interface_t ota_interfaces = + { + .ota_file_open = cy_ota_storage_open, + .ota_file_read = cy_ota_storage_read, + .ota_file_write = cy_ota_storage_write, + .ota_file_close = cy_ota_storage_close, + .ota_file_verify = cy_ota_storage_verify, + .ota_file_validate = cy_ota_storage_image_validate, + .ota_file_get_app_info = cy_ota_storage_get_app_info + }; + + /* Register OTA storage interface callbacks with OTA agent */ + cy_ota_agent_start(&ota_test_network_params, &ota_test_agent_params, &ota_interfaces, &ota_context); + + ``` + +- OTA storage interface calls Flash operations(Read, Write, erase) to store upgrade images in UPGRADE slot. + *ota-bootloader-abstraction* implements flash operation using *mtb-pdl-cat1* library APIs and implementation is available in [configs folder](./configs/COMPONENT_MCUBOOT/flash/). + User can use same implementation by copying contents of [configs folder](./configs/COMPONENT_MCUBOOT/flash/) to application space or Can implement flash operation APIs defined in [cy_ota_flash.h](./source/COMPONENT_MCUBOOT/cy_ota_flash.h). + +- For Secure platforms like PSoC64, MCUBootloader will get programmed during kit provisioning process. Follow steps in 3.1 before building OTA application. + +- During application build, Required BOOT and UPGRADE images(.bin) of OTA application will get generated in configured build directory. + +- Program the BOOT image and use UPGRADE image (.bin) for OTA. + + 3.1 Provisioning PSoC64
+- For Secure platforms like PSoC64, MCUBootloader will get programmed during kit provisioning process. + +- Prior to provisioning the PSoC64 kit (CY8CKIT-064B0S2-4343W), User need to create *policies* and *keys* for provisioning. To do this, execute the following 'init' command from application root folder. + ``` + cysecuretools -t CY8CKIT-064B0S2-4343W init + ``` + +- The *init* command creates the *keys*, *packets*, *policy*, and *prebuilt* directories in application root folder. These keys and policies are utilized during the provisioning and OTA image signing process. + +- Copy policy *policy_single_CM0_CM4_smif_swap.json* from [configs folder](./configs/COMPONENT_MCUBOOT/flashmap/) and replace it with the one in *policy* folder which is generated after executing *init* command. + +- Please copy the *policy_single_CM0_CM4_smif_swap.json* file from the [configs folder](./configs/COMPONENT_MCUBOOT/flashmap/) and replace it with the version in the *policy* folder, which will be generated after running the *init* command. + +- The public key is programmed during the provisioning for further image verification. The private key is used to sign the image with the user application. Create a private key using below command. The public part of the key will be taken from the private during provisioning. + ``` + cysecuretools -t CY8CKIT-064B0S2-4343W -p policy/policy_single_CM0_CM4_swap.json create-keys + ``` + +- Provision the kit with policy *policy_single_CM0_CM4_smif_swap.json*. Refer [Provisioning Steps for CY8CKIT-064B0S2-4343W](https://github.com/Infineon/cysecuretools/blob/master/docs/README_PSOC64.md) for complete provisionig steps. + +- During provisioning, the MCU bootloader is also loaded and executed from the CM0 core upon reboot. + + +## 4. Enabling Debug Output + +The *ota-bootloader-abstraction* library disables all debug log messages by default. Do the following to enable log messages: + +1. Add the `ENABLE_OTA_BOOTLOADER_ABSTRACTION_LOGS` macro to the *DEFINES* in the code example's makefile. The makefile entry should look like as follows: + ``` + DEFINES+=ENABLE_OTA_BOOTLOADER_ABSTRACTION_LOGS + ``` + +2. Call the `cy_log_init()` function provided by the *cy-log* module. cy-log is part of the *connectivity-utilities* library. See [connectivity-utilities library API documentation](https://infineon.github.io/connectivity-utilities/api_reference_manual/html/group__logging__utils.html) for cy-log details. + +## 5. Note on Using Windows 10 + +When using ModusToolbox, you will need to install the pip requirements to Python in the ModusToolbox installation. + +``` +\/tools_3.*/python/python -m pip install -r \scripts/mcuboot/imgtool/requirements.txt +``` + +## 6. Supported Toolchains + +- GCC +- IAR +- ARM C + +For the toolchain version information, please refer to [ota-bootloader-abstraction Release.md](./RELEASE.md). + +## 7. Supported OS + +- FreeRTOS + +## 8. Supported Kits + +- [PSoC™ 6 Wi-Fi BT Prototyping Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8cproto-062-4343w/) (CY8CPROTO-062-4343W) +- [PSoC™ 62S2 Wi-Fi BT Pioneer Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062s2-43012/) (CY8CKIT-062S2-43012) +- [PSoC™ 62S3 Wi-Fi BT Prototyping Kit ](https://www.infineon.com/cms/en/product/evaluation-boards/cy8cproto-062s3-4343w/)(CY8CPROTO-062S3-4343W) +- [PSoC™ 64 Secure Boot Wi-Fi BT Pioneer Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-064b0s2-4343w/) (CY8CKIT-064B0S2-4343W) +- [CY8CEVAL-062S2 Evaluation Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ceval-062s2/)(CY8CEVAL-062S2-LAI-4373M2 and CY8CEVAL-062S2-MUR-43439M2) +- [PSoC™ 6-BLE Pioneer Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062-ble/) (CY8CKIT-062-BLE) +- [PSoC™ 6 BLE Prototyping Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8cproto-063-ble/) (CY8CPROTO-063-BLE) +- [EZ-BLE Arduino Evaluation Board](https://www.infineon.com/cms/en/product/evaluation-boards/cyble-416045-eval/) (CYBLE-416045-EVAL) +- [AIROC™ CYW20829 Bluetooth® LE SoC](https://www.infineon.com/cms/en/product/promopages/airoc20829/) (CYW920829M2EVK-02) +- [XMC7200 Evaluation Kit](https://www.infineon.com/cms/en/product/evaluation-boards/kit_xmc72_evk/) (KIT_XMC72_EVK) + +## 9. Hardware Setup + +This example uses the board's default configuration. See the kit user guide to ensure the board is configured correctly. + +**Note:** Before using this code example, make sure that the board is upgraded to KitProg3. The tool and instructions are available in the [Firmware Loader](https://github.com/Infineon/Firmware-loader) GitHub repository. If you do not upgrade, you will see an error like "unable to find CMSIS-DAP device" or "KitProg firmware is out of date". + +## 10. Additional Information + +- [OTA bootloader Abstraction Library RELEASE.md](./RELEASE.md) + +- [OTA bootloader Abstraction Library version](./version.xml) + +- [OTA bootloader Abstraction Library Makefile Information](./source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md) + +- [Connectivity utilities API documentation - for cy-log details](https://Infineon.github.io/connectivity-utilities/api_reference_manual/html/group__logging__utils.html) + +- [ModusToolbox Software Environment, Quick Start Guide, Documentation, and Videos](https://www.infineon.com/modustoolbox) + +- [ModusToolbox™ code examples](https://github.com/infineon?q=mtb-example-anycloud%20NOT%20Deprecated) + +Infineon also provides a wealth of data at www.infineon.com to help you select the right device, and quickly and effectively integrate it into your design. + +For PSoC™ 6 MCU devices, see [How to Design with PSoC 6 MCU - KBA223067](https://community.infineon.com/t5/Knowledge-Base-Articles/How-to-Design-with-PSoC-6-MCU-KBA223067/ta-p/248857) in the Infineon community. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..c4cb9ea --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,43 @@ +# Infineon OTA Bootloader Support Library + +## What's Included? + +See the [README.md](./README.md) for a complete description of the OTA bootloader support library. + +## Known issues + +| Problem | Workaround | +| ------- | ---------- | +| OTA Bootloader Support Middleware is currently not supported on IAR toolchain with CYW20829B0 kit. | No workaround. Support will be added in a future release. | + + +## Changelog + +### v1.0.0 + +- New ota-bootloader-abstraction library +- This ota-bootloader-abstraction has mcubootloader support. +- ota-bootloader-abstraction v1.0.0 works with MTB 3.1 +- Legacy support for these devices: + - CY8CKIT-062S2-43012 + - CY8CKIT-064B0S2-4343W + - CY8CPROTO-062-4343W + - CY8CPROTO-062S3-4343W + - CY8CEVAL-062S2-CYW943439M2IPA1 + - CY8CEVAL-062S2-LAI-4373M2 + - CY8CEVAL-062S2-MUR-43439M2 + - CYW920829M2EVK-02 + - XMC7200(KIT_XMC72_EVK) + +## Supported Software and Tools +This version of the library was validated for compatibility with the following software and tools: + +| Software and Tools | Version | +| :--- | :----: | +| ModusToolbox™ Software Environment | 3.1 | +| - ModusToolbox™ Device Configurator | 4.10 | +| - ModusToolbox™ CapSense Configurator / Tuner tools | 6.10.0 | +| Peripheral Driver Library (PDL CAT1) | 3.9.0 | +| GCC Compiler | 11.3.1 | +| IAR Compiler | 9.30.1 | +| Arm Compiler 6 | 6.16 | diff --git a/configs/COMPONENT_MCUBOOT/flash/COMPONENT_OTA_PSOC_062/flash_qspi.c b/configs/COMPONENT_MCUBOOT/flash/COMPONENT_OTA_PSOC_062/flash_qspi.c new file mode 100644 index 0000000..631d3a4 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flash/COMPONENT_OTA_PSOC_062/flash_qspi.c @@ -0,0 +1,507 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Source file of external flash driver adaptation layer between PSoC6 + * and standard MCUBoot code. + */ + + +#ifdef OTA_USE_EXTERNAL_FLASH + +#include "cy_pdl.h" +#include +#include "flash_qspi.h" + +#define CY_SMIF_SYSCLK_HFCLK_DIVIDER CY_SYSCLK_CLKHF_DIVIDE_BY_2 + +#define CY_SMIF_INIT_TRY_COUNT (10U) + +/* This is the board specific stuff that should align with your board. + * + * QSPI resources: + * + * SS0 - P11_2 + * SS1 - P11_1 + * SS2 - P11_0 + * SS3 - P12_4 + * + * D3 - P11_3 + * D2 - P11_4 + * D1 - P11_5 + * D0 - P11_6 + * + * SCK - P11_7 + * + * SMIF Block - SMIF0 + * + */ + +/* SMIF SlaveSelect Configurations */ +struct qspi_ss_config +{ + GPIO_PRT_Type* SS_Port; + uint32_t SS_Pin; + en_hsiom_sel_t SS_Mux; +}; + +#if (defined(PSOC_064_2M) || \ + defined(PSOC_064_1M) || \ + defined(PSOC_062_2M) || \ + defined(PSOC_062_1M)) + #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 4 +#elif defined(PSOC_064_512K) || defined(PSOC_062_512K) || defined(CYW20829) + #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 3 +#else +#error "Platform device name is unsupported." +#endif +static struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] = +{ + { + .SS_Port = GPIO_PRT11, + .SS_Pin = 2u, + .SS_Mux = P11_2_SMIF_SPI_SELECT0 + }, + { + .SS_Port = GPIO_PRT11, + .SS_Pin = 1u, + .SS_Mux = P11_1_SMIF_SPI_SELECT1 + }, + { + .SS_Port = GPIO_PRT11, + .SS_Pin = 0u, + .SS_Mux = P11_0_SMIF_SPI_SELECT2 + }, +#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3) + { + .SS_Port = GPIO_PRT12, + .SS_Pin = 4u, + .SS_Mux = P12_4_SMIF_SPI_SELECT3 + } +#endif +}; + +static GPIO_PRT_Type *D3Port = GPIO_PRT11; +static uint32_t D3Pin = 3u; +static en_hsiom_sel_t D3MuxPort = P11_3_SMIF_SPI_DATA3; + +static GPIO_PRT_Type *D2Port = GPIO_PRT11; +static uint32_t D2Pin = 4u; +static en_hsiom_sel_t D2MuxPort = P11_4_SMIF_SPI_DATA2; + +static GPIO_PRT_Type *D1Port = GPIO_PRT11; +static uint32_t D1Pin = 5u; +static en_hsiom_sel_t D1MuxPort = P11_5_SMIF_SPI_DATA1; + +static GPIO_PRT_Type *D0Port = GPIO_PRT11; +static uint32_t D0Pin = 6u; +static en_hsiom_sel_t D0MuxPort = P11_6_SMIF_SPI_DATA0; + +static GPIO_PRT_Type *SCKPort = GPIO_PRT11; +static uint32_t SCKPin = 7u; +static en_hsiom_sel_t SCKMuxPort = P11_7_SMIF_SPI_CLK; + +static SMIF_Type *QSPIPort = SMIF0; + +static cy_stc_smif_mem_cmd_t sfdpcmd = +{ + .command = 0x5A, + .cmdWidth = CY_SMIF_WIDTH_SINGLE, + .addrWidth = CY_SMIF_WIDTH_SINGLE, + .mode = 0xFFFFFFFFU, + .dummyCycles = 8, + .dataWidth = CY_SMIF_WIDTH_SINGLE, +}; + +static cy_stc_smif_mem_cmd_t rdcmd0; +static cy_stc_smif_mem_cmd_t wrencmd0; +static cy_stc_smif_mem_cmd_t wrdiscmd0; +static cy_stc_smif_mem_cmd_t erasecmd0; +static cy_stc_smif_mem_cmd_t chiperasecmd0; +static cy_stc_smif_mem_cmd_t pgmcmd0; +static cy_stc_smif_mem_cmd_t readsts0; +static cy_stc_smif_mem_cmd_t readstsqecmd0; +static cy_stc_smif_mem_cmd_t writestseqcmd0; + +static cy_stc_smif_mem_device_cfg_t dev_sfdp_0 = +{ + .numOfAddrBytes = 4, + .readSfdpCmd = &sfdpcmd, + .readCmd = &rdcmd0, + .writeEnCmd = &wrencmd0, + .writeDisCmd = &wrdiscmd0, + .programCmd = &pgmcmd0, + .eraseCmd = &erasecmd0, + .chipEraseCmd = &chiperasecmd0, + .readStsRegWipCmd = &readsts0, + .readStsRegQeCmd = &readstsqecmd0, + .writeStsRegQeCmd = &writestseqcmd0, +}; + +static cy_stc_smif_mem_config_t mem_sfdp_0 = +{ + /* The base address the memory slave is mapped to in the PSoC memory map. + Valid when the memory-mapped mode is enabled. */ + .baseAddress = CY_XIP_BASE, + /* The size allocated in the PSoC memory map, for the memory slave device. + The size is allocated from the base address. Valid when the memory mapped mode is enabled. */ + .memMappedSize = CY_XIP_SIZE, + .flags = CY_SMIF_FLAG_DETECT_SFDP | CY_SMIF_FLAG_MEMORY_MAPPED, + .slaveSelect = CY_SMIF_SLAVE_SELECT_0, + .dataSelect = CY_SMIF_DATA_SEL0, + .deviceCfg = &dev_sfdp_0 +}; + + +static cy_stc_smif_mem_config_t *mems_sfdp[1] = +{ + &mem_sfdp_0 +}; + +static cy_stc_smif_block_config_t smifBlockConfig_sfdp = +{ + .memCount = 1, + .memConfig = mems_sfdp, +}; + +static cy_stc_smif_block_config_t *smif_blk_config; + +static cy_stc_smif_context_t QSPI_context; + +static cy_stc_smif_config_t const QSPI_config = +{ + .mode = (uint32_t)CY_SMIF_NORMAL, + .deselectDelay = 1, + .rxClockSel = (uint32_t)CY_SMIF_SEL_INV_INTERNAL_CLK, + .blockEvent = (uint32_t)CY_SMIF_BUS_ERROR +}; + +#ifdef CM0P +static cy_stc_sysint_t smifIntConfig = +{/* ATTENTION: make sure proper Interrupts configured for CM0p or M4 cores */ + .intrSrc = NvicMux7_IRQn, + .cm0pSrc = smif_interrupt_IRQn, + .intrPriority = 1 +}; +#endif + +/* SMIF pinouts configurations */ +static cy_stc_gpio_pin_config_t QSPI_SS_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG_IN_OFF, + .hsiom = P11_2_SMIF_SPI_SELECT0, /* lets use SS0 by default */ + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +static const cy_stc_gpio_pin_config_t QSPI_DATA3_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_3_SMIF_SPI_DATA3, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +static const cy_stc_gpio_pin_config_t QSPI_DATA2_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_4_SMIF_SPI_DATA2, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +static const cy_stc_gpio_pin_config_t QSPI_DATA1_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_5_SMIF_SPI_DATA1, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +static const cy_stc_gpio_pin_config_t QSPI_DATA0_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_6_SMIF_SPI_DATA0, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +static const cy_stc_gpio_pin_config_t QSPI_SCK_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG_IN_OFF, + .hsiom = P11_7_SMIF_SPI_CLK, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; + +#ifdef CM0P +static void Isr_SMIF(void) +{ + Cy_SMIF_Interrupt(QSPIPort, &QSPI_context); +} +#endif + +cy_en_smif_status_t qspi_init_hardware(void) +{ + cy_en_smif_status_t st; + + + (void)Cy_GPIO_Pin_Init(D3Port, D3Pin, &QSPI_DATA3_config); + Cy_GPIO_SetHSIOM(D3Port, D3Pin, D3MuxPort); + + (void)Cy_GPIO_Pin_Init(D2Port, D2Pin, &QSPI_DATA2_config); + Cy_GPIO_SetHSIOM(D2Port, D2Pin, D2MuxPort); + + (void)Cy_GPIO_Pin_Init(D1Port, D1Pin, &QSPI_DATA1_config); + Cy_GPIO_SetHSIOM(D1Port, D1Pin, D1MuxPort); + + (void)Cy_GPIO_Pin_Init(D0Port, D0Pin, &QSPI_DATA0_config); + Cy_GPIO_SetHSIOM(D0Port, D0Pin, D0MuxPort); + + (void)Cy_GPIO_Pin_Init(SCKPort, SCKPin, &QSPI_SCK_config); + Cy_GPIO_SetHSIOM(SCKPort, SCKPin, SCKMuxPort); + + (void)Cy_SysClk_ClkHfSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SYSCLK_CLKHF_IN_CLKPATH0); + (void)Cy_SysClk_ClkHfSetDivider(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SMIF_SYSCLK_HFCLK_DIVIDER); + (void)Cy_SysClk_ClkHfEnable(CY_SYSCLK_CLKHF_IN_CLKPATH2); + + /* + * Setup the interrupt for the SMIF block. For the CM0 there + * is a two stage process to setup the interrupts. + */ +#ifdef CM0P + (void)Cy_SysInt_Init(&smifIntConfig, Isr_SMIF); +#endif + + st = Cy_SMIF_Init(QSPIPort, &QSPI_config, 1000, &QSPI_context); + if (st != CY_SMIF_SUCCESS) + { + return st; + } + +#ifdef CM0P + NVIC_EnableIRQ(smifIntConfig.intrSrc); /* Finally, Enable the SMIF interrupt */ +#endif + + Cy_SMIF_Enable(QSPIPort, &QSPI_context); + + return CY_SMIF_SUCCESS; +} + +cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index) +{ + return smif_blk_config->memConfig[index]; +} + +SMIF_Type *qspi_get_device(void) +{ + return QSPIPort; +} + +cy_stc_smif_context_t *qspi_get_context(void) +{ + return &QSPI_context; +} + +cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config) +{ + cy_en_smif_status_t st; + + st = qspi_init_hardware(); + if (st == CY_SMIF_SUCCESS) + { + smif_blk_config = blk_config; + st = Cy_SMIF_MemInit(QSPIPort, smif_blk_config, &QSPI_context); + } + return st; +} + +cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id) +{ + cy_en_smif_status_t stat = CY_SMIF_SUCCESS; + + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + + GPIO_PRT_Type *SS_Port; + uint32_t SS_Pin; + en_hsiom_sel_t SS_MuxPort; + + switch(smif_id) + { + case 1: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_0; + break; + case 2: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_1; + break; + case 3: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_2; + break; +#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3) + case 4: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_3; + break; +#endif + default: + stat = CY_SMIF_BAD_PARAM; + break; + } + + if(CY_SMIF_SUCCESS == stat) + { + SS_Port = qspi_SS_Configuration[smif_id-1U].SS_Port; + SS_Pin = qspi_SS_Configuration[smif_id-1U].SS_Pin; + SS_MuxPort = qspi_SS_Configuration[smif_id-1U].SS_Mux; + + QSPI_SS_config.hsiom = SS_MuxPort; + + (void)Cy_GPIO_Pin_Init(SS_Port, SS_Pin, &QSPI_SS_config); + Cy_GPIO_SetHSIOM(SS_Port, SS_Pin, SS_MuxPort); + + uint32_t try_count = CY_SMIF_INIT_TRY_COUNT; + do { + stat = qspi_init(&smifBlockConfig_sfdp); + + try_count--; + if (stat != CY_SMIF_SUCCESS) + { + Cy_SysLib_Delay(500U); + } + } while ((stat != CY_SMIF_SUCCESS) && (try_count > 0U)); + } + return stat; +} + +uint32_t qspi_get_prog_size(void) +{ + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + return (*memCfg)->deviceCfg->programSize; +} + +uint32_t qspi_get_erase_size(void) +{ + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + return (*memCfg)->deviceCfg->eraseSize; +} + +uint32_t qspi_get_mem_size(void) +{ + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + return (*memCfg)->deviceCfg->memSize; +} + +void qspi_deinit(uint32_t smif_id) +{ + Cy_SMIF_MemDeInit(QSPIPort); + + Cy_SMIF_Disable(QSPIPort); + + (void)Cy_SysClk_ClkHfDisable(CY_SYSCLK_CLKHF_IN_CLKPATH2); + +#ifdef CM0P + NVIC_DisableIRQ(smifIntConfig.intrSrc); + Cy_SysInt_DisconnectInterruptSource(smifIntConfig.intrSrc, smifIntConfig.cm0pSrc); +#endif + + Cy_GPIO_Port_Deinit(qspi_SS_Configuration[smif_id-1U].SS_Port); + Cy_GPIO_Port_Deinit(SCKPort); + Cy_GPIO_Port_Deinit(D0Port); + Cy_GPIO_Port_Deinit(D1Port); + Cy_GPIO_Port_Deinit(D2Port); + Cy_GPIO_Port_Deinit(D3Port); +} + +void qspi_set_mode(cy_en_smif_mode_t mode) +{ + SMIF_Type* smif_mem = qspi_get_device(); + + Cy_SMIF_SetMode(smif_mem, mode); +} + +cy_en_smif_mode_t qspi_get_mode(void) +{ + SMIF_Type* smif_mem = qspi_get_device(); + + return Cy_SMIF_GetMode(smif_mem); +} + +#endif /* OTA_USE_EXTERNAL_FLASH */ diff --git a/configs/COMPONENT_MCUBOOT/flash/COMPONENT_OTA_PSOC_062/flash_qspi.h b/configs/COMPONENT_MCUBOOT/flash/COMPONENT_OTA_PSOC_062/flash_qspi.h new file mode 100644 index 0000000..80c96de --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flash/COMPONENT_OTA_PSOC_062/flash_qspi.h @@ -0,0 +1,64 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Header file for PSoC6 external flash driver adoption layer. + */ + +#ifndef _FLASH_QSPI_H +#define _FLASH_QSPI_H + +#ifdef OTA_USE_EXTERNAL_FLASH + +#include +#include "cy_pdl.h" + +cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id); +cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config); +cy_en_smif_status_t qspi_init_hardware(void); +uint32_t qspi_get_prog_size(void); +uint32_t qspi_get_erase_size(void); +uint32_t qspi_get_mem_size(void); + +SMIF_Type *qspi_get_device(void); +cy_stc_smif_context_t *qspi_get_context(void); +cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index); + +void qspi_deinit(uint32_t smif_id); + +void qspi_set_mode(cy_en_smif_mode_t mode); +cy_en_smif_mode_t qspi_get_mode(void); + +#endif /* OTA_USE_EXTERNAL_FLASH */ + +#endif /* _FLASH_QSPI_H */ diff --git a/configs/COMPONENT_MCUBOOT/flash/cy_ota_flash.c b/configs/COMPONENT_MCUBOOT/flash/cy_ota_flash.c new file mode 100644 index 0000000..f30d01f --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flash/cy_ota_flash.c @@ -0,0 +1,1127 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Flash operation callback implementation for OTA update. + */ + +/* Header file includes */ +#include +#include +#include +#include +#include "cy_pdl.h" +#include "cyhal.h" +#include "cybsp.h" +#include "cy_ota_flash.h" + +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) +#include +#endif + +/********************************************************************************************************************************** + * local defines + **********************************************************************************************************************************/ +/* This defines if External Flash (SMIF) will be used for Upgrade Slots */ +#if defined(CYW20829) +#define CY_FLASH_BASE CY_XIP_BASE /* Override value in /mtb-pdl-cat1/devices/COMPONENT_CAT1A/include/cy_device_common.h for CYW20829 */ +#define CY_FLASH_SIZEOF_ROW 512u /* Override value in /mtb-pdl-cat1/devices/COMPONENT_CAT1A/include/cy_device_common.h for CYW20829 */ +#endif /* CYW20829 */ + +#if defined(XMC7200) +#define CY_XIP_BASE 0x60000000UL +#define CY_FLASH_SIZE 0x830000UL +#define CY_FLASH_BASE 0x10000000UL +#endif /* XMC7200 */ + +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) +/* UN-comment to test the write functionality */ +//#define READBACK_SMIF_WRITE_TEST + +// SMIF slot from which the memory configuration is picked up - fixed to 0 as +// the driver supports only one device +#define MEM_SLOT (0u) + +/* Set it high enough for the sector erase operation to complete */ +#define MEMORY_BUSY_CHECK_RETRIES (750ul) +#define _CYHAL_QSPI_DESELECT_DELAY (7UL) + +/* cyhal_qspi_init() succeeded */ +#define FLAG_HAL_INIT_DONE (0x01lu << 0) + +#define IS_FLAG_SET(mask) (status_flags & (mask)) +#define SET_FLAG(mask) (status_flags |= (mask)) +#define CLEAR_FLAG(mask) (status_flags &= ~(mask)) + +/* QSPI bus frequency set to 50 Mhz */ +#define QSPI_BUS_FREQUENCY_HZ (50000000lu) + +#define TIMEOUT_1_MS (1000lu) + +#define CY_SMIF_BASE_MEM_OFFSET CY_XIP_BASE + +#ifdef CY_XIP_SMIF_MODE_CHANGE + +/* + * IMPORTANT NOTE. Do not add calls to non-RAM resident routines + * between TURN_OFF_XIP and TURN_ON_XIP calls or you will break + * XIP environments. + */ + +#define PRE_SMIF_ACCESS_TURN_OFF_XIP \ + uint32_t interruptState; \ + interruptState = Cy_SysLib_EnterCriticalSection(); \ + while(Cy_SMIF_BusyCheck(SMIF0)); \ + (void)Cy_SMIF_SetMode(SMIF0, CY_SMIF_NORMAL); + +#define POST_SMIF_ACCESS_TURN_ON_XIP \ + while(Cy_SMIF_BusyCheck(SMIF0)); \ + (void)Cy_SMIF_SetMode(SMIF0, CY_SMIF_MEMORY); \ + Cy_SysLib_ExitCriticalSection(interruptState); + + +#else +#define PRE_SMIF_ACCESS_TURN_OFF_XIP +#define POST_SMIF_ACCESS_TURN_ON_XIP +#endif + +/********************************************************************************************************************************** + * local variables & data + **********************************************************************************************************************************/ + +static cy_stc_smif_context_t ota_QSPI_context; +static volatile uint32_t status_flags; + +/* Default QSPI configuration */ +const cy_stc_smif_config_t ota_SMIF_config = +{ + .mode = (uint32_t)CY_SMIF_NORMAL, + .deselectDelay = _CYHAL_QSPI_DESELECT_DELAY, +#if (CY_IP_MXSMIF_VERSION >= 2) + .rxClockSel = (uint32_t)CY_SMIF_SEL_INVERTED_FEEDBACK_CLK, +#else + .rxClockSel = (uint32_t)CY_SMIF_SEL_INV_INTERNAL_CLK, +#endif + .blockEvent = (uint32_t)CY_SMIF_BUS_ERROR, +}; + +extern const cy_stc_smif_mem_config_t* const smifMemConfigs[]; +extern const cy_stc_smif_block_config_t smifBlockConfig; + +#ifdef READBACK_SMIF_WRITE_TEST +/* Used for testing the write functionality */ +static uint8_t read_back_test[1024]; +#endif +#endif /* CY_IP_MXSMIF & !XMC7200 */ + + +/********************************************************************************************************************************** + * Internal Functions + **********************************************************************************************************************************/ +#if defined(CY_IP_MXSMIF) && !defined(PSOC_062_1M) && !defined(XMC7200) +#if defined(OTA_USE_EXTERNAL_FLASH) +/******************************************************************************* +* Function Name: IsMemoryReady +****************************************************************************//** +* +* Polls the memory device to check whether it is ready to accept new commands or +* not until either it is ready or the retries have exceeded the limit. +* +* \param memConfig +* memory device configuration +* +* \return Status of the operation. +* CY_SMIF_SUCCESS - Memory is ready to accept new commands. +* CY_SMIF_EXCEED_TIMEOUT - Memory is busy. +* +*******************************************************************************/ +static cy_en_smif_status_t IsMemoryReady(cy_stc_smif_mem_config_t const *memConfig) +{ + uint32_t retries = 0; + bool isBusy; + + do + { + isBusy = Cy_SMIF_Memslot_IsBusy(SMIF0, (cy_stc_smif_mem_config_t* )memConfig, &ota_QSPI_context); + Cy_SysLib_Delay(5); + retries++; + }while(isBusy && (retries < MEMORY_BUSY_CHECK_RETRIES)); + + return (isBusy ? CY_SMIF_EXCEED_TIMEOUT : CY_SMIF_SUCCESS); +} + +/******************************************************************************* +* Function Name: IsQuadEnabled +****************************************************************************//** +* +* Checks whether QE (Quad Enable) bit is set or not in the configuration +* register of the memory. +* +* \param memConfig +* Memory device configuration +* +* \param isQuadEnabled +* This parameter is updated to indicate whether Quad mode is enabled (true) or +* not (false). The value is valid only when the function returns +* CY_SMIF_SUCCESS. +* +* \return Status of the operation. See cy_en_smif_status_t. +* +*******************************************************************************/ +static cy_en_smif_status_t IsQuadEnabled(cy_stc_smif_mem_config_t const *memConfig, bool *isQuadEnabled) +{ + cy_en_smif_status_t status; + uint8_t readStatus = 0; + uint32_t statusCmd = memConfig->deviceCfg->readStsRegQeCmd->command; + uint8_t maskQE = (uint8_t) memConfig->deviceCfg->stsRegQuadEnableMask; + + status = Cy_SMIF_Memslot_CmdReadSts(SMIF0, memConfig, &readStatus, statusCmd, &ota_QSPI_context); + + *isQuadEnabled = false; + if(CY_SMIF_SUCCESS == status) + { + /* Check whether Quad mode is already enabled or not */ + *isQuadEnabled = (maskQE == (readStatus & maskQE)); + } + + return status; +} + +/******************************************************************************* +* Function Name: EnableQuadMode +****************************************************************************//** +* +* This function sets the QE (QUAD Enable) bit in the external memory +* configuration register to enable Quad SPI mode. +* +* \param memConfig +* Memory device configuration +* +* \return Status of the operation. See cy_en_smif_status_t. +* +*******************************************************************************/ +static cy_en_smif_status_t EnableQuadMode(cy_stc_smif_mem_config_t const *memConfig) +{ + cy_en_smif_status_t status; + + /* Send Write Enable to external memory */ + status = Cy_SMIF_Memslot_CmdWriteEnable(SMIF0, smifMemConfigs[0], &ota_QSPI_context); + + if(CY_SMIF_SUCCESS == status) + { + status = Cy_SMIF_Memslot_QuadEnable(SMIF0, (cy_stc_smif_mem_config_t* )memConfig, &ota_QSPI_context); + + if(CY_SMIF_SUCCESS == status) + { + /* Poll memory for the completion of operation */ + status = IsMemoryReady(memConfig); + } + } + + return status; +} +#endif /* OTA_USE_EXTERNAL_FLASH */ +#endif /* CY_IP_MXSMIF & !PSOC_062_1M & !XMC7200 */ + +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML) || defined (XMC7200)) +static int psoc6_internal_flash_write(uint8_t data[], uint32_t address, size_t len) +{ + int retCode; + cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS; + + uint32_t writeBuffer[CY_FLASH_SIZEOF_ROW / sizeof(uint32_t)]; + uint32_t rowId; + uint32_t dstIndex; + uint32_t srcIndex = 0u; + uint32_t eeOffset; + uint32_t byteOffset; + uint32_t rowsNotEqual; + uint8_t *writeBufferPointer; + + eeOffset = (uint32_t)address; + writeBufferPointer = (uint8_t*)writeBuffer; + + bool cond1; + + /* Make sure, that varFlash[] points to Flash */ + cond1 = ((eeOffset >= CY_FLASH_BASE) && ((eeOffset + len) <= (CY_FLASH_BASE + CY_FLASH_SIZE))); + + if(cond1) + { + eeOffset -= CY_FLASH_BASE; + rowId = eeOffset / CY_FLASH_SIZEOF_ROW; + byteOffset = CY_FLASH_SIZEOF_ROW * rowId; + + while((srcIndex < len) && (rc == CY_FLASH_DRV_SUCCESS)) + { + rowsNotEqual = 0u; + /* Copy data to the write buffer either from the source buffer or from the flash */ + for(dstIndex = 0u; dstIndex < CY_FLASH_SIZEOF_ROW; dstIndex++) + { + if((byteOffset >= eeOffset) && (srcIndex < len)) + { + writeBufferPointer[dstIndex] = data[srcIndex]; + /* Detect that row programming is required */ + if((rowsNotEqual == 0u) && ( (CY_GET_REG8(CY_FLASH_BASE + byteOffset) != data[srcIndex]) ) ) + { + rowsNotEqual = 1u; + } + srcIndex++; + } + else + { + writeBufferPointer[dstIndex] = CY_GET_REG8(CY_FLASH_BASE + byteOffset); + } + byteOffset++; + } + + if(rowsNotEqual != 0u) + { + /* Write flash row */ + rc = Cy_Flash_WriteRow((rowId * CY_FLASH_SIZEOF_ROW) + CY_FLASH_BASE, writeBuffer); + } + + /* Go to the next row */ + rowId++; + } + } + else + { + rc = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS; + } + + /* Return error code */ + switch(rc) + { + case CY_FLASH_DRV_SUCCESS: + retCode = 0; + break; + + case CY_FLASH_DRV_INVALID_INPUT_PARAMETERS: + case CY_FLASH_DRV_INVALID_FLASH_ADDR: + retCode = 1; + break; + + default: + retCode = 2; + break; + } + return(retCode); +} + +static int psoc6_internal_flash_erase(uint32_t addr, size_t size) +{ + int rc = 0; + + uint32_t addrStart, addrEnd, address; + uint32_t remStart, remEnd; + uint32_t rowIdxStart, rowIdxEnd, rowNum; + uint8_t buff[CY_FLASH_SIZEOF_ROW]; + + /* flash_area_write() uses offsets, we need absolute address here */ + addr += CY_FLASH_BASE; + + addrStart = addr; + addrEnd = addrStart + size; + + /* find if area bounds are aligned to rows */ + remStart = addrStart%CY_FLASH_SIZEOF_ROW; + remEnd = addrEnd%CY_FLASH_SIZEOF_ROW; + + /* find which row numbers are affected for full Erase */ + rowIdxStart = addrStart/CY_FLASH_SIZEOF_ROW; + rowIdxEnd = addrEnd/CY_FLASH_SIZEOF_ROW; + + if(remStart != 0) + {/* first row is fragmented, move to next */ + rowIdxStart++; + } + + /* total number of rows for full erase */ + rowNum = rowIdxEnd - rowIdxStart; + address = rowIdxStart*CY_FLASH_SIZEOF_ROW; + + while(rowNum>0) + { + rc = Cy_Flash_EraseRow(address); + assert(rc == 0); + address += CY_FLASH_SIZEOF_ROW; + rowNum--; + } + + /* if Start of erase area is unaligned */ + if(remStart != 0) + { + /* first row is fragmented, shift left by one*/ + rowIdxStart--; + + /* find start address of fragmented row */ + address = rowIdxStart*CY_FLASH_SIZEOF_ROW; + + /* store fragmented row contents first */ + memcpy((void *)buff, (const void*)address, remStart); + + /* erase fragmented row */ + rc = Cy_Flash_EraseRow(address); + assert(rc == 0); + + /* write stored back */ + rc = psoc6_internal_flash_write(buff, address, remStart); + assert(rc == 0); + } + /* if End of erase area is unaligned */ + if(remEnd != 0) + { + /* find start address of fragmented row */ + address = rowIdxEnd*CY_FLASH_SIZEOF_ROW; + + /* store fragmented row contents first */ + memcpy((void *)buff, (const void*)addrEnd, CY_FLASH_SIZEOF_ROW-remEnd); + + /* erase fragmented row */ + rc = Cy_Flash_EraseRow(address); + assert(rc == 0); + + /* write stored back */ + rc = psoc6_internal_flash_write(buff, addrEnd, CY_FLASH_SIZEOF_ROW-remEnd); + assert(rc == 0); + } + return rc; +} +#endif + +#if defined (XMC7200) +CY_SECTION_RAMFUNC_BEGIN +static int xmc_internal_flash_erase(uint32_t addr, size_t size) +{ + int rc = 0; + uint32_t row_addr = 0u; + uint32_t erase_sz = 0x8000U; //32KB + cy_en_flashdrv_status_t flashEraseStatus; + + /* flash_area_write() uses offsets, we need absolute address here */ + addr += CY_FLASH_BASE; + + uintptr_t erase_end_addr = addr + size; + uint32_t row_start_addr = (addr / erase_sz) * erase_sz; + uint32_t row_end_addr = (erase_end_addr / erase_sz) * erase_sz; + uint32_t row_number = (row_end_addr - row_start_addr) / erase_sz; + + /* assume single row needs to be erased */ + if (row_start_addr == row_end_addr) { + row_number = 1U; + } + + Cy_Flash_Init(); + Cy_Flashc_MainWriteEnable(); + + while (row_number != 0u) { + row_number--; + row_addr = row_start_addr + row_number * (uint32_t)erase_sz; + + flashEraseStatus = Cy_Flash_EraseSector((uint32_t) row_addr); + // Wait for completion with counting + while(Cy_Flash_IsOperationComplete() != CY_FLASH_DRV_SUCCESS) + { + } + if (flashEraseStatus != CY_FLASH_DRV_SUCCESS) + { + rc = 1; /* BOOT_EFLASH */ + break; + } else { + rc = 0; + } + } + + return rc; +} +CY_SECTION_RAMFUNC_END + +/* + * Writes `len` bytes of flash memory at `off` from the buffer at `src` + */ +CY_SECTION_RAMFUNC_BEGIN +static int xmc_internal_flash_write(uint8_t data[], uint32_t address, size_t len) +{ + int retCode; + cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS; + + uint32_t writeBuffer[CY_FLASH_SIZEOF_ROW / sizeof(uint32_t)]; + uint32_t rowId; + uint32_t dstIndex; + uint32_t srcIndex = 0u; + uint32_t eeOffset; + uint32_t byteOffset; + uint32_t rowsNotEqual; + uint8_t *writeBufferPointer; + + eeOffset = (uint32_t)address; + writeBufferPointer = (uint8_t*)writeBuffer; + + bool cond1; + + /* Make sure, that varFlash[] points to Flash */ + cond1 = ((eeOffset >= CY_FLASH_BASE) && ((eeOffset + len) <= (CY_FLASH_BASE + CY_FLASH_SIZE))); + + if(cond1) + { + eeOffset -= CY_FLASH_BASE; + rowId = eeOffset / CY_FLASH_SIZEOF_ROW; + byteOffset = CY_FLASH_SIZEOF_ROW * rowId; + + while((srcIndex < len) && (rc == CY_FLASH_DRV_SUCCESS)) + { + rowsNotEqual = 0u; + /* Copy data to the write buffer either from the source buffer or from the flash */ + for(dstIndex = 0u; dstIndex < CY_FLASH_SIZEOF_ROW; dstIndex++) + { + if((byteOffset >= eeOffset) && (srcIndex < len)) + { + writeBufferPointer[dstIndex] = data[srcIndex]; + /* Detect that row programming is required */ + if((rowsNotEqual == 0u) && ( (CY_GET_REG8(CY_FLASH_BASE + byteOffset) != data[srcIndex]) ) ) + { + rowsNotEqual = 1u; + } + srcIndex++; + } + else + { + writeBufferPointer[dstIndex] = CY_GET_REG8(CY_FLASH_BASE + byteOffset); + } + byteOffset++; + } + + if(rowsNotEqual != 0u) + { + rc = Cy_Flash_ProgramRow((rowId * CY_FLASH_SIZEOF_ROW) + CY_FLASH_BASE, writeBuffer); + if(rc == CY_FLASH_DRV_SUCCESS) + { + while(Cy_Flash_IsOperationComplete() != CY_FLASH_DRV_SUCCESS) + { + } + } + } + + /* Go to the next row */ + rowId++; + } + } + else + { + rc = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS; + } + + /* Return error code */ + switch(rc) + { + case CY_FLASH_DRV_SUCCESS: + retCode = 0; + break; + + case CY_FLASH_DRV_INVALID_INPUT_PARAMETERS: + case CY_FLASH_DRV_INVALID_FLASH_ADDR: + retCode = 1; + break; + + default: + retCode = 2; + break; + } + return(retCode); +} +CY_SECTION_RAMFUNC_END +#endif /* XMC7200 */ + +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) +static uint32_t ota_smif_get_memory_size(void) +{ + uint32_t size = 0; + + if (SMIF0 != NULL) + { + size = smifBlockConfig.memConfig[MEM_SLOT]->deviceCfg->memSize; + } + + return size; +} +#endif /* CY_IP_MXSMIF & !XMC7200 */ + +/********************************************************************************************************************************** + * External Functions + **********************************************************************************************************************************/ +/** + * @brief Initializes flash, QSPI flash, or any other external memory type + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +cy_rslt_t cy_ota_mem_init( void ) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) +#if defined(OTA_USE_EXTERNAL_FLASH) + cy_rslt_t smif_status = CY_SMIF_BAD_PARAM; /* Does not return error if SMIF Quad fails */ + bool QE_status = false; + + /* pre-access to SMIF */ + PRE_SMIF_ACCESS_TURN_OFF_XIP; + +#if (defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + /* SMIF is already initialized for 20829 so we are only initializing the + * SMIF base address and the context variables. + */ + smif_status = Cy_SMIF_Init(SMIF0, &ota_SMIF_config, TIMEOUT_1_MS, &ota_QSPI_context); + if (smif_status != CY_SMIF_SUCCESS) + { + result = smif_status; + goto _bail; + } +#endif + + /* Set up SMIF */ + Cy_SMIF_SetDataSelect(SMIF0, smifMemConfigs[0]->slaveSelect, smifMemConfigs[0]->dataSelect); + Cy_SMIF_Enable(SMIF0, &ota_QSPI_context); + + /* Map memory device to memory map */ + smif_status = Cy_SMIF_Memslot_Init(SMIF0, &smifBlockConfig, &ota_QSPI_context); + if (smif_status != CY_SMIF_SUCCESS) + { + result = smif_status; + goto _bail; + } + +#if (defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + /* Even after SFDP enumeration QE command is not initialized */ + /* So, it should be 1.0 device */ + if ((smifMemConfigs[0]->deviceCfg->readStsRegQeCmd->command == 0) || /* 0 - if configurator generated code */ + (smifMemConfigs[0]->deviceCfg->readStsRegQeCmd->command == CY_SMIF_NO_COMMAND_OR_MODE)) /* 0xFF's if SFDP enumerated */ + { + smif_status = Cy_SMIF_MemInitSfdpMode(SMIF0, + smifMemConfigs[0], + CY_SMIF_WIDTH_QUAD, + CY_SMIF_SFDP_QER_1, + &ota_QSPI_context); + if (smif_status != CY_SMIF_SUCCESS) + { + result = smif_status; + goto _bail; + } + } +#else /* NON - CYW20829A0LKML/CYW20829B0LKML */ + #if !defined(CY_RUN_CODE_FROM_XIP) && (OTA_USE_EXTERNAL_FLASH) + { + /* Choose SMIF slot number (slave select). + * Acceptable values are: + * 0 - SMIF disabled (no external memory); + * 1, 2, 3 or 4 - slave select line memory module is connected to. + */ + #define SMIF_ID (1U) /* Assume SlaveSelect_0 is used for External Memory */ + #include "flash_qspi.h" + cy_en_smif_status_t qspi_status = CY_SMIF_SUCCESS; + qspi_status = qspi_init_sfdp(SMIF_ID); + if(CY_SMIF_SUCCESS == qspi_status) + { + result = CY_RSLT_SUCCESS; + } + else + { + result = CY_RSLT_TYPE_ERROR; + } + } + #endif /* ! CY_RUN_CODE_FROM_XIP */ +#endif /* CYW20829A0LKML/CYW20829B0LKML */ + + smif_status = IsQuadEnabled(smifMemConfigs[0], &QE_status); + if(smif_status != CY_RSLT_SUCCESS) + { + result = CY_RSLT_TYPE_ERROR; + } + + /* If not enabled, enable quad mode */ + if(!QE_status) + { + /* Enable Quad mode */ + smif_status = EnableQuadMode(smifMemConfigs[0]); + if(smif_status != CY_RSLT_SUCCESS) + { + result = CY_RSLT_TYPE_ERROR; + } + } + + SET_FLAG(FLAG_HAL_INIT_DONE); + + _bail: + /* post-access to SMIF */ + POST_SMIF_ACCESS_TURN_ON_XIP; +#endif +#endif /* CY_IP_MXSMIF & !XMC7200 */ + return result; +} + +/** + * @brief Read from flash, QSPI flash, or any other external memory type + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to read from. + * @param[out] data Pointer to the buffer to store the data read from the memory. + * @param[in] len Number of data bytes to read. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +cy_rslt_t cy_ota_mem_read( cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len ) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + + if( mem_type == CY_OTA_MEM_TYPE_INTERNAL_FLASH ) + { +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + /* flash_area_read() uses offsets, we need absolute address here */ + addr += CY_FLASH_BASE; + + /* flash read by simple memory copying */ + memcpy((void *)data, (const void*)addr, (size_t)len); + return result; +#else + (void)result; + printf("%s() READ not supported for memory type %d\n", __func__, (int)mem_type); + return CY_RSLT_TYPE_ERROR; +#endif + } + else if( mem_type == CY_OTA_MEM_TYPE_EXTERNAL_FLASH ) + { +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) + cy_en_smif_status_t cy_smif_result = CY_SMIF_SUCCESS; + if (addr >= CY_SMIF_BASE_MEM_OFFSET) + { + addr -= CY_SMIF_BASE_MEM_OFFSET; + } + + if (IS_FLAG_SET(FLAG_HAL_INIT_DONE)) + { + /* pre-access to SMIF */ + PRE_SMIF_ACCESS_TURN_OFF_XIP; + + cy_smif_result = Cy_SMIF_MemRead(SMIF0, smifBlockConfig.memConfig[MEM_SLOT], + addr, data, len, &ota_QSPI_context); + /* post-access to SMIF */ + POST_SMIF_ACCESS_TURN_ON_XIP; + } + + return (cy_smif_result == CY_SMIF_SUCCESS) ? CY_RSLT_SUCCESS : CY_RSLT_TYPE_ERROR; +#else + return CY_RSLT_TYPE_ERROR; +#endif /* CY_IP_MXSMIF & !XMC7200 */ + } + else + { + printf("%s() READ not supported for memory type %d\n", __func__, (int)mem_type); + return CY_RSLT_TYPE_ERROR; + } +} + +static cy_rslt_t cy_ota_mem_write_row_size( cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len ) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + + if( mem_type == CY_OTA_MEM_TYPE_INTERNAL_FLASH ) + { +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + int rc = 0; + + /* flash_area_write() uses offsets, we need absolute address here */ + addr += CY_FLASH_BASE; + +#if defined (XMC7200) + rc = xmc_internal_flash_write((uint8_t *)data, addr, len); + if (rc != 0 ) + { + printf("xmc_internal_flash_write(0x%08x, 0x%08x, %u) FAILED rc:%u\n", (unsigned int)data, (unsigned int)addr, len, rc); + result = CY_RSLT_TYPE_ERROR; + } + return result; +#else + rc = psoc6_internal_flash_write((uint8_t *)data, addr, len); + if (rc != 0 ) + { + result = CY_RSLT_TYPE_ERROR; + } + return result; +#endif + +#else + (void)result; + printf("%s() Write not supported for memory type %d\n", __func__, (int)mem_type); + return CY_RSLT_TYPE_ERROR; +#endif + } + else if( mem_type == CY_OTA_MEM_TYPE_EXTERNAL_FLASH ) + { +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) + cy_en_smif_status_t cy_smif_result = CY_SMIF_SUCCESS; + + if (addr >= CY_SMIF_BASE_MEM_OFFSET) + { + addr -= CY_SMIF_BASE_MEM_OFFSET; + } + + if (IS_FLAG_SET(FLAG_HAL_INIT_DONE)) + { + /* pre-access to SMIF */ + PRE_SMIF_ACCESS_TURN_OFF_XIP; + + cy_smif_result = Cy_SMIF_MemWrite(SMIF0, smifBlockConfig.memConfig[MEM_SLOT], + addr, data, len, &ota_QSPI_context); + + /* post-access to SMIF */ + POST_SMIF_ACCESS_TURN_ON_XIP; + } + else + { + cy_smif_result = (cy_en_smif_status_t)CY_RSLT_SERIAL_FLASH_ERR_NOT_INITED; + } + + #ifdef READBACK_SMIF_WRITE_TEST + if (cy_smif_result == CY_SMIF_SUCCESS) + { + if (ota_mem_read(CY_OTA_MEM_TYPE_EXTERNAL_FLASH, addr, read_back_test, ((16 < length) ? 16 : len)) == CY_RSLT_SUCCESS) + { + int i; + for (i=0; (i<16 && i 0x0U) + { + chunk_size = bytes_to_write; + if(chunk_size > CY_FLASH_SIZEOF_ROW) + { + chunk_size = CY_FLASH_SIZEOF_ROW; + } + + /* Is the chunk_size smaller than a flash row? */ + if((chunk_size % CY_FLASH_SIZEOF_ROW) != 0x0U) + { + uint32_t row_offset = 0; + uint32_t row_base = 0; + + row_base = (curr_addr / CY_FLASH_SIZEOF_ROW) * CY_FLASH_SIZEOF_ROW; + row_offset = curr_addr - row_base; + + if((row_offset + chunk_size) > CY_FLASH_SIZEOF_ROW) + { + chunk_size = (CY_FLASH_SIZEOF_ROW - row_offset); + } + + /* we will read a CY_FLASH_SIZEOF_ROW byte block, write the new data into the block, then write the whole block */ + result = cy_ota_mem_read( mem_type, row_base, (void *)(&block_buffer[0]), sizeof(block_buffer)); + if(result != CY_RSLT_SUCCESS) + { + return CY_RSLT_TYPE_ERROR; + } + memcpy (&block_buffer[row_offset], curr_src, chunk_size); + + result = cy_ota_mem_write_row_size(mem_type, row_base, (void *)(&block_buffer[0]), sizeof(block_buffer)); + if(result != CY_RSLT_SUCCESS) + { + return CY_RSLT_TYPE_ERROR; + } + } + else + { + result = cy_ota_mem_write_row_size(mem_type, addr, data, len); + if(result != CY_RSLT_SUCCESS) + { + return CY_RSLT_TYPE_ERROR; + } + } + + curr_addr += chunk_size; + curr_src += chunk_size; + bytes_to_write -= chunk_size; + } + + return CY_RSLT_SUCCESS; +} + +/** + * @brief Erase flash, QSPI flash, or any other external memory type + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to begin erasing. + * @param[in] len Number of bytes to erase. + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_TYPE_ERROR + */ +cy_rslt_t cy_ota_mem_erase( cy_ota_mem_type_t mem_type, uint32_t addr, size_t len ) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + + if( mem_type == CY_OTA_MEM_TYPE_INTERNAL_FLASH ) + { +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + int rc = 0; + +#if defined (XMC7200) + rc = xmc_internal_flash_erase(addr, len); + if (rc != 0 ) + { + printf("xmc_internal_flash_erase(0x%08x, %u) FAILED rc:%d\n", (unsigned int)addr, len, rc); + result = CY_RSLT_TYPE_ERROR; + } +#else + rc = psoc6_internal_flash_erase(addr, len); + if (rc != 0 ) + { + result = CY_RSLT_TYPE_ERROR; + } +#endif + return result; +#else + (void)result; + printf("%s() Erase not supported for memory type %d\n", __func__, (int)mem_type); + return CY_RSLT_TYPE_ERROR; +#endif + } + else if( mem_type == CY_OTA_MEM_TYPE_EXTERNAL_FLASH ) + { +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) + cy_en_smif_status_t cy_smif_result = CY_SMIF_SUCCESS; + + if (addr >= CY_SMIF_BASE_MEM_OFFSET) + { + addr -= CY_SMIF_BASE_MEM_OFFSET; + } + + if (IS_FLAG_SET(FLAG_HAL_INIT_DONE)) + { + /* pre-access to SMIF */ + PRE_SMIF_ACCESS_TURN_OFF_XIP; + + // If the erase is for the entire chip, use chip erase command + if ((addr == 0u) && (len == ota_smif_get_memory_size())) + { + cy_smif_result = Cy_SMIF_MemEraseChip(SMIF0, + smifBlockConfig.memConfig[MEM_SLOT], + &ota_QSPI_context); + } + else + { + // Cy_SMIF_MemEraseSector() returns error if (addr + length) > total flash size or if + // addr is not aligned to erase sector size or if (addr + length) is not aligned to + // erase sector size. + /* Make sure the base offset is correct */ + uint32_t erase_size; + uint32_t diff; + erase_size = cy_ota_mem_get_erase_size(CY_OTA_MEM_TYPE_EXTERNAL_FLASH, addr); + diff = addr & (erase_size - 1); + addr -= diff; + len += diff; + /* Make sure the length is correct */ + len = (len + (erase_size - 1)) & ~(erase_size - 1); + Cy_SMIF_SetReadyPollingDelay(20000, &ota_QSPI_context); + cy_smif_result = Cy_SMIF_MemEraseSector(SMIF0, + smifBlockConfig.memConfig[MEM_SLOT], + addr, len, &ota_QSPI_context); + Cy_SMIF_SetReadyPollingDelay(0, &ota_QSPI_context); + } + + /* post-access to SMIF */ + POST_SMIF_ACCESS_TURN_ON_XIP; + } + else + { + return CY_RSLT_SERIAL_FLASH_ERR_NOT_INITED; + } + + return (cy_smif_result == CY_SMIF_SUCCESS) ? CY_RSLT_SUCCESS : CY_RSLT_TYPE_ERROR; +#else + return CY_RSLT_TYPE_ERROR; +#endif /* CY_IP_MXSMIF & !XMC7200 */ + } + else + { + printf("%s() Erase not supported for memory type %d\n", __func__, (int)mem_type); + return CY_RSLT_TYPE_ERROR; + } +} + +/** + * @brief To get page size for programming flash, QSPI flash, or any other external memory type + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Address that belongs to the sector for which programming page size needs to be returned. + * + * @return Page size in bytes. + */ +size_t cy_ota_mem_get_prog_size ( cy_ota_mem_type_t mem_type, uint32_t addr ) +{ + if( mem_type == CY_OTA_MEM_TYPE_INTERNAL_FLASH ) + { +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + return CY_FLASH_SIZEOF_ROW; +#else + return 0; +#endif + } + else if( mem_type == CY_OTA_MEM_TYPE_EXTERNAL_FLASH ) + { +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) + uint32_t program_size = 0; + (void)addr; /* Hybrid parts not yet supported */ + /* pre-access to SMIF is not needed, as we are just reading data from RAM */ + if (IS_FLAG_SET(FLAG_HAL_INIT_DONE)) + { + if (SMIF0 != NULL) + { + program_size = smifBlockConfig.memConfig[MEM_SLOT]->deviceCfg->programSize; + } + } + /* post-access to SMIF is not needed, as we are just reading data from RAM */ + + return program_size; +#else + return 0; +#endif /* CY_IP_MXSMIF & !XMC7200 */ + } + else + { + return 0; + } +} + +/** + * @brief To get sector size of flash, QSPI flash, or any other external memory type + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Address that belongs to the sector for which sector erase size needs to be returned. + * + * @return Sector size in bytes. + */ +size_t cy_ota_mem_get_erase_size ( cy_ota_mem_type_t mem_type, uint32_t addr ) +{ + if( mem_type == CY_OTA_MEM_TYPE_INTERNAL_FLASH ) + { +#if !(defined (CYW20829A0LKML) || defined (CYW20829B0LKML)) + return CY_FLASH_SIZEOF_ROW; +#else + return 0; +#endif + } + else if( mem_type == CY_OTA_MEM_TYPE_EXTERNAL_FLASH ) + { +#if (defined (CY_IP_MXSMIF) && !defined (XMC7200)) + uint32_t erase_sector_size = 0; + cy_stc_smif_hybrid_region_info_t* hybrid_info = NULL; + cy_en_smif_status_t smif_status; + + if (addr >= CY_SMIF_BASE_MEM_OFFSET) + { + addr -= CY_SMIF_BASE_MEM_OFFSET; + } + + /* pre-access to SMIF is not needed, as we are just reading data from RAM */ + if (IS_FLAG_SET(FLAG_HAL_INIT_DONE)) + { + /* Cy_SMIF_MemLocateHybridRegion() does not access the external flash, just data tables from RAM */ + smif_status = Cy_SMIF_MemLocateHybridRegion(smifBlockConfig.memConfig[MEM_SLOT], &hybrid_info, addr); + + if (CY_SMIF_SUCCESS != smif_status) + { + erase_sector_size = (size_t)smifBlockConfig.memConfig[MEM_SLOT]->deviceCfg->eraseSize; + } + else + { + erase_sector_size = (size_t)hybrid_info->eraseSize; + } + } + /* post-access to SMIF is not needed, as we are just reading data from RAM */ + + return erase_sector_size; +#else + return 0; +#endif /* CY_IP_MXSMIF & !XMC7200 */ + } + else + { + return 0; + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_overwrite_single.json b/configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_overwrite_single.json new file mode 100644 index 0000000..06af448 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_overwrite_single.json @@ -0,0 +1,40 @@ +{ + "external_flash": [ + { + "flash-size": "0x100000", + "erase-size": "0x1000", + "mode": "XIP" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x60000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x20000" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x60020000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x00060000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x60080000" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x00060000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_swap_single.json new file mode 100644 index 0000000..940d609 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_swap_single.json @@ -0,0 +1,56 @@ +{ + "external_flash": [ + { + "flash-size": "0x100000", + "erase-size": "0x1000", + "mode": "XIP" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x60000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00020000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x600EC000" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x00002000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x600E0000" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x0000C000" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x60020000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x00060000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x60080000" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x00060000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/policy_single_CM0_CM4_smif_swap.json b/configs/COMPONENT_MCUBOOT/flashmap/policy_single_CM0_CM4_smif_swap.json new file mode 100644 index 0000000..fad11f7 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/policy_single_CM0_CM4_smif_swap.json @@ -0,0 +1,188 @@ +{ + "policy": { + "platform": "psoc64", + "version": 1.0 + }, + "debug": { + "m0p": { + "permission": "enabled", + "control": "firmware", + "key": 5 + }, + "m4": { + "permission": "allowed", + "control": "firmware", + "key": 5 + }, + "system": { + "permission": "enabled", + "control": "firmware", + "key": 5, + "flashw": true, + "flashr": true + }, + "rma": { + "permission": "allowed", + "destroy_fuses": [ + { + "start": 888, + "size": 136 + } + ], + "destroy_flash": [ + { + "start": 268435456, + "size": 512 + } + ], + "key": 5 + } + }, + "boot_upgrade": { + "title": "upgrade_policy", + "firmware": [ + { + "boot_auth": [ + 3 + ], + "bootloader_keys": [ + { + "kid": 3, + "key": "../keys/cy_pub_key.json" + } + ], + "id": 0, + "launch": 1, + "upgrade_mode": "swap", + "acq_win": 100, + "wdt_timeout": 4000, + "wdt_enable": true, + "reset_after_failure": 0, + "monotonic": 0, + "clock_flags": 578, + "protect_flags": 1, + "upgrade": false, + "resources": [ + { + "type": "FLASH_PC1_SPM", + "address": 270336000, + "size": 65536 + }, + { + "type": "SRAM_SPM_PRIV", + "address": 135135232, + "size": 65536 + }, + { + "type": "SRAM_DAP", + "address": 135184384, + "size": 16384 + }, + { + "type": "STATUS_PARTITION", + "address": 270303232, + "size": 32768 + }, + { + "type": "SCRATCH", + "address": 405012480, + "size": 786432 + } + ] + }, + { + "boot_auth": [ + 8 + ], + "boot_keys": [ + { + "kid": 8, + "key": "../keys/USERAPP_CM4_KEY.json" + } + ], + "id": 1, + "launch": 16, + "monotonic": 0, + "smif_id": 1, + "smif_sector_size": 262144, + "acq_win": 100, + "wdt_timeout": 4000, + "wdt_enable": false, + "set_img_ok": false, + "upgrade": true, + "version": "0.1", + "rollback_counter": 0, + "encrypt": false, + "encrypt_key_id": 1, + "encrypt_peer": "../keys/dev_pub_key.pem", + "resources": [ + { + "type": "BOOT", + "address": 268435456, + "size": 1867776 + }, + { + "type": "UPGRADE", + "address": 402883584, + "size": 1867776 + } + ] + }, + { + "boot_auth": [ + 8 + ], + "boot_keys": [ + { + "kid": 8, + "key": "../keys/USERAPP_CM4_KEY.json" + } + ], + "id": 16, + "monotonic": 8, + "smif_id": 0, + "upgrade": false, + "version": "0.1", + "rollback_counter": 0, + "encrypt": false, + "encrypt_key_id": 1, + "encrypt_peer": "../keys/dev_pub_key.pem", + "resources": [ + { + "type": "BOOT", + "address": 268500992, + "size": 1802240 + } + ] + } + ], + "reprogram": [ + { + "start": 270336000, + "size": 65536 + } + ], + "reprovision": { + "boot_loader": true, + "keys_and_policies": true + } + }, + "cy_bootloader": { + "mode": "debug" + }, + "provisioning": { + "packet_dir": "../packets", + "chain_of_trust": [] + }, + "pre_build": { + "oem_public_key": "../keys/oem_state.json", + "oem_private_key": "../keys/oem_state.json", + "hsm_public_key": "../keys/hsm_state.json", + "hsm_private_key": "../keys/hsm_state.json", + "provision_group_private_key": false, + "group_private_key": "../keys/grp_priv_key.json", + "provision_device_private_key": false, + "device_private_key": "../keys/dev_priv_key.json", + "cy_auth": "../packets/cy_auth_2m_b0_sample.jwt" + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_1m_cm0_int_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_1m_cm0_int_swap_single.json new file mode 100644 index 0000000..b42b6d8 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_1m_cm0_int_swap_single.json @@ -0,0 +1,53 @@ +{ + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00018000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x100e0400" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x00004000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x100e4400" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x00002400" + } + }, + "application_1": { + "core": { + "description": "Run app on the specific core. PSoC6: CM0P or CM4", + "value": "CM0P" + }, + "address": { + "description": "Address of the application primary slot", + "value": "0x10020000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x00060000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x10080400" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x00060000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_overwrite_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_overwrite_single.json new file mode 100644 index 0000000..ba861c0 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_overwrite_single.json @@ -0,0 +1,38 @@ +{ + "external_flash": [ + { + "model": "S25HS256T" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00018000" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x10018000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x001c0000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x18000200" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x001c0000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_swap_single.json new file mode 100644 index 0000000..3e18e63 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_swap_single.json @@ -0,0 +1,54 @@ +{ + "external_flash": [ + { + "model": "S25HS256T" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00028000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x18440000" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x00080000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x101e8000" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x00006c00" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x10028000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x001c0000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x18000200" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x001c0000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_overwrite_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_overwrite_single.json new file mode 100644 index 0000000..56d1ffd --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_overwrite_single.json @@ -0,0 +1,33 @@ +{ + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00018000" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x10018000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x000EE000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x10106000" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x000EE000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_swap_single.json new file mode 100644 index 0000000..2dfe0c7 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_swap_single.json @@ -0,0 +1,49 @@ +{ + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00028000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x101f7c00" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x1000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x101f4000" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x00003c00" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x10028000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x000E6000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x1010E000" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x000E6000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_overwrite_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_overwrite_single.json new file mode 100644 index 0000000..218b669 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_overwrite_single.json @@ -0,0 +1,38 @@ +{ + "external_flash": [ + { + "model": "S25HS256T" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00018000" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x10018000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x00058200" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x18028000" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x00058200" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_swap_single.json new file mode 100644 index 0000000..3878d30 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_swap_single.json @@ -0,0 +1,54 @@ +{ + "external_flash": [ + { + "model": "S25HS256T" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00028000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x180C0000" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x00080000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x10074400" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x00003c00" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x10028000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x0004C000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x18034200" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x0004C000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_xip_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_xip_swap_single.json new file mode 100644 index 0000000..40f2840 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_xip_swap_single.json @@ -0,0 +1,55 @@ +{ + "external_flash": [ + { + "model": "S25HS256T", + "mode": "XIP" + } + ], + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x18000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x18440000" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x80000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x10018000" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x3c00" + } + }, + "application_1": { + "address": { + "description": "Address of the application primary slot", + "value": "0x18000000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x00140200" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x18180000" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x00140200" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/psoc63_1m_cm0_int_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/psoc63_1m_cm0_int_swap_single.json new file mode 100644 index 0000000..b42b6d8 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/psoc63_1m_cm0_int_swap_single.json @@ -0,0 +1,53 @@ +{ + "boot_and_upgrade": + { + "bootloader": { + "address": { + "description": "Address of the bootloader", + "value": "0x10000000" + }, + "size": { + "description": "Size of the bootloader", + "value": "0x00018000" + }, + "scratch_address": { + "description": "Address of the scratch area", + "value": "0x100e0400" + }, + "scratch_size": { + "description": "Size of the scratch area", + "value": "0x00004000" + }, + "status_address": { + "description": "Address of the swap status partition", + "value": "0x100e4400" + }, + "status_size": { + "description": "Size of the swap status partition", + "value": "0x00002400" + } + }, + "application_1": { + "core": { + "description": "Run app on the specific core. PSoC6: CM0P or CM4", + "value": "CM0P" + }, + "address": { + "description": "Address of the application primary slot", + "value": "0x10020000" + }, + "size": { + "description": "Size of the application primary slot", + "value": "0x00060000" + }, + "upgrade_address": { + "description": "Address of the application secondary slot", + "value": "0x10080400" + }, + "upgrade_size": { + "description": "Size of the application secondary slot", + "value": "0x00060000" + } + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_overwrite_single.json b/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_overwrite_single.json new file mode 100644 index 0000000..f5fb5d5 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_overwrite_single.json @@ -0,0 +1,19 @@ +{ + "bootloader": + { + "bootloader_area": + { + "address" : "0x10000000", + "size" : "0x20000" + } + }, + "application_1": + { + "slots": + { + "boot" : "0x10080000", + "upgrade" : "0x103F8000", + "size" : "0x00200000" + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_swap_single.json b/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_swap_single.json new file mode 100644 index 0000000..723a2a9 --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_swap_single.json @@ -0,0 +1,31 @@ +{ + "bootloader": + { + "bootloader_area": + { + "address" : "0x10000000", + "size" : "0x20000" + }, + + "status_area": + { + "address" : "0x14030000", + "size" : "0x2800" + }, + + "scratch_area": + { + "address" : "0x14000000", + "size" : "0x8000" + } + }, + "application_1": + { + "slots": + { + "boot" : "0x10080000", + "upgrade" : "0x103F8000", + "size" : "0x00200000" + } + } +} diff --git a/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_platform.json b/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_platform.json new file mode 100644 index 0000000..90216ab --- /dev/null +++ b/configs/COMPONENT_MCUBOOT/flashmap/xmc7200_platform.json @@ -0,0 +1,55 @@ +{ + "memory_regions": + [ + { + "address" : "0x10000000", + "size" : "0x7F0000", + "erase_size" : "0x8000", + "erase_value" : "0xFF", + "type" : "INTERNAL_FLASH_CODE_LARGE" + }, + + { + "address" : "0x107F0000", + "size" : "0x40000", + "erase_size" : "0x2000", + "erase_value" : "0xFF", + "type" : "INTERNAL_FLASH_CODE_SMALL" + }, + + { + "address" : "0x14000000", + "size" : "0x30000", + "erase_size" : "0x800", + "erase_value" : "0xFF", + "type" : "INTERNAL_FLASH_WORK_LARGE" + }, + + { + "address" : "0x14030000", + "size" : "0x10000", + "erase_size" : "0x80", + "erase_value" : "0xFF", + "type" : "INTERNAL_FLASH_WORK_SMALL" + } + ], + + "core_list": + [ + { + "name" : "CM0P", + "id" : 0 + }, + + { + "name" : "CM7_0", + "id" : 1 + }, + + { + "name" : "CM7_1", + "id" : 2 + } + ] + +} diff --git a/docs/api_reference_manual.html b/docs/api_reference_manual.html new file mode 100644 index 0000000..f36eb75 --- /dev/null +++ b/docs/api_reference_manual.html @@ -0,0 +1,15 @@ + + + +Redirect to API Reference Manual main page after 0 seconds + + + + +

+ If the automatic redirection is failing, click the following link to open API Reference Manual. +

+ + diff --git a/docs/api_reference_manual/html/bc_s.png b/docs/api_reference_manual/html/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/docs/api_reference_manual/html/bc_s.png differ diff --git a/docs/api_reference_manual/html/bdwn.png b/docs/api_reference_manual/html/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/docs/api_reference_manual/html/bdwn.png differ diff --git a/docs/api_reference_manual/html/closed.png b/docs/api_reference_manual/html/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/docs/api_reference_manual/html/closed.png differ diff --git a/docs/api_reference_manual/html/doxygen.png b/docs/api_reference_manual/html/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/docs/api_reference_manual/html/doxygen.png differ diff --git a/docs/api_reference_manual/html/doxygen_style.css b/docs/api_reference_manual/html/doxygen_style.css new file mode 100644 index 0000000..75194dd --- /dev/null +++ b/docs/api_reference_manual/html/doxygen_style.css @@ -0,0 +1,1544 @@ +/* The standard CSS for doxygen 1.8.11 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #A8A8A8; + color: #000; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 250% sans-serif, Tahoma, Ariel; + margin: 0px; + padding: 2px 0px 2px 25px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + color: grey; + margin: 0 0 0 26px; + padding: 0; + + height: 0px; +} + +#projectnumber +{ + font: 40% sans-serif, Tahoma, Ariel; + color: #606060; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + + +/* ****************************************************/ + +/* + +#navrow1 +{ + display: none; +} + +*/ + +/* cypress logo */ +img[src="infineon_logo.png"]{ + height:75px; + /*float: right;*/ +} + +/* \section format */ +h1 +{ + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: bold; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +/* \subsection format */ +h2 +{ + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.0em; + padding-top: 4px; + width: 100%; +} + +/* \ssububsection format */ +h3 +{ + color: #354C7B; + font-size: 100%; + font-weight: bold; + margin-top: 1.0em; + padding-top: 4px; + width: 100%; +} + +/* \snippet_begin */ +pre.snippet_code +{ + font: 100% Consolas, Courier New; + border: 1px solid black; + border-radius: 0.5em; + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + padding: 8px; + margin: 0px 0px 0px -12px; +} diff --git a/docs/api_reference_manual/html/dynsections.js b/docs/api_reference_manual/html/dynsections.js new file mode 100644 index 0000000..9d6f320 --- /dev/null +++ b/docs/api_reference_manual/html/dynsections.js @@ -0,0 +1,96 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: Infineon OTA Bootloader Support API + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
Infineon OTA Bootloader Support API
+
+
+

General Description

+

OTA Bootloader support for handling and installing firmware updates.

+ + + + + + + + + + + +

+API Reference

 OTA Bootloader Support Macros
 Macros used to define the OTA Bootloader Support behavior.
 
 Bootloader Support Typedefs
 Typedefs used by the OTA Bootloader Support.
 
 Bootloader Support Functions
 Functions for handling and installing firmware updates.
 
+
+
+ + + + diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport.js b/docs/api_reference_manual/html/group__group__ota__bootsupport.js new file mode 100644 index 0000000..1d6d7ff --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport.js @@ -0,0 +1,6 @@ +var group__group__ota__bootsupport = +[ + [ "OTA Bootloader Support Macros", "group__group__ota__bootsupport__macros.html", "group__group__ota__bootsupport__macros" ], + [ "Bootloader Support Typedefs", "group__group__ota__bootsupport__typedefs.html", "group__group__ota__bootsupport__typedefs" ], + [ "Bootloader Support Functions", "group__group__ota__bootsupport__functions.html", "group__group__ota__bootsupport__functions" ] +]; \ No newline at end of file diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport__functions.html b/docs/api_reference_manual/html/group__group__ota__bootsupport__functions.html new file mode 100644 index 0000000..a82d219 --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport__functions.html @@ -0,0 +1,640 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: Bootloader Support Functions + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
Bootloader Support Functions
+
+
+

General Description

+

Functions for handling and installing firmware updates.

+

Bootloader based storage interface APIs for handling downloaded UPGRADE image of OTA application.

+

OTA Bootloader support library flash operation APIs.

+

Storage Interface APIs call these flash operation APIs to store downloaded UPGRADE image on Internal or External Flash based on target platforms.

+

These callbacks are defind in ota-update library and expected to register these callbacks during OTA agent start. ota-bootloader-abstraction library has implementation of these bootloader specific storage interface APIs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

cy_rslt_t cy_ota_mem_init (void)
 Initializes flash, QSPI flash, or any other external memory type. More...
 
cy_rslt_t cy_ota_mem_read (cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len)
 Read from flash, QSPI flash, or any other external memory type. More...
 
cy_rslt_t cy_ota_mem_write (cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len)
 Write to flash, QSPI flash, or any other external memory type. More...
 
cy_rslt_t cy_ota_mem_erase (cy_ota_mem_type_t mem_type, uint32_t addr, size_t len)
 Erase flash, QSPI flash, or any other external memory type. More...
 
size_t cy_ota_mem_get_prog_size (cy_ota_mem_type_t mem_type, uint32_t addr)
 To get page size for programming flash, QSPI flash, or any other external memory type. More...
 
size_t cy_ota_mem_get_erase_size (cy_ota_mem_type_t mem_type, uint32_t addr)
 To get sector size of flash, QSPI flash, or any other external memory type. More...
 
cy_rslt_t cy_ota_storage_init (void)
 Initialize Storage area. More...
 
cy_rslt_t cy_ota_storage_open (cy_ota_storage_context_t *storage_ptr)
 Open storage area for storing OTA UPGRADE images. More...
 
cy_rslt_t cy_ota_storage_read (cy_ota_storage_context_t *storage_ptr, cy_ota_storage_read_info_t *chunk_info)
 Read data from storage area. More...
 
cy_rslt_t cy_ota_storage_write (cy_ota_storage_context_t *storage_ptr, cy_ota_storage_write_info_t *chunk_info)
 Write data to configured storage area. More...
 
cy_rslt_t cy_ota_storage_close (cy_ota_storage_context_t *storage_ptr)
 Close Storage area for download. More...
 
cy_rslt_t cy_ota_storage_verify (cy_ota_storage_context_t *storage_ptr)
 Verify downloaded UPGRADE OTA image. More...
 
cy_rslt_t cy_ota_storage_image_validate (uint16_t app_id)
 Application has validated the new OTA Image. More...
 
cy_rslt_t cy_ota_storage_get_app_info (void *file_des, cy_ota_app_info_t *app_info)
 Get Application image information. More...
 
+

Function Documentation

+ +
+
+ + + + + + + + +
cy_rslt_t cy_ota_mem_init (void )
+
+ +

Initializes flash, QSPI flash, or any other external memory type.

+

NOTE: This function must be implemented in the user's code.

+
Returns
CY_RSLT_SUCCESS on success CY_RSLT_TYPE_ERROR on failure
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
cy_rslt_t cy_ota_mem_read (cy_ota_mem_type_t mem_type,
uint32_t addr,
void * data,
size_t len 
)
+
+ +

Read from flash, QSPI flash, or any other external memory type.

+

NOTE: This function must be implemented in the user's code.

+
Parameters
+ + + + + +
[in]mem_typeMemory type cy_ota_mem_type_t
[in]addrStarting address to read from.
[out]dataPointer to the buffer to store the data read from the memory.
[in]lenNumber of data bytes to read.
+
+
+
Returns
CY_RSLT_SUCCESS on success CY_RSLT_TYPE_ERROR on failure
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
cy_rslt_t cy_ota_mem_write (cy_ota_mem_type_t mem_type,
uint32_t addr,
void * data,
size_t len 
)
+
+ +

Write to flash, QSPI flash, or any other external memory type.

+

NOTE: This function must be implemented in the user's code.

+
Parameters
+ + + + + +
[in]mem_typeMemory type cy_ota_mem_type_t
[in]addrStarting address to write to.
[in]dataPointer to the buffer containing the data to be written.
[in]lenNumber of bytes to write.
+
+
+
Returns
CY_RSLT_SUCCESS on success CY_RSLT_TYPE_ERROR on failure
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
cy_rslt_t cy_ota_mem_erase (cy_ota_mem_type_t mem_type,
uint32_t addr,
size_t len 
)
+
+ +

Erase flash, QSPI flash, or any other external memory type.

+

NOTE: This function must be implemented in the user's code.

+
Parameters
+ + + + +
[in]mem_typeMemory type cy_ota_mem_type_t
[in]addrStarting address to begin erasing.
[in]lenNumber of bytes to erase.
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_TYPE_ERROR
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
size_t cy_ota_mem_get_prog_size (cy_ota_mem_type_t mem_type,
uint32_t addr 
)
+
+ +

To get page size for programming flash, QSPI flash, or any other external memory type.

+

NOTE: This function must be implemented in the user's code.

+
Parameters
+ + + +
[in]mem_typeMemory type cy_ota_mem_type_t
[in]addrAddress that belongs to the sector for which programming page size needs to be returned.
+
+
+
Returns
Page size in bytes.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
size_t cy_ota_mem_get_erase_size (cy_ota_mem_type_t mem_type,
uint32_t addr 
)
+
+ +

To get sector size of flash, QSPI flash, or any other external memory type.

+

NOTE: This function must be implemented in the user's code.

+
Parameters
+ + + +
[in]mem_typeMemory type cy_ota_mem_type_t
[in]addrAddress that belongs to the sector for which sector erase size needs to be returned.
+
+
+
Returns
Sector size in bytes.
+ +
+
+ +
+
+ + + + + + + + +
cy_rslt_t cy_ota_storage_init (void )
+
+ +

Initialize Storage area.

+

NOTE: Typically, this initializes flash hardware and Application is expected to call this API once before any other flash operation.

+
Returns
CY_RSLT_SUCCESS CY_RSLT_TYPE_ERROR
+ +
+
+ +
+
+ + + + + + + + +
cy_rslt_t cy_ota_storage_open (cy_ota_storage_context_t * storage_ptr)
+
+ +

Open storage area for storing OTA UPGRADE images.

+

NOTE: Typically, This erases UPGRADE Slots.

+
Parameters
+ + +
[in]storage_ptrPointer to the OTA Agent storage context 'cy_ota_storage_context_t'
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_OTA_ERROR_OPEN_STORAGE
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
cy_rslt_t cy_ota_storage_read (cy_ota_storage_context_t * storage_ptr,
cy_ota_storage_read_info_t * chunk_info 
)
+
+ +

Read data from storage area.

+
Parameters
+ + + +
[in]storage_ptrPointer to the OTA Agent storage context 'cy_ota_storage_context_t'
[in]chunk_infoPointer to read chunk information, buffer pointer used for the read
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_OTA_ERROR_READ_STORAGE
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
cy_rslt_t cy_ota_storage_write (cy_ota_storage_context_t * storage_ptr,
cy_ota_storage_write_info_t * chunk_info 
)
+
+ +

Write data to configured storage area.

+
Parameters
+ + + +
[in]storage_ptrPointer to the OTA Agent storage context 'cy_ota_storage_context_t'
[in]chunk_infoPointer to write data chunk information
+
+
+
Returns
CY_UNTAR_SUCCESS CY_UNTAR_ERROR
+ +
+
+ +
+
+ + + + + + + + +
cy_rslt_t cy_ota_storage_close (cy_ota_storage_context_t * storage_ptr)
+
+ +

Close Storage area for download.

+
Parameters
+ + +
[in]storage_ptrPointer to the OTA Agent storage context 'cy_ota_storage_context_t'
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_OTA_ERROR_CLOSE_STORAGE
+ +
+
+ +
+
+ + + + + + + + +
cy_rslt_t cy_ota_storage_verify (cy_ota_storage_context_t * storage_ptr)
+
+ +

Verify downloaded UPGRADE OTA image.

+
Parameters
+ + +
[in]storage_ptrPointer to the OTA Agent storage context 'cy_ota_storage_context_t'
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_OTA_ERROR_GENERAL
+ +
+
+ +
+
+ + + + + + + + +
cy_rslt_t cy_ota_storage_image_validate (uint16_t app_id)
+
+ +

Application has validated the new OTA Image.

+

This call needs to be after reboot and Bootloader has started the upgrade version of Application. to the Primary Slot.

+
Parameters
+ + +
[in]app_idApplication ID.
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_OTA_ERROR_GENERAL
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
cy_rslt_t cy_ota_storage_get_app_info (void * file_des,
cy_ota_app_info_t * app_info 
)
+
+ +

Get Application image information.

+

This call needs to be after reboot and Bootloader has started the upgrade version of Application. to the Primary Slot.

+
Parameters
+ + + +
[in]file_desPointer to the storage context.
[in]app_infoPointer to the OTA Application information structure.
+
+
+
Returns
CY_RSLT_SUCCESS CY_RSLT_OTA_ERROR_GENERAL
+ +
+
+
+
+ + + + diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport__functions.js b/docs/api_reference_manual/html/group__group__ota__bootsupport__functions.js new file mode 100644 index 0000000..91bea24 --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport__functions.js @@ -0,0 +1,17 @@ +var group__group__ota__bootsupport__functions = +[ + [ "cy_ota_mem_init", "group__group__ota__bootsupport__functions.html#ga8992438c302b7b07295524c1ff9a1103", null ], + [ "cy_ota_mem_read", "group__group__ota__bootsupport__functions.html#gaee479d591db0b2861504f1753fac752d", null ], + [ "cy_ota_mem_write", "group__group__ota__bootsupport__functions.html#ga9faaf895a1256d1406c9727e8f3cf991", null ], + [ "cy_ota_mem_erase", "group__group__ota__bootsupport__functions.html#gaff6ed4e415f3d05be3266208316daf86", null ], + [ "cy_ota_mem_get_prog_size", "group__group__ota__bootsupport__functions.html#gac32ab4f247a4d4cee8a65ee9ce38e0d5", null ], + [ "cy_ota_mem_get_erase_size", "group__group__ota__bootsupport__functions.html#ga9acc08068e0389f280ee19a67b84a7d6", null ], + [ "cy_ota_storage_init", "group__group__ota__bootsupport__functions.html#gad1e6294598ad971d3cb35eb789ea4b7b", null ], + [ "cy_ota_storage_open", "group__group__ota__bootsupport__functions.html#gade56090dfaf908e2aa14a35d1ace6b06", null ], + [ "cy_ota_storage_read", "group__group__ota__bootsupport__functions.html#gae935166cb14ce63a64e6f58bafe1c2af", null ], + [ "cy_ota_storage_write", "group__group__ota__bootsupport__functions.html#ga2636ed026fa43484ae0f24e74c6bc472", null ], + [ "cy_ota_storage_close", "group__group__ota__bootsupport__functions.html#ga7148e14b70eec5343c693dc92147e257", null ], + [ "cy_ota_storage_verify", "group__group__ota__bootsupport__functions.html#gafec15fe9e456d05c41e5e8803d18193d", null ], + [ "cy_ota_storage_image_validate", "group__group__ota__bootsupport__functions.html#ga5afcd58a2720b61217def6d2fd86cf7f", null ], + [ "cy_ota_storage_get_app_info", "group__group__ota__bootsupport__functions.html#gac4a3664a8d4f9e33e3bcc877e78f84f8", null ] +]; \ No newline at end of file diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport__macros.html b/docs/api_reference_manual/html/group__group__ota__bootsupport__macros.html new file mode 100644 index 0000000..d67b668 --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport__macros.html @@ -0,0 +1,161 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: OTA Bootloader Support Macros + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
OTA Bootloader Support Macros
+
+
+

General Description

+

Macros used to define the OTA Bootloader Support behavior.

+ + + + + + + + + + + + + + + + + + + + +

+Macros

+#define CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 1))
 The function or operation is not supported on the target or the memory.
 
+#define CY_RSLT_SERIAL_FLASH_ERR_NOT_INITED   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 2))
 The Serial Flash not initialized.
 
+#define CY_RSLT_SERIAL_FLASH_ERR_BAD_PARAM   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 3))
 Parameters passed to a function are invalid.
 
+#define CY_RSLT_SERIAL_FLASH_ERR_READ_BUSY   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 4))
 A previously initiated read operation is not yet complete.
 
+#define CY_RSLT_SERIAL_FLASH_ERR_DMA   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 5))
 A DMA error occurred during read transfer.
 
#define CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 6))
 Read abort failed. More...
 
+

Macro Definition Documentation

+ +
+
+ + + + +
#define CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY   (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 6))
+
+ +

Read abort failed.

+

QSPI block is busy.

+ +
+
+
+
+ + + + diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport__macros.js b/docs/api_reference_manual/html/group__group__ota__bootsupport__macros.js new file mode 100644 index 0000000..4ae8263 --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport__macros.js @@ -0,0 +1,9 @@ +var group__group__ota__bootsupport__macros = +[ + [ "CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED", "group__group__ota__bootsupport__macros.html#gabe7c8c3af5cdc0f9640b70402f543dd7", null ], + [ "CY_RSLT_SERIAL_FLASH_ERR_NOT_INITED", "group__group__ota__bootsupport__macros.html#ga0d92d6f94defc5de93d6ff25a9c5c922", null ], + [ "CY_RSLT_SERIAL_FLASH_ERR_BAD_PARAM", "group__group__ota__bootsupport__macros.html#ga21e3c8199504eb76df66c793488e01e8", null ], + [ "CY_RSLT_SERIAL_FLASH_ERR_READ_BUSY", "group__group__ota__bootsupport__macros.html#ga41875c99fa454d69ec187e772234ce44", null ], + [ "CY_RSLT_SERIAL_FLASH_ERR_DMA", "group__group__ota__bootsupport__macros.html#ga63374cfb508c830f53f25682c183b610", null ], + [ "CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY", "group__group__ota__bootsupport__macros.html#ga959a08da14d528096cf8ebbfb48c5da4", null ] +]; \ No newline at end of file diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport__typedefs.html b/docs/api_reference_manual/html/group__group__ota__bootsupport__typedefs.html new file mode 100644 index 0000000..3881025 --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport__typedefs.html @@ -0,0 +1,163 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: Bootloader Support Typedefs + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
Bootloader Support Typedefs
+
+
+

General Description

+

Typedefs used by the OTA Bootloader Support.

+ + + + + +

+Enumerations

enum  cy_ota_mem_type_t {
+  CY_OTA_MEM_TYPE_INTERNAL_FLASH = 0, +
+  CY_OTA_MEM_TYPE_EXTERNAL_FLASH, +
+  CY_OTA_MEM_TYPE_RRAM, +
+  CY_OTA_MEM_TYPE_NONE +
+ }
 Enumeration of OTA storage types. More...
 
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum cy_ota_mem_type_t
+
+ +

Enumeration of OTA storage types.

+ + + + + +
Enumerator
CY_OTA_MEM_TYPE_INTERNAL_FLASH  +

For internal flash type.

+
CY_OTA_MEM_TYPE_EXTERNAL_FLASH  +

For external flash type.

+
CY_OTA_MEM_TYPE_RRAM  +

For RRAM type.

+
CY_OTA_MEM_TYPE_NONE  +

Default value.

+
+ +
+
+
+
+ + + + diff --git a/docs/api_reference_manual/html/group__group__ota__bootsupport__typedefs.js b/docs/api_reference_manual/html/group__group__ota__bootsupport__typedefs.js new file mode 100644 index 0000000..3aaa50e --- /dev/null +++ b/docs/api_reference_manual/html/group__group__ota__bootsupport__typedefs.js @@ -0,0 +1,9 @@ +var group__group__ota__bootsupport__typedefs = +[ + [ "cy_ota_mem_type_t", "group__group__ota__bootsupport__typedefs.html#gaab757db963c4503260e549eadfdbaf09", [ + [ "CY_OTA_MEM_TYPE_INTERNAL_FLASH", "group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09aaaba78afcb0a2d0e2ecce4d38985f249", null ], + [ "CY_OTA_MEM_TYPE_EXTERNAL_FLASH", "group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09a62af14d0a3f7a5928e8b3d31ba74c9e4", null ], + [ "CY_OTA_MEM_TYPE_RRAM", "group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09a2665c22f1ff174dea35b677a57ba76ec", null ], + [ "CY_OTA_MEM_TYPE_NONE", "group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09ad422b17cdb988fcc9e56655cc8e52326", null ] + ] ] +]; \ No newline at end of file diff --git a/docs/api_reference_manual/html/index.html b/docs/api_reference_manual/html/index.html new file mode 100644 index 0000000..38311ff --- /dev/null +++ b/docs/api_reference_manual/html/index.html @@ -0,0 +1,435 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: Over The Air(OTA) Bootloader Abstraction Library Overview + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Over The Air(OTA) Bootloader Abstraction Library Overview
+
+
+

This library offers assistance for handling downloaded over-the-air (OTA) updates of the application code that is executed on a PSoC™ 6 Connectivity Device, a 20829(CYW920829M2EVK-02) Device, or an XMC7200(KIT_XMC72_EVK) Device based on selected bootloader.
+
+ The library implements storage interface APIs required by ota-update library to complete OTA on supported platforms. Current version(v1.X) of ota-bootloader-abstraction has storage interface APIs for MCUBootloader based OTA.
+
+ The ModusToolbox MCUBootloader based OTA code examples import this library automatically along with ota-update library.

+

+Features and Functionality

+

This library has implementation of storage interface APIs required by ota-update library to complete OTA on supported platforms.

+

Other features:

+
    +
  • Template flashmaps for supported platforms.
  • +
  • Template OTA linker files for supported platforms and toolchains.
  • +
  • Prebuild and Postbuild scripts for generating BOOT and UPGRADE images of OTA Application.
  • +
  • OTA image signing scripts.
  • +
+

+Integration Notes

+

To add different bootloader support on Infineon connectivity-enabled MCU platforms, ota-update library offloads bootloader dependent storage interface APIs using callback mechanism. To handle downloaded OTA upgrade images ota-update library calls registered storage interface callbacks. This ota-bootloader-abstraction library provides implementation of these storage interface APIs for different bootloaders along with build environment required to generate BOOT and UPGRADE images of OTA applications.
+ Current version of library supports only MCUBootloader based OTA image handling.

+

The user is expected to:
+

    +
  1. Build and program MCUBootApp on the chosen platform(s) before enabling MCUBootloader based OTA in an application. Refer to refer to MCUBootApp README <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md.
    +
  2. +
  3. Update OTA Application Makefile by referring OTA Bootloader Abstraction Makefile Readme <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md.
    +
  4. +
  5. ota-bootloader-abstraction library has makefile mcuboot_support.mk located in <mtb_shared>/ota-bootloader-abstraction/<version>/makefiles/mcuboot/ which has necessary pre and post build scripts for generating MCUBootloader based BOOT and UPGRADE images of OTA application.
    +
  6. +
  7. Include mcuboot_support.mk which is located in <mtb_shared>/ota-bootloader-abstraction/<version>/makefiles/mcuboot/ from OTA Application Makefile.
    +
  8. +
  9. Configure OTA storage interface callback APIs in OTA application, And pass the same storage interface while starting OTA agent.
    +
  10. +
  11. OTA storage interface calls Flash operations(Read, Write, erase) to store upgrade images in UPGRADE slot. ota-bootloader-abstraction implements flash operation using mtb-pdl-cat1 library APIs and implementation is available in configs folder <mtb_shared>/ota-bootloader-abstraction/<version>/configs/COMPONENT_MCUBOOT/flash/. User can use same implementation by copying contents of <mtb_shared>/ota-bootloader-abstraction/<version>/configs/COMPONENT_MCUBOOT/flash/) to application space or Can implement flash operation APIs defined in <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/cy_ota_flash.h.
    +
  12. +
  13. For MCUBootloader based OTA Support, add the following to the project Makefile:
    +
    CY_BOOTLOADER=MCUBOOT
    +

    +
  14. +
  15. Add Application Build Directory in the project Makefile:
    +
    CY_BUILD_LOCATION=<Application's Build Working Directory path>
    +

    +
  16. +
  17. Add OTA platform in the project Makefile:
    +
    OTA_PLATFORM=<platform_type>
    +
    Refer OTA Bootloader Abstraction Makefile Readme <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md.
    +
    +
  18. +
  19. Add linker file path for MCUBootloader based OTA on choosen platform in the project Makefile:
    +
    OTA_LINKER_FILE=<OTA linker file path>
    +

    + There are other components that may be needed based on support. Please refer to the various readme files in the folder <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/.
    + MCUBOOT_APP_README.md
    + MCUBOOT_BUILD_COMMANDS.md
    + MCUBOOT_OTA_FLASH_LAYOUT_README.md
    + MCUBOOT_OTA_MAKEFILE_INFO_README.md
    + README.md in library root directory.
    +
  20. +
+

+General Concept

+

The OTA Bootloader Abstraction provides bootloader specific storage interface API implementation which can be used with ota-update library for handling downloaded OTA application upgrade images. During reboot bootloader validates and boots upgrade image.
+
+ The basic device boot sequence is as follows:
+

    +
  1. ROM boot will start Bootloader.
    +
  2. +
  3. Bootloader runs the current application(BOOT Image) in the Primary slot.
    +
  4. +
  5. The OTA Agent downloads the update(UPGRADE Image) and stores it in the Secondary slot using storage interface APIs.
    +
  6. +
  7. The OTA Agent marks the upgrade as ready using storage interface API.
    +
    + On the next system boot:
    +
  8. +
+
    +
  1. ROM boot will start Bootloader.
    +
  2. +
  3. If no update is downloaded, Bootloader starts the current application.
    +
  4. +
  5. Bootloader determines if there is an update in the Secondary Slot.
    +
  6. +
  7. If there is an update available:
    + a. Bootloader verifies the update.
    + b. Bootloader boots upgrade image either by copying or switching Primary and Secondary Slots.
    + c. The updated application must call cy_ota_storage_validated() to validate the update.
    +
    + MCUBootloader Support:
    + This library has below support for MCUBootloader based OTA on PSoC6, 20829,and XMC7200 platforms.
    +
  8. +
+
    +
  1. Template flashmaps for PSoC6, 20829, and XMC7200 platforms.
    +
  2. +
  3. Template linker files for GCC_ARM, ARM, and IAR toolchains.
    +
  4. +
  5. Storage operation callback APIs to handle MCUBootloader based upgrade image.
    +
  6. +
  7. Prebuild and Postbuild scripts for generating and signing MCUBootloader based BOOT and UPGRADE image of an OTA Application.
    +
  8. +
+

+API Overview

+

1. Initialize Storage Area

+

cy_ota_storage_init() - Initializes flash, QSPI flash, or any other external memory type.
+ Application is expected to call this API once before starting OTA agent.
+ cy_rslt_t cy_ota_storage_init(void);

+

2. Open Storage Area

+

cy_ota_storage_open() - Open storage Area for storing OTA UPGRADE images.
+ Typically, this erases UPGRADE slots as well. The OTA agent will call this API once OTA image download starts.
+ cy_rslt_t cy_ota_storage_open(cy_ota_storage_context_t *storage_ptr);

+

3. Read data from Storage Area.

+

cy_ota_storage_read() - Read data from Storage Area.
+ The Read API is primarily used by OTA agents to read OTA Image headers.
+ cy_rslt_t cy_ota_storage_read(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_read_info_t *chunk_info);

+

4. Write data to Storage Area.

+

cy_ota_storage_write() - Write data to Storage Area.
+ The Write API is mainly utilized by OTA agents to write OTA upgrade images that have been downloaded.
+ cy_rslt_t cy_ota_storage_write(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_write_info_t *chunk_info);

+

5. Close Storage Area.

+

cy_ota_storage_close() - Close Storage Area.
+ This API is responsible for closing the storage context. After the context is closed, it will not be possible to perform any write or read operations.
+ cy_rslt_t cy_ota_storage_close(cy_ota_storage_context_t *storage_ptr);

+

6. Verify downloaded UPGRADE OTA image.

+

cy_ota_storage_verify() - Verify OTA image.
+ The OTA agent provides an application callback for image verification before invoking this API.
+ cy_rslt_t cy_ota_storage_verify(cy_ota_storage_context_t *storage_ptr);

+

7. Validate currently running APP.

+

cy_ota_storage_validated() - Validates currently executing application and makes it boot image until next upgrade is available.
+ The application is expected to call this API to execute an image as the boot image until the next upgrade image becomes available.
+ cy_rslt_t cy_ota_storage_validated(void);

+

8. Get Application Image information

+

cy_ota_storage_get_app_info() - Get Application version, Application ID information.
+ The header of an application image (BOOT/UPGRADE) typically includes the following information.
+ cy_rslt_t cy_ota_storage_get_app_info(void* file_des, cy_ota_app_info_t *app_info);

+

+Code Snippets

+

1. Override Default Flash operations API implementation:
+ Copy flash operation implementations from folder ota-bootloader-abstraction/<version>/configs/COMPONENT_MCUBOOT/flash directory to the top-level code example directory in the project. Change these implementation if required.
+

+
/*
+
* Copy flash operation flash implementations from '<ota-bootloader-abstraction>/configs/COMPONENT_MCUBOOT/flash/' to application space.
+
* Change default implementation if required.
+
*/
+
+
cy_rslt_t cy_ota_mem_init(void)
+
{
+
/*
+
* Implement code logic to Initialize flash, QSPI flash, or any other external memory type
+
*/
+
return CY_RSLT_SUCCESS;
+
}
+
+
cy_rslt_t cy_ota_mem_read(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len)
+
{
+
UNUSED_ARG(mem_type);
+
UNUSED_ARG(addr);
+
UNUSED_ARG(data);
+
UNUSED_ARG(len);
+
+
/*
+
* Implement code logic to read from flash, QSPI flash, or any other external memory type
+
*/
+
+
return CY_RSLT_SUCCESS;
+
}
+
+
cy_rslt_t cy_ota_mem_write(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len)
+
{
+
UNUSED_ARG(mem_type);
+
UNUSED_ARG(addr);
+
UNUSED_ARG(data);
+
UNUSED_ARG(len);
+
+
/*
+
* Implement code logic to write data to flash, QSPI flash, or any other external memory type
+
*/
+
+
return CY_RSLT_SUCCESS;
+
}
+
+
cy_rslt_t cy_ota_mem_erase(cy_ota_mem_type_t mem_type, uint32_t addr, size_t len)
+
{
+
UNUSED_ARG(mem_type);
+
UNUSED_ARG(addr);
+
UNUSED_ARG(len);
+
+
/*
+
* Implement code logic to erase flash, QSPI flash, or any other external memory type
+
*/
+
+
return CY_RSLT_SUCCESS;
+
}
+
+
size_t cy_ota_mem_get_prog_size(cy_ota_mem_type_t mem_type, uint32_t addr)
+
{
+
UNUSED_ARG(mem_type);
+
UNUSED_ARG(addr);
+
+
/*
+
* Implement code logic to get programming page size of flash, QSPI flash, or any other external memory type
+
*/
+
+
return CY_RSLT_SUCCESS;
+
}
+
+
size_t cy_ota_mem_get_erase_size(cy_ota_mem_type_t mem_type, uint32_t addr)
+
{
+
UNUSED_ARG(mem_type);
+
UNUSED_ARG(addr);
+
+
/*
+
* Implement code logic to get sector erase size flash, QSPI flash, or any other external memory type
+
*/
+
+
return CY_RSLT_SUCCESS;
+
}
+
+


+ 2. Registering Storage Interface APIs:
+ The following code snippet demonstrates an example for initializing the cy_ota_storage_interface_t structure which is required to start the OTA Agent.
+ This example functions also demonstrates the usage of the OTA Storage Interface APIs for Upgrade image handling (read/write/validate) callback functions.
+

/* Macro to enable/disable TLS. */
+
#define ENABLE_TLS (false)
+
+
#define HTTP_SERVER "my.httpserver.com"
+
#define HTTP_SERVER_PORT (80) /* 443 for TLS. */
+
+
/* Number of MQTT topic filters. */
+
#define MQTT_TOPIC_FILTER_NUM (1)
+
+
#define MQTT_BROKER "mqtt.broker.com"
+
+
#define MQTT_BROKER_PORT (1883) /* (8883) for TLS support. */
+
/* MQTT topics. */
+
const char * mqtt_topics[ MQTT_TOPIC_FILTER_NUM ] =
+
{
+
"mtb/test/ota/image"
+
};
+
+
/* Root CA Certificate.
+
Must include the PEM header and footer:
+
+
"-----BEGIN CERTIFICATE-----\n" \
+
".........base64 data.......\n" \
+
"-----END CERTIFICATE-------\n"
+
*/
+
#define ROOT_CA_CERTIFICATE ""
+
+
/* Client Certificate.
+
Must include the PEM header and footer:
+
+
"-----BEGIN CERTIFICATE-----\n" \
+
".........base64 data.......\n" \
+
"-----END CERTIFICATE-------\n"
+
*/
+
#define CLIENT_CERTIFICATE ""
+
+
+
/* Private Key.
+
Must include the PEM header and footer:
+
+
"-----BEGIN RSA PRIVATE KEY-----\n" \
+
"...........base64 data.........\n" \
+
"-----END RSA PRIVATE KEY-------\n"
+
*/
+
#define CLIENT_KEY ""
+
+
/* OTA context. */
+
static cy_ota_context_ptr ota_context;
+
+
/* OTA callback function define. */
+
cy_ota_callback_results_t ota_callback(cy_ota_cb_struct_t *cb_data);
+
+
+
/* network parameters for OTA. */
+
cy_ota_network_params_t network_params = { CY_OTA_CONNECTION_UNKNOWN };
+
+
/* Parameters for the OTA Agent. */
+
cy_ota_agent_params_t ota_agent_params =
+
{
+
.cb_func = ota_callback, /* Set the value to NULL if the callback function is not used. */
+
.cb_arg = &ota_context, /* Set the value to NULL if the callback function is not used. */
+
.reboot_upon_completion = 1 /* Reboot after completing OTA with success. */
+
};
+
+
cy_ota_storage_interface_t ota_interfaces =
+
{
+
.ota_file_open = cy_ota_storage_open,
+
.ota_file_read = cy_ota_storage_read,
+
.ota_file_write = cy_ota_storage_write,
+
.ota_file_close = cy_ota_storage_close,
+
.ota_file_verify = cy_ota_storage_verify,
+
.ota_file_validate = cy_ota_storage_validated,
+
.ota_file_get_app_info = cy_ota_storage_get_app_info
+
};
+
+
int main(void)
+
{
+
/* BSP Init */
+
+
/* Memory Init */
+
+
/* Start OTA Agent.*/
+
result = cy_ota_agent_start(&ota_test_network_params, &ota_test_agent_params, &ota_interfaces, &ota_context);
+
if (result != CY_RSLT_SUCCESS)
+
{
+
printf("Agent start Failed - result: 0x%lx\n", result);
+
while (true)
+
{
+
cy_rtos_delay_milliseconds(10);
+
}
+
}
+
}
+


+

+

+ModusToolbox OTA Code Examples

+

ModusToolbox OTA Example using MQTT: https://github.com/infineon/mtb-example-ota-mqtt
+ ModusToolbox OTA Update Bluetooth® example: https://github.com/infineon/mtb-example-btstack-freertos-cyw20829-keyboard
+ MCUboot documentation: https://github.com/JuulLabs-OSS/mcuboot/blob/cypress/docs/design.md
+

+
+
+ + + + diff --git a/docs/api_reference_manual/html/infineon_logo.png b/docs/api_reference_manual/html/infineon_logo.png new file mode 100644 index 0000000..fdb81f3 Binary files /dev/null and b/docs/api_reference_manual/html/infineon_logo.png differ diff --git a/docs/api_reference_manual/html/jquery.js b/docs/api_reference_manual/html/jquery.js new file mode 100644 index 0000000..daead15 --- /dev/null +++ b/docs/api_reference_manual/html/jquery.js @@ -0,0 +1,72 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType; +if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1 +},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av); +ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length; +if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b +})}})(window); +/*! + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null; +p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + +
+
+
API Reference
+
+
+
The following provides a list of driver API documentation
+
[detail level 12]
+ + + + +
 Infineon OTA Bootloader Support APIOTA Bootloader support for handling and installing firmware updates
 OTA Bootloader Support MacrosMacros used to define the OTA Bootloader Support behavior
 Bootloader Support TypedefsTypedefs used by the OTA Bootloader Support
 Bootloader Support FunctionsFunctions for handling and installing firmware updates
+ + + + + + + diff --git a/docs/api_reference_manual/html/modules.js b/docs/api_reference_manual/html/modules.js new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/docs/api_reference_manual/html/modules.js @@ -0,0 +1,4 @@ +var modules = +[ + [ "Infineon OTA Bootloader Support API", "group__group__ota__bootsupport.html", "group__group__ota__bootsupport" ] +]; \ No newline at end of file diff --git a/docs/api_reference_manual/html/nav_f.png b/docs/api_reference_manual/html/nav_f.png new file mode 100644 index 0000000..72a58a5 Binary files /dev/null and b/docs/api_reference_manual/html/nav_f.png differ diff --git a/docs/api_reference_manual/html/nav_g.png b/docs/api_reference_manual/html/nav_g.png new file mode 100644 index 0000000..2093a23 Binary files /dev/null and b/docs/api_reference_manual/html/nav_g.png differ diff --git a/docs/api_reference_manual/html/nav_h.png b/docs/api_reference_manual/html/nav_h.png new file mode 100644 index 0000000..33389b1 Binary files /dev/null and b/docs/api_reference_manual/html/nav_h.png differ diff --git a/docs/api_reference_manual/html/navtree.css b/docs/api_reference_manual/html/navtree.css new file mode 100644 index 0000000..3b16de1 --- /dev/null +++ b/docs/api_reference_manual/html/navtree.css @@ -0,0 +1,142 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:#fff; +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + background-color: #FAFAFF; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: 250px; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background:url("ftv2splitbar.png") repeat scroll right center transparent; + cursor:e-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} diff --git a/docs/api_reference_manual/html/navtree.js b/docs/api_reference_manual/html/navtree.js new file mode 100644 index 0000000..358fa66 --- /dev/null +++ b/docs/api_reference_manual/html/navtree.js @@ -0,0 +1,541 @@ +var NAVTREE = +[ + [ "Over The Air (OTA) Bootloader Abstraction Library", "index.html", [ + [ "Over The Air(OTA) Bootloader Abstraction Library Overview", "index.html", null ], + [ "API Reference", "modules.html", "modules" ] + ] ] +]; + +var NAVTREEINDEX = +[ +"group__group__ota__bootsupport.html" +]; + +var SYNCONMSG = 'click to disable panel synchronisation'; +var SYNCOFFMSG = 'click to enable panel synchronisation'; +var navTreeSubIndices = new Array(); + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + if ($.browser.msie && $.browser.version<=8) { + // script.onload does not work with older versions of IE + script.onreadystatechange = function() { + if (script.readyState=='complete' || script.readyState=='loaded') { + func(); if (show) showRoot(); + } + } + } + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("img"); + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.width = 16; + imgNode.height = 22; + imgNode.border = 0; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.src = node.relpath+"ftv2pnode.png"; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + imgNode.src = node.relpath+"ftv2pnode.png"; + } else { + var span = document.createElement("span"); + span.style.display = 'inline-block'; + span.style.width = 16*(level+1)+'px'; + span.style.height = '22px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',0,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } if (imm || ($.browser.msie && $.browser.version>8)) { + // somehow slideDown jumps to the start of tree for IE9 :-( + $(node.getChildrenUL()).show(); + } else { + $(node.getChildrenUL()).slideDown("fast"); + } + if (node.isLast) { + node.plus_img.src = node.relpath+"ftv2mlastnode.png"; + } else { + node.plus_img.src = node.relpath+"ftv2mnode.png"; + } + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } + gotoAnchor(anchor,aname,false); +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + $('#nav-sync').css('top','30px'); + } else { + $('#nav-sync').css('top','5px'); + } + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + if (node.isLast) { + node.plus_img.src = node.relpath+"ftv2mlastnode.png"; + } else { + node.plus_img.src = node.relpath+"ftv2mnode.png"; + } + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("img"); + o.node.plus_img.src = relpath+"ftv2pnode.png"; + o.node.plus_img.width = 16; + o.node.plus_img.height = 22; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + $(window).load(function(){ + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + }); + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + $(document).bind('touchmove',function(e){ + var device = navigator.userAgent.toLowerCase(); + var ios = device.match(/(iphone|ipod|ipad)/); + if (ios) { + try { + var target = e.target; + while (target) { + if ($(target).css('-webkit-overflow-scrolling')=='touch') return; + target = target.parentNode; + } + e.preventDefault(); + } catch(err) { + e.preventDefault(); + } + } + }); +} diff --git a/docs/api_reference_manual/html/search/all_0.html b/docs/api_reference_manual/html/search/all_0.html new file mode 100644 index 0000000..86e6c08 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_0.js b/docs/api_reference_manual/html/search/all_0.js new file mode 100644 index 0000000..54e19e7 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['already_5fparsed_5fcomponents_5fjson',['already_parsed_components_json',['../structcy__untar__context__t.html#afd6fd860e8be2bb3d6694c767617506d',1,'cy_untar_context_t']]], + ['app_5fversion',['app_version',['../structcy__untar__context__t.html#afee8cb27ad40cb891e975a6c51ec217f',1,'cy_untar_context_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_1.html b/docs/api_reference_manual/html/search/all_1.html new file mode 100644 index 0000000..122fcbb --- /dev/null +++ b/docs/api_reference_manual/html/search/all_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_1.js b/docs/api_reference_manual/html/search/all_1.js new file mode 100644 index 0000000..2ed4b62 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_1.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['bytes_5fprocessed',['bytes_processed',['../structcy__untar__context__t.html#a2d24086b0b996d9c13b9b866689fc9cb',1,'cy_untar_context_t']]], + ['bootloader_20support_20functions',['Bootloader Support Functions',['../group__group__ota__bootsupport__functions.html',1,'']]], + ['bootloader_20support_20typedefs',['Bootloader Support Typedefs',['../group__group__ota__bootsupport__typedefs.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/all_10.html b/docs/api_reference_manual/html/search/all_10.html new file mode 100644 index 0000000..ae54baf --- /dev/null +++ b/docs/api_reference_manual/html/search/all_10.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_10.js b/docs/api_reference_manual/html/search/all_10.js new file mode 100644 index 0000000..e9b42f2 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_10.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['version',['version',['../structustar__header__t.html#a221e6c066702728c67bd6f60b54f255d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_2.html b/docs/api_reference_manual/html/search/all_2.html new file mode 100644 index 0000000..6850d19 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_2.js b/docs/api_reference_manual/html/search/all_2.js new file mode 100644 index 0000000..aa88fa1 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_2.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['cb_5farg',['cb_arg',['../structcy__untar__context__t.html#ac13257d1e1d3090ddb4d97aa041dc0de',1,'cy_untar_context_t']]], + ['cb_5ffunc',['cb_func',['../structcy__untar__context__t.html#af1d4dc5f0b084e596b4b154dd2208d16',1,'cy_untar_context_t']]], + ['chksum',['chksum',['../structustar__header__t.html#a12406bfa1ee66e4d884bb142274d0618',1,'ustar_header_t']]], + ['coalesce_5fbuffer',['coalesce_buffer',['../structcy__untar__context__t.html#a69f5d559fa5d1e5c750140ec45426bfd',1,'cy_untar_context_t']]], + ['coalesce_5fbytes',['coalesce_bytes',['../structcy__untar__context__t.html#a794984131402d9be815ce7dcf1f25ef9',1,'cy_untar_context_t']]], + ['coalesce_5fneeds',['coalesce_needs',['../structcy__untar__context__t.html#a3053bb3b91d7e2830ec488ffe488fffa',1,'cy_untar_context_t']]], + ['coalesce_5fstream_5foffset',['coalesce_stream_offset',['../structcy__untar__context__t.html#a0f17bc00f2b56dcaf99a7aaf74f18460',1,'cy_untar_context_t']]], + ['curr_5ffile_5fin_5fjson',['curr_file_in_json',['../structcy__untar__context__t.html#abf2c32e09a702d991b0b86cc233c972e',1,'cy_untar_context_t']]], + ['current_5ffile',['current_file',['../structcy__untar__context__t.html#af8dc6c9b003d6afc1a94ab9bd052d5f6',1,'cy_untar_context_t']]], + ['cy_5fota_5ffile_5finfo_5ft',['cy_ota_file_info_t',['../structcy__ota__file__info__t.html',1,'']]], + ['cy_5fota_5fmem_5ferase',['cy_ota_mem_erase',['../group__group__ota__bootsupport__functions.html#gaff6ed4e415f3d05be3266208316daf86',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fget_5ferase_5fsize',['cy_ota_mem_get_erase_size',['../group__group__ota__bootsupport__functions.html#ga9acc08068e0389f280ee19a67b84a7d6',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fget_5fprog_5fsize',['cy_ota_mem_get_prog_size',['../group__group__ota__bootsupport__functions.html#gac32ab4f247a4d4cee8a65ee9ce38e0d5',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5finit',['cy_ota_mem_init',['../group__group__ota__bootsupport__functions.html#ga8992438c302b7b07295524c1ff9a1103',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fread',['cy_ota_mem_read',['../group__group__ota__bootsupport__functions.html#gaee479d591db0b2861504f1753fac752d',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5fexternal_5fflash',['CY_OTA_MEM_TYPE_EXTERNAL_FLASH',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09a62af14d0a3f7a5928e8b3d31ba74c9e4',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5finternal_5fflash',['CY_OTA_MEM_TYPE_INTERNAL_FLASH',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09aaaba78afcb0a2d0e2ecce4d38985f249',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5fnone',['CY_OTA_MEM_TYPE_NONE',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09ad422b17cdb988fcc9e56655cc8e52326',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5frram',['CY_OTA_MEM_TYPE_RRAM',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09a2665c22f1ff174dea35b677a57ba76ec',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5ft',['cy_ota_mem_type_t',['../group__group__ota__bootsupport__typedefs.html#gaab757db963c4503260e549eadfdbaf09',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fwrite',['cy_ota_mem_write',['../group__group__ota__bootsupport__functions.html#ga9faaf895a1256d1406c9727e8f3cf991',1,'cy_ota_flash.h']]], + ['cy_5fota_5fstorage_5fclose',['cy_ota_storage_close',['../group__group__ota__bootsupport__functions.html#ga7148e14b70eec5343c693dc92147e257',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fget_5fapp_5finfo',['cy_ota_storage_get_app_info',['../group__group__ota__bootsupport__functions.html#gac4a3664a8d4f9e33e3bcc877e78f84f8',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fimage_5fvalidate',['cy_ota_storage_image_validate',['../group__group__ota__bootsupport__functions.html#ga5afcd58a2720b61217def6d2fd86cf7f',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5finit',['cy_ota_storage_init',['../group__group__ota__bootsupport__functions.html#gad1e6294598ad971d3cb35eb789ea4b7b',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fopen',['cy_ota_storage_open',['../group__group__ota__bootsupport__functions.html#gade56090dfaf908e2aa14a35d1ace6b06',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fread',['cy_ota_storage_read',['../group__group__ota__bootsupport__functions.html#gae935166cb14ce63a64e6f58bafe1c2af',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fverify',['cy_ota_storage_verify',['../group__group__ota__bootsupport__functions.html#gafec15fe9e456d05c41e5e8803d18193d',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fwrite',['cy_ota_storage_write',['../group__group__ota__bootsupport__functions.html#ga2636ed026fa43484ae0f24e74c6bc472',1,'cy_ota_storage_api.h']]], + ['cy_5frslt_5fserial_5fflash_5ferr_5fbad_5fparam',['CY_RSLT_SERIAL_FLASH_ERR_BAD_PARAM',['../group__group__ota__bootsupport__macros.html#ga21e3c8199504eb76df66c793488e01e8',1,'cy_ota_flash.h']]], + ['cy_5frslt_5fserial_5fflash_5ferr_5fdma',['CY_RSLT_SERIAL_FLASH_ERR_DMA',['../group__group__ota__bootsupport__macros.html#ga63374cfb508c830f53f25682c183b610',1,'cy_ota_flash.h']]], + ['cy_5frslt_5fserial_5fflash_5ferr_5fnot_5finited',['CY_RSLT_SERIAL_FLASH_ERR_NOT_INITED',['../group__group__ota__bootsupport__macros.html#ga0d92d6f94defc5de93d6ff25a9c5c922',1,'cy_ota_flash.h']]], + ['cy_5frslt_5fserial_5fflash_5ferr_5fqspi_5fbusy',['CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY',['../group__group__ota__bootsupport__macros.html#ga959a08da14d528096cf8ebbfb48c5da4',1,'cy_ota_flash.h']]], + ['cy_5frslt_5fserial_5fflash_5ferr_5fread_5fbusy',['CY_RSLT_SERIAL_FLASH_ERR_READ_BUSY',['../group__group__ota__bootsupport__macros.html#ga41875c99fa454d69ec187e772234ce44',1,'cy_ota_flash.h']]], + ['cy_5frslt_5fserial_5fflash_5ferr_5funsupported',['CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED',['../group__group__ota__bootsupport__macros.html#gabe7c8c3af5cdc0f9640b70402f543dd7',1,'cy_ota_flash.h']]], + ['cy_5funtar_5fcontext_5ft',['cy_untar_context_t',['../structcy__untar__context__t.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/all_3.html b/docs/api_reference_manual/html/search/all_3.html new file mode 100644 index 0000000..914288c --- /dev/null +++ b/docs/api_reference_manual/html/search/all_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_3.js b/docs/api_reference_manual/html/search/all_3.js new file mode 100644 index 0000000..9039a40 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['devmajor',['devmajor',['../structustar__header__t.html#a42fe83915f1911cea4a0231ef7c69658',1,'ustar_header_t']]], + ['devminor',['devminor',['../structustar__header__t.html#a13f59a9d8eace697cf52e101adb803e8',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_4.html b/docs/api_reference_manual/html/search/all_4.html new file mode 100644 index 0000000..47becb8 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_4.js b/docs/api_reference_manual/html/search/all_4.js new file mode 100644 index 0000000..1afad8f --- /dev/null +++ b/docs/api_reference_manual/html/search/all_4.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['fa_5fdevice_5fid',['fa_device_id',['../structflash__area.html#a5d78c6ab00bab1bd0e825743925216a9',1,'flash_area']]], + ['fa_5fid',['fa_id',['../structflash__area.html#acfe73a1f4f00fdf58129b21e5b71f5d4',1,'flash_area']]], + ['fa_5foff',['fa_off',['../structflash__area.html#a44fbf0af3ba0e7fa1c3623e7d48e0739',1,'flash_area']]], + ['fa_5fsize',['fa_size',['../structflash__area.html#ac580f8ab560582c02f12e96cb67b0e59',1,'flash_area']]], + ['files',['files',['../structcy__untar__context__t.html#aad55ac42754b5b1de2684eed7c2ee734',1,'cy_untar_context_t']]], + ['flash_5farea',['flash_area',['../structflash__area.html',1,'']]], + ['found_5fin_5ftar',['found_in_tar',['../structcy__ota__file__info__t.html#a04f24e4fc35fafe52b94112e3b01c58f',1,'cy_ota_file_info_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_5.html b/docs/api_reference_manual/html/search/all_5.html new file mode 100644 index 0000000..b11c1d1 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_5.js b/docs/api_reference_manual/html/search/all_5.js new file mode 100644 index 0000000..003ba03 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['gid',['gid',['../structustar__header__t.html#a7204b3906dbe365727577672681d49a7',1,'ustar_header_t']]], + ['gname',['gname',['../structustar__header__t.html#a3f843657c6f316bde2d3a93487dbc00d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_6.html b/docs/api_reference_manual/html/search/all_6.html new file mode 100644 index 0000000..a57d74f --- /dev/null +++ b/docs/api_reference_manual/html/search/all_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_6.js b/docs/api_reference_manual/html/search/all_6.js new file mode 100644 index 0000000..605304b --- /dev/null +++ b/docs/api_reference_manual/html/search/all_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['header_5foffset',['header_offset',['../structcy__ota__file__info__t.html#ac66d23e077df5a73e8e00ae3c5297a78',1,'cy_ota_file_info_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_7.html b/docs/api_reference_manual/html/search/all_7.html new file mode 100644 index 0000000..ecca251 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_7.js b/docs/api_reference_manual/html/search/all_7.js new file mode 100644 index 0000000..aa20cd1 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['infineon_20ota_20bootloader_20support_20api',['Infineon OTA Bootloader Support API',['../group__group__ota__bootsupport.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/all_8.html b/docs/api_reference_manual/html/search/all_8.html new file mode 100644 index 0000000..f8f8560 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_8.js b/docs/api_reference_manual/html/search/all_8.js new file mode 100644 index 0000000..16d4403 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['linkname',['linkname',['../structustar__header__t.html#af040f7b9edb6b2a7b36331baac3b0b29',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_9.html b/docs/api_reference_manual/html/search/all_9.html new file mode 100644 index 0000000..cb525ab --- /dev/null +++ b/docs/api_reference_manual/html/search/all_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_9.js b/docs/api_reference_manual/html/search/all_9.js new file mode 100644 index 0000000..298595c --- /dev/null +++ b/docs/api_reference_manual/html/search/all_9.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['magic',['magic',['../structustar__header__t.html#a8d5c6b8de6f7d54ca09eec05bd687e57',1,'ustar_header_t::magic()'],['../structcy__untar__context__t.html#aa83f06b776e1625eee055ced4c090ed0',1,'cy_untar_context_t::magic()']]], + ['mode',['mode',['../structustar__header__t.html#a746c05cc5a8b6d2c3a32b047b339b5e4',1,'ustar_header_t']]], + ['mtime',['mtime',['../structustar__header__t.html#a864536a60b77e8f2c02a069fec5eb5bb',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_a.html b/docs/api_reference_manual/html/search/all_a.html new file mode 100644 index 0000000..393a236 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_a.js b/docs/api_reference_manual/html/search/all_a.js new file mode 100644 index 0000000..145cf7f --- /dev/null +++ b/docs/api_reference_manual/html/search/all_a.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['name',['name',['../structustar__header__t.html#ac17cf92e0b804a003eee900e2321bc6a',1,'ustar_header_t::name()'],['../structcy__ota__file__info__t.html#a2e8934999aa4c06e18163853846b51c7',1,'cy_ota_file_info_t::name()']]], + ['num_5ffiles',['num_files',['../structcy__untar__context__t.html#a8ee4b7ed02b7f8b211dcb10969cbb6d4',1,'cy_untar_context_t']]], + ['num_5ffiles_5fin_5fjson',['num_files_in_json',['../structcy__untar__context__t.html#a901d9f8ffbf5202704f140197e823a04',1,'cy_untar_context_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_b.html b/docs/api_reference_manual/html/search/all_b.html new file mode 100644 index 0000000..6d33464 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_b.js b/docs/api_reference_manual/html/search/all_b.js new file mode 100644 index 0000000..3af6443 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_b.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['ota_20bootloader_20support_20macros',['OTA Bootloader Support Macros',['../group__group__ota__bootsupport__macros.html',1,'']]], + ['over_20the_20air_28ota_29_20bootloader_20abstraction_20library_20overview',['Over The Air(OTA) Bootloader Abstraction Library Overview',['../index.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/all_c.html b/docs/api_reference_manual/html/search/all_c.html new file mode 100644 index 0000000..cbf7d06 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_c.js b/docs/api_reference_manual/html/search/all_c.js new file mode 100644 index 0000000..5748c7c --- /dev/null +++ b/docs/api_reference_manual/html/search/all_c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['pad16',['pad16',['../structflash__area.html#af98b8f20c0219bfcdd2fc20037845a99',1,'flash_area']]], + ['prefix',['prefix',['../structustar__header__t.html#a98499864c2abd68676cebcbd59e3b7c1',1,'ustar_header_t']]], + ['processed',['processed',['../structcy__ota__file__info__t.html#ab7fd9fd36bfc153bcf2c201950467889',1,'cy_ota_file_info_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_d.html b/docs/api_reference_manual/html/search/all_d.html new file mode 100644 index 0000000..67a6960 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_d.js b/docs/api_reference_manual/html/search/all_d.js new file mode 100644 index 0000000..fef3fcf --- /dev/null +++ b/docs/api_reference_manual/html/search/all_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['size',['size',['../structustar__header__t.html#a58aba9d733b71d336d77a479499bb12c',1,'ustar_header_t::size()'],['../structcy__ota__file__info__t.html#a412e487cd5f86ed45293fce86071e07e',1,'cy_ota_file_info_t::size()']]] +]; diff --git a/docs/api_reference_manual/html/search/all_e.html b/docs/api_reference_manual/html/search/all_e.html new file mode 100644 index 0000000..92ab0e3 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_e.js b/docs/api_reference_manual/html/search/all_e.js new file mode 100644 index 0000000..2e8e222 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['tar_5fstate',['tar_state',['../structcy__untar__context__t.html#ac065c394e3e966b08d5afe0287961ccd',1,'cy_untar_context_t']]], + ['type',['type',['../structcy__ota__file__info__t.html#aa3f1124969b36367c1441456fd435e9c',1,'cy_ota_file_info_t']]], + ['typeflag',['typeflag',['../structustar__header__t.html#afec77696bbb04d88e95dbc52e531482d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/all_f.html b/docs/api_reference_manual/html/search/all_f.html new file mode 100644 index 0000000..6ff4c97 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/all_f.js b/docs/api_reference_manual/html/search/all_f.js new file mode 100644 index 0000000..60614e4 --- /dev/null +++ b/docs/api_reference_manual/html/search/all_f.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['uid',['uid',['../structustar__header__t.html#ae4a4fd8cc9dd8bb5c4a6339f3f7ff0c3',1,'ustar_header_t']]], + ['uname',['uname',['../structustar__header__t.html#a45e43cc7b591833fbb654d05a9138a8d',1,'ustar_header_t']]], + ['ustar_5fheader_5ft',['ustar_header_t',['../structustar__header__t.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/classes_0.html b/docs/api_reference_manual/html/search/classes_0.html new file mode 100644 index 0000000..d2e0c9a --- /dev/null +++ b/docs/api_reference_manual/html/search/classes_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/classes_0.js b/docs/api_reference_manual/html/search/classes_0.js new file mode 100644 index 0000000..727cac8 --- /dev/null +++ b/docs/api_reference_manual/html/search/classes_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['cy_5fota_5ffile_5finfo_5ft',['cy_ota_file_info_t',['../structcy__ota__file__info__t.html',1,'']]], + ['cy_5funtar_5fcontext_5ft',['cy_untar_context_t',['../structcy__untar__context__t.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/classes_1.html b/docs/api_reference_manual/html/search/classes_1.html new file mode 100644 index 0000000..b04aca3 --- /dev/null +++ b/docs/api_reference_manual/html/search/classes_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/classes_1.js b/docs/api_reference_manual/html/search/classes_1.js new file mode 100644 index 0000000..b7e902f --- /dev/null +++ b/docs/api_reference_manual/html/search/classes_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['flash_5farea',['flash_area',['../structflash__area.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/classes_2.html b/docs/api_reference_manual/html/search/classes_2.html new file mode 100644 index 0000000..ef9c9ed --- /dev/null +++ b/docs/api_reference_manual/html/search/classes_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/classes_2.js b/docs/api_reference_manual/html/search/classes_2.js new file mode 100644 index 0000000..c5c64ae --- /dev/null +++ b/docs/api_reference_manual/html/search/classes_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ustar_5fheader_5ft',['ustar_header_t',['../structustar__header__t.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/close.png b/docs/api_reference_manual/html/search/close.png new file mode 100644 index 0000000..9342d3d Binary files /dev/null and b/docs/api_reference_manual/html/search/close.png differ diff --git a/docs/api_reference_manual/html/search/enums_0.html b/docs/api_reference_manual/html/search/enums_0.html new file mode 100644 index 0000000..c2879e4 --- /dev/null +++ b/docs/api_reference_manual/html/search/enums_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/enums_0.js b/docs/api_reference_manual/html/search/enums_0.js new file mode 100644 index 0000000..8601eea --- /dev/null +++ b/docs/api_reference_manual/html/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['cy_5fota_5fmem_5ftype_5ft',['cy_ota_mem_type_t',['../group__group__ota__bootsupport__typedefs.html#gaab757db963c4503260e549eadfdbaf09',1,'cy_ota_flash.h']]] +]; diff --git a/docs/api_reference_manual/html/search/enumvalues_0.html b/docs/api_reference_manual/html/search/enumvalues_0.html new file mode 100644 index 0000000..3c489a3 --- /dev/null +++ b/docs/api_reference_manual/html/search/enumvalues_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/enumvalues_0.js b/docs/api_reference_manual/html/search/enumvalues_0.js new file mode 100644 index 0000000..60f3bf9 --- /dev/null +++ b/docs/api_reference_manual/html/search/enumvalues_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['cy_5fota_5fmem_5ftype_5fexternal_5fflash',['CY_OTA_MEM_TYPE_EXTERNAL_FLASH',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09a62af14d0a3f7a5928e8b3d31ba74c9e4',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5finternal_5fflash',['CY_OTA_MEM_TYPE_INTERNAL_FLASH',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09aaaba78afcb0a2d0e2ecce4d38985f249',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5fnone',['CY_OTA_MEM_TYPE_NONE',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09ad422b17cdb988fcc9e56655cc8e52326',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5ftype_5frram',['CY_OTA_MEM_TYPE_RRAM',['../group__group__ota__bootsupport__typedefs.html#ggaab757db963c4503260e549eadfdbaf09a2665c22f1ff174dea35b677a57ba76ec',1,'cy_ota_flash.h']]] +]; diff --git a/docs/api_reference_manual/html/search/functions_0.html b/docs/api_reference_manual/html/search/functions_0.html new file mode 100644 index 0000000..a3f28dc --- /dev/null +++ b/docs/api_reference_manual/html/search/functions_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/functions_0.js b/docs/api_reference_manual/html/search/functions_0.js new file mode 100644 index 0000000..9a07a70 --- /dev/null +++ b/docs/api_reference_manual/html/search/functions_0.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['cy_5fota_5fmem_5ferase',['cy_ota_mem_erase',['../group__group__ota__bootsupport__functions.html#gaff6ed4e415f3d05be3266208316daf86',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fget_5ferase_5fsize',['cy_ota_mem_get_erase_size',['../group__group__ota__bootsupport__functions.html#ga9acc08068e0389f280ee19a67b84a7d6',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fget_5fprog_5fsize',['cy_ota_mem_get_prog_size',['../group__group__ota__bootsupport__functions.html#gac32ab4f247a4d4cee8a65ee9ce38e0d5',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5finit',['cy_ota_mem_init',['../group__group__ota__bootsupport__functions.html#ga8992438c302b7b07295524c1ff9a1103',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fread',['cy_ota_mem_read',['../group__group__ota__bootsupport__functions.html#gaee479d591db0b2861504f1753fac752d',1,'cy_ota_flash.h']]], + ['cy_5fota_5fmem_5fwrite',['cy_ota_mem_write',['../group__group__ota__bootsupport__functions.html#ga9faaf895a1256d1406c9727e8f3cf991',1,'cy_ota_flash.h']]], + ['cy_5fota_5fstorage_5fclose',['cy_ota_storage_close',['../group__group__ota__bootsupport__functions.html#ga7148e14b70eec5343c693dc92147e257',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fget_5fapp_5finfo',['cy_ota_storage_get_app_info',['../group__group__ota__bootsupport__functions.html#gac4a3664a8d4f9e33e3bcc877e78f84f8',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fimage_5fvalidate',['cy_ota_storage_image_validate',['../group__group__ota__bootsupport__functions.html#ga5afcd58a2720b61217def6d2fd86cf7f',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5finit',['cy_ota_storage_init',['../group__group__ota__bootsupport__functions.html#gad1e6294598ad971d3cb35eb789ea4b7b',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fopen',['cy_ota_storage_open',['../group__group__ota__bootsupport__functions.html#gade56090dfaf908e2aa14a35d1ace6b06',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fread',['cy_ota_storage_read',['../group__group__ota__bootsupport__functions.html#gae935166cb14ce63a64e6f58bafe1c2af',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fverify',['cy_ota_storage_verify',['../group__group__ota__bootsupport__functions.html#gafec15fe9e456d05c41e5e8803d18193d',1,'cy_ota_storage_api.h']]], + ['cy_5fota_5fstorage_5fwrite',['cy_ota_storage_write',['../group__group__ota__bootsupport__functions.html#ga2636ed026fa43484ae0f24e74c6bc472',1,'cy_ota_storage_api.h']]] +]; diff --git a/docs/api_reference_manual/html/search/groups_0.html b/docs/api_reference_manual/html/search/groups_0.html new file mode 100644 index 0000000..ad8fbe9 --- /dev/null +++ b/docs/api_reference_manual/html/search/groups_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/groups_0.js b/docs/api_reference_manual/html/search/groups_0.js new file mode 100644 index 0000000..3b28d82 --- /dev/null +++ b/docs/api_reference_manual/html/search/groups_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['bootloader_20support_20functions',['Bootloader Support Functions',['../group__group__ota__bootsupport__functions.html',1,'']]], + ['bootloader_20support_20typedefs',['Bootloader Support Typedefs',['../group__group__ota__bootsupport__typedefs.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/groups_1.html b/docs/api_reference_manual/html/search/groups_1.html new file mode 100644 index 0000000..4e2bb17 --- /dev/null +++ b/docs/api_reference_manual/html/search/groups_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/groups_1.js b/docs/api_reference_manual/html/search/groups_1.js new file mode 100644 index 0000000..aa20cd1 --- /dev/null +++ b/docs/api_reference_manual/html/search/groups_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['infineon_20ota_20bootloader_20support_20api',['Infineon OTA Bootloader Support API',['../group__group__ota__bootsupport.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/groups_2.html b/docs/api_reference_manual/html/search/groups_2.html new file mode 100644 index 0000000..ad86db7 --- /dev/null +++ b/docs/api_reference_manual/html/search/groups_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/groups_2.js b/docs/api_reference_manual/html/search/groups_2.js new file mode 100644 index 0000000..0bfbf00 --- /dev/null +++ b/docs/api_reference_manual/html/search/groups_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ota_20bootloader_20support_20macros',['OTA Bootloader Support Macros',['../group__group__ota__bootsupport__macros.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/mag_sel.png b/docs/api_reference_manual/html/search/mag_sel.png new file mode 100644 index 0000000..81f6040 Binary files /dev/null and b/docs/api_reference_manual/html/search/mag_sel.png differ diff --git a/docs/api_reference_manual/html/search/nomatches.html b/docs/api_reference_manual/html/search/nomatches.html new file mode 100644 index 0000000..b1ded27 --- /dev/null +++ b/docs/api_reference_manual/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/docs/api_reference_manual/html/search/pages_0.html b/docs/api_reference_manual/html/search/pages_0.html new file mode 100644 index 0000000..8ce1299 --- /dev/null +++ b/docs/api_reference_manual/html/search/pages_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/pages_0.js b/docs/api_reference_manual/html/search/pages_0.js new file mode 100644 index 0000000..197edd2 --- /dev/null +++ b/docs/api_reference_manual/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['over_20the_20air_28ota_29_20bootloader_20abstraction_20library_20overview',['Over The Air(OTA) Bootloader Abstraction Library Overview',['../index.html',1,'']]] +]; diff --git a/docs/api_reference_manual/html/search/search.css b/docs/api_reference_manual/html/search/search.css new file mode 100644 index 0000000..9e3d349 --- /dev/null +++ b/docs/api_reference_manual/html/search/search.css @@ -0,0 +1,270 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:111px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} diff --git a/docs/api_reference_manual/html/search/search.js b/docs/api_reference_manual/html/search/search.js new file mode 100644 index 0000000..1a24275 --- /dev/null +++ b/docs/api_reference_manual/html/search/search.js @@ -0,0 +1,806 @@ +// Search script generated by doxygen +// Copyright (C) 2009 by Dimitri van Heesch. + +// The code in this file is loosly based on main.js, part of Natural Docs, +// which is Copyright (C) 2003-2008 Greg Valure +// Natural Docs is licensed under the GPL. + +var indexSectionsWithContent = +{ + 0: "abcdfghilmnopstuv", + 1: "cfu", + 2: "c", + 3: "abcdfghlmnpstuv", + 4: "c", + 5: "c", + 6: "bio", + 7: "o" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "functions", + 3: "variables", + 4: "enums", + 5: "enumvalues", + 6: "groups", + 7: "pages" +}; + +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_0.js b/docs/api_reference_manual/html/search/variables_0.js new file mode 100644 index 0000000..54e19e7 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['already_5fparsed_5fcomponents_5fjson',['already_parsed_components_json',['../structcy__untar__context__t.html#afd6fd860e8be2bb3d6694c767617506d',1,'cy_untar_context_t']]], + ['app_5fversion',['app_version',['../structcy__untar__context__t.html#afee8cb27ad40cb891e975a6c51ec217f',1,'cy_untar_context_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_1.html b/docs/api_reference_manual/html/search/variables_1.html new file mode 100644 index 0000000..1e306bd --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_1.js b/docs/api_reference_manual/html/search/variables_1.js new file mode 100644 index 0000000..e0473f1 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['bytes_5fprocessed',['bytes_processed',['../structcy__untar__context__t.html#a2d24086b0b996d9c13b9b866689fc9cb',1,'cy_untar_context_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_2.html b/docs/api_reference_manual/html/search/variables_2.html new file mode 100644 index 0000000..938e165 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_2.js b/docs/api_reference_manual/html/search/variables_2.js new file mode 100644 index 0000000..403b4d9 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_2.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['cb_5farg',['cb_arg',['../structcy__untar__context__t.html#ac13257d1e1d3090ddb4d97aa041dc0de',1,'cy_untar_context_t']]], + ['cb_5ffunc',['cb_func',['../structcy__untar__context__t.html#af1d4dc5f0b084e596b4b154dd2208d16',1,'cy_untar_context_t']]], + ['chksum',['chksum',['../structustar__header__t.html#a12406bfa1ee66e4d884bb142274d0618',1,'ustar_header_t']]], + ['coalesce_5fbuffer',['coalesce_buffer',['../structcy__untar__context__t.html#a69f5d559fa5d1e5c750140ec45426bfd',1,'cy_untar_context_t']]], + ['coalesce_5fbytes',['coalesce_bytes',['../structcy__untar__context__t.html#a794984131402d9be815ce7dcf1f25ef9',1,'cy_untar_context_t']]], + ['coalesce_5fneeds',['coalesce_needs',['../structcy__untar__context__t.html#a3053bb3b91d7e2830ec488ffe488fffa',1,'cy_untar_context_t']]], + ['coalesce_5fstream_5foffset',['coalesce_stream_offset',['../structcy__untar__context__t.html#a0f17bc00f2b56dcaf99a7aaf74f18460',1,'cy_untar_context_t']]], + ['curr_5ffile_5fin_5fjson',['curr_file_in_json',['../structcy__untar__context__t.html#abf2c32e09a702d991b0b86cc233c972e',1,'cy_untar_context_t']]], + ['current_5ffile',['current_file',['../structcy__untar__context__t.html#af8dc6c9b003d6afc1a94ab9bd052d5f6',1,'cy_untar_context_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_3.html b/docs/api_reference_manual/html/search/variables_3.html new file mode 100644 index 0000000..7ca5d9b --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_3.js b/docs/api_reference_manual/html/search/variables_3.js new file mode 100644 index 0000000..9039a40 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['devmajor',['devmajor',['../structustar__header__t.html#a42fe83915f1911cea4a0231ef7c69658',1,'ustar_header_t']]], + ['devminor',['devminor',['../structustar__header__t.html#a13f59a9d8eace697cf52e101adb803e8',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_4.html b/docs/api_reference_manual/html/search/variables_4.html new file mode 100644 index 0000000..002145f --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_4.js b/docs/api_reference_manual/html/search/variables_4.js new file mode 100644 index 0000000..7855c24 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_4.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['fa_5fdevice_5fid',['fa_device_id',['../structflash__area.html#a5d78c6ab00bab1bd0e825743925216a9',1,'flash_area']]], + ['fa_5fid',['fa_id',['../structflash__area.html#acfe73a1f4f00fdf58129b21e5b71f5d4',1,'flash_area']]], + ['fa_5foff',['fa_off',['../structflash__area.html#a44fbf0af3ba0e7fa1c3623e7d48e0739',1,'flash_area']]], + ['fa_5fsize',['fa_size',['../structflash__area.html#ac580f8ab560582c02f12e96cb67b0e59',1,'flash_area']]], + ['files',['files',['../structcy__untar__context__t.html#aad55ac42754b5b1de2684eed7c2ee734',1,'cy_untar_context_t']]], + ['found_5fin_5ftar',['found_in_tar',['../structcy__ota__file__info__t.html#a04f24e4fc35fafe52b94112e3b01c58f',1,'cy_ota_file_info_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_5.html b/docs/api_reference_manual/html/search/variables_5.html new file mode 100644 index 0000000..c7c2549 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_5.js b/docs/api_reference_manual/html/search/variables_5.js new file mode 100644 index 0000000..003ba03 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['gid',['gid',['../structustar__header__t.html#a7204b3906dbe365727577672681d49a7',1,'ustar_header_t']]], + ['gname',['gname',['../structustar__header__t.html#a3f843657c6f316bde2d3a93487dbc00d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_6.html b/docs/api_reference_manual/html/search/variables_6.html new file mode 100644 index 0000000..70eccea --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_6.js b/docs/api_reference_manual/html/search/variables_6.js new file mode 100644 index 0000000..605304b --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['header_5foffset',['header_offset',['../structcy__ota__file__info__t.html#ac66d23e077df5a73e8e00ae3c5297a78',1,'cy_ota_file_info_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_7.html b/docs/api_reference_manual/html/search/variables_7.html new file mode 100644 index 0000000..6a3546c --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_7.js b/docs/api_reference_manual/html/search/variables_7.js new file mode 100644 index 0000000..16d4403 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['linkname',['linkname',['../structustar__header__t.html#af040f7b9edb6b2a7b36331baac3b0b29',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_8.html b/docs/api_reference_manual/html/search/variables_8.html new file mode 100644 index 0000000..987bf29 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_8.js b/docs/api_reference_manual/html/search/variables_8.js new file mode 100644 index 0000000..298595c --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_8.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['magic',['magic',['../structustar__header__t.html#a8d5c6b8de6f7d54ca09eec05bd687e57',1,'ustar_header_t::magic()'],['../structcy__untar__context__t.html#aa83f06b776e1625eee055ced4c090ed0',1,'cy_untar_context_t::magic()']]], + ['mode',['mode',['../structustar__header__t.html#a746c05cc5a8b6d2c3a32b047b339b5e4',1,'ustar_header_t']]], + ['mtime',['mtime',['../structustar__header__t.html#a864536a60b77e8f2c02a069fec5eb5bb',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_9.html b/docs/api_reference_manual/html/search/variables_9.html new file mode 100644 index 0000000..bad0939 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_9.js b/docs/api_reference_manual/html/search/variables_9.js new file mode 100644 index 0000000..145cf7f --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_9.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['name',['name',['../structustar__header__t.html#ac17cf92e0b804a003eee900e2321bc6a',1,'ustar_header_t::name()'],['../structcy__ota__file__info__t.html#a2e8934999aa4c06e18163853846b51c7',1,'cy_ota_file_info_t::name()']]], + ['num_5ffiles',['num_files',['../structcy__untar__context__t.html#a8ee4b7ed02b7f8b211dcb10969cbb6d4',1,'cy_untar_context_t']]], + ['num_5ffiles_5fin_5fjson',['num_files_in_json',['../structcy__untar__context__t.html#a901d9f8ffbf5202704f140197e823a04',1,'cy_untar_context_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_a.html b/docs/api_reference_manual/html/search/variables_a.html new file mode 100644 index 0000000..b80e823 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_a.js b/docs/api_reference_manual/html/search/variables_a.js new file mode 100644 index 0000000..5748c7c --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_a.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['pad16',['pad16',['../structflash__area.html#af98b8f20c0219bfcdd2fc20037845a99',1,'flash_area']]], + ['prefix',['prefix',['../structustar__header__t.html#a98499864c2abd68676cebcbd59e3b7c1',1,'ustar_header_t']]], + ['processed',['processed',['../structcy__ota__file__info__t.html#ab7fd9fd36bfc153bcf2c201950467889',1,'cy_ota_file_info_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_b.html b/docs/api_reference_manual/html/search/variables_b.html new file mode 100644 index 0000000..3f86c73 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_b.js b/docs/api_reference_manual/html/search/variables_b.js new file mode 100644 index 0000000..fef3fcf --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['size',['size',['../structustar__header__t.html#a58aba9d733b71d336d77a479499bb12c',1,'ustar_header_t::size()'],['../structcy__ota__file__info__t.html#a412e487cd5f86ed45293fce86071e07e',1,'cy_ota_file_info_t::size()']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_c.html b/docs/api_reference_manual/html/search/variables_c.html new file mode 100644 index 0000000..9d038c0 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_c.js b/docs/api_reference_manual/html/search/variables_c.js new file mode 100644 index 0000000..2e8e222 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['tar_5fstate',['tar_state',['../structcy__untar__context__t.html#ac065c394e3e966b08d5afe0287961ccd',1,'cy_untar_context_t']]], + ['type',['type',['../structcy__ota__file__info__t.html#aa3f1124969b36367c1441456fd435e9c',1,'cy_ota_file_info_t']]], + ['typeflag',['typeflag',['../structustar__header__t.html#afec77696bbb04d88e95dbc52e531482d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_d.html b/docs/api_reference_manual/html/search/variables_d.html new file mode 100644 index 0000000..bdcc0e6 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_d.js b/docs/api_reference_manual/html/search/variables_d.js new file mode 100644 index 0000000..00e83d5 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_d.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['uid',['uid',['../structustar__header__t.html#ae4a4fd8cc9dd8bb5c4a6339f3f7ff0c3',1,'ustar_header_t']]], + ['uname',['uname',['../structustar__header__t.html#a45e43cc7b591833fbb654d05a9138a8d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/search/variables_e.html b/docs/api_reference_manual/html/search/variables_e.html new file mode 100644 index 0000000..198fca8 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/api_reference_manual/html/search/variables_e.js b/docs/api_reference_manual/html/search/variables_e.js new file mode 100644 index 0000000..e9b42f2 --- /dev/null +++ b/docs/api_reference_manual/html/search/variables_e.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['version',['version',['../structustar__header__t.html#a221e6c066702728c67bd6f60b54f255d',1,'ustar_header_t']]] +]; diff --git a/docs/api_reference_manual/html/structcy__ota__file__info__t.html b/docs/api_reference_manual/html/structcy__ota__file__info__t.html new file mode 100644 index 0000000..11eea73 --- /dev/null +++ b/docs/api_reference_manual/html/structcy__ota__file__info__t.html @@ -0,0 +1,212 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: cy_ota_file_info_t Struct Reference + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
cy_ota_file_info_t Struct Reference
+
+
+

Description

+

Structure used for keeping track of files in the tar archive while extracting.

+
+ + + + + + + + + + + + + + + + + + + +

+Data Fields

+char name [TNAMELEN]
 Copied from the components.json file.
 
char type [CY_FILE_TYPE_LEN]
 From components.json. More...
 
uint16_t found_in_tar
 Encountered the header in the tar file. More...
 
uint32_t header_offset
 Offset of the header in the tar file. More...
 
uint32_t size
 From components.json, verified from the header. More...
 
uint32_t processed
 Bytes processed from the tar file. More...
 
+

Field Documentation

+ +
+
+ + + + +
char cy_ota_file_info_t::type[CY_FILE_TYPE_LEN]
+
+ +

From components.json.

+ +
+
+ +
+
+ + + + +
uint16_t cy_ota_file_info_t::found_in_tar
+
+ +

Encountered the header in the tar file.

+ +
+
+ +
+
+ + + + +
uint32_t cy_ota_file_info_t::header_offset
+
+ +

Offset of the header in the tar file.

+ +
+
+ +
+
+ + + + +
uint32_t cy_ota_file_info_t::size
+
+ +

From components.json, verified from the header.

+ +
+
+ +
+
+ + + + +
uint32_t cy_ota_file_info_t::processed
+
+ +

Bytes processed from the tar file.

+ +
+
+
+
+ + + + diff --git a/docs/api_reference_manual/html/structcy__untar__context__t.html b/docs/api_reference_manual/html/structcy__untar__context__t.html new file mode 100644 index 0000000..487c411 --- /dev/null +++ b/docs/api_reference_manual/html/structcy__untar__context__t.html @@ -0,0 +1,395 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: cy_untar_context_t Struct Reference + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
cy_untar_context_t Struct Reference
+
+
+

Description

+

Struct to hold information on the un-tar process.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

uint32_t magic
 CY_UNTAR_CONTEXT_MAGIC. More...
 
cy_tar_parse_state_t tar_state
 Current parsing state. More...
 
untar_write_callback_t cb_func
 Callback function to deal with the data. More...
 
void * cb_arg
 Opaque argument passed to callback. More...
 
uint16_t already_parsed_components_json
 True if components.json is parsed. More...
 
uint32_t bytes_processed
 Bytes processed from the archive. More...
 
char app_version [CY_VERSION_STRING_MAX]
 String of major.minor.build. More...
 
uint16_t num_files_in_json
 Number of files in components.json. More...
 
uint16_t curr_file_in_json
 Parsing file info in components.json. More...
 
uint16_t current_file
 Currently processing this file from the tar archive. More...
 
uint16_t num_files
 number of files encountered. More...
 
cy_ota_file_info_t files [CY_MAX_TAR_FILES]
 File info. More...
 
uint32_t coalesce_stream_offset
 Offset into the stream where the coalesce buffer starts. More...
 
uint32_t coalesce_bytes
 Number of bytes in the coalesce buffer. More...
 
uint32_t coalesce_needs
 Number of bytes needed in the coalesce buffer. More...
 
uint8_t coalesce_buffer [CY_TAR_COALESCE_BUFFER_SIZE]
 Used to coalesce buffers for longer sequential data. More...
 
+

Field Documentation

+ +
+
+ + + + +
uint32_t cy_untar_context_t::magic
+
+ +

CY_UNTAR_CONTEXT_MAGIC.

+ +
+
+ +
+
+ + + + +
cy_tar_parse_state_t cy_untar_context_t::tar_state
+
+ +

Current parsing state.

+ +
+
+ +
+
+ + + + +
untar_write_callback_t cy_untar_context_t::cb_func
+
+ +

Callback function to deal with the data.

+ +
+
+ +
+
+ + + + +
void* cy_untar_context_t::cb_arg
+
+ +

Opaque argument passed to callback.

+ +
+
+ +
+
+ + + + +
uint16_t cy_untar_context_t::already_parsed_components_json
+
+ +

True if components.json is parsed.

+ +
+
+ +
+
+ + + + +
uint32_t cy_untar_context_t::bytes_processed
+
+ +

Bytes processed from the archive.

+ +
+
+ +
+
+ + + + +
char cy_untar_context_t::app_version[CY_VERSION_STRING_MAX]
+
+ +

String of major.minor.build.

+ +
+
+ +
+
+ + + + +
uint16_t cy_untar_context_t::num_files_in_json
+
+ +

Number of files in components.json.

+ +
+
+ +
+
+ + + + +
uint16_t cy_untar_context_t::curr_file_in_json
+
+ +

Parsing file info in components.json.

+ +
+
+ +
+
+ + + + +
uint16_t cy_untar_context_t::current_file
+
+ +

Currently processing this file from the tar archive.

+ +
+
+ +
+
+ + + + +
uint16_t cy_untar_context_t::num_files
+
+ +

number of files encountered.

+ +
+
+ +
+
+ + + + +
cy_ota_file_info_t cy_untar_context_t::files[CY_MAX_TAR_FILES]
+
+ +

File info.

+ +
+
+ +
+
+ + + + +
uint32_t cy_untar_context_t::coalesce_stream_offset
+
+ +

Offset into the stream where the coalesce buffer starts.

+ +
+
+ +
+
+ + + + +
uint32_t cy_untar_context_t::coalesce_bytes
+
+ +

Number of bytes in the coalesce buffer.

+ +
+
+ +
+
+ + + + +
uint32_t cy_untar_context_t::coalesce_needs
+
+ +

Number of bytes needed in the coalesce buffer.

+ +
+
+ +
+
+ + + + +
uint8_t cy_untar_context_t::coalesce_buffer[CY_TAR_COALESCE_BUFFER_SIZE]
+
+ +

Used to coalesce buffers for longer sequential data.

+ +
+
+
+
+ + + + diff --git a/docs/api_reference_manual/html/structflash__area.html b/docs/api_reference_manual/html/structflash__area.html new file mode 100644 index 0000000..7ef3eae --- /dev/null +++ b/docs/api_reference_manual/html/structflash__area.html @@ -0,0 +1,151 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: flash_area Struct Reference + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
flash_area Struct Reference
+
+
+

Description

+

Provides abstraction of flash regions for type of use.

+

I.e. dude where's my image?

+

System will contain a map which contains flash areas. Every region will contain flash identifier, offset within flash and length.

+
    +
  1. This system map could be in a file within filesystem (Initializer must know/figure out where the filesystem is at).
  2. +
  3. Map could be at fixed location for project (compiled to code)
  4. +
  5. Map could be at specific place in flash (put in place at mfg time).
  6. +
+

Note that the map you use must be valid for BSP it's for, match the linker scripts when platform executes from flash, and match the target offset specified in download script. Structure describing an area on a flash device.

+

Multiple flash devices may be available in the system, each of which may have its own areas. For this reason, flash areas track which flash device they are part of.

+
+ + + + + + + + + + + + + + + + +

+Data Fields

+uint8_t fa_id
 This flash area's ID; unique in the system.
 
+uint8_t fa_device_id
 ID of the flash device this area is a part of.
 
+uint16_t pad16
 Pad for Word length(32 Bytes).
 
+uint32_t fa_off
 This area's offset, relative to the beginning of its flash device's storage.
 
+uint32_t fa_size
 This area's size, in bytes.
 
+
+
+ + + + diff --git a/docs/api_reference_manual/html/structustar__header__t.html b/docs/api_reference_manual/html/structustar__header__t.html new file mode 100644 index 0000000..8c9fe1e --- /dev/null +++ b/docs/api_reference_manual/html/structustar__header__t.html @@ -0,0 +1,383 @@ + + + + + + + + +Over The Air (OTA) Bootloader Abstraction Library: ustar_header_t Struct Reference + + + + + + + + + + + + + +
+
+ + + + + + + +
+
Over The Air (OTA) Bootloader Abstraction Library
+
+
+ + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+ +
+
ustar_header_t Struct Reference
+
+
+

Description

+

Structure defined by IEEE for start of each file within the archive.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+uint8_t name [TNAMELEN]
 0 0x00 100 File name (NUL terminated)
 
uint8_t mode [8]
 100 0x64 8 See mode bits above. More...
 
uint8_t uid [8]
 108 0x6c 8 User ID. More...
 
uint8_t gid [8]
 116 0x74 8 Group ID. More...
 
uint8_t size [12]
 124 0x7c 12 File size. More...
 
uint8_t mtime [12]
 136 0x88 12 Modified time. More...
 
uint8_t chksum [8]
 148 0x94 8 Checksum. More...
 
uint8_t typeflag
 156 0x9c 1 Type (see above). More...
 
uint8_t linkname [TNAMELEN]
 157 0x9d 100 Linked file name. More...
 
uint8_t magic [TMAGLEN]
 257 0x101 6 TMAGIC (NUL terminated). More...
 
uint8_t version [TVERSLEN]
 263 0x107 2 TVERSION. More...
 
uint8_t uname [32]
 265 0x109 32 user name. More...
 
uint8_t gname [32]
 297 0x129 32 Group name. More...
 
uint8_t devmajor [8]
 329 0x149 8 Major. More...
 
uint8_t devminor [8]
 337 0x151 8 Minor. More...
 
uint8_t prefix [155]
 345 0x159 155 Prefix. More...
 
+

Field Documentation

+ +
+
+ + + + +
uint8_t ustar_header_t::mode[8]
+
+ +

100 0x64 8 See mode bits above.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::uid[8]
+
+ +

108 0x6c 8 User ID.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::gid[8]
+
+ +

116 0x74 8 Group ID.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::size[12]
+
+ +

124 0x7c 12 File size.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::mtime[12]
+
+ +

136 0x88 12 Modified time.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::chksum[8]
+
+ +

148 0x94 8 Checksum.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::typeflag
+
+ +

156 0x9c 1 Type (see above).

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::linkname[TNAMELEN]
+
+ +

157 0x9d 100 Linked file name.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::magic[TMAGLEN]
+
+ +

257 0x101 6 TMAGIC (NUL terminated).

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::version[TVERSLEN]
+
+ +

263 0x107 2 TVERSION.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::uname[32]
+
+ +

265 0x109 32 user name.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::gname[32]
+
+ +

297 0x129 32 Group name.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::devmajor[8]
+
+ +

329 0x149 8 Major.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::devminor[8]
+
+ +

337 0x151 8 Minor.

+ +
+
+ +
+
+ + + + +
uint8_t ustar_header_t::prefix[155]
+
+ +

345 0x159 155 Prefix.

+

500 0x1f4 12 Padding implied to the end of the 512-byte block.

+ +
+
+
+
+ + + + diff --git a/docs/api_reference_manual/html/sync_off.png b/docs/api_reference_manual/html/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/docs/api_reference_manual/html/sync_off.png differ diff --git a/docs/api_reference_manual/html/sync_on.png b/docs/api_reference_manual/html/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/docs/api_reference_manual/html/sync_on.png differ diff --git a/docs/api_reference_manual/html/tab_a.png b/docs/api_reference_manual/html/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/docs/api_reference_manual/html/tab_a.png differ diff --git a/docs/api_reference_manual/html/tab_b.png b/docs/api_reference_manual/html/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/docs/api_reference_manual/html/tab_b.png differ diff --git a/docs/api_reference_manual/html/tab_h.png b/docs/api_reference_manual/html/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/docs/api_reference_manual/html/tab_h.png differ diff --git a/docs/api_reference_manual/html/tab_s.png b/docs/api_reference_manual/html/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/docs/api_reference_manual/html/tab_s.png differ diff --git a/docs/api_reference_manual/html/tabs.css b/docs/api_reference_manual/html/tabs.css new file mode 100644 index 0000000..9cf578f --- /dev/null +++ b/docs/api_reference_manual/html/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/images/Banner.png b/images/Banner.png new file mode 100644 index 0000000..fdb81f3 Binary files /dev/null and b/images/Banner.png differ diff --git a/include/cy_ota_bootloader_abstraction_log.h b/include/cy_ota_bootloader_abstraction_log.h new file mode 100644 index 0000000..c8f23b9 --- /dev/null +++ b/include/cy_ota_bootloader_abstraction_log.h @@ -0,0 +1,45 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +#ifndef CY_OTA_BOOTLOADER_ABSTRACTION_LOG_H__ +#define CY_OTA_BOOTLOADER_ABSTRACTION_LOG_H__ 1 + +#include "cy_log.h" + +#ifdef ENABLE_OTA_BOOTLOADER_ABSTRACTION_LOGS +#define cy_ota_bootloader_abstraction_log_msg cy_log_msg +#else +#define cy_ota_bootloader_abstraction_log_msg(a,b,c,...) +#endif + +#endif /* CY_OTA_BOOTLOADER_ABSTRACTION_LOG_H__ */ diff --git a/makefiles/mcuboot/mcuboot_support.mk b/makefiles/mcuboot/mcuboot_support.mk new file mode 100644 index 0000000..8320b51 --- /dev/null +++ b/makefiles/mcuboot/mcuboot_support.mk @@ -0,0 +1,848 @@ +################################################################################ +# \file mcuboot_support.mk +# \version 1.0 +# +# \brief +# Makefile containing the MCUboot flashmap dependencies. +# +################################################################################ +# \copyright +# Copyright 2018-2022 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################# +# Find the Relative path between the bootloader support Makefiles and the Application's Build Directory +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Darwin) + + ota_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) + ota_dir:=$(shell cd $(shell dirname $(ota_path)); pwd) + current_dir := $(shell PWD) + + # current_dir = $(shell pwd -P) + RELATIVE_FILE1_FILE2:=$(shell perl -MFile::Spec::Functions=abs2rel -E 'say abs2rel(shift, shift)' $(ota_dir) $(current_dir)) +else + ota_dir := $(realpath $(patsubst %/,%,$(dir $(realpath $(lastword $(MAKEFILE_LIST)))))) + current_dir = $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) + RELATIVE_FILE1_FILE2:=$(shell realpath --relative-to $(current_dir) $(ota_dir)) +endif + +################################################################################################### +# OTA SUPPORT +################################################################################################### +# This is the size of the header that imgtool will pre-pend to application +# Must match with MCUBoot +# Do not change +MCUBOOT_HEADER_SIZE=0x400 + +# Default Bootstrap size for MCUBootloader +APP_BOOTSTRAP_SIZE=0x2400 + +# Internal and external erased flash values +CY_INTERNAL_FLASH_ERASE_VALUE=0x00 +CY_EXTERNAL_FLASH_ERASE_VALUE=0xFF + +# Define App version +APP_BUILD_VERSION?=$(APP_VERSION_MAJOR).$(APP_VERSION_MINOR).$(APP_VERSION_BUILD) +DEFINES+=APP_BUILD_VERSION=$(APP_BUILD_VERSION) + +################################################################################################### +# Default OTA_PLATFORM based on TARGET +################################################################################################### +#---------------------------------- +# CYW920829M2EVK-02 +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CYW920829M2EVK-02) + OTA_PLATFORM?=CYW20829 +endif + +#---------------------------------- +# CY8CKIT-062S2-43012 +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CKIT-062S2-43012) + OTA_PLATFORM?=PSOC_062_2M +endif + +#---------------------------------- +# CY8CPROTO-062-4343W +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CPROTO-062-4343W) + OTA_PLATFORM?=PSOC_062_2M +endif + +#---------------------------------- +# CY8CPROTO-062S3-4343W +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CPROTO-062S3-4343W) + OTA_PLATFORM?=PSOC_062_512K +endif + +#---------------------------------- +# CY8CEVAL-062S2-CYW943439M2IPA1 +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CEVAL-062S2-CYW943439M2IPA1) + OTA_PLATFORM?=PSOC_062_2M +endif + +#---------------------------------- +# CY8CEVAL-062S2-LAI-4373M2 +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CEVAL-062S2-LAI-4373M2) + OTA_PLATFORM?=PSOC_062_2M +endif + +#---------------------------------- +# CY8CEVAL-062S2-MUR-43439M2 +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CEVAL-062S2-MUR-43439M2) + OTA_PLATFORM?=PSOC_062_2M +endif + +#---------------------------------- +# CY8CKIT-062-BLE +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CKIT-062-BLE) + OTA_PLATFORM?=PSOC_062_1M +endif + +#---------------------------------- +# CY8CPROTO-063-BLE +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CPROTO-063-BLE) + OTA_PLATFORM?=PSOC_063_1M +endif + +#---------------------------------- +# CYBLE-416045-EVAL +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CYBLE-416045-EVAL) + OTA_PLATFORM?=PSOC_063_1M +endif + +#---------------------------------- +# CY8CKIT-064B0S2-4343W +#---------------------------------- +ifeq ($(ACTUAL_TARGET), CY8CKIT-064B0S2-4343W) + OTA_PLATFORM?=PSOC_064_2M +endif + +#---------------------------------- +# KIT_XMC72_EVK +#---------------------------------- +ifeq ($(ACTUAL_TARGET), KIT_XMC72_EVK) + OTA_PLATFORM?=XMC7200 +endif + +################################################################################################### +# Default flashmaps based on OTA_PLATFORM +################################################################################################### +ifeq ($(OTA_PLATFORM),PSOC_062_2M) + # Default to Internal + External Flash, Swap, Single Image + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_ext_swap_single.json +endif + +ifeq ($(OTA_PLATFORM),PSOC_062_1M) + # Default to int Swap, BLESS requires cm0p code inclusion + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/psoc62_1m_cm0_int_swap_single.json +endif + +ifeq ($(OTA_PLATFORM),PSOC_063_1M) + # Default to int Swap, BLESS requires cm0p code inclusion + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/psoc63_1m_cm0_int_swap_single.json +endif + +ifeq ($(OTA_PLATFORM),PSOC_062_512K) + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_xip_swap_single.json +endif + +ifeq ($(OTA_PLATFORM),PSOC_064_2M) + # Default to ext Swap, we need to define for later in the Makefile + # Although we don't actually use it. + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/policy_single_CM0_CM4_smif_swap.json + # Policy name here for reference when provisioning CY8CKIT-064B0S2-4343W + CY_SECURE_POLICY_NAME = policy_single_CM0_CM4_smif_swap +endif + +ifeq ($(OTA_PLATFORM),CYW20829) + # Default to XIP Swap + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_swap_single.json +endif + +ifeq ($(OTA_PLATFORM),XMC7200) + OTA_FLASH_MAP?=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/xmc7200_int_swap_single.json + OTA_PLATFORM_CONFIG_JSON=$(RELATIVE_FILE1_FILE2)/../../configs/COMPONENT_MCUBOOT/flashmap/xmc7200_platform.json +endif + +############################# +# Check for Required defines +############################# + +# MUST provide platform type +# Must be one of these names +OTA_PSOC_062_SUPPORTED_PLATFORMS="PSOC_062_512K PSOC_062_1M PSOC_062_2M " +OTA_PSOC_063_SUPPORTED_PLATFORMS="PSOC_063_1M " +OTA_PSOC_064_SUPPORTED_PLATFORMS="PSOC_064_2M " +OTA_PSOC_06X_SUPPORTED_PLATFORMS=$(OTA_PSOC_062_SUPPORTED_PLATFORMS)$(OTA_PSOC_063_SUPPORTED_PLATFORMS)$(OTA_PSOC_064_SUPPORTED_PLATFORMS) +OTA_OTHER_SUPPORTED_PLATFORMS="CYW20829 XMC7200" +OTA_SUPPORTED_PLATFORMS=$(OTA_PSOC_06X_SUPPORTED_PLATFORMS) $(OTA_OTHER_SUPPORTED_PLATFORMS) + +# Add OTA_PLATFORM in DEFINES for platform-specific code +DEFINES+=$(OTA_PLATFORM) + +# for use when running flashmap.py +FLASHMAP_PLATFORM=$(OTA_PLATFORM) + +# For generalized PSOC based specifics +ifneq ($(findstring $(OTA_PLATFORM), $(OTA_PSOC_06X_SUPPORTED_PLATFORMS)),) + #ifeq ($(OTA_BUILD_VERBOSE),2) + $(info FOUND $(OTA_PLATFORM) Use COMPONENT_OTA_PSOC_062) + #endif + COMPONENTS+=OTA_PSOC_062 +endif + +################################################################################################### +# OTA Flashmap JSON file Usage +################################################################################################### +# +# flashmap.py creates flashmap.mk, a number of defines which are then included in the build. +# It is important to include the defines here (and not just in cy_flash_map.c) as they are used in POSTBUILD processing +# +# Look in configs/COMPONENT_MCUBOOT/flashmap for an appropriate JSON file +# +# CYW920829 +# Single image JSON files, always external flash +# flashmap/cyw20829_ext_overwrite_single.json +# flashmap/cyw20829_ext_swap_single.json +# CY8CPROTO-062S3-4343W +# Single image JSON files, internal flash +# flashmap/psoc62s3_int_overwrite_single.json +# flashmap/psoc62s3_int_swap_single.json +# Single image JSON files, XIP from external flash +# flashmap/psoc62s3_xip_swap_single.json +# CY8CKIT-062-BLE +# Single image JSON files, internal flash +# flashmap/psoc62_1m_int_swap_single.json +# Single image JSON files, XIP from external flash +# flashmap/psoc62_1m_xip_swap_single.json +# Other PSoC6 targets +# Single image JSON files, internal flash only +# flashmap/psoc62_int_overwrite_single.json +# flashmap/psoc62_int_swap_single.json +# Single image JSON files, internal + external flash +# flashmap/psoc62_ext_overwrite_single.json +# flashmap/psoc62_ext_swap_single.json +# Single image JSON files, XIP from external flash +# flashmap/psoc62_xip_swap_single.json +# +# CY8CPROTO-063-BLE +# Single image JSON files, internal flash +# flashmap/psoc63_1m_int_swap_single.json +# Single image JSON files, XIP from external flash +# flashmap/psoc63_1m_xip_swap_single.json +# +# CY8CKIT-064B0S2-4343W +# DOES NOT USE JSON FILE at this time +# +# Example output that is piped into flashmap.mk for an XIP application: +# +# AUTO-GENERATED FILE, DO NOT EDIT. ALL CHANGES WILL BE LOST! +# FLASH_AREA_BOOTLOADER_DEV_ID :=FLASH_DEVICE_INTERNAL_FLASH +# FLASH_AREA_BOOTLOADER_START :=0x000000 +# FLASH_AREA_BOOTLOADER_SIZE :=0x018000 +# FLASH_AREA_IMG_1_PRIMARY_DEV_ID :=FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX) +# FLASH_AREA_IMG_1_PRIMARY_START :=0x000000 +# FLASH_AREA_IMG_1_PRIMARY_SIZE :=0x140200 +# FLASH_AREA_IMG_1_SECONDARY_DEV_ID :=FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX) +# FLASH_AREA_IMG_1_SECONDARY_START :=0x180000 +# FLASH_AREA_IMG_1_SECONDARY_SIZE :=0x140200 +# FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID :=FLASH_DEVICE_INTERNAL_FLASH +# FLASH_AREA_IMAGE_SWAP_STATUS_START :=0x018000 +# FLASH_AREA_IMAGE_SWAP_STATUS_SIZE :=0x003c00 +# FLASH_AREA_IMAGE_SCRATCH_DEV_ID :=FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX) +# FLASH_AREA_IMAGE_SCRATCH_START :=0x440000 +# FLASH_AREA_IMAGE_SCRATCH_SIZE :=0x080000 +# MCUBOOT_IMAGE_NUMBER := 1 +# MCUBOOT_MAX_IMG_SECTORS := 32 +# USE_EXTERNAL_FLASH := 1 +# USE_XIP := 1 +# +# Always update the flash area definitions. +# Note: The build system will not re-build all files as the defines have not changed since last build. +#$(shell rm -f flashmap.mk) + +ifeq ($(OTA_PLATFORM),PSOC_064_2M) + # CY8CKIT-064B0S2-4343W + # Single image JSON File, int + ext flash + # flashmap.py does not support this platform at this time + $(info flashmap.py does not support PSOC_064_2M - We write out directly here!) #IMP_CHECK + + # Define FLASHMAP_PYTHON_SCRIPT as nothing so it is not executed after start.mk at end of Makefile + FLASHMAP_PYTHON_SCRIPT= + + $(shell echo "# AUTO-GENERATED FILE, DO NOT EDIT. ALL CHANGES WILL BE LOST!" > flashmap.mk) + $(shell echo "FLASH_AREA_BOOTLOADER_DEV_ID :=FLASH_DEVICE_INTERNAL_FLASH" >> flashmap.mk) + $(shell echo "FLASH_AREA_BOOTLOADER_START :=0x1e0000" >> flashmap.mk) + $(shell echo "FLASH_AREA_BOOTLOADER_SIZE :=0x018000" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMG_1_PRIMARY_DEV_ID :=FLASH_DEVICE_INTERNAL_FLASH" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMG_1_PRIMARY_START :=0x000000" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMG_1_PRIMARY_SIZE :=0x1c8000" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMG_1_SECONDARY_DEV_ID :=FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX)" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMG_1_SECONDARY_START :=0x038400" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMG_1_SECONDARY_SIZE :=0x1c8000" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID :=FLASH_DEVICE_INTERNAL_FLASH" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMAGE_SWAP_STATUS_START :=0x1cc000" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMAGE_SWAP_STATUS_SIZE :=0x006c00" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMAGE_SCRATCH_DEV_ID :=FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX)" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMAGE_SCRATCH_START :=0x280000" >> flashmap.mk) + $(shell echo "FLASH_AREA_IMAGE_SCRATCH_SIZE :=0x0c0000" >> flashmap.mk) + $(shell echo "MCUBOOT_IMAGE_NUMBER := 1" >> flashmap.mk) + $(shell echo "MCUBOOT_MAX_IMG_SECTORS := 3648" >> flashmap.mk) + $(shell echo "USE_EXTERNAL_FLASH := 1" >> flashmap.mk) + +else + # non-PSOC_064_2M here + ifneq ($(findstring $(MAKECMDGOALS), build program all),) + ifeq ($(CY_PYTHON_PATH),) + $(error CY_PYTHON_PATH is not configured) + else + $(info setting CY_PYTHON_PATH = $(CY_PYTHON_PATH)) + endif # checking for python path + + ifeq ($(OTA_PLATFORM),XMC7200) + # XMC7200 here + FLASHMAP_PYTHON_SCRIPT=flashmap_xmc.py + IMG_ID=1 + ifneq ($(FLASHMAP_PYTHON_SCRIPT),) + $(info : OTA_FLASH_MAP = $(OTA_FLASH_MAP)) + $(info "flashmap_xmc.py $(CY_PYTHON_PATH) $(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/$(FLASHMAP_PYTHON_SCRIPT) run -p $(OTA_PLATFORM_CONFIG_JSON) -i $(OTA_FLASH_MAP) -o $(RELATIVE_FILE1_FILE2)/../../source/COMPONENT_MCUBOOT/ -n cy_flash_map -d $(IMG_ID) > flashmap.mk") + $(shell $(CY_PYTHON_PATH) $(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/$(FLASHMAP_PYTHON_SCRIPT) run -p $(OTA_PLATFORM_CONFIG_JSON) -i $(OTA_FLASH_MAP) -o $(RELATIVE_FILE1_FILE2)/../../source/COMPONENT_MCUBOOT/ -n cy_flash_map -d $(IMG_ID) > flashmap.mk) + endif # check for flashmap name + else + # Non-XMC7200 here + FLASHMAP_PYTHON_SCRIPT=flashmap.py + ifneq ($(FLASHMAP_PYTHON_SCRIPT),) + $(info : OTA_FLASH_MAP = $(OTA_FLASH_MAP)) + $(info "flashmap.py $(CY_PYTHON_PATH) $(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/$(FLASHMAP_PYTHON_SCRIPT) -p $(FLASHMAP_PLATFORM) -i $(OTA_FLASH_MAP) -o $(RELATIVE_FILE1_FILE2)/../../source/COMPONENT_MCUBOOT/cy_flash_map.h > flashmap.mk") + $(shell $(CY_PYTHON_PATH) $(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/$(FLASHMAP_PYTHON_SCRIPT) -p $(FLASHMAP_PLATFORM) -i $(OTA_FLASH_MAP) -o $(RELATIVE_FILE1_FILE2)/../../source/COMPONENT_MCUBOOT/cy_flash_map.h > flashmap.mk) + endif # check for flashmap name + endif # XMC7200 check + + flash_map_status=$(shell if [ -s "flashmap.mk" ]; then echo "success"; fi ) + ifeq ($(flash_map_status),) + $(info "") + $(error Failed to create flashmap.mk !) + $(info "") + endif # check for flashmap.mk created + endif # check for build command +endif # PSOC_064_2M check + +flash_map_mk_exists=$(shell if [ -s "flashmap.mk" ]; then echo "success"; fi ) + +ifneq ($(flash_map_mk_exists),) + $(info include flashmap.mk) + include ./flashmap.mk +endif # flash_map_mk_exists + +############################ +# IF FLASH_MAP sets USE_XIP, +# we are executing code +# from external flash +############################ + +ifeq ($(USE_XIP),1) + ifeq ($(OTA_BUILD_VERBOSE),1) + $(info Makefile: USE_XIP=1) + endif + + CY_RUN_CODE_FROM_XIP=1 + + # For IAR XIP builds, we need to move some code to RAM #IMP_CHECK + ifeq ($(TOOLCHAIN),IAR) + ifeq ($(OTA_BUILD_VERBOSE),1) + $(info Makefile: ADD CY_INIT_CODECOPY_ENABLE for IAR XIP) + endif + DEFINES+=CY_INIT_CODECOPY_ENABLE + endif + + # When running from external flash + # That we need to turn off XIP and enter critical section when accessing SMIF + # NOTE: CYW920829 does not need this. Generalize for now, + # we may need to change this criteria for future devices + ifneq ($(OTA_PLATFORM),CYW20829) + CY_XIP_SMIF_MODE_CHANGE=1 + + # Since we are running hybrid (some in RAM, some in External FLash), #IMP_CHECK + # we need to override the WEAK functions in CYHAL + DEFINES+=CYHAL_DISABLE_WEAK_FUNC_IMPL=1 + endif # Not CYW20829 +endif # USE_XIP + +# TODO: Can we base this on the flash area at RUNTIME rather than defining it at build time? +# Flash areas / images are allowed to be placed willy-nilly +ifeq ($(FLASH_AREA_IMG_1_SECONDARY_DEV_ID),FLASH_DEVICE_INTERNAL_FLASH) + FLASH_ERASE_SECONDARY_SLOT_VALUE= $(CY_INTERNAL_FLASH_ERASE_VALUE) +else + FLASH_ERASE_SECONDARY_SLOT_VALUE= $(CY_EXTERNAL_FLASH_ERASE_VALUE) +endif # SECONDARY_DEV_ID + +# Application MUST provide a flash map +ifneq ($(MAKECMDGOALS),getlibs) + ifeq ($(OTA_FLASH_MAP),) + $(info "") + $(error Application makefile must define OTA_FLASH_MAP. For more info, see /configs/COMPONENT_MCUBOOT/flashmap/MCUBOOT_BUILD_COMMANDS.md) + $(info "") + endif +endif + +################################### +# The Defines for the flash map +################################### +DEFINES+=\ + MCUBOOT_MAX_IMG_SECTORS=$(MCUBOOT_MAX_IMG_SECTORS)\ + MCUBOOT_IMAGE_NUMBER=$(MCUBOOT_IMAGE_NUMBER)\ + FLASH_AREA_BOOTLOADER_DEV_ID="$(FLASH_AREA_BOOTLOADER_DEV_ID)"\ + FLASH_AREA_BOOTLOADER_START=$(FLASH_AREA_BOOTLOADER_START)\ + FLASH_AREA_BOOTLOADER_SIZE=$(FLASH_AREA_BOOTLOADER_SIZE)\ + FLASH_AREA_IMG_1_PRIMARY_DEV_ID="$(FLASH_AREA_IMG_1_PRIMARY_DEV_ID)"\ + FLASH_AREA_IMG_1_PRIMARY_START=$(FLASH_AREA_IMG_1_PRIMARY_START) \ + FLASH_AREA_IMG_1_PRIMARY_SIZE=$(FLASH_AREA_IMG_1_PRIMARY_SIZE) \ + FLASH_AREA_IMG_1_SECONDARY_DEV_ID="$(FLASH_AREA_IMG_1_SECONDARY_DEV_ID)"\ + FLASH_AREA_IMG_1_SECONDARY_START=$(FLASH_AREA_IMG_1_SECONDARY_START) \ + FLASH_AREA_IMG_1_SECONDARY_SIZE=$(FLASH_AREA_IMG_1_SECONDARY_SIZE) + +ifneq ($(FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID),) + DEFINES+=\ + FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID="$(FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID)"\ + FLASH_AREA_IMAGE_SWAP_STATUS_START=$(FLASH_AREA_IMAGE_SWAP_STATUS_START)\ + FLASH_AREA_IMAGE_SWAP_STATUS_SIZE=$(FLASH_AREA_IMAGE_SWAP_STATUS_SIZE) +endif + +ifneq ($(FLASH_AREA_IMAGE_SCRATCH_DEV_ID),) + DEFINES+=\ + FLASH_AREA_IMAGE_SCRATCH_DEV_ID="$(FLASH_AREA_IMAGE_SCRATCH_DEV_ID)"\ + FLASH_AREA_IMAGE_SCRATCH_START=$(FLASH_AREA_IMAGE_SCRATCH_START)\ + FLASH_AREA_IMAGE_SCRATCH_SIZE=$(FLASH_AREA_IMAGE_SCRATCH_SIZE) +endif + + +ifeq ($(MCUBOOT_IMAGE_NUMBER),2) + DEFINES+=\ + FLASH_AREA_IMG_2_PRIMARY_DEV_ID=$(FLASH_AREA_IMG_2_PRIMARY_DEV_ID)\ + FLASH_AREA_IMG_2_PRIMARY_START=$(FLASH_AREA_IMG_2_PRIMARY_START) \ + FLASH_AREA_IMG_2_PRIMARY_SIZE=$(FLASH_AREA_IMG_2_PRIMARY_SIZE) \ + FLASH_AREA_IMG_2_SECONDARY_DEV_ID=$(FLASH_AREA_IMG_2_SECONDARY_DEV_ID) \ + FLASH_AREA_IMG_2_SECONDARY_START=$(FLASH_AREA_IMG_2_SECONDARY_START) \ + FLASH_AREA_IMG_2_SECONDARY_SIZE=$(FLASH_AREA_IMG_2_SECONDARY_SIZE) +endif + +ifeq ($(USE_EXTERNAL_FLASH),1) + DEFINES+=OTA_USE_EXTERNAL_FLASH=1 +endif + +ifeq ($(CY_RUN_CODE_FROM_XIP),1) + DEFINES+=CY_RUN_CODE_FROM_XIP=1 +endif + +ifeq ($(CY_XIP_SMIF_MODE_CHANGE),1) + DEFINES+=CY_XIP_SMIF_MODE_CHANGE=1 +endif + +################################## +# Additional / custom linker flags. +################################## + +#IMP_CHECK : Usage of -Wl LDFlag. + +ifeq ($(TOOLCHAIN),GCC_ARM) + CY_ELF_TO_HEX=$(MTB_TOOLCHAIN_GCC_ARM__OBJCOPY) + CY_ELF_TO_HEX_OPTIONS="-O ihex" + CY_ELF_TO_HEX_FILE_ORDER="elf_first" + LDFLAGS+="-Wl,--defsym,MCUBOOT_HEADER_SIZE=$(MCUBOOT_HEADER_SIZE),--defsym,FLASH_AREA_IMG_1_PRIMARY_START=$(FLASH_AREA_IMG_1_PRIMARY_START),--defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=$(FLASH_AREA_IMG_1_PRIMARY_SIZE)" +else + ifeq ($(TOOLCHAIN),IAR) + CY_ELF_TO_HEX="$(CY_COMPILER_IAR_DIR)/bin/ielftool" + CY_ELF_TO_HEX_OPTIONS="--ihex" + CY_ELF_TO_HEX_FILE_ORDER="elf_first" + LDFLAGS+=--config_def MCUBOOT_HEADER_SIZE=$(MCUBOOT_HEADER_SIZE) --config_def FLASH_AREA_IMG_1_PRIMARY_START=$(FLASH_AREA_IMG_1_PRIMARY_START) --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=$(FLASH_AREA_IMG_1_PRIMARY_SIZE) + ifeq ($(OTA_PLATFORM),XMC7200) + CY_OTA_APP_HEAP_SIZE?=0x40000 + LDFLAGS+=--config_def __HEAP_SIZE=$(CY_OTA_APP_HEAP_SIZE) + endif + else + ifeq ($(TOOLCHAIN),ARM) + ifeq ($(OS),Windows_NT) + CY_ELF_TO_HEX=$(MTB_TOOLCHAIN_ARM__BASE_DIR)/bin/fromelf.exe + else + CY_ELF_TO_HEX=$(MTB_TOOLCHAIN_ARM__BASE_DIR)/bin/fromelf + endif + CY_ELF_TO_HEX_OPTIONS="--i32combined --output" + CY_ELF_TO_HEX_FILE_ORDER="hex_first" + LDFLAGS+=--pd=-DMCUBOOT_HEADER_SIZE=$(MCUBOOT_HEADER_SIZE) --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=$(FLASH_AREA_IMG_1_PRIMARY_START) --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=$(FLASH_AREA_IMG_1_PRIMARY_SIZE) + LDFLAGS+=--diag_suppress=L6314W + else + $(error Must define toolchain ! GCC_ARM, ARM, or IAR) + endif #ARM + endif #IAR +endif #GCC_ARM + +# Find Linker Script using wildcard +# Directory within ota-upgrade library + +ifeq ($(OTA_SUPPORT),1) + ifeq ($(OTA_LINKER_FILE), ) + $(info ======================================================================= ) + $(error Provide OTA linker file for $(TARGET)) + else + LINKER_SCRIPT=$(OTA_LINKER_FILE) + endif +endif + +################################################################################################### +# +# Build information +# +################################################################################################### + +ifneq ($(CY_SECONDSTAGE),) + ifeq ($(OTA_BUILD_VERBOSE),1) + $(info Makefile:) + $(info Makefile: TARGET = $(TARGET)) + $(info Makefile: OTA_PLATFORM = $(OTA_PLATFORM)) + $(info Makefile: OTA_FLASH_MAP = $(OTA_FLASH_MAP)) + $(info Makefile: APP_VERSION_MAJOR = $(APP_VERSION_MAJOR)) + $(info Makefile: APP_VERSION_MINOR = $(APP_VERSION_MINOR)) + $(info Makefile: APP_VERSION_BUILD = $(APP_VERSION_BUILD)) + $(info Makefile: CY_TEST_APP_VERSION_IN_TAR = $(CY_TEST_APP_VERSION_IN_TAR)) + $(info Makefile: USE_XIP = $(USE_XIP)) + $(info Makefile: CY_RUN_CODE_FROM_XIP = $(CY_RUN_CODE_FROM_XIP)) + $(info Makefile: CY_XIP_SMIF_MODE_CHANGE = $(CY_XIP_SMIF_MODE_CHANGE)) + $(info Makefile: USE_EXTERNAL_FLASH = $(USE_EXTERNAL_FLASH)) + endif # OTA_BUILD_VERBOSE=1 + + ifeq ($(OTA_BUILD_FLASH_VERBOSE),1) + $(info MCUBOOT_MAX_IMG_SECTORS = $(MCUBOOT_MAX_IMG_SECTORS)) + $(info FLASH_AREA_BOOTLOADER_DEV_ID = $(FLASH_AREA_BOOTLOADER_DEV_ID)) + $(info FLASH_AREA_BOOTLOADER_START = $(FLASH_AREA_BOOTLOADER_START)) + $(info FLASH_AREA_BOOTLOADER_SIZE = $(FLASH_AREA_BOOTLOADER_SIZE)) + $(info MCUBOOT_IMAGE_NUMBER = $(MCUBOOT_IMAGE_NUMBER)) + $(info FLASH_AREA_IMG_1_PRIMARY_DEV_ID = $(FLASH_AREA_IMG_1_PRIMARY_DEV_ID)) + $(info FLASH_AREA_IMG_1_PRIMARY_START = $(FLASH_AREA_IMG_1_PRIMARY_START)) + $(info FLASH_AREA_IMG_1_PRIMARY_SIZE = $(FLASH_AREA_IMG_1_PRIMARY_SIZE)) + $(info FLASH_AREA_IMG_1_SECONDARY_DEV_ID = $(FLASH_AREA_IMG_1_SECONDARY_DEV_ID)) + $(info FLASH_AREA_IMG_1_SECONDARY_START = $(FLASH_AREA_IMG_1_SECONDARY_START)) + $(info FLASH_AREA_IMG_1_SECONDARY_SIZE = $(FLASH_AREA_IMG_1_SECONDARY_SIZE)) + $(info FLASH_AREA_IMAGE_SCRATCH_DEV_ID = $(FLASH_AREA_IMAGE_SCRATCH_DEV_ID)) + $(info FLASH_AREA_IMAGE_SCRATCH_START = $(FLASH_AREA_IMAGE_SCRATCH_START)) + $(info FLASH_AREA_IMAGE_SCRATCH_SIZE = $(FLASH_AREA_IMAGE_SCRATCH_SIZE)) + ifeq ($(MCUBOOT_IMAGE_NUMBER),2) + $(info FLASH_AREA_IMG_2_PRIMARY_DEV_ID = $(FLASH_AREA_IMG_2_PRIMARY_DEV_ID)) + $(info FLASH_AREA_IMG_2_PRIMARY_START = $(FLASH_AREA_IMG_2_PRIMARY_START)) + $(info FLASH_AREA_IMG_2_PRIMARY_SIZE = $(FLASH_AREA_IMG_2_PRIMARY_SIZE)) + $(info FLASH_AREA_IMG_2_SECONDARY_DEV_ID = $(FLASH_AREA_IMG_2_SECONDARY_DEV_ID)) + $(info FLASH_AREA_IMG_2_SECONDARY_START = $(FLASH_AREA_IMG_2_SECONDARY_START)) + $(info FLASH_AREA_IMG_2_SECONDARY_SIZE = $(FLASH_AREA_IMG_2_SECONDARY_SIZE)) + endif + $(info FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID = $(FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID)) + $(info FLASH_AREA_IMAGE_SWAP_STATUS_START = $(FLASH_AREA_IMAGE_SWAP_STATUS_START)) + $(info FLASH_AREA_IMAGE_SWAP_STATUS_SIZE = $(FLASH_AREA_IMAGE_SWAP_STATUS_SIZE)) + endif # OTA_BUILD_FLASH_VERBOSE + + ifeq ($(OTA_BUILD_COMPONENTS_VERBOSE),1) + $(info COMPONENTS) + $(info COMPONENTS=$(COMPONENTS)) + endif + + ifeq ($(OTA_BUILD_DEFINES_VERBOSE),1) + $(info DEFINES) + $(info DEFINES=$(DEFINES)) + endif + + ifeq ($(OTA_BUILD_IGNORE_VERBOSE),1) + $(info CY_IGNORE) + $(info CY_IGNORE=$(CY_IGNORE)) + endif # OTA_BUILD_VERBOSE = COMPONENTS +endif # SECOND STAGE of build + + +################################################################################################### +# OTA POST BUILD scripting +################################################################################################### + +###################################### +# Build Location / Output directory +###################################### + +# output directory for use in the sign_script.bash +ifneq ($(CY_SECONDSTAGE),) + OUTPUT_FILE_PATH=$(CY_BUILD_LOCATION)/$(TARGET)/$(CONFIG) + $(info CY_BUILD_LOCATION $(CY_BUILD_LOCATION)) + $(info TARGET $(TARGET)) + $(info CONFIG $(CONFIG)) + $(info OUTPUT_FILE_PATH $(OUTPUT_FILE_PATH)) + $(info CY_COMPILER_GCC_ARM_DIR $(CY_COMPILER_GCC_ARM_DIR)) + ifeq ($(CY_COMPILER_GCC_ARM_DIR),) + CY_COMPILER_GCC_ARM_DIR=$(CY_TOOLS_DIR)/gcc + endif + $(info CY_COMPILER_GCC_ARM_DIR $(CY_COMPILER_GCC_ARM_DIR)) + + # POSTBUILD script is NOT provided by the Application. Use default OTA POSTBUILD scripts. + ifeq ($(OTA_APP_POSTBUILD),) + $(info "") + $(info Application Makefile has not defined OTA_APP_POSTBUILD. Using OTA library's default POSTBUILD commands.) + $(info "") + + # Check for Policy file path for 20829 devices + ifeq ($(OTA_PLATFORM), CYW20829) + ifeq ($(OTA_APP_POLICY_PATH),) + $(info "") + $(info Application makefile has not defined OTA_APP_POLICY_PATH. Using OTA library's default Policy file for 20829 device.) + $(info "") + OTA_APP_POLICY_PATH?=$(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/policy/policy_CM33_no_secure.json + $(info OTA_APP_POLICY_PATH = $(OTA_APP_POLICY_PATH) ) + endif + endif + + CY_HEX_TO_BIN="$(MTB_TOOLCHAIN_GCC_ARM__OBJCOPY)" + + # MCUBoot flash support location + MCUBOOT_DIR=$(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot + IMG_SIGNING_SCRIPT_TOOL_PATH?=$(MCUBOOT_DIR)/imgtool/imgtool.py + CY_SIGN_KEY_PATH?=$(MCUBOOT_DIR)/keys/cypress-test-ec-p256.pem + + IMGTOOL_SCRIPT_NAME:= $(shell echo $(IMG_SIGNING_SCRIPT_TOOL_PATH)|rev|cut -d "/" -f1 |rev ) + MCUBOOT_SCRIPT_FILE_DIR := $(shell echo "$(IMG_SIGNING_SCRIPT_TOOL_PATH)" | sed "s@/$(IMGTOOL_SCRIPT_NAME)@@") + MCUBOOT_KEY_FILE := $(shell echo $(CY_SIGN_KEY_PATH)|rev|cut -d "/" -f1 |rev ) + MCUBOOT_KEY_DIR := $(shell echo "$(CY_SIGN_KEY_PATH)" | sed "s@/$(MCUBOOT_KEY_FILE)@@") + + #-------------------------------------- + # CYW20829 POSTBUILD + #-------------------------------------- + ifeq ($(OTA_PLATFORM), CYW20829) + $(info Makefile: CYW20829 POSTBUILD ) + + MCUBOOT_SCRIPT_FILE_PATH?=$(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/sign_script_20829.bash + CY_ELF_TO_HEX=$(CY_HEX_TO_BIN) + + CY_TOC2_GENERATOR = $(SEARCH_recipe-make-cat1b)/make/scripts/20829/run_toc2_generator.sh + + _MTB_RECIPE_20829_SREC_CAT_UTIL=$(CY_TOOL_srec_cat_EXE_ABS) + + ifeq ($(TOOLCHAIN),ARM) + POSTBUILD=$(MTB_TOOLCHAIN_ARM__BASE_DIR)/bin/fromelf $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf --bin --output=$(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).bin; + POSTBUILD+=$(MTB_TOOLS__BASH_CMD) $(MTB_TOOLS__RECIPE_DIR)/make/scripts/20829/flash_postbuild.sh "$(TOOLCHAIN)" "$(MTB_TOOLS__OUTPUT_CONFIG_DIR)" "$(APPNAME)" "$(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR)/bin" "$(_MTB_RECIPE_20829_SREC_CAT_UTIL)" "$(BOOTSTRAP_SIZE)"; + else + ifeq ($(TOOLCHAIN),IAR) + ifeq ($(APPTYPE),flash) + OTA_POSTBUILD_PARAM=--bin-multi + else + OTA_POSTBUILD_PARAM=--bin + endif + POSTBUILD=$(MTB_TOOLCHAIN_IAR__BASE_DIR)/bin/ielftool $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf $(OTA_POSTBUILD_PARAM) $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).bin; + POSTBUILD+=$(MTB_TOOLCHAIN_IAR__BASE_DIR)/bin/ielfdumparm -a $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf > $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).dis; + POSTBUILD+=$(MTB_TOOLS__BASH_CMD) $(MTB_TOOLS__RECIPE_DIR)/make/scripts/20829/flash_postbuild.sh "$(TOOLCHAIN)" "$(MTB_TOOLS__OUTPUT_CONFIG_DIR)" "$(APPNAME)" "$(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR)/bin" "$(_MTB_RECIPE_20829_SREC_CAT_UTIL)" "$(BOOTSTRAP_SIZE)"; + else + ifeq ($(TOOLCHAIN),GCC_ARM) + POSTBUILD="$(MTB_TOOLCHAIN_GCC_ARM__OBJCOPY)" "$(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf" -S -O binary "$(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).bin"; + endif # GCC_ARM + endif # IAR + endif # ARM + + CY_ENC_IMG ?= 0 + FLASH_BASE_ADDRESS ?= 0x60000000 + CY_SERVICE_APP_DESCR_ADDR = 0x0 + + # If POSTBUILD fails, Turn this on to check that all args are present + ifneq ($(CY_SECONDSTAGE),) + ifeq ($(OTA_BUILD_POST_VERBOSE),1) + # Check that all arguments for the POSTBUILD functionality are present + $(info MCUBOOT_SCRIPT_FILE_PATH =$(MCUBOOT_SCRIPT_FILE_PATH)) + $(info APPNAME =$(APPNAME)) + $(info CY_ELF_TO_HEX =$(CY_ELF_TO_HEX)) + $(info CY_ELF_TO_HEX_OPTIONS =$(CY_ELF_TO_HEX_OPTIONS)) + $(info CY_ELF_TO_HEX_FILE_ORDER =$(CY_ELF_TO_HEX_FILE_ORDER)) + $(info CY_HEX_TO_BIN =$(CY_HEX_TO_BIN)) + $(info FLASH_ERASE_SECONDARY_SLOT_VALUE =$(FLASH_ERASE_SECONDARY_SLOT_VALUE)) + $(info MCUBOOT_HEADER_SIZE =$(MCUBOOT_HEADER_SIZE)) + $(info APP_BUILD_VERSION =$(APP_BUILD_VERSION)) + $(info FLASH_BASE_ADDRESS =$(FLASH_BASE_ADDRESS)) + $(info FLASH_AREA_IMG_1_PRIMARY_START =$(FLASH_AREA_IMG_1_PRIMARY_START)) + $(info MCUBOOT_KEY_DIR =$(MCUBOOT_KEY_DIR)) + $(info MCUBOOT_KEY_FILE =$(MCUBOOT_KEY_FILE)) + $(info CY_TOC2_GENERATOR =$(CY_TOC2_GENERATOR)) + $(info CY_LCS =$(CY_LCS)) + $(info DEVICE_(MPN_LIST)_SRAM_KB =$(DEVICE_$(MPN_LIST)_SRAM_KB)) + $(info MTB_TOOLS__OUTPUT_CONFIG_DIR =$(MTB_TOOLS__OUTPUT_CONFIG_DIR)) + $(info APPTYPE =$(APPTYPE)) + $(info current_dir =$(current_dir)) + $(info SMIF_CRYPTO_CONFIG =$(SMIF_CRYPTO_CONFIG)) + $(info MTB_TOOLCHAIN_GCC_ARM__BASE_DIR =$(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR)) + $(info OTA_APP_POLICY_PATH =$(OTA_APP_POLICY_PATH)) + $(info CY_SLOT_SIZE =$(CY_SLOT_SIZE)) + $(info CY_ENCRYPTION =$(CY_ENCRYPTION)) + $(info CY_SERVICE_APP_DESCR_ADDR =$(CY_SERVICE_APP_DESCR_ADDR)) + $(info BOOTSTRAP_SIZE =$(BOOTSTRAP_SIZE)) + $(info DEVICE_SRAM_SIZE_KB =$(DEVICE_SRAM_SIZE_KB)) + endif # OTA_BUILD_VERBOSE = POST + endif # SECOND STAGE + + # CYW920829 POSTBUILD call + POSTBUILD+=$(MCUBOOT_SCRIPT_FILE_PATH) $(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR) $(CY_PYTHON_PATH) $(MTB_TOOLS__OUTPUT_CONFIG_DIR) $(APPNAME) \ + $(CY_ELF_TO_HEX) $(CY_ELF_TO_HEX_OPTIONS) $(CY_ELF_TO_HEX_FILE_ORDER) $(CY_HEX_TO_BIN) \ + $(FLASH_ERASE_SECONDARY_SLOT_VALUE) $(MCUBOOT_HEADER_SIZE) $(APP_BUILD_VERSION) $(FLASH_BASE_ADDRESS) \ + $(FLASH_AREA_IMG_1_PRIMARY_START) $(FLASH_AREA_IMG_1_PRIMARY_SIZE) $(FLASH_AREA_IMG_1_SECONDARY_START) \ + $(MCUBOOT_KEY_DIR) $(MCUBOOT_KEY_FILE)\ + $(CY_TOC2_GENERATOR) $(CY_LCS) $(MTB_TOOLS__OUTPUT_CONFIG_DIR) $(APPNAME) $(APPTYPE) $(current_dir) $(SMIF_CRYPTO_CONFIG) $(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR) $(OTA_APP_POLICY_PATH) $(FLASH_AREA_IMG_1_PRIMARY_SIZE) $(CY_ENC_IMG) $(CY_SERVICE_APP_DESCR_ADDR) $(BOOTSTRAP_SIZE) $(DEVICE_$(MPN_LIST)_SRAM_KB); + POSTBUILD+=rm -rf $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).final.hex + + endif# end (CYW920829) section + + #-------------------------------------- + # XMC7200 POSTBUILD + #-------------------------------------- + ifeq ($(OTA_PLATFORM), XMC7200) + $(info Makefile: XMC7200 POSTBUILD ) + + MCUBOOT_XMC_SCRIPT_FILE_PATH?=$(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/sign_script_xmc7200.bash + CY_ELF_TO_HEX=$(CY_HEX_TO_BIN) + + ifeq ($(TOOLCHAIN),ARM) + POSTBUILD=$(MTB_TOOLCHAIN_ARM__BASE_DIR)/bin/fromelf $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf --bin --output=$(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).unsigned.bin; + else + ifeq ($(TOOLCHAIN),IAR) + ifeq ($(APPTYPE),flash) + OTA_POSTBUILD_PARAM=--bin-multi + else + OTA_POSTBUILD_PARAM=--bin + endif + POSTBUILD=$(MTB_TOOLCHAIN_IAR__BASE_DIR)/bin/ielftool $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf $(OTA_POSTBUILD_PARAM) $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).unsigned.bin; + POSTBUILD+=$(MTB_TOOLCHAIN_IAR__BASE_DIR)/bin/ielfdumparm -a $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf > $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).dis; + else + ifeq ($(TOOLCHAIN),GCC_ARM) + POSTBUILD=$(MTB_TOOLCHAIN_GCC_ARM__OBJCOPY) $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).elf -S -O binary $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).unsigned.bin; + $(info Makefile: after GCC POSTBUILD ) + endif # GCC_ARM + endif # IAR + endif # ARM + + CY_ENC_IMG ?= 0 + FLASH_BASE_ADDRESS ?= 0x10000000 + CY_SERVICE_APP_DESCR_ADDR = 0x0 + CY_LCS? = NORMAL_NO_SECURE + ERASED_VALUE = 0xFF + + ifeq ($(USE_OVERWRITE), 1) + UPGRADE_TYPE := --overwrite-only + DEFINES_APP += -DMCUBOOT_OVERWRITE_ONLY + endif + + # If POSTBUILD fails, Turn this on to check that all args are present + ifneq ($(CY_SECONDSTAGE),) + ifeq ($(OTA_BUILD_POST_VERBOSE),1) + # Check that all arguments for the POSTBUILD functionality are present + $(info MCUBOOT_XMC_SCRIPT_FILE_PATH =$(MCUBOOT_XMC_SCRIPT_FILE_PATH)) + $(info APPNAME =$(APPNAME)) + $(info CY_ELF_TO_HEX =$(CY_ELF_TO_HEX)) + $(info CY_ELF_TO_HEX_OPTIONS =$(CY_ELF_TO_HEX_OPTIONS)) + $(info CY_ELF_TO_HEX_FILE_ORDER =$(CY_ELF_TO_HEX_FILE_ORDER)) + $(info CY_HEX_TO_BIN =$(CY_HEX_TO_BIN)) + $(info FLASH_ERASE_SECONDARY_SLOT_VALUE =$(FLASH_ERASE_SECONDARY_SLOT_VALUE)) + $(info MCUBOOT_HEADER_SIZE =$(MCUBOOT_HEADER_SIZE)) + $(info APP_BUILD_VERSION =$(APP_BUILD_VERSION)) + $(info FLASH_BASE_ADDRESS =$(FLASH_BASE_ADDRESS)) + $(info FLASH_AREA_IMG_1_PRIMARY_START =$(FLASH_AREA_IMG_1_PRIMARY_START)) + $(info MCUBOOT_KEY_DIR =$(MCUBOOT_KEY_DIR)) + $(info MCUBOOT_KEY_FILE =$(MCUBOOT_KEY_FILE)) + $(info CY_TOC2_GENERATOR =$(CY_TOC2_GENERATOR)) + $(info CY_LCS =$(CY_LCS)) + $(info DEVICE_(MPN_LIST)_SRAM_KB =$(DEVICE_$(MPN_LIST)_SRAM_KB)) + $(info MTB_TOOLS__OUTPUT_CONFIG_DIR =$(MTB_TOOLS__OUTPUT_CONFIG_DIR)) + $(info APPTYPE =$(APPTYPE)) + $(info current_dir =$(current_dir)) + $(info SMIF_CRYPTO_CONFIG =$(SMIF_CRYPTO_CONFIG)) + $(info MTB_TOOLCHAIN_GCC_ARM__BASE_DIR =$(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR)) + $(info OTA_APP_POLICY_PATH =$(OTA_APP_POLICY_PATH)) + $(info CY_SLOT_SIZE =$(CY_SLOT_SIZE)) + $(info CY_ENCRYPTION =$(CY_ENCRYPTION)) + $(info CY_SERVICE_APP_DESCR_ADDR =$(CY_SERVICE_APP_DESCR_ADDR)) + $(info BOOTSTRAP_SIZE =$(BOOTSTRAP_SIZE)) + $(info DEVICE_SRAM_SIZE_KB =$(DEVICE_SRAM_SIZE_KB)) + endif # OTA_BUILD_VERBOSE = POST + endif # SECOND STAGE + + # XMC7200 POSTBUILD call + POSTBUILD+=$(MCUBOOT_XMC_SCRIPT_FILE_PATH) $(MTB_TOOLCHAIN_GCC_ARM__BASE_DIR) $(CY_PYTHON_PATH) $(MTB_TOOLS__OUTPUT_CONFIG_DIR) $(APPNAME) \ + $(CY_ELF_TO_HEX) $(CY_ELF_TO_HEX_OPTIONS) $(CY_ELF_TO_HEX_FILE_ORDER) $(CY_HEX_TO_BIN) \ + $(FLASH_ERASE_SECONDARY_SLOT_VALUE) $(MCUBOOT_HEADER_SIZE) $(APP_BUILD_VERSION) $(FLASH_BASE_ADDRESS) \ + $(FLASH_AREA_IMG_1_PRIMARY_START) $(FLASH_AREA_IMG_1_PRIMARY_SIZE) $(FLASH_AREA_IMG_1_SECONDARY_START) \ + $(MCUBOOT_KEY_DIR) $(MCUBOOT_KEY_FILE)\ + POSTBUILD+=rm -rf $(MTB_TOOLS__OUTPUT_CONFIG_DIR)/$(APPNAME).bin; + endif + + #-------------------------------------- + # PSoC POSTBUILD + #-------------------------------------- + ifneq ($(OTA_PLATFORM), XMC7200) + ifneq ($(OTA_PLATFORM), CYW20829) + # PSoC 062, PSoC 062s3, PSoC 064B0S2 Here + + SIGN_SCRIPT_FILE_PATH=$(RELATIVE_FILE1_FILE2)/../../scripts/mcuboot/sign_script.bash + IMGTOOL_COMMAND_ARG=sign + CY_SIGNING_KEY_ARG="-k $(MCUBOOT_KEY_DIR)/$(MCUBOOT_KEY_FILE)" + + ifeq ($(ACTUAL_TARGET),CY8CKIT-064B0S2-4343W) #IMP_CHECK + # values changed for 064B0S2 board + IMGTOOL_COMMAND_ARG=do_not_sign + endif + + # If POSTBUILD fails, Turn this on to check all args are present + ifneq ($(CY_SECONDSTAGE),) + ifeq ($(OTA_BUILD_POST_VERBOSE),1) + $(info SIGN_SCRIPT_FILE_PATH =$(SIGN_SCRIPT_FILE_PATH)) + $(info OUTPUT_FILE_PATH =$(OUTPUT_FILE_PATH)) + $(info APPNAME =$(APPNAME)) + $(info CY_ELF_TO_HEX =$(CY_ELF_TO_HEX)) + $(info CY_ELF_TO_HEX_OPTIONS =$(CY_ELF_TO_HEX_OPTIONS)) + $(info CY_ELF_TO_HEX_FILE_ORDER =$(CY_ELF_TO_HEX_FILE_ORDER)) + $(info MCUBOOT_SCRIPT_FILE_DIR =$(MCUBOOT_SCRIPT_FILE_DIR)) + $(info IMGTOOL_SCRIPT_NAME =$(IMGTOOL_SCRIPT_NAME)) + $(info IMGTOOL_COMMAND_ARG =$(IMGTOOL_COMMAND_ARG)) + $(info FLASH_ERASE_SECONDARY_SLOT_VALUE =$(FLASH_ERASE_SECONDARY_SLOT_VALUE)) + $(info MCUBOOT_HEADER_SIZE =$(MCUBOOT_HEADER_SIZE)) + $(info MCUBOOT_MAX_IMG_SECTORS =$(MCUBOOT_MAX_IMG_SECTORS)) + $(info APP_BUILD_VERSION =$(APP_BUILD_VERSION)) + $(info FLASH_AREA_IMG_1_PRIMARY_START =$(FLASH_AREA_IMG_1_PRIMARY_START)) + $(info FLASH_AREA_IMG_1_PRIMARY_SIZE =$(FLASH_AREA_IMG_1_PRIMARY_SIZE)) + $(info CY_HEX_TO_BIN =$(CY_HEX_TO_BIN)) + $(info CY_SIGNING_KEY_ARG =$(CY_SIGNING_KEY_ARG)) + endif # OTA_BUILD_VERBOSE = POST + endif # SECOND STAGE + + POSTBUILD=$(SIGN_SCRIPT_FILE_PATH) $(OUTPUT_FILE_PATH) $(APPNAME) $(CY_PYTHON_PATH)\ + $(CY_ELF_TO_HEX) $(CY_ELF_TO_HEX_OPTIONS) $(CY_ELF_TO_HEX_FILE_ORDER)\ + $(MCUBOOT_SCRIPT_FILE_DIR) $(IMGTOOL_SCRIPT_NAME) $(IMGTOOL_COMMAND_ARG) $(FLASH_ERASE_SECONDARY_SLOT_VALUE) $(MCUBOOT_HEADER_SIZE)\ + $(MCUBOOT_MAX_IMG_SECTORS) $(APP_BUILD_VERSION) $(FLASH_AREA_IMG_1_PRIMARY_START) $(FLASH_AREA_IMG_1_PRIMARY_SIZE)\ + $(CY_HEX_TO_BIN) $(CY_SIGNING_KEY_ARG) + + endif # Not 20829 + endif # Not XMC7200 + else + # POSTBUILD script provided by the Application. + ifneq ($(CY_SECONDSTAGE),) + $(info "") + $(info OTA_APP_POSTBUILD is defined by Application Makefile.) + $(info "") + endif # SECOND STAGE + POSTBUILD=$(OTA_APP_POSTBUILD) + endif #OTA_APP_POSTBUILD +endif #CY_SECONDSTAGE diff --git a/scripts/mcuboot/flashmap.py b/scripts/mcuboot/flashmap.py new file mode 100644 index 0000000..46f7aa0 --- /dev/null +++ b/scripts/mcuboot/flashmap.py @@ -0,0 +1,870 @@ +"""MCUBoot Flash Map Converter (JSON to .h) +Copyright (c) 2022 Infineon Technologies AG +""" + +import sys +import getopt +import json + +# Supported Platforms +allCores_PSOC_06x = { + # Cortex-M0+ + 'cortex-m0+': 'CM0P', + 'cm0+': 'CM0P', + 'm0+': 'CM0P', + 'cortex-m0p': 'CM0P', + 'cm0p': 'CM0P', + 'm0p': 'CM0P', + 'cortex-m0plus': 'CM0P', + 'cm0plus': 'CM0P', + 'm0plus': 'CM0P', + # Cortex-M4 + 'cortex-m4': 'CM4', + 'cm4': 'CM4', + 'm4': 'CM4' +} + +platDict = { + 'PSOC_063_1M': { + 'flashAddr': 0x10000000, + 'flashSize': 0x100000, # 1 MByte + 'eraseSize': 0x200, # 512 bytes + 'VTAlign': 0x400, # Vector Table alignment + 'allCores': allCores_PSOC_06x, + 'appCore': 'Cortex-M4' + }, + 'PSOC_062_2M': { + 'flashAddr': 0x10000000, + 'flashSize': 0x200000, # 2 MBytes + 'eraseSize': 0x200, # 512 bytes + 'smifAddr': 0x18000000, + 'smifSize': 0x8000000, # i.e., window size + 'VTAlign': 0x400, # Vector Table alignment + 'allCores': allCores_PSOC_06x, + 'appCore': 'Cortex-M4' + }, + 'PSOC_062_1M': { + 'flashAddr': 0x10000000, + 'flashSize': 0x100000, # 1 MByte + 'eraseSize': 0x200, # 512 bytes + 'smifAddr': 0x18000000, + 'smifSize': 0x8000000, # i.e., window size + 'VTAlign': 0x400, # Vector Table alignment + 'allCores': allCores_PSOC_06x, + 'appCore': 'Cortex-M4' + }, + 'PSOC_062_512K': { + 'flashAddr': 0x10000000, + 'flashSize': 0x80000, # 512 KBytes + 'eraseSize': 0x200, # 512 bytes + 'smifAddr': 0x18000000, + 'smifSize': 0x8000000, # i.e., window size + 'VTAlign': 0x400, # Vector Table alignment + 'allCores': allCores_PSOC_06x, + 'appCore': 'Cortex-M4' + }, + 'CYW20829': { + 'flashSize': 0, # n/a + 'smifAddr': 0x60000000, + 'smifSize': 0x8000000, # i.e., window size + 'VTAlign': 0x200, # Vector Table alignment + 'allCores': { + 'cortex-m33': 'CM33', + 'cm33': 'CM33', + 'm33': 'CM33' + }, + 'appCore': 'Cortex-M33' + }, + 'EXPLORER': { + 'flashSize': 0, # n/a + 'smifAddr': 0x60000000, + 'smifSize': 0x8000000, # i.e., window size + 'VTAlign': 0x200 # Vector Table alignment + } +} + +# Supported SPI Flash ICs +flashDict = { + # Fudan + 'FM25Q04': { + 'flashSize': 0x80000, # 4 Mbits + 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each + }, + 'FM25W04': { + 'flashSize': 0x80000, # 4 Mbits + 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each + }, + 'FM25Q08': { + 'flashSize': 0x100000, # 8 Mbits + 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each + }, + 'FM25W08': { + 'flashSize': 0x100000, # 8 Mbits + 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each + }, + # Puya + 'P25Q05H': { + 'flashSize': 0x10000, # 512 Kbits + 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase + }, + 'P25Q10H': { + 'flashSize': 0x20000, # 1 Mbit + 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase + }, + 'P25Q20H': { + 'flashSize': 0x40000, # 2 Mbits + 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase + }, + 'P25Q40H': { + 'flashSize': 0x80000, # 4 Mbits + 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase + }, + # Infineon + 'S25HS256T': { + 'flashSize': 0x2000000, # 256 Mbits + 'eraseSize': 0x40000, # Uniform Sector Architecture + }, + 'S25HS512T': { + 'flashSize': 0x4000000, # 512 Mbits + 'eraseSize': 0x40000, # Uniform Sector Architecture + }, + 'S25FL512S': { + 'flashSize': 0x4000000, # 512 Mbits + 'eraseSize': 0x40000, # Uniform Sector Architecture + }, + 'S25HS01GT': { + 'flashSize': 0x8000000, # 1 Gbit + 'eraseSize': 0x40000, # Uniform Sector Architecture + } +} + + +def is_overlap(fa1off, fa1size, fa2off, fa2size, align): + """Check if two flash areas on the same device overlap""" + mask = align - 1 + assert align > 0 and (align & mask) == 0 # ensure align is a power of 2 + fa1end = (fa1off + fa1size + mask) & ~mask + fa2end = (fa2off + fa2size + mask) & ~mask + fa1off = fa1off & ~mask + fa2off = fa2off & ~mask + return fa1off < fa2end and fa2off < fa1end + + +def is_same_mem(fa1addr, fa2addr): + """Check if two addresses belong to the same memory""" + if fa1addr is None or fa2addr is None: + return False + mask = 0xFF000000 + return (fa1addr & mask) == (fa2addr & mask) + + +class CmdLineParams: + """Command line parameters""" + + def __init__(self): + self.plat_id = '' + self.in_file = '' + self.out_file = '' + self.img_id = None + + usage = 'USAGE:\n' + sys.argv[0] + \ + ''' -p -i -o -d + +OPTIONS: +-h --help Display the usage information +-p --platform= Target (e.g., PSOC_062_512K) +-i --ifile= JSON flash map file +-o --ofile= C header file to be generated +-d --img_id ID of application to build''' + + try: + opts, unused = getopt.getopt( + sys.argv[1:], 'hi:o:p:d:', + ['help', 'platform=', 'ifile=', 'ofile=', 'img_id=']) + if len(unused) > 0: + print(usage, file=sys.stderr) + sys.exit(1) + except getopt.GetoptError: + print(usage, file=sys.stderr) + sys.exit(1) + + for opt, arg in opts: + if opt in ('-h', '--help'): + print(usage, file=sys.stderr) + sys.exit() + elif opt in ('-p', '--platform'): + self.plat_id = arg + elif opt in ('-i', '--ifile'): + self.in_file = arg + elif opt in ('-o', '--ofile'): + self.out_file = arg + elif opt in ('-d', '--img_id'): + self.img_id = arg + + # [stde] For ota-update library usage, we do not need output 'c' file, just flashmap.mk + # [stde] which is piped from strdout to flashmap.mk + # if len(self.in_file) == 0 or len(self.out_file) == 0: + if len(self.in_file) == 0: + print(usage, file=sys.stderr) + sys.exit(1) + + +class AreaList: + """List of flash areas""" + + def __init__(self, plat, flash, use_overwrite): + self.plat = plat + self.flash = flash + self.use_overwrite = use_overwrite + self.areas = [] + self.peers = {} + self.trailers = {} + self.internal_flash = False + self.external_flash = False + self.external_flash_xip = False + + def get_min_erase_size(self): + """Calculate minimum erase block size for int./ext. Flash """ + return self.plat['eraseSize'] if self.plat['flashSize'] > 0 \ + else self.flash['eraseSize'] + + def get_img_trailer_size(self): + """Calculate image trailer size""" + return self.get_min_erase_size() + + def process_int_area(self, title, fa_addr, fa_size, + img_trailer_size, shared_slot): + """Process internal flash area""" + fa_device_id = 'FLASH_DEVICE_INTERNAL_FLASH' + fa_off = fa_addr - self.plat['flashAddr'] + if img_trailer_size is not None: + if self.use_overwrite: + if shared_slot: + print('Shared slot', title, + 'is not supported in OVERWRITE mode', + file=sys.stderr) + sys.exit(7) + else: + # Check trailer alignment (start at the sector boundary) + align = (fa_off + fa_size - img_trailer_size) % \ + self.plat['eraseSize'] + if align != 0: + fa_addr += self.plat['eraseSize'] - align + if fa_addr + fa_size <= \ + self.plat['flashAddr'] + self.plat['flashSize']: + print('Misaligned', title, + '- suggested address', hex(fa_addr), + file=sys.stderr) + else: + print('Misaligned', title, file=sys.stderr) + sys.exit(7) + else: + # Check alignment (flash area should start at the sector boundary) + if fa_off % self.plat['eraseSize'] != 0: + print('Misaligned', title, file=sys.stderr) + sys.exit(7) + slot_sectors = int((fa_off % self.plat['eraseSize'] + + fa_size + self.plat['eraseSize'] - 1) // + self.plat['eraseSize']) + return fa_device_id, fa_off, slot_sectors + + def process_ext_area(self, title, fa_addr, fa_size, + img_trailer_size, shared_slot): + """Process external flash area""" + if self.flash is None: + print('Unspecified SPI Flash IC', + file=sys.stderr) + sys.exit(3) + if fa_addr + fa_size <= \ + self.plat['smifAddr'] + self.flash['flashSize']: + flash_idx = 'CY_BOOT_EXTERNAL_DEVICE_INDEX' + fa_device_id = f'FLASH_DEVICE_EXTERNAL_FLASH({flash_idx})' + fa_off = fa_addr - self.plat['smifAddr'] + else: + print('Misfitting', title, file=sys.stderr) + sys.exit(7) + if img_trailer_size is not None: + if self.use_overwrite: + if shared_slot: + print('Shared slot', title, + 'is not supported in OVERWRITE mode', + file=sys.stderr) + sys.exit(7) + else: + # Check trailer alignment (start at the sector boundary) + align = (fa_off + fa_size - img_trailer_size) % \ + self.flash['eraseSize'] + if align != 0: + peer_addr = self.peers.get(fa_addr) + if shared_slot: + # Special case when using both int. and ext. memory + if self.plat['flashSize'] > 0 and \ + align % self.plat['eraseSize'] == 0: + print('Note:', title, 'requires', align, + 'padding bytes before trailer', + file=sys.stderr) + else: + print('Misaligned', title, file=sys.stderr) + sys.exit(7) + elif is_same_mem(fa_addr, peer_addr) and \ + fa_addr % self.flash['eraseSize'] == \ + peer_addr % self.flash['eraseSize']: + pass # postpone checking + else: + fa_addr += self.flash['eraseSize'] - align + if fa_addr + fa_size <= \ + self.plat['smifAddr'] + self.flash['flashSize']: + print('Misaligned', title, + '- suggested address', hex(fa_addr), + file=sys.stderr) + else: + print('Misaligned', title, file=sys.stderr) + sys.exit(7) + else: + # Check alignment (flash area should start at the sector boundary) + if fa_off % self.flash['eraseSize'] != 0: + print('Misaligned', title, file=sys.stderr) + sys.exit(7) + slot_sectors = int((fa_off % self.flash['eraseSize'] + + fa_size + self.flash['eraseSize'] - 1) // + self.flash['eraseSize']) + self.external_flash = True + if self.flash['XIP']: + self.external_flash_xip = True + return fa_device_id, fa_off, slot_sectors + + def chk_area(self, fa_addr, fa_size, peer_addr=None): + """Check area location (internal/external flash)""" + if peer_addr is not None: + self.peers[peer_addr] = fa_addr + fa_limit = fa_addr + fa_size + if self.plat['flashSize'] and \ + fa_addr >= self.plat['flashAddr'] and \ + fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']: + # Internal flash + self.internal_flash = True + + def add_area(self, title, + fa_id, fa_addr, fa_size, + img_trailer_size=None, shared_slot=False): + """Add flash area to AreaList. + Internal/external flash is detected by address. + Returns number of sectors in a slot""" + if fa_size == 0: + print('Empty', title, file=sys.stderr) + sys.exit(7) + + fa_limit = fa_addr + fa_size + if self.plat['flashSize'] and \ + fa_addr >= self.plat['flashAddr'] and \ + fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']: + # Internal flash + fa_device_id, fa_off, slot_sectors = self.process_int_area( + title, fa_addr, fa_size, img_trailer_size, shared_slot) + align = self.plat['eraseSize'] + elif self.plat['smifSize'] and \ + fa_addr >= self.plat['smifAddr'] and \ + fa_limit <= self.plat['smifAddr'] + self.plat['smifSize']: + # External flash + fa_device_id, fa_off, slot_sectors = self.process_ext_area( + title, fa_addr, fa_size, img_trailer_size, shared_slot) + align = self.flash['eraseSize'] + else: + print('Invalid', title, file=sys.stderr) + # [stde] More interesting output + if self.plat['flashSize']: + if fa_addr < self.plat['flashAddr']: + print(' addr < start of flash ! (' + str(hex(fa_addr)) + ' < ' + str(hex(self.plat['flashAddr'])) + ')', file=sys.stderr) + if fa_limit > (self.plat['flashAddr'] + self.plat['flashSize']): + print(' addr + size > end of flash ! (' + str(hex(fa_limit)) + ' > ' + str(hex(self.plat['flashAddr'] + self.plat['flashSize'])) + ')', file=sys.stderr) + if self.plat['smifSize']: + if fa_addr < self.plat['smifAddr']: + print(' addr < start of flash ! (' + str(hex(fa_addr)) + ' < ' + str(hex(self.plat['smifAddr'])) + ')', file=sys.stderr) + if fa_limit > (self.plat['smifAddr'] + self.plat['flashSize']): + print(' addr + size > end of flash ! (' + str(hex(fa_limit)) + ' > ' + str(hex(self.plat['smifAddr'] + self.plat['smifSize'])) + ')', file=sys.stderr) + # [stde] End of more interesting output + sys.exit(7) + + if shared_slot: + assert img_trailer_size is not None + tr_addr = fa_addr + fa_size - img_trailer_size + tr_name = self.trailers.get(tr_addr) + if tr_name is not None: + print('Same trailer address for', title, 'and', tr_name, + file=sys.stderr) + sys.exit(7) + self.trailers[tr_addr] = title + + # Ensure no flash areas on this device will overlap, except the + # shared slot + for area in self.areas: + if fa_device_id == area['fa_device_id']: + over = is_overlap(fa_off, fa_size, + area['fa_off'], area['fa_size'], + align) + if shared_slot and area['shared_slot']: + if not over: # images in shared slot should overlap + print(title, 'is not shared with', area['title'], + file=sys.stderr) + sys.exit(7) + elif over: + print(title, 'overlaps with', area['title'], + file=sys.stderr) + sys.exit(7) + + self.areas.append({'title': title, + 'shared_slot': shared_slot, + 'fa_id': fa_id, + 'fa_device_id': fa_device_id, + 'fa_off': fa_off, + 'fa_size': fa_size}) + return slot_sectors + + def generate_c_source(self, params): + """Generate C source""" + c_array = 'flash_areas' + + try: + with open(params.out_file, "w", encoding='UTF-8') as out_f: + out_f.write('/* AUTO-GENERATED FILE, DO NOT EDIT.' + ' ALL CHANGES WILL BE LOST! */\n') + out_f.write(f'/* Platform: {params.plat_id} */\n') + out_f.write("#ifndef CY_FLASH_MAP_H\n") + out_f.write("#define CY_FLASH_MAP_H\n\n") + + if self.plat.get('bitsPerCnt'): + out_f.write('#ifdef NEED_FLASH_MAP\n') + out_f.write(f'static struct flash_area {c_array}[] = {{\n') + comma = len(self.areas) + area_count = 0 + for area in self.areas: + comma -= 1 + if area['fa_id'] is not None: + sss = ' /* Shared secondary slot */' \ + if area['shared_slot'] else '' + out_f.writelines('\n'.join([ + ' {' + sss, + f" .fa_id = {area['fa_id']},", + f" .fa_device_id = {area['fa_device_id']},", + f" .fa_off = {hex(area['fa_off'])}U,", + f" .fa_size = {hex(area['fa_size'])}U", + ' },' if comma else ' }', ''])) + area_count += 1 + out_f.write('};\n\n' + 'struct flash_area *boot_area_descs[] = {\n') + for area_index in range(area_count): + out_f.write(f' &{c_array}[{area_index}U],\n') + out_f.write(' NULL\n};\n') + + if self.plat.get('bitsPerCnt'): + out_f.write('#endif /* NEED_FLASH_MAP */\n') + out_f.close() + + # inserted here to fix misra 'header guard' + list_counters = process_policy_20829(params.policy) + if list_counters is not None: + form_max_counter_array(list_counters, params.out_file) + with open(params.out_file, "a", encoding='UTF-8') as out_f: + out_f.write("#endif /* CY_FLASH_MAP_H */\n") + else: + out_f.write("#endif /* CY_FLASH_MAP_H */\n") + + except (FileNotFoundError, OSError): + print('Cannot create', params.out_file, file=sys.stderr) + sys.exit(4) + + +def cvt_dec_or_hex(val, desc): + """Convert (hexa)decimal string to number""" + try: + return int(val, 0) + except ValueError: + print('Invalid value', val, 'for', desc, file=sys.stderr) + sys.exit(6) + + +def get_val(obj, attr): + """Get JSON 'value'""" + obj = obj[attr] + try: + return cvt_dec_or_hex(obj['value'], obj['description']) + except KeyError as key: + print('Malformed JSON:', key, + 'is missing in', "'" + attr + "'", + file=sys.stderr) + sys.exit(5) + + +def get_bool(obj, attr, def_val=False): + """Get JSON boolean value (returns def_val if it is missing)""" + ret_val = def_val + obj = obj.get(attr) + if obj is not None: + try: + val = str(obj['value']).lower() + desc = obj['description'] + if val == 'true': + ret_val = True + elif val == 'false': + ret_val = False + else: + print('Invalid value', val, 'for', desc, file=sys.stderr) + sys.exit(6) + except KeyError as key: + print('Malformed JSON:', key, + 'is missing in', "'" + attr + "'", + file=sys.stderr) + sys.exit(5) + return ret_val + + +def get_str(obj, attr, def_val=None): + """Get JSON string value (returns def_val if it is missing)""" + ret_val = def_val + obj = obj.get(attr) + if obj is not None: + try: + ret_val = str(obj['value']) + except KeyError as key: + print('Malformed JSON:', key, + 'is missing in', "'" + attr + "'", + file=sys.stderr) + sys.exit(5) + return ret_val + + +class AddrSize: + """Bootloader area""" + + def __init__(self, bootloader, addr_name, size_name): + self.fa_addr = get_val(bootloader, addr_name) + self.fa_size = get_val(bootloader, size_name) + + +def calc_status_size(boot_swap_status_row_sz, max_img_sectors, + img_number, scratch_flag=True): + """Estimate status size, see swap_status.h""" + boot_swap_status_cnt_sz = 4 + boot_swap_status_crc_sz = 4 + boot_swap_status_mgcrec_sz = 4 + boot_swap_status_trailer_size = 64 + boot_swap_status_payld_sz = \ + boot_swap_status_row_sz - boot_swap_status_mgcrec_sz - \ + boot_swap_status_cnt_sz - boot_swap_status_crc_sz + boot_swap_status_sect_rows_num = \ + int((max_img_sectors - 1) // + boot_swap_status_payld_sz) + 1 + boot_swap_status_trail_rows_num = \ + int((boot_swap_status_trailer_size - 1) // + boot_swap_status_payld_sz) + 1 + boot_swap_status_d_size = \ + boot_swap_status_row_sz * \ + (boot_swap_status_sect_rows_num + boot_swap_status_trail_rows_num) + boot_swap_status_mult = 2 + boot_swap_status_size = boot_swap_status_mult * boot_swap_status_d_size + status_zone_cnt = 2 * img_number + if scratch_flag: + status_zone_cnt += 1 + return boot_swap_status_size * status_zone_cnt + + +def process_json(in_file): + """Process JSON""" + try: + with open(in_file, encoding='UTF-8') as in_f: + try: + flash_map = json.load(in_f) + except ValueError: + print('Cannot parse', in_file, file=sys.stderr) + sys.exit(4) + except (FileNotFoundError, OSError): + print('Cannot open', in_file, file=sys.stderr) + sys.exit(4) + flash = flash_map.get('external_flash') + if flash is not None: + flash = flash[0] + model = flash.get('model') + mode = flash.get('mode') + if model is not None: + try: + flash = flashDict[model] + except KeyError: + print('Supported SPI Flash ICs are:', + ', '.join(flashDict.keys()), + file=sys.stderr) + sys.exit(3) + else: + try: + flash = {'flashSize': cvt_dec_or_hex(flash['flash-size'], + 'flash-size'), + 'eraseSize': cvt_dec_or_hex(flash['erase-size'], + 'erase-size')} + except KeyError as key: + print('Malformed JSON:', key, + "is missing in 'external_flash'", + file=sys.stderr) + sys.exit(3) + flash.update({'XIP': str(mode).upper() == 'XIP'}) + return flash_map['boot_and_upgrade'], flash + + +def process_images(area_list, boot_and_upgrade): + """Process images""" + app_count = 0 + slot_sectors_max = 0 + all_shared = get_bool(boot_and_upgrade['bootloader'], 'shared_slot') + any_shared = all_shared + app_core = None + apps_flash_map = [None, ] + + for stage in range(2): + for app_index in range(1, 5): + + app_flash_map = {} + + try: + app_ident = f'application_{app_index}' + application = boot_and_upgrade[app_ident] + try: + primary_addr = get_val(application, 'address') + primary_size = get_val(application, 'size') + secondary_addr = get_val(application, 'upgrade_address') + secondary_size = get_val(application, 'upgrade_size') + except KeyError as key: + print('Malformed JSON:', key, 'is missing', + file=sys.stderr) + sys.exit(5) + if stage == 0: + if primary_size != secondary_size: + print('Primary and secondary slot sizes' + ' are different for', app_ident, + file=sys.stderr) + sys.exit(6) + area_list.chk_area(primary_addr, primary_size) + area_list.chk_area(secondary_addr, secondary_size, + primary_addr) + if application.get('core') is None: + if app_index == 1: + app_core = area_list.plat['appCore'] + elif app_index > 1: + print('"core" makes sense only for the 1st app', + file=sys.stderr) + sys.exit(6) + else: + app_core = get_str(application, 'core', + area_list.plat['appCore']) + if app_index == 1: + app_core = area_list.plat['allCores'].get(app_core.lower()) + if app_core is None: + print('Unknown "core"', file=sys.stderr) + sys.exit(6) + else: + slot_sectors_max = max( + slot_sectors_max, + area_list.add_area( + f'{app_ident} (primary slot)', + f'FLASH_AREA_IMG_{app_index}_PRIMARY', + primary_addr, primary_size, + area_list.get_img_trailer_size())) + shared_slot = get_bool(application, 'shared_slot', all_shared) + any_shared = any_shared or shared_slot + slot_sectors_max = max( + slot_sectors_max, + area_list.add_area( + f'{app_ident} (secondary slot)', + f'FLASH_AREA_IMG_{app_index}_SECONDARY', + secondary_addr, secondary_size, + area_list.get_img_trailer_size(), + shared_slot)) + + app_slot_prim = {"address": hex(primary_addr), "size": hex(primary_size)} + app_slot_sec = {"address": hex(secondary_addr), "size": hex(secondary_size)} + + app_flash_map.update({"primary": app_slot_prim, "secondary": app_slot_sec}) + apps_flash_map.append(app_flash_map) + + app_count = app_index + + except KeyError: + break + if app_count == 0: + print('Malformed JSON: no application(s) found', + file=sys.stderr) + sys.exit(5) + + return app_core, app_count, slot_sectors_max, apps_flash_map, any_shared + + +def main(): + """Flash map converter""" + params = CmdLineParams() + + try: + plat = platDict[params.plat_id] + except KeyError: + print('Supported platforms are:', ', '.join(platDict.keys()), + file=sys.stderr) + sys.exit(2) + + try: + boot_and_upgrade, flash = process_json(params.in_file) + bootloader = boot_and_upgrade['bootloader'] + boot = AddrSize(bootloader, 'address', 'size') + except KeyError as key: + print('Malformed JSON:', key, 'is missing', + file=sys.stderr) + sys.exit(5) + + try: + scratch = AddrSize(bootloader, 'scratch_address', 'scratch_size') + except KeyError: + scratch = None + + try: + swap_status = AddrSize(bootloader, 'status_address', 'status_size') + except KeyError: + swap_status = None + + # Create flash areas + area_list = AreaList(plat, flash, scratch is None and swap_status is None) + area_list.add_area('bootloader', 'FLASH_AREA_BOOTLOADER', + boot.fa_addr, boot.fa_size) + + # Service RAM app (optional) + service_app = boot_and_upgrade.get('service_app') + app_binary = None + input_params = None + app_desc = None + if service_app is not None: + if plat['flashSize'] > 0: + print('service_app is unsupported on this platform', + file=sys.stderr) + sys.exit(7) + try: + app_binary = AddrSize(service_app, 'address', 'size') + input_params = AddrSize(service_app, 'params_address', 'params_size') + app_desc = AddrSize(service_app, 'desc_address', 'desc_size') + if input_params.fa_addr != app_binary.fa_addr + app_binary.fa_size or \ + app_desc.fa_addr != input_params.fa_addr + input_params.fa_size or \ + app_desc.fa_size != 0x20: + print('Malformed service_app definition', file=sys.stderr) + sys.exit(7) + area_list.add_area('service_app', None, app_binary.fa_addr, + app_binary.fa_size + input_params.fa_size + app_desc.fa_size) + except KeyError as key: + print('Malformed JSON:', key, 'is missing', + file=sys.stderr) + sys.exit(5) + + # Fill flash areas + app_core, app_count, slot_sectors_max, apps_flash_map, shared_slot = \ + process_images(area_list, boot_and_upgrade) + + cy_img_hdr_size = 0x400 + app_start = int(apps_flash_map[1].get("primary").get("address"), 0) + cy_img_hdr_size + + if app_start % plat['VTAlign'] != 0: + print('Starting address', apps_flash_map[1].get("primary").get("address"), + '+', hex(cy_img_hdr_size), + 'must be aligned to', hex(plat['VTAlign']), + file=sys.stderr) + sys.exit(7) + + slot_sectors_max = max(slot_sectors_max, 32) + + if swap_status is not None: + status_size_min = calc_status_size(area_list.get_min_erase_size(), + slot_sectors_max, + app_count, + scratch is not None) + + if swap_status.fa_size < status_size_min: + print('Insufficient swap status area - suggested size', + hex(status_size_min), + file=sys.stderr) + sys.exit(7) + area_list.add_area('swap status partition', + 'FLASH_AREA_IMAGE_SWAP_STATUS', + swap_status.fa_addr, swap_status.fa_size) + + if scratch is not None: + area_list.add_area('scratch area', + 'FLASH_AREA_IMAGE_SCRATCH', + scratch.fa_addr, scratch.fa_size) + + # [stde] Moved this printf above the call to generate_c_source + # [stde] generate_c_source() now outputs flash area names and values + # [stde] to both cy_flash_map.h and stdout, which is captured for flashmap.mk + # Report necessary values back to make + print('# AUTO-GENERATED FILE, DO NOT EDIT. ALL CHANGES WILL BE LOST!') + + # Image id parameter is not used for MCUBootApp + if params.img_id is None: + # [stde] we do not need the .c file for ota-update, just flashmap.mk + if len(params.out_file) != 0: + area_list.generate_c_source(params) + # [stde] Start of modifications + # [stde] Output the DEFINES and the values to match flashmap.mk + # out_f.writelines("\n") + comma = len(area_list.areas) + area_count = 0 + for area in area_list.areas: + comma -= 1 + if area['fa_id'] is not None: + print(str(area['fa_id']) + "_DEV_ID :=" + area['fa_device_id'] ) + print(str(area['fa_id']) + "_START :=" + str.format("{:#08x}",(area['fa_off'])) ) + print(str(area['fa_id']) + "_SIZE :=" + str.format("{:#08x}",(area['fa_size'])) ) + area_count += 1 + # [stde] End of modifications + else: + # [stde] Start of modifications + # [stde] Output the DEFINES and the values to match flashmap.mk + # out_f.writelines("\n") + comma = len(area_list.areas) + area_count = 0 + for area in area_list.areas: + comma -= 1 + if area['fa_id'] is not None: + print(str(area['fa_id']) + "_DEV_ID :=" + area['fa_device_id'] ) + print(str(area['fa_id']) + "_START :=" + str.format("{:#08x}",(area['fa_off'])) ) + print(str(area['fa_id']) + "_SIZE :=" + str.format("{:#08x}",(area['fa_size'])) ) + area_count += 1 + # [stde] End of modifications + + if params.img_id is not None: + primary_img_start = (apps_flash_map[int(params.img_id)].get("primary")).get("address") + secondary_img_start = (apps_flash_map[int(params.img_id)].get("secondary")).get("address") + bootloader_size = (bootloader.get("size")).get("value") + slot_size = (apps_flash_map[int(params.img_id)].get("primary")).get("size") + + print('PRIMARY_IMG_START := ' + primary_img_start) + print('SECONDARY_IMG_START := ' + secondary_img_start) + print('SLOT_SIZE := ' + slot_size) + print('BOOTLOADER_SIZE := ' + bootloader_size) + else: + print('MCUBOOT_IMAGE_NUMBER :=', app_count) + # [stde] added "MCUBOOT_" for ota-update Makefile + print('MCUBOOT_MAX_IMG_SECTORS :=', slot_sectors_max) + + print('APP_CORE :=', app_core) + + if area_list.use_overwrite: + print('USE_OVERWRITE := 1') + if area_list.external_flash: + print('USE_EXTERNAL_FLASH := 1') + if area_list.external_flash_xip: + print('USE_XIP := 1') + if shared_slot: + print('USE_SHARED_SLOT := 1') + if service_app is not None: + print('PLATFORM_SERVICE_APP_OFFSET :=', + hex(app_binary.fa_addr - plat['smifAddr'])) + print('PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET :=', + hex(input_params.fa_addr - plat['smifAddr'])) + print('PLATFORM_SERVICE_APP_DESC_OFFSET :=', + hex(app_desc.fa_addr - plat['smifAddr'])) + print('USE_HW_ROLLBACK_PROT := 1') + + +if __name__ == '__main__': + main() diff --git a/scripts/mcuboot/flashmap_xmc.py b/scripts/mcuboot/flashmap_xmc.py new file mode 100644 index 0000000..06a6b24 --- /dev/null +++ b/scripts/mcuboot/flashmap_xmc.py @@ -0,0 +1,645 @@ +""" +Copyright 2023 Cypress Semiconductor Corporation (an Infineon company) +or an affiliate of Cypress Semiconductor Corporation. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import sys +import json +import click + +APP_LIMIT = 8 + +settings_dict = { + 'overwrite' : 'USE_OVERWRITE' + , 'swap' : 'USE_SWAP' + , 'status' : 'USE_STATUS' + , 'scratch' : 'USE_SCRATCH' + , 'measured_boot' : 'USE_MEASURED_BOOT' + , 'data_sharing' : 'USE_DATA_SHARING' + , 'ram_load' : 'USE_MCUBOOT_RAM_LOAD' + , 'multi_memory_load' : 'USE_MCUBOOT_MULTI_MEMORY_LOAD' + , 'shared_slot' : 'USE_SHARED_SLOT' + , 'ram_load_address' : 'IMAGE_EXECUTABLE_RAM_START' + , 'ram_load_size' : 'IMAGE_EXECUTABLE_RAM_SIZE' + , 'shared_data_address' : 'BOOT_SHARED_DATA_ADDRESS' + , 'shared_data_size' : 'BOOT_SHARED_DATA_SIZE' + , 'shared_data_record_size' : 'BOOT_SHARED_DATA_RECORD_SIZE' + , 'bootloader_app_address' : 'FLASH_AREA_BOOTLOADER_START' + , 'bootloader_app_size' : 'FLASH_AREA_BOOTLOADER_SIZE' + , 'bootloader_ram_address' : 'BOOTLOADER_RAM_ORIGIN' + , 'bootloader_ram_size' : 'BOOTLOADER_RAM_SIZE' + , 'application_count' : 'MCUBOOT_IMAGE_NUMBER' + , 'boot_image' : 'BOOT_IMAGE_NUMBER' + , 'sectors_count' : 'MCUBOOT_MAX_IMG_SECTORS' + , 'core' : 'APP_CORE' + , 'image_ram_address' : 'IMG_RAM_ORIGIN' + , 'image_ram_size' : 'IMG_RAM_SIZE' + , 'primary_image_start' : 'FLASH_AREA_IMG_1_PRIMARY_START' + , 'primary_image_size' : 'FLASH_AREA_IMG_1_PRIMARY_SIZE' + , 'secondary_image_start' : 'FLASH_AREA_IMG_1_SECONDARY_START' + , 'secondary_image_size' : 'FLASH_AREA_IMG_1_SECONDARY_SIZE' + , 'swap_status_image_start' : 'FLASH_AREA_IMAGE_SWAP_STATUS_START' + , 'scratch_image_start' : 'FLASH_AREA_IMAGE_SCRATCH_START' + , 'image_size' : 'SLOT_SIZE' + , 'swap_status_image_size' : 'FLASH_AREA_IMAGE_SWAP_STATUS_SIZE' + , 'scratch_image_size' : 'FLASH_AREA_IMAGE_SCRATCH_SIZE' + , 'bootloader_id' : 'FLASH_AREA_BOOTLOADER_DEV_ID' + , 'primary_image_id' : 'FLASH_AREA_IMG_1_PRIMARY_DEV_ID' + , 'secondary_image_id' : 'FLASH_AREA_IMG_1_SECONDARY_DEV_ID' + , 'swap_status_image_id' : 'FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID' + , 'scratch_image_id' : 'FLASH_AREA_IMAGE_SCRATCH_DEV_ID' + + +} + + +def header_guard_generate(file): + file.write('/* AUTO-GENERATED FILE, DO NOT EDIT.' + ' ALL CHANGES WILL BE LOST! */\n') + file.write("#pragma once\n\n") + +def is_overlap(x : int, y : int) -> bool: + if x.start == x.stop or y.start == y.stop: + return False + return x.start < y.stop and y.start < x.stop + +def is_aligned(addr : int, sz : int) -> bool: + ''' Check address alignment ''' + return addr % sz == 0 + +class Memory: + ''' Memory handler ''' + def __init__(self, addr, sz): + self.addr : int = addr + self.sz : int = sz + + def overlaps_with(self, other) -> bool: + ''' Check Memory for intersection + @return Bool + ''' + first = range(self.addr, self.addr + self.sz) + second = range(other.addr, other.addr + other.sz) + + return is_overlap(first, second) + + def fits_with(self, other) -> bool: + ''' + + ''' + return \ + self.addr >= other.addr and \ + self.addr + self.sz <= other.addr + other.sz + +class MemoryRegion(Memory): + ''' Memory region handler ''' + def __init__(self, addr, sz, erase_sz, erase_val, type): + super().__init__(addr, sz) + self.erase_sz : int = erase_sz + self.erase_val : int = erase_val + self.type = type + +class BootloaderLayout: + ''' + Handler for bootloader memory layout + ''' + def __init__(self): + self.bootloader_area : Memory = None + self.ram : Memory = None + self.scratch_area : Memory = None + self.status_area : Memory = None + self.shared_data : Memory = None + self.shared_upgrade : Memory = None + self.core_name : int = None + + @property + def has_shared_upgrade(self) -> bool: + return self.shared_upgrade is not None + + @property + def has_shared_data(self) -> bool: + return self.shared_data is not None + + @property + def has_scratch_area(self) -> bool: + return self.scratch_area is not None + + @property + def has_status_area(self) -> bool: + return self.status_area is not None + + def parse(self, section : json): + ''' + Parse JSON section and init fields. + ''' + try: + fields = ('bootloader_area', 'scratch_area', 'status_area', \ + 'shared_data', 'shared_upgrade', 'ram') + for field in fields: + area = section.get(field) + if area: + setattr(self, field, Memory(int(area['address'], 0), + int(area['size'], 0))) + + core = section.get('core') + if core: + self.core_name = core + + except KeyError as key: + print('Malformed JSON:', key, 'is missing') + +class MemoryAreaConfig: + ''' + Handler for flash area configuration + ''' + def __init__(self, area_name, device_name, offset, size): + self.fa_id : str = area_name + self.fa_device_id : str = device_name + self.fa_off : int = offset + self.fa_size : int = size + +class ApplicationLayout: + ''' + Handler for application memory layout + ''' + def __init__(self): + self.boot_area : Memory = None + self.upgrade_area : Memory = None + self.ram : Memory = None + self.ram_boot : Memory = None + self.core_name : str = None + + @property + def has_ram_boot(self) -> bool: + return self.ram_boot is not None + + @property + def has_upgrade_area(self) -> bool: + return self.upgrade_area is not None + + def overlaps_with(self, other) -> bool: + return \ + self.boot_area.overlaps_with(other.boot_area) or \ + self.upgrade_area.overlaps_with(other.upgrade_area) + + def parse(self, section : json): + ''' + Parse JSON section and init fields. + ''' + try: + slots = section['slots'] + boot_address = int(slots['boot'], 0) + upgrade_address = int(slots['upgrade'], 0) + slot_size = int(slots['size'], 0) + + self.boot_area = Memory(boot_address, slot_size) + self.upgrade_area = Memory(upgrade_address, slot_size) + + fields = ('ram', 'ram_boot') + for field in fields: + area = section.get(field) + if area: + setattr(self, field, Memory(int(area['address'], 0), + int(area['size'], 0))) + + core = section.get('core') + if core: + self.core_name = core + + except KeyError as key: + print('Malformed JSON:', key, 'is missing') + +class FlashMap: + ''' + General handler + ''' + def __init__(self): + self.boot_layout : BootloaderLayout = None + self.regions : MemoryRegion = [] + self.region_types : str = [] + self.apps : ApplicationLayout = [] + self.primary_slots : str = [] + self.secondary_slots: str = [] + self.mem_areas : MemoryAreaConfig = [] + self.param_dict = {} + self.map_json : json = None + self.platform_json : json = None + self.output_folder = None + self.output_name = None + self.max_sectors = 32 + + def __apps_init(self): + for image_number in range(1, APP_LIMIT): + app_ident = f'application_{image_number}' + section = self.map_json.get(app_ident) + + if section: + app_layout = ApplicationLayout() + app_layout.parse(section) + + self.apps.append(app_layout) + else: + break + + def __boot_layout_init(self): + self.boot_layout = BootloaderLayout() + self.boot_layout.parse(self.map_json['bootloader']) + + def __memory_regions_init(self): + memory_regions = self.platform_json['memory_regions'] + for region in memory_regions: + try: + addr = int(region['address'], 0) + size = int(region['size'], 0) + erase_size = int(region['erase_size'], 0) + erase_value = int(region['erase_value'], 0) + type = str(region['type']) + + if type not in self.region_types: + self.region_types.append(type) + + self.regions.append(MemoryRegion(addr, size, erase_size, erase_value, type)) + except KeyError as key: + print('Malformed JSON:', key, 'is missing') + + # Check regions for overlap + for this in self.regions: + for other in self.regions: + if this is other: + continue + if this.overlaps_with(other): + # TODO: Notify regions overlap + raise Exception() + + def __memory_area_find_region_id(self, area : Memory) -> int: + for region_id, region in enumerate(self.regions): + if area.fits_with(region): + return region_id + return None + + def __memory_area_config_create(self, key): + param_dict = self.param_dict + area = param_dict[key][0] + area_name = param_dict[key][1] + + region_id = self.__memory_area_find_region_id(area) + region = self.regions[region_id] + region_name = region.type + + offset = area.addr - region.addr + size = area.sz + + area_config = MemoryAreaConfig(area_name,\ + region_name, \ + offset, \ + size) + + self.mem_areas.append(area_config) + + # Update max sectors + slot_sectors = int((offset % region.erase_sz + + size + region.erase_sz - 1) // + region.erase_sz) + + self.max_sectors = max(self.max_sectors, slot_sectors) + + def __memory_areas_create(self): + # Generate FA indexes + param_dict = self.param_dict + bootloader_area = self.boot_layout.bootloader_area + main_app = self.apps[0] + boot_area = main_app.boot_area + upgrade_area = main_app.upgrade_area + scratch_area = self.boot_layout.scratch_area + + param_dict.update({'bootloader': [bootloader_area, 'FLASH_AREA_BOOTLOADER', 0]}) + param_dict.update({'app_1_boot': [boot_area, 'FLASH_AREA_IMG_1_PRIMARY', 1]}) + param_dict.update({'app_1_upgrade': [upgrade_area, 'FLASH_AREA_IMG_1_SECONDARY', 2]}) + + self.primary_slots.append('FLASH_AREA_IMG_1_PRIMARY') + self.secondary_slots.append('FLASH_AREA_IMG_1_SECONDARY') + + # Generate scratch area index + if self.boot_layout.has_scratch_area: + param_dict.update({'scratch_area': [scratch_area, 'FLASH_AREA_IMAGE_SCRATCH', 3]}) + + # Generate multiple app area indexes + multi_app_area_idx = 4 + if len(self.apps) > 1: + for app_id, app in enumerate(self.apps[1:], 1): + idx = multi_app_area_idx + (app_id-1) * 2 + app_num = app_id + 1 + key = f'app_{app_num}_boot' + fmt = f'FLASH_AREA_IMG_{app_num}_PRIMARY' + param_dict.update({key: [app.boot_area, fmt, idx]}) + + self.primary_slots.append(fmt) + + key = f'app_{app_num}_upgrade' + fmt = f'FLASH_AREA_IMG_{app_num}_SECONDARY' + param_dict.update({key: [app.upgrade_area, fmt, idx+1]}) + + self.secondary_slots.append(fmt) + + # Generate status area indexes + if self.boot_layout.has_status_area: + area = self.boot_layout.status_area + idx = multi_app_area_idx + (len(self.apps)-1) * 2 + fmt = 'FLASH_AREA_IMAGE_SWAP_STATUS' + param_dict.update({'status_area': [area, fmt, idx]}) + + # Create areas + for key in param_dict: + self.__memory_area_config_create(key) + + def __source_gen(self): + path = f'{self.output_folder}/{self.output_name}.c' + include = f'{self.output_name}.h' + + with open(path, "w", encoding='UTF-8') as f_out: + f_out.write(f'#include "{include}"\n') + f_out.write(f'#include "flash_map_backend.h"\n\n') + f_out.write('struct flash_device flash_devices[] =\n') + f_out.write('{\n') + for region in self.regions: + f_out.write('\t{\n') + f_out.write(f'\t\t.address = {hex(region.addr)}U,\n') + f_out.write(f'\t\t.size = {hex(region.sz)}U,\n') + f_out.write(f'\t\t.erase_size = {hex(region.erase_sz)}U,\n') + f_out.write(f'\t\t.erase_val = {hex(region.erase_val)}U,\n') + f_out.write(f'\t\t.device_id = {str(region.type)},\n') + f_out.write('\t},\n') + f_out.write('};\n\n') + + f_out.write(f'struct flash_area flash_areas[] =\n') + f_out.write('{\n') + for area in self.mem_areas: + f_out.writelines('\n'.join([ + '\t{', + f"\t\t.fa_id = {area.fa_id},", + f"\t\t.fa_device_id = {area.fa_device_id},", + f"\t\t.fa_off = {hex(area.fa_off)}U,", + f"\t\t.fa_size = {hex(area.fa_size)}U,", + '\t},\n'])) + f_out.write('};\n\n') + + f_out.write('struct flash_area *boot_area_descs[] =\n') + f_out.write('{\n') + for index, area in enumerate(self.mem_areas): + f_out.write(f'\t&flash_areas[{index}U],\n') + f_out.write('\tNULL\n};\n\n') + + f_out.write('uint8_t memory_areas_primary[] =\n') + f_out.write('{\n') + for slot in self.primary_slots: + f_out.write(f'\t{slot}, ') + f_out.write('\n};\n\n') + + f_out.write('uint8_t memory_areas_secondary[] =\n') + f_out.write('{\n') + for slot in self.secondary_slots: + f_out.write(f'\t{slot}, ') + f_out.write('\n};\n\n') + + def __header_gen(self): + path = f'{self.output_folder}/{self.output_name}.h' + with open(path, "w", encoding='UTF-8') as f_out: + header_guard_generate(f_out) + + f_out.write(f'#include \n') + f_out.write(f'#include "flash_map_backend.h"\n\n') + f_out.write(f'#define FLASHMAP_GENERATED_AREAS 1\n\n') + f_out.write('extern struct flash_device flash_devices[];\n') + f_out.write('extern struct flash_area *boot_area_descs[];\n\n') + f_out.write('extern uint8_t memory_areas_primary[];\n') + f_out.write('extern uint8_t memory_areas_secondary[];\n\n') + + f_out.write('enum \n{\n') + for id, type in enumerate(self.region_types): + f_out.write(f'\t{type} = {id}U,\n') + f_out.write('};\n\n') + + f_out.write('enum \n{\n') + for area_param in self.param_dict.values(): + f_out.write(f'\t{area_param[1]} = {area_param[2]}U,\n') + f_out.write('};\n\n') + + def __ota_xmc7200_flashmap_header_gen(self): + path = f'{self.output_folder}/{self.output_name}.h' + with open(path, "w", encoding='UTF-8') as f_out: + #header_guard_generate(f_out) + f_out.write('/* AUTO-GENERATED FILE, DO NOT EDIT.' + ' ALL CHANGES WILL BE LOST! */\n') + f_out.write(f'/* Platform: XMC7200 */\n\n') + f_out.write("#ifndef CY_FLASH_MAP_H\n") + f_out.write("#define CY_FLASH_MAP_H\n\n") + f_out.write(f'/* Below definitions are based on xmc7200_platform.json and these needs to be updated when xmc7200_platform.json is updated. */\n') + f_out.write(f'/* Note : If the fa_device_id is not INTERNAL_FLASH_CODE_LARGE then while accessing memory section appropriate offset should be added.*/\n') + f_out.write(f'/* If the fa_device_id is INTERNAL_FLASH_CODE_SMALL then .fa_off should be fa_off + 0x7F0000.*/\n') + f_out.write(f'/* If the fa_device_id is INTERNAL_FLASH_WORK_LARGE then .fa_off should be fa_off + 0x4000000.*/\n') + f_out.write(f'/* If the fa_device_id is INTERNAL_FLASH_WORK_SMALL then .fa_off should be fa_off + 0x4030000.*/\n\n') + + f_out.write(f'static struct flash_area flash_areas[] =\n') + f_out.write('{\n') + for area in self.mem_areas: + f_out.writelines('\n'.join([ + '\t{', + f"\t\t.fa_id = {area.fa_id},", + f"\t\t.fa_device_id = {area.fa_device_id},", + f"\t\t.fa_off = {hex(area.fa_off)}U,", + f"\t\t.fa_size = {hex(area.fa_size)}U", + '\t},\n'])) + f_out.write('};\n\n') + + f_out.write('struct flash_area *boot_area_descs[] =\n') + f_out.write('{\n') + for index, area in enumerate(self.mem_areas): + f_out.write(f'\t&flash_areas[{index}U],\n') + f_out.write('\tNULL\n};\n\n') + f_out.write("#endif /* CY_FLASH_MAP_H */\n") + + def __bootloader_mk_file_gen(self): + boot = self.boot_layout + # Upgrade mode + if boot.scratch_area is None and boot.status_area is None: + print(settings_dict['overwrite'], ':= 1') + else: + print(settings_dict['overwrite'], ':= 0') + print(settings_dict['swap'], ':= 1') + print(settings_dict['scratch'], f':= {0 if boot.scratch_area is None else 1}') + print(settings_dict['status'], f':= {0 if boot.status_area is None else 1}') + print('# Shared data') + if boot.shared_data is not None: + shared_data = boot.shared_data + print(settings_dict['measured_boot'], ':= 1') + print(settings_dict['data_sharing'], ':= 1') + + print(f'{settings_dict["shared_data_address"]} :=', hex(shared_data.addr)) + print(f'{settings_dict["shared_data_size"]} :=', hex(shared_data.sz)) + print(f'{settings_dict["shared_data_record_size"]} :=', hex(shared_data.sz)) + + print('# Bootloader app area') + print(f'{settings_dict["bootloader_app_address"]} :=', hex(boot.bootloader_area.addr)) + print(f'{settings_dict["bootloader_app_size"]} :=', hex(boot.bootloader_area.sz)) + + print('# Bootloader ram area') + if boot.ram is not None: + print(f'{settings_dict["bootloader_ram_address"]} :=', hex(boot.ram.addr)) + print(f'{settings_dict["bootloader_ram_size"]} :=', hex(boot.ram.sz)) + + print('# Application area') + for id, app in enumerate(self.apps): + print(f'APPLICATION_{id+1}_BOOT_SLOT_ADDRESS := {hex(app.boot_area.addr)}') + print(f'APPLICATION_{id+1}_BOOT_SLOT_SIZE := {hex(app.boot_area.sz)}') + print(f'APPLICATION_{id+1}_UPGRADE_SLOT_ADDRESS := {hex(app.upgrade_area.addr)}') + print(f'APPLICATION_{id+1}_UPGRADE_SLOT_SIZE := {hex(app.upgrade_area.sz)}') + + print('# Ram load') + # Ram load single + if len(self.apps) == 1: + if self.apps[0].ram_boot is not None: + ram_boot = self.apps[0].ram_boot + print(settings_dict['ram_load'], ':= 1') + print(f'{settings_dict["ram_load_address"]} :=', hex(ram_boot.addr)) + print(f'{settings_dict["ram_load_size"]} :=', hex(ram_boot.sz)) + else: + # Ram load multiple + ram_boot_counter = 0 + ram_addr_overlap_counter = 0 + + for app1 in self.apps: + for app2 in self.apps: + if app1 is app2: + continue + if app1.overlaps_with(app2): + ram_addr_overlap_counter += 1 + + for id, app in enumerate(self.apps): + if app.ram_boot is not None: + ram_boot_counter += 1 + ram_boot = app.ram_boot + + print(f'APPLICATION_{id+1}_RAM_LOAD_ADDRESS := {hex(ram_boot.addr)}') + print(f'APPLICATION_{id+1}_RAM_LOAD_SIZE := {hex(ram_boot.sz)}') + + if ram_boot_counter != 0: + print(settings_dict['ram_load'], ':= 1') + + if ram_boot_counter != len(self.apps) or ram_addr_overlap_counter == 0: + print(settings_dict['multi_memory_load'], ':= 1') + + print('# Mcuboot') + print(settings_dict['application_count'], f'= {len(self.apps)}') + print(settings_dict['sectors_count'], f'= {self.max_sectors}') + + def __application_mk_file_gen(self): + app = self.apps[self.app_id-1] + boot = self.boot_layout + + print(settings_dict['application_count'], f'= {len(self.apps)}') + print(settings_dict['bootloader_id'], ':=', 'FLASH_DEVICE_INTERNAL_FLASH') + print(settings_dict['bootloader_app_address'], ':=', str.format("{:#08x}",(boot.bootloader_area.addr - cy_xmc_flash_base))) + print(settings_dict['bootloader_app_size'], ':=', str.format("{:#08x}",(boot.bootloader_area.sz))) + print(settings_dict['primary_image_id'], ':=', 'FLASH_DEVICE_INTERNAL_FLASH') + print(settings_dict['primary_image_start'], ':=', str.format("{:#08x}",(app.boot_area.addr - cy_xmc_flash_base))) + print(settings_dict['primary_image_size'], ':=', str.format("{:#08x}",(app.boot_area.sz))) + print(settings_dict['secondary_image_id'], ':=', 'FLASH_DEVICE_INTERNAL_FLASH') + print(settings_dict['secondary_image_start'], ':=', str.format("{:#08x}",(app.upgrade_area.addr - cy_xmc_flash_base))) + print(settings_dict['secondary_image_size'], ':=', str.format("{:#08x}",(app.boot_area.sz))) #hex(app.upgrade_area.sz)) + + # Upgrade mode + if boot.scratch_area is None and boot.status_area is None: + print(settings_dict['overwrite'], ':= 1') + else: + print(settings_dict['swap_status_image_id'], ':=', 'FLASH_DEVICE_INTERNAL_FLASH' ) + print(settings_dict['swap_status_image_start'], ':=', str.format("{:#08x}",(boot.status_area.addr - cy_xmc_flash_base))) + print(settings_dict['swap_status_image_size'], ':=', str.format("{:#08x}",(boot.status_area.sz))) + print(settings_dict['scratch_image_id'], ':=', 'FLASH_DEVICE_INTERNAL_FLASH' ) + print(settings_dict['scratch_image_start'], ':=', str.format("{:#08x}",(boot.scratch_area.addr - cy_xmc_flash_base))) + print(settings_dict['scratch_image_size'], ':=', str.format("{:#08x}",(boot.scratch_area.sz))) #hex(boot.scratch_area.sz)) + + print(settings_dict['sectors_count'], ':=', self.max_sectors ) + print(settings_dict['core'], ':=', cy_ota_app_core) + + if app.ram_boot: + print(settings_dict['ram_load'], ':= 1') + if app.ram: + print(settings_dict['image_ram_address'], ':=', hex(app.ram.addr)) + print(settings_dict['image_ram_size'], ':=', hex(app.ram.sz)) + if app.core_name: + print(settings_dict['core'], ':=', app.core_name) + + def parse(self, memory_map, platform_config, output_folder, output_name, app_id): + try: + with open(memory_map, "r", encoding='UTF-8') as f_in: + self.map_json = json.load(f_in) + + with open(platform_config, "r", encoding='UTF-8') as f_in: + self.platform_json = json.load(f_in) + + self.output_folder = output_folder + self.output_name = output_name + + if app_id is not None: + self.app_id = int(app_id) + + self.__memory_regions_init() + self.__boot_layout_init() + self.__apps_init() + self.__memory_areas_create() + + #self.__source_gen() + #self.__header_gen() + self.__ota_xmc7200_flashmap_header_gen() + + if app_id is None: + self.__bootloader_mk_file_gen() + else: + self.__application_mk_file_gen() + + except (FileNotFoundError, OSError): + print('\nERROR: Cannot open ', f_in, file=sys.stderr) + sys.exit(-1) + + +@click.group() +def cli(): + ''' + Flash map layout parser-configurator + ''' + +@cli.command() +@click.option('-i', '--memory_config', required=True, + help='memory configuration file path') +@click.option('-p', '--platform_config', required=True, + help='platform configuration file path') +@click.option('-n', '--output_name', required=True, + help='generated areas path') +@click.option('-o', '--output_folder', required=True, + help='generated regions path') +@click.option('-d', '--image_id', required=False, + help='application image number') + +def run(memory_config, platform_config, output_folder, output_name, image_id): + map = FlashMap() + map.parse(memory_config, + platform_config, + output_folder, + output_name, + image_id) + +if __name__ == '__main__': + cy_xmc_flash_base = 0x10000000 + cy_ota_app_core = 'CM7' + cli() diff --git a/scripts/mcuboot/imgtool/assemble.py b/scripts/mcuboot/imgtool/assemble.py new file mode 100644 index 0000000..0f39fcc --- /dev/null +++ b/scripts/mcuboot/imgtool/assemble.py @@ -0,0 +1,148 @@ +#! /usr/bin/env python3 +# +# Copyright 2017 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Assemble multiple images into a single image that can be flashed on the device. +""" + +import argparse +import errno +import io +import re +import os +import os.path +import sys + +def same_keys(a, b): + """Determine if the dicts a and b have the same keys in them""" + for ak in a.keys(): + if ak not in b: + return False + for bk in b.keys(): + if bk not in a: + return False + return True + +offset_re = re.compile(r"^#define DT_FLASH_AREA_([0-9A-Z_]+)_OFFSET(_0)?\s+(0x[0-9a-fA-F]+|[0-9]+)$") +size_re = re.compile(r"^#define DT_FLASH_AREA_([0-9A-Z_]+)_SIZE(_0)?\s+(0x[0-9a-fA-F]+|[0-9]+)$") + +class Assembly(): + def __init__(self, output, bootdir, edt): + self.find_slots(edt) + try: + os.unlink(output) + except OSError as e: + if e.errno != errno.ENOENT: + raise + self.output = output + + def find_slots(self, edt): + offsets = {} + sizes = {} + + part_nodes = edt.compat2nodes["fixed-partitions"] + for node in part_nodes: + for child in node.children.values(): + if "label" in child.props: + label = child.props["label"].val + offsets[label] = child.regs[0].addr + sizes[label] = child.regs[0].size + + if not same_keys(offsets, sizes): + raise Exception("Inconsistent data in devicetree.h") + + # We care about the mcuboot, image-0, and image-1 partitions. + if 'mcuboot' not in offsets: + raise Exception("Board partition table does not have mcuboot partition") + + if 'image-0' not in offsets: + raise Exception("Board partition table does not have image-0 partition") + + if 'image-1' not in offsets: + raise Exception("Board partition table does not have image-1 partition") + + self.offsets = offsets + self.sizes = sizes + + def add_image(self, source, partition): + with open(self.output, 'ab') as ofd: + pos = ofd.tell() + print("partition {}, pos={}, offset={}".format(partition, pos, self.offsets[partition])) + if pos > self.offsets[partition]: + raise Exception("Partitions not in order, unsupported") + if pos < self.offsets[partition]: + buf = b'\xFF' * (self.offsets[partition] - pos) + ofd.write(buf) + with open(source, 'rb') as rfd: + ibuf = rfd.read() + if len(ibuf) > self.sizes[partition]: + raise Exception("Image {} is too large for partition".format(source)) + ofd.write(ibuf) + +def find_board_name(bootdir): + suffix = ".dts.pre.tmp" + + for _, _, files in os.walk(os.path.join(bootdir, "zephyr")): + for filename in files: + if filename.endswith(suffix): + return filename[:-len(suffix)] + + +def main(): + parser = argparse.ArgumentParser() + + parser.add_argument('-b', '--bootdir', required=True, + help='Directory of built bootloader') + parser.add_argument('-p', '--primary', required=True, + help='Signed image file for primary image') + parser.add_argument('-s', '--secondary', + help='Signed image file for secondary image') + parser.add_argument('-o', '--output', required=True, + help='Filename to write full image to') + parser.add_argument('-z', '--zephyr-base', + help='Zephyr base containing the Zephyr repository') + + args = parser.parse_args() + + zephyr_base = args.zephyr_base + if zephyr_base is None: + try: + zephyr_base = os.environ['ZEPHYR_BASE'] + except KeyError: + print('Need to either have ZEPHYR_BASE in environment or pass in -z') + sys.exit(1) + + sys.path.insert(0, os.path.join(zephyr_base, "scripts", "dts", "python-devicetree", "src")) + import devicetree.edtlib + + board = find_board_name(args.bootdir) + + dts_path = os.path.join(args.bootdir, "zephyr", board + ".dts.pre.tmp") + + edt = devicetree.edtlib.EDT(dts_path, [os.path.join(zephyr_base, "dts", "bindings")], + warn_reg_unit_address_mismatch=False) + + output = Assembly(args.output, args.bootdir, edt) + + output.add_image(os.path.join(args.bootdir, 'zephyr', 'zephyr.bin'), 'mcuboot') + output.add_image(args.primary, "image-0") + if args.secondary is not None: + output.add_image(args.secondary, "image-1") + +if __name__ == '__main__': + main() diff --git a/scripts/mcuboot/imgtool/flash.sh b/scripts/mcuboot/imgtool/flash.sh new file mode 100644 index 0000000..7cb5bdb --- /dev/null +++ b/scripts/mcuboot/imgtool/flash.sh @@ -0,0 +1,20 @@ +#! /bin/bash +# +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname $0)/../target.sh + +lscript=/tmp/flash$$.jlink + +cat >$lscript < $gscript < {}; +let + # Nixpkgs has fairly recent versions of the dependencies, so we can + # rely on them without having to build our own derivations. + imgtoolPythonEnv = python37.withPackages ( + _: [ + python37.pkgs.click + python37.pkgs.cryptography + python37.pkgs.intelhex + python37.pkgs.setuptools + python37.pkgs.cbor + ] + ); +in +myEnvFun { + name = "imgtool"; + + buildInputs = [ imgtoolPythonEnv ]; +} diff --git a/scripts/mcuboot/imgtool/imgtool.py b/scripts/mcuboot/imgtool/imgtool.py new file mode 100644 index 0000000..e29e224 --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool.py @@ -0,0 +1,22 @@ +#! /usr/bin/env python3 +# +# Copyright 2017 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from imgtool import main + +if __name__ == '__main__': + main.imgtool() diff --git a/scripts/mcuboot/imgtool/imgtool/__init__.py b/scripts/mcuboot/imgtool/imgtool/__init__.py new file mode 100644 index 0000000..ca43b8d --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2017-2020 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +imgtool_version = "1.8.0" diff --git a/scripts/mcuboot/imgtool/imgtool/boot_record.py b/scripts/mcuboot/imgtool/imgtool/boot_record.py new file mode 100644 index 0000000..ac433aa --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/boot_record.py @@ -0,0 +1,49 @@ +# Copyright (c) 2019, Arm Limited. +# Copyright (c) 2020, Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from enum import Enum +import cbor + + +class SwComponent(int, Enum): + """ + Software component property IDs specified by + Arm's PSA Attestation API 1.0 document. + """ + TYPE = 1 + MEASUREMENT_VALUE = 2 + VERSION = 4 + SIGNER_ID = 5 + MEASUREMENT_DESCRIPTION = 6 + + +def create_sw_component_data(sw_type, sw_version, sw_measurement_description, + sw_measurement_value, sw_signer_id): + + # List of software component properties (Key ID + value) + properties = { + SwComponent.TYPE: sw_type, + SwComponent.VERSION: sw_version, + SwComponent.SIGNER_ID: sw_signer_id, + SwComponent.MEASUREMENT_DESCRIPTION: sw_measurement_description, + } + + # Note: The measurement value must be the last item of the property + # list because later it will be modified by the bootloader. + properties[SwComponent.MEASUREMENT_VALUE] = sw_measurement_value + + return cbor.dumps(properties) diff --git a/scripts/mcuboot/imgtool/imgtool/encrypt_mxs40sv2.py b/scripts/mcuboot/imgtool/imgtool/encrypt_mxs40sv2.py new file mode 100644 index 0000000..f95a3a5 --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/encrypt_mxs40sv2.py @@ -0,0 +1,110 @@ +""" +Copyright (c) 2021 Cypress Semiconductor Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import os +import struct +from cryptography.hazmat.primitives.ciphers import ( + Cipher, algorithms, modes +) + +NONCE_SIZE = 12 + +class EncryptorMXS40Sv2: + def __init__(self, key, nonce, initial_counter=0): + # with open(key_path, 'rb') as f: + # self.key = f.read() + self.key = key + self.nonce = nonce + self.counter = 0 + self.initial_counter = initial_counter + cipher = Cipher(algorithms.AES(key), modes.ECB()) + self.encryptor = cipher.encryptor() + + def _load(self, image_path): + with open(image_path, 'rb') as f: + image = f.read() + return image + + def _save(self, data, output_path): + with open(output_path, 'wb') as f: + f.write(data) + + def update(self, data): + """ + Encrypts a byte array using a customized AES-CTR mode + where a counter is incremented by 16 per block. + A nonce format is (128 bit): + bits 0...31 - counter + initial values + bits 32...127 - random nonce + """ + chunk_size = 16 + counter = self.counter + ciphertext = bytes() + for i in range(0, len(image), chunk_size): + indata = struct.pack('' +} + +VerifyResult = Enum('VerifyResult', + """ + OK INVALID_MAGIC INVALID_TLV_INFO_MAGIC INVALID_HASH + INVALID_SIGNATURE + """) + + +class TLV(): + def __init__(self, endian, magic=TLV_INFO_MAGIC): + self.magic = magic + self.buf = bytearray() + self.endian = endian + + def __len__(self): + return TLV_INFO_SIZE + len(self.buf) + + def add(self, kind, payload): + """ + Add a TLV record. Kind should be a string found in TLV_VALUES above. + """ + e = STRUCT_ENDIAN_DICT[self.endian] + if isinstance(kind, int): + buf = struct.pack(e + 'BBH', kind, 0, len(payload)) + else: + buf = struct.pack(e + 'BBH', TLV_VALUES[kind], 0, len(payload)) + self.buf += buf + self.buf += payload + + def get(self): + if len(self.buf) == 0: + return bytes() + e = STRUCT_ENDIAN_DICT[self.endian] + header = struct.pack(e + 'HH', self.magic, len(self)) + return header + bytes(self.buf) + + +class Image(): + + def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, + pad_header=False, pad=False, confirm=False, align=1, + slot_size=0, max_sectors=DEFAULT_MAX_SECTORS, + overwrite_only=False, endian="little", load_addr=0, + rom_fixed=None, erased_val=None, save_enctlv=False, + security_counter=None): + + if load_addr and rom_fixed: + raise click.UsageError("Can not set rom_fixed and load_addr at the same time") + + self.version = version or versmod.decode_version("0") + self.header_size = header_size + self.pad_header = pad_header + self.pad = pad + self.confirm = confirm + self.align = align + self.slot_size = slot_size + self.max_sectors = max_sectors + self.overwrite_only = overwrite_only + self.endian = endian + self.base_addr = None + self.load_addr = 0 if load_addr is None else load_addr + self.rom_fixed = rom_fixed + self.erased_val = 0xff if erased_val is None else int(erased_val, 0) + self.payload = [] + self.enckey = None + self.save_enctlv = save_enctlv + self.enctlv_len = 0 + self.hkdf_salt = None + self.hkdf_len = 48 + self.enc_nonce = bytes([0] * 16) + + if security_counter == 'auto': + # Security counter has not been explicitly provided, + # generate it from the version number + self.security_counter = ((self.version.major << 24) + + (self.version.minor << 16) + + self.version.revision) + else: + self.security_counter = security_counter + + def __repr__(self): + return "".format( + self.version, + self.header_size, + self.security_counter, + self.base_addr if self.base_addr is not None else "N/A", + self.load_addr, + self.align, + self.slot_size, + self.max_sectors, + self.overwrite_only, + self.endian, + self.__class__.__name__, + len(self.payload)) + + def load(self, path): + """Load an image from a given file""" + ext = os.path.splitext(path)[1][1:].lower() + try: + if ext == INTEL_HEX_EXT: + ih = IntelHex(path) + self.payload = ih.tobinarray() + self.base_addr = ih.minaddr() + else: + with open(path, 'rb') as f: + self.payload = f.read() + except FileNotFoundError: + raise click.UsageError("Input file not found") + + # Add the image header if needed. + if self.pad_header and self.header_size > 0: + if self.base_addr: + # Adjust base_addr for new header + self.base_addr -= self.header_size + self.payload = bytes([self.erased_val] * self.header_size) + \ + self.payload + + self.check_header() + + def save(self, path, hex_addr=None): + """Save an image from a given file""" + ext = os.path.splitext(path)[1][1:].lower() + if ext == INTEL_HEX_EXT: + # input was in binary format, but HEX needs to know the base addr + if self.base_addr is None and hex_addr is None: + raise click.UsageError("No address exists in input file " + "neither was it provided by user") + h = IntelHex() + if hex_addr is not None: + self.base_addr = hex_addr + h.frombytes(bytes=self.payload, offset=self.base_addr) + if self.pad: + trailer_size = self._trailer_size(self.align, self.max_sectors, + self.overwrite_only, + self.enckey, + self.save_enctlv, + self.enctlv_len) + trailer_addr = (self.base_addr + self.slot_size) - trailer_size + padding = bytearray([self.erased_val] * + (trailer_size - len(boot_magic))) + if self.confirm and not self.overwrite_only: + padding[-MAX_ALIGN] = 0x01 # image_ok = 0x01 + padding += boot_magic + h.puts(trailer_addr, bytes(padding)) + h.tofile(path, 'hex') + else: + if self.pad: + self.pad_to(self.slot_size) + with open(path, 'wb') as f: + f.write(self.payload) + + def check_header(self): + if self.header_size > 0 and not self.pad_header: + if any(v != 0 for v in self.payload[0:self.header_size]): + raise click.UsageError("Header padding was not requested and " + "image does not start with zeros") + + def check_trailer(self): + if self.slot_size > 0: + tsize = self._trailer_size(self.align, self.max_sectors, + self.overwrite_only, self.enckey, + self.save_enctlv, self.enctlv_len) + padding = self.slot_size - (len(self.payload) + tsize) + if padding < 0: + msg = "Image size (0x{:x}) + trailer (0x{:x}) exceeds " \ + "requested size 0x{:x}".format( + len(self.payload), tsize, self.slot_size) + raise click.UsageError(msg) + + def ecies_hkdf(self, enckey, plainkey): + if isinstance(enckey, ecdsa.ECDSA256P1Public): + newpk = ec.generate_private_key(ec.SECP256R1(), default_backend()) + shared = newpk.exchange(ec.ECDH(), enckey._get_public()) + else: + newpk = X25519PrivateKey.generate() + shared = newpk.exchange(enckey._get_public()) + derived_key = HKDF( + algorithm=hashes.SHA256(), length=self.hkdf_len, salt=self.hkdf_salt, + info=b'MCUBoot_ECIES_v1', backend=default_backend()).derive(shared) + if self.hkdf_salt is not None: + key_nonce = derived_key[48:64] + self.enc_nonce = derived_key[64:76] + bytes([0] * 4) + else: + key_nonce = bytes([0] * 16) + encryptor = Cipher(algorithms.AES(derived_key[:16]), + modes.CTR(key_nonce), + backend=default_backend()).encryptor() + cipherkey = encryptor.update(plainkey) + encryptor.finalize() + mac = hmac.HMAC(derived_key[16:48], hashes.SHA256(), + backend=default_backend()) + mac.update(cipherkey) + ciphermac = mac.finalize() + if isinstance(enckey, ecdsa.ECDSA256P1Public): + pubk = newpk.public_key().public_bytes( + encoding=Encoding.X962, + format=PublicFormat.UncompressedPoint) + else: + pubk = newpk.public_key().public_bytes( + encoding=Encoding.Raw, + format=PublicFormat.Raw) + return cipherkey, ciphermac, pubk + + def create(self, key, public_key_format, enckey, dependencies=None, + sw_type=None, custom_tlvs=None, encrypt_keylen=128, use_random_iv=False): + self.enckey = enckey + + if use_random_iv: + self.hkdf_salt = os.urandom(32) + self.hkdf_len += 16 * 2 # 48 for basic scheme + 16 * 2 for random IVs + + # Calculate the hash of the public key + if key is not None: + pub = key.get_public_bytes() + sha = hashlib.sha256() + sha.update(pub) + pubbytes = sha.digest() + else: + pubbytes = bytes(hashlib.sha256().digest_size) + + protected_tlv_size = 0 + + if self.security_counter is not None: + # Size of the security counter TLV: header ('HH') + payload ('I') + # = 4 + 4 = 8 Bytes + protected_tlv_size += TLV_SIZE + 4 + + if sw_type is not None: + if len(sw_type) > MAX_SW_TYPE_LENGTH: + msg = "'{}' is too long ({} characters) for sw_type. Its " \ + "maximum allowed length is 12 characters.".format( + sw_type, len(sw_type)) + raise click.UsageError(msg) + + image_version = (str(self.version.major) + '.' + + str(self.version.minor) + '.' + + str(self.version.revision)) + + # The image hash is computed over the image header, the image + # itself and the protected TLV area. However, the boot record TLV + # (which is part of the protected area) should contain this hash + # before it is even calculated. For this reason the script fills + # this field with zeros and the bootloader will insert the right + # value later. + digest = bytes(hashlib.sha256().digest_size) + + # Create CBOR encoded boot record + boot_record = create_sw_component_data(sw_type, image_version, + "SHA256", digest, + pubbytes) + + protected_tlv_size += TLV_SIZE + len(boot_record) + + if dependencies is not None: + # Size of a Dependency TLV = Header ('HH') + Payload('IBBHI') + # = 4 + 12 = 16 Bytes + dependencies_num = len(dependencies[DEP_IMAGES_KEY]) + protected_tlv_size += (dependencies_num * 16) + + if custom_tlvs is not None: + for value in custom_tlvs.values(): + protected_tlv_size += TLV_SIZE + len(value) + + if protected_tlv_size != 0: + # Add the size of the TLV info header + protected_tlv_size += TLV_INFO_SIZE + + # At this point the image is already on the payload + # + # This adds the padding if image is not aligned to the 16 Bytes + # in encrypted mode + if self.enckey is not None: + pad_len = len(self.payload) % 16 + if pad_len > 0: + pad = bytes(16 - pad_len) + if isinstance(self.payload, bytes): + self.payload += pad + else: + self.payload.extend(pad) + + # This adds the header to the payload as well + if encrypt_keylen == 256: + self.add_header(enckey, protected_tlv_size, 256) + else: + self.add_header(enckey, protected_tlv_size) + + prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC) + + # Protected TLVs must be added first, because they are also included + # in the hash calculation + protected_tlv_off = None + if protected_tlv_size != 0: + + e = STRUCT_ENDIAN_DICT[self.endian] + + if self.security_counter is not None: + payload = struct.pack(e + 'I', self.security_counter) + prot_tlv.add('SEC_CNT', payload) + + if sw_type is not None: + prot_tlv.add('BOOT_RECORD', boot_record) + + if dependencies is not None: + for i in range(dependencies_num): + payload = struct.pack( + e + 'B3x'+'BBHI', + int(dependencies[DEP_IMAGES_KEY][i]), + dependencies[DEP_VERSIONS_KEY][i].major, + dependencies[DEP_VERSIONS_KEY][i].minor, + dependencies[DEP_VERSIONS_KEY][i].revision, + dependencies[DEP_VERSIONS_KEY][i].build + ) + prot_tlv.add('DEPENDENCY', payload) + + if custom_tlvs is not None: + for tag, value in custom_tlvs.items(): + prot_tlv.add(tag, value) + + protected_tlv_off = len(self.payload) + self.payload += prot_tlv.get() + + tlv = TLV(self.endian) + + # Note that ecdsa wants to do the hashing itself, which means + # we get to hash it twice. + sha = hashlib.sha256() + sha.update(self.payload) + digest = sha.digest() + + tlv.add('SHA256', digest) + + if key is not None: + if public_key_format == 'hash': + tlv.add('KEYHASH', pubbytes) + else: + tlv.add('PUBKEY', pub) + + # `sign` expects the full image payload (sha256 done internally), + # while `sign_digest` expects only the digest of the payload + + if hasattr(key, 'sign'): + sig = key.sign(bytes(self.payload)) + else: + sig = key.sign_digest(digest) + tlv.add(key.sig_tlv(), sig) + + # At this point the image was hashed + signed, we can remove the + # protected TLVs from the payload (will be re-added later) + if protected_tlv_off is not None: + self.payload = self.payload[:protected_tlv_off] + + if enckey is not None: + if encrypt_keylen == 256: + plainkey = os.urandom(32) + else: + plainkey = os.urandom(16) + + if isinstance(enckey, rsa.RSAPublic): + cipherkey = enckey._get_public().encrypt( + plainkey, padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), + label=None)) + self.enctlv_len = len(cipherkey) + tlv.add('ENCRSA2048', cipherkey) + elif isinstance(enckey, (ecdsa.ECDSA256P1Public, + x25519.X25519Public)): + cipherkey, mac, pubk = self.ecies_hkdf(enckey, plainkey) + enctlv = pubk + mac + cipherkey + if self.hkdf_salt is not None: + enctlv += self.hkdf_salt + self.enctlv_len = len(enctlv) + if isinstance(enckey, ecdsa.ECDSA256P1Public): + tlv.add('ENCEC256', enctlv) + else: + tlv.add('ENCX25519', enctlv) + + nonce = self.enc_nonce + cipher = Cipher(algorithms.AES(plainkey), modes.CTR(nonce), + backend=default_backend()) + encryptor = cipher.encryptor() + img = bytes(self.payload[self.header_size:]) + self.payload[self.header_size:] = \ + encryptor.update(img) + encryptor.finalize() + + self.payload += prot_tlv.get() + self.payload += tlv.get() + + self.check_trailer() + + def add_header(self, enckey, protected_tlv_size, aes_length=128): + """Install the image header.""" + + flags = 0 + if enckey is not None: + if aes_length == 128: + flags |= IMAGE_F['ENCRYPTED_AES128'] + else: + flags |= IMAGE_F['ENCRYPTED_AES256'] + if self.load_addr != 0: + # Indicates that this image should be loaded into RAM + # instead of run directly from flash. + flags |= IMAGE_F['RAM_LOAD'] + if self.rom_fixed: + flags |= IMAGE_F['ROM_FIXED'] + + e = STRUCT_ENDIAN_DICT[self.endian] + fmt = (e + + # type ImageHdr struct { + 'I' + # Magic uint32 + 'I' + # LoadAddr uint32 + 'H' + # HdrSz uint16 + 'H' + # PTLVSz uint16 + 'I' + # ImgSz uint32 + 'I' + # Flags uint32 + 'BBHI' + # Vers ImageVersion + 'I' # Pad1 uint32 + ) # } + assert struct.calcsize(fmt) == IMAGE_HEADER_SIZE + header = struct.pack(fmt, + IMAGE_MAGIC, + self.rom_fixed or self.load_addr, + self.header_size, + protected_tlv_size, # TLV Info header + Protected TLVs + len(self.payload) - self.header_size, # ImageSz + flags, + self.version.major, + self.version.minor or 0, + self.version.revision or 0, + self.version.build or 0, + 0) # Pad1 + self.payload = bytearray(self.payload) + self.payload[:len(header)] = header + + def _trailer_size(self, write_size, max_sectors, overwrite_only, enckey, + save_enctlv, enctlv_len): + # NOTE: should already be checked by the argument parser + magic_size = 16 + if overwrite_only: + return MAX_ALIGN * 2 + magic_size + else: + if write_size not in set([1, 2, 4, 8]): + raise click.BadParameter("Invalid alignment: {}".format( + write_size)) + m = DEFAULT_MAX_SECTORS if max_sectors is None else max_sectors + trailer = m * 3 * write_size # status area + if enckey is not None: + if save_enctlv: + # TLV saved by the bootloader is aligned + keylen = (int((enctlv_len - 1) / MAX_ALIGN) + 1) * MAX_ALIGN + else: + keylen = 16 + trailer += keylen * 2 # encryption keys + trailer += MAX_ALIGN * 4 # image_ok/copy_done/swap_info/swap_size + trailer += magic_size + return trailer + + def pad_to(self, size): + """Pad the image to the given size, with the given flash alignment.""" + tsize = self._trailer_size(self.align, self.max_sectors, + self.overwrite_only, self.enckey, + self.save_enctlv, self.enctlv_len) + padding = size - (len(self.payload) + tsize) + pbytes = bytearray([self.erased_val] * padding) + pbytes += bytearray([self.erased_val] * (tsize - len(boot_magic))) + if self.confirm and not self.overwrite_only: + pbytes[-MAX_ALIGN] = 0x01 # image_ok = 0x01 + pbytes += boot_magic + self.payload += pbytes + + @staticmethod + def verify(imgfile, key): + with open(imgfile, "rb") as f: + b = f.read() + + magic, _, header_size, _, img_size = struct.unpack('IIHHI', b[:16]) + version = struct.unpack('BBHI', b[20:28]) + + if magic != IMAGE_MAGIC: + return VerifyResult.INVALID_MAGIC, None, None + + tlv_off = header_size + img_size + tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] + magic, tlv_tot = struct.unpack('HH', tlv_info) + if magic == TLV_PROT_INFO_MAGIC: + tlv_off += tlv_tot + tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] + magic, tlv_tot = struct.unpack('HH', tlv_info) + + if magic != TLV_INFO_MAGIC: + return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None + + sha = hashlib.sha256() + prot_tlv_size = tlv_off + sha.update(b[:prot_tlv_size]) + digest = sha.digest() + + tlv_end = tlv_off + tlv_tot + tlv_off += TLV_INFO_SIZE # skip tlv info + while tlv_off < tlv_end: + tlv = b[tlv_off:tlv_off+TLV_SIZE] + tlv_type, _, tlv_len = struct.unpack('BBH', tlv) + if tlv_type == TLV_VALUES["SHA256"]: + off = tlv_off + TLV_SIZE + if digest == b[off:off+tlv_len]: + if key is None: + return VerifyResult.OK, version, digest + else: + return VerifyResult.INVALID_HASH, None, None + elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]: + off = tlv_off + TLV_SIZE + tlv_sig = b[off:off+tlv_len] + payload = b[:prot_tlv_size] + try: + if hasattr(key, 'verify'): + key.verify(tlv_sig, payload) + else: + key.verify_digest(tlv_sig, digest) + return VerifyResult.OK, version, digest + except InvalidSignature: + # continue to next TLV + pass + tlv_off += TLV_SIZE + tlv_len + return VerifyResult.INVALID_SIGNATURE, None, None diff --git a/scripts/mcuboot/imgtool/imgtool/keys/__init__.py b/scripts/mcuboot/imgtool/imgtool/keys/__init__.py new file mode 100644 index 0000000..dfd101d --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2017 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Cryptographic key management for imgtool. +""" + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKey, RSAPublicKey) +from cryptography.hazmat.primitives.asymmetric.ec import ( + EllipticCurvePrivateKey, EllipticCurvePublicKey) +from cryptography.hazmat.primitives.asymmetric.ed25519 import ( + Ed25519PrivateKey, Ed25519PublicKey) +from cryptography.hazmat.primitives.asymmetric.x25519 import ( + X25519PrivateKey, X25519PublicKey) + +from .rsa import RSA, RSAPublic, RSAUsageError, RSA_KEY_SIZES +from .ecdsa import ECDSA256P1, ECDSA256P1Public, ECDSAUsageError +from .ed25519 import Ed25519, Ed25519Public, Ed25519UsageError +from .x25519 import X25519, X25519Public, X25519UsageError + + +class PasswordRequired(Exception): + """Raised to indicate that the key is password protected, but a + password was not specified.""" + pass + + +def load(path, passwd=None): + """Try loading a key from the given path. Returns None if the password wasn't specified.""" + with open(path, 'rb') as f: + raw_pem = f.read() + try: + pk = serialization.load_pem_private_key( + raw_pem, + password=passwd, + backend=default_backend()) + # Unfortunately, the crypto library raises unhelpful exceptions, + # so we have to look at the text. + except TypeError as e: + msg = str(e) + if "private key is encrypted" in msg: + return None + raise e + except ValueError: + # This seems to happen if the key is a public key, let's try + # loading it as a public key. + pk = serialization.load_pem_public_key( + raw_pem, + backend=default_backend()) + + if isinstance(pk, RSAPrivateKey): + if pk.key_size not in RSA_KEY_SIZES: + raise Exception("Unsupported RSA key size: " + pk.key_size) + return RSA(pk) + elif isinstance(pk, RSAPublicKey): + if pk.key_size not in RSA_KEY_SIZES: + raise Exception("Unsupported RSA key size: " + pk.key_size) + return RSAPublic(pk) + elif isinstance(pk, EllipticCurvePrivateKey): + if pk.curve.name != 'secp256r1': + raise Exception("Unsupported EC curve: " + pk.curve.name) + if pk.key_size != 256: + raise Exception("Unsupported EC size: " + pk.key_size) + return ECDSA256P1(pk) + elif isinstance(pk, EllipticCurvePublicKey): + if pk.curve.name != 'secp256r1': + raise Exception("Unsupported EC curve: " + pk.curve.name) + if pk.key_size != 256: + raise Exception("Unsupported EC size: " + pk.key_size) + return ECDSA256P1Public(pk) + elif isinstance(pk, Ed25519PrivateKey): + return Ed25519(pk) + elif isinstance(pk, Ed25519PublicKey): + return Ed25519Public(pk) + elif isinstance(pk, X25519PrivateKey): + return X25519(pk) + elif isinstance(pk, X25519PublicKey): + return X25519Public(pk) + else: + raise Exception("Unknown key type: " + str(type(pk))) diff --git a/scripts/mcuboot/imgtool/imgtool/keys/ecdsa.py b/scripts/mcuboot/imgtool/imgtool/keys/ecdsa.py new file mode 100644 index 0000000..e45492b --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/ecdsa.py @@ -0,0 +1,159 @@ +""" +ECDSA key management +""" + +# SPDX-License-Identifier: Apache-2.0 + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.hashes import SHA256 + +from .general import KeyClass + +class ECDSAUsageError(Exception): + pass + +class ECDSA256P1Public(KeyClass): + def __init__(self, key): + self.key = key + + def shortname(self): + return "ecdsa" + + def _unsupported(self, name): + raise ECDSAUsageError("Operation {} requires private key".format(name)) + + def _get_public(self): + return self.key + + def get_public_bytes(self): + # The key is embedded into MBUboot in "SubjectPublicKeyInfo" format + return self._get_public().public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + + def get_private_bytes(self, minimal): + self._unsupported('get_private_bytes') + + def export_private(self, path, passwd=None): + self._unsupported('export_private') + + def export_public(self, path): + """Write the public key to the given file.""" + pem = self._get_public().public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + with open(path, 'wb') as f: + f.write(pem) + + def sig_type(self): + return "ECDSA256_SHA256" + + def sig_tlv(self): + return "ECDSA256" + + def sig_len(self): + # Early versions of MCUboot (< v1.5.0) required ECDSA + # signatures to be padded to 72 bytes. Because the DER + # encoding is done with signed integers, the size of the + # signature will vary depending on whether the high bit is set + # in each value. This padding was done in a + # not-easily-reversible way (by just adding zeros). + # + # The signing code no longer requires this padding, and newer + # versions of MCUboot don't require it. But, continue to + # return the total length so that the padding can be done if + # requested. + return 72 + + def verify(self, signature, payload): + # strip possible paddings added during sign + signature = signature[:signature[1] + 2] + k = self.key + if isinstance(self.key, ec.EllipticCurvePrivateKey): + k = self.key.public_key() + return k.verify(signature=signature, data=payload, + signature_algorithm=ec.ECDSA(SHA256())) + + +class ECDSA256P1(ECDSA256P1Public): + """ + Wrapper around an ECDSA private key. + """ + + def __init__(self, key): + """key should be an instance of EllipticCurvePrivateKey""" + self.key = key + self.pad_sig = False + + @staticmethod + def generate(): + pk = ec.generate_private_key( + ec.SECP256R1(), + backend=default_backend()) + return ECDSA256P1(pk) + + def _get_public(self): + return self.key.public_key() + + def _build_minimal_ecdsa_privkey(self, der): + ''' + Builds a new DER that only includes the EC private key, removing the + public key that is added as an "optional" BITSTRING. + ''' + offset_PUB = 68 + EXCEPTION_TEXT = "Error parsing ecdsa key. Please submit an issue!" + if der[offset_PUB] != 0xa1: + raise ECDSAUsageError(EXCEPTION_TEXT) + len_PUB = der[offset_PUB + 1] + b = bytearray(der[:-offset_PUB]) + offset_SEQ = 29 + if b[offset_SEQ] != 0x30: + raise ECDSAUsageError(EXCEPTION_TEXT) + b[offset_SEQ + 1] -= len_PUB + offset_OCT_STR = 27 + if b[offset_OCT_STR] != 0x04: + raise ECDSAUsageError(EXCEPTION_TEXT) + b[offset_OCT_STR + 1] -= len_PUB + if b[0] != 0x30 or b[1] != 0x81: + raise ECDSAUsageError(EXCEPTION_TEXT) + b[2] -= len_PUB + return b + + def get_private_bytes(self, minimal): + priv = self.key.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption()) + if minimal: + priv = self._build_minimal_ecdsa_privkey(priv) + return priv + + def export_private(self, path, passwd=None): + """Write the private key to the given file, protecting it with the optional password.""" + if passwd is None: + enc = serialization.NoEncryption() + else: + enc = serialization.BestAvailableEncryption(passwd) + pem = self.key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=enc) + with open(path, 'wb') as f: + f.write(pem) + + def raw_sign(self, payload): + """Return the actual signature""" + return self.key.sign( + data=payload, + signature_algorithm=ec.ECDSA(SHA256())) + + def sign(self, payload): + sig = self.raw_sign(payload) + if self.pad_sig: + # To make fixed length, pad with one or two zeros. + sig += b'\000' * (self.sig_len() - len(sig)) + return sig + else: + return sig diff --git a/scripts/mcuboot/imgtool/imgtool/keys/ecdsa_test.py b/scripts/mcuboot/imgtool/imgtool/keys/ecdsa_test.py new file mode 100644 index 0000000..65b709f --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/ecdsa_test.py @@ -0,0 +1,101 @@ +""" +Tests for ECDSA keys +""" + +# SPDX-License-Identifier: Apache-2.0 + +import io +import os.path +import sys +import tempfile +import unittest + +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.hashes import SHA256 + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) + +from imgtool.keys import load, ECDSA256P1, ECDSAUsageError + +class EcKeyGeneration(unittest.TestCase): + + def setUp(self): + self.test_dir = tempfile.TemporaryDirectory() + + def tname(self, base): + return os.path.join(self.test_dir.name, base) + + def tearDown(self): + self.test_dir.cleanup() + + def test_keygen(self): + name1 = self.tname("keygen.pem") + k = ECDSA256P1.generate() + k.export_private(name1, b'secret') + + self.assertIsNone(load(name1)) + + k2 = load(name1, b'secret') + + pubname = self.tname('keygen-pub.pem') + k2.export_public(pubname) + pk2 = load(pubname) + + # We should be able to export the public key from the loaded + # public key, but not the private key. + pk2.export_public(self.tname('keygen-pub2.pem')) + self.assertRaises(ECDSAUsageError, + pk2.export_private, self.tname('keygen-priv2.pem')) + + def test_emit(self): + """Basic sanity check on the code emitters.""" + k = ECDSA256P1.generate() + + ccode = io.StringIO() + k.emit_c_public(ccode) + self.assertIn("ecdsa_pub_key", ccode.getvalue()) + self.assertIn("ecdsa_pub_key_len", ccode.getvalue()) + + rustcode = io.StringIO() + k.emit_rust_public(rustcode) + self.assertIn("ECDSA_PUB_KEY", rustcode.getvalue()) + + def test_emit_pub(self): + """Basic sanity check on the code emitters.""" + pubname = self.tname("public.pem") + k = ECDSA256P1.generate() + k.export_public(pubname) + + k2 = load(pubname) + + ccode = io.StringIO() + k2.emit_c_public(ccode) + self.assertIn("ecdsa_pub_key", ccode.getvalue()) + self.assertIn("ecdsa_pub_key_len", ccode.getvalue()) + + rustcode = io.StringIO() + k2.emit_rust_public(rustcode) + self.assertIn("ECDSA_PUB_KEY", rustcode.getvalue()) + + def test_sig(self): + k = ECDSA256P1.generate() + buf = b'This is the message' + sig = k.raw_sign(buf) + + # The code doesn't have any verification, so verify this + # manually. + k.key.public_key().verify( + signature=sig, + data=buf, + signature_algorithm=ec.ECDSA(SHA256())) + + # Modify the message to make sure the signature fails. + self.assertRaises(InvalidSignature, + k.key.public_key().verify, + signature=sig, + data=b'This is thE message', + signature_algorithm=ec.ECDSA(SHA256())) + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/mcuboot/imgtool/imgtool/keys/ed25519.py b/scripts/mcuboot/imgtool/imgtool/keys/ed25519.py new file mode 100644 index 0000000..b6367e7 --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/ed25519.py @@ -0,0 +1,107 @@ +""" +ED25519 key management +""" + +# SPDX-License-Identifier: Apache-2.0 + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ed25519 + +from .general import KeyClass + + +class Ed25519UsageError(Exception): + pass + + +class Ed25519Public(KeyClass): + def __init__(self, key): + self.key = key + + def shortname(self): + return "ed25519" + + def _unsupported(self, name): + raise Ed25519UsageError("Operation {} requires private key".format(name)) + + def _get_public(self): + return self.key + + def get_public_bytes(self): + # The key is embedded into MBUboot in "SubjectPublicKeyInfo" format + return self._get_public().public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + + def get_private_bytes(self, minimal): + self._unsupported('get_private_bytes') + + def export_private(self, path, passwd=None): + self._unsupported('export_private') + + def export_public(self, path): + """Write the public key to the given file.""" + pem = self._get_public().public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + with open(path, 'wb') as f: + f.write(pem) + + def sig_type(self): + return "ED25519" + + def sig_tlv(self): + return "ED25519" + + def sig_len(self): + return 64 + + +class Ed25519(Ed25519Public): + """ + Wrapper around an ED25519 private key. + """ + + def __init__(self, key): + """key should be an instance of EllipticCurvePrivateKey""" + self.key = key + + @staticmethod + def generate(): + pk = ed25519.Ed25519PrivateKey.generate() + return Ed25519(pk) + + def _get_public(self): + return self.key.public_key() + + def get_private_bytes(self, minimal): + raise Ed25519UsageError("Operation not supported with {} keys".format( + self.shortname())) + + def export_private(self, path, passwd=None): + """ + Write the private key to the given file, protecting it with the + optional password. + """ + if passwd is None: + enc = serialization.NoEncryption() + else: + enc = serialization.BestAvailableEncryption(passwd) + pem = self.key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=enc) + with open(path, 'wb') as f: + f.write(pem) + + def sign_digest(self, digest): + """Return the actual signature""" + return self.key.sign(data=digest) + + def verify_digest(self, signature, digest): + """Verify that signature is valid for given digest""" + k = self.key + if isinstance(self.key, ed25519.Ed25519PrivateKey): + k = self.key.public_key() + return k.verify(signature=signature, data=digest) diff --git a/scripts/mcuboot/imgtool/imgtool/keys/ed25519_test.py b/scripts/mcuboot/imgtool/imgtool/keys/ed25519_test.py new file mode 100644 index 0000000..ef6ebd0 --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/ed25519_test.py @@ -0,0 +1,105 @@ +""" +Tests for ECDSA keys +""" + +# SPDX-License-Identifier: Apache-2.0 + +import hashlib +import io +import os.path +import sys +import tempfile +import unittest + +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.primitives.asymmetric import ed25519 + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) + +from imgtool.keys import load, Ed25519, Ed25519UsageError + + +class Ed25519KeyGeneration(unittest.TestCase): + + def setUp(self): + self.test_dir = tempfile.TemporaryDirectory() + + def tname(self, base): + return os.path.join(self.test_dir.name, base) + + def tearDown(self): + self.test_dir.cleanup() + + def test_keygen(self): + name1 = self.tname("keygen.pem") + k = Ed25519.generate() + k.export_private(name1, b'secret') + + self.assertIsNone(load(name1)) + + k2 = load(name1, b'secret') + + pubname = self.tname('keygen-pub.pem') + k2.export_public(pubname) + pk2 = load(pubname) + + # We should be able to export the public key from the loaded + # public key, but not the private key. + pk2.export_public(self.tname('keygen-pub2.pem')) + self.assertRaises(Ed25519UsageError, + pk2.export_private, self.tname('keygen-priv2.pem')) + + def test_emit(self): + """Basic sanity check on the code emitters.""" + k = Ed25519.generate() + + ccode = io.StringIO() + k.emit_c_public(ccode) + self.assertIn("ed25519_pub_key", ccode.getvalue()) + self.assertIn("ed25519_pub_key_len", ccode.getvalue()) + + rustcode = io.StringIO() + k.emit_rust_public(rustcode) + self.assertIn("ED25519_PUB_KEY", rustcode.getvalue()) + + def test_emit_pub(self): + """Basic sanity check on the code emitters.""" + pubname = self.tname("public.pem") + k = Ed25519.generate() + k.export_public(pubname) + + k2 = load(pubname) + + ccode = io.StringIO() + k2.emit_c_public(ccode) + self.assertIn("ed25519_pub_key", ccode.getvalue()) + self.assertIn("ed25519_pub_key_len", ccode.getvalue()) + + rustcode = io.StringIO() + k2.emit_rust_public(rustcode) + self.assertIn("ED25519_PUB_KEY", rustcode.getvalue()) + + def test_sig(self): + k = Ed25519.generate() + buf = b'This is the message' + sha = hashlib.sha256() + sha.update(buf) + digest = sha.digest() + sig = k.sign_digest(digest) + + # The code doesn't have any verification, so verify this + # manually. + k.key.public_key().verify(signature=sig, data=digest) + + # Modify the message to make sure the signature fails. + sha = hashlib.sha256() + sha.update(b'This is thE message') + new_digest = sha.digest() + self.assertRaises(InvalidSignature, + k.key.public_key().verify, + signature=sig, + data=new_digest) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/mcuboot/imgtool/imgtool/keys/general.py b/scripts/mcuboot/imgtool/imgtool/keys/general.py new file mode 100644 index 0000000..8e3c65b --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/general.py @@ -0,0 +1,47 @@ +"""General key class.""" + +# SPDX-License-Identifier: Apache-2.0 + +import sys + +AUTOGEN_MESSAGE = "/* Autogenerated by imgtool.py, do not edit. */" + +class KeyClass(object): + def _emit(self, header, trailer, encoded_bytes, indent, file=sys.stdout, len_format=None): + print(AUTOGEN_MESSAGE, file=file) + print(header, end='', file=file) + for count, b in enumerate(encoded_bytes): + if count % 8 == 0: + print("\n" + indent, end='', file=file) + else: + print(" ", end='', file=file) + print("0x{:02x},".format(b), end='', file=file) + print("\n" + trailer, file=file) + if len_format is not None: + print(len_format.format(len(encoded_bytes)), file=file) + + def emit_c_public(self, file=sys.stdout): + self._emit( + header="const unsigned char {}_pub_key[] = {{".format(self.shortname()), + trailer="};", + encoded_bytes=self.get_public_bytes(), + indent=" ", + len_format="const unsigned int {}_pub_key_len = {{}};".format(self.shortname()), + file=file) + + def emit_rust_public(self, file=sys.stdout): + self._emit( + header="static {}_PUB_KEY: &[u8] = &[".format(self.shortname().upper()), + trailer="];", + encoded_bytes=self.get_public_bytes(), + indent=" ", + file=file) + + def emit_private(self, minimal, file=sys.stdout): + self._emit( + header="const unsigned char enc_priv_key[] = {", + trailer="};", + encoded_bytes=self.get_private_bytes(minimal), + indent=" ", + len_format="const unsigned int enc_priv_key_len = {};", + file=file) diff --git a/scripts/mcuboot/imgtool/imgtool/keys/rsa.py b/scripts/mcuboot/imgtool/imgtool/keys/rsa.py new file mode 100644 index 0000000..d8543ed --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/rsa.py @@ -0,0 +1,165 @@ +""" +RSA Key management +""" + +# SPDX-License-Identifier: Apache-2.0 + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.asymmetric.padding import PSS, MGF1 +from cryptography.hazmat.primitives.hashes import SHA256 + +from .general import KeyClass + + +# Sizes that bootutil will recognize +RSA_KEY_SIZES = [2048, 3072] + + +class RSAUsageError(Exception): + pass + + +class RSAPublic(KeyClass): + """The public key can only do a few operations""" + def __init__(self, key): + self.key = key + + def key_size(self): + return self.key.key_size + + def shortname(self): + return "rsa" + + def _unsupported(self, name): + raise RSAUsageError("Operation {} requires private key".format(name)) + + def _get_public(self): + return self.key + + def get_public_bytes(self): + # The key embedded into MCUboot is in PKCS1 format. + return self._get_public().public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.PKCS1) + + def get_private_bytes(self, minimal): + self._unsupported('get_private_bytes') + + def export_private(self, path, passwd=None): + self._unsupported('export_private') + + def export_public(self, path): + """Write the public key to the given file.""" + pem = self._get_public().public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + with open(path, 'wb') as f: + f.write(pem) + + def sig_type(self): + return "PKCS1_PSS_RSA{}_SHA256".format(self.key_size()) + + def sig_tlv(self): + return"RSA{}".format(self.key_size()) + + def sig_len(self): + return self.key_size() / 8 + + def verify(self, signature, payload): + k = self.key + if isinstance(self.key, rsa.RSAPrivateKey): + k = self.key.public_key() + return k.verify(signature=signature, data=payload, + padding=PSS(mgf=MGF1(SHA256()), salt_length=32), + algorithm=SHA256()) + + +class RSA(RSAPublic): + """ + Wrapper around an RSA key, with imgtool support. + """ + + def __init__(self, key): + """The key should be a private key from cryptography""" + self.key = key + + @staticmethod + def generate(key_size=2048): + if key_size not in RSA_KEY_SIZES: + raise RSAUsageError("Key size {} is not supported by MCUboot" + .format(key_size)) + pk = rsa.generate_private_key( + public_exponent=65537, + key_size=key_size, + backend=default_backend()) + return RSA(pk) + + def _get_public(self): + return self.key.public_key() + + def _build_minimal_rsa_privkey(self, der): + ''' + Builds a new DER that only includes N/E/D/P/Q RSA parameters; + standard DER private bytes provided by OpenSSL also includes + CRT params (DP/DQ/QP) which can be removed. + ''' + OFFSET_N = 7 # N is always located at this offset + b = bytearray(der) + off = OFFSET_N + if b[off + 1] != 0x82: + raise RSAUsageError("Error parsing N while minimizing") + len_N = (b[off + 2] << 8) + b[off + 3] + 4 + off += len_N + if b[off + 1] != 0x03: + raise RSAUsageError("Error parsing E while minimizing") + len_E = b[off + 2] + 4 + off += len_E + if b[off + 1] != 0x82: + raise RSAUsageError("Error parsing D while minimizing") + len_D = (b[off + 2] << 8) + b[off + 3] + 4 + off += len_D + if b[off + 1] != 0x81: + raise RSAUsageError("Error parsing P while minimizing") + len_P = b[off + 2] + 3 + off += len_P + if b[off + 1] != 0x81: + raise RSAUsageError("Error parsing Q while minimizing") + len_Q = b[off + 2] + 3 + off += len_Q + # adjust DER size for removed elements + b[2] = (off - 4) >> 8 + b[3] = (off - 4) & 0xff + return b[:off] + + def get_private_bytes(self, minimal): + priv = self.key.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption()) + if minimal: + priv = self._build_minimal_rsa_privkey(priv) + return priv + + def export_private(self, path, passwd=None): + """Write the private key to the given file, protecting it with the + optional password.""" + if passwd is None: + enc = serialization.NoEncryption() + else: + enc = serialization.BestAvailableEncryption(passwd) + pem = self.key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=enc) + with open(path, 'wb') as f: + f.write(pem) + + def sign(self, payload): + # The verification code only allows the salt length to be the + # same as the hash length, 32. + return self.key.sign( + data=payload, + padding=PSS(mgf=MGF1(SHA256()), salt_length=32), + algorithm=SHA256()) diff --git a/scripts/mcuboot/imgtool/imgtool/keys/rsa_test.py b/scripts/mcuboot/imgtool/imgtool/keys/rsa_test.py new file mode 100644 index 0000000..4b2106a --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/rsa_test.py @@ -0,0 +1,117 @@ +""" +Tests for RSA keys +""" + +# SPDX-License-Identifier: Apache-2.0 + +import io +import os +import sys +import tempfile +import unittest + +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.primitives.asymmetric.padding import PSS, MGF1 +from cryptography.hazmat.primitives.hashes import SHA256 + +# Setup sys path so 'imgtool' is in it. +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), + '../..'))) + +from imgtool.keys import load, RSA, RSAUsageError +from imgtool.keys.rsa import RSA_KEY_SIZES + + +class KeyGeneration(unittest.TestCase): + + def setUp(self): + self.test_dir = tempfile.TemporaryDirectory() + + def tname(self, base): + return os.path.join(self.test_dir.name, base) + + def tearDown(self): + self.test_dir.cleanup() + + def test_keygen(self): + # Try generating a RSA key with non-supported size + with self.assertRaises(RSAUsageError): + RSA.generate(key_size=1024) + + for key_size in RSA_KEY_SIZES: + name1 = self.tname("keygen.pem") + k = RSA.generate(key_size=key_size) + k.export_private(name1, b'secret') + + # Try loading the key without a password. + self.assertIsNone(load(name1)) + + k2 = load(name1, b'secret') + + pubname = self.tname('keygen-pub.pem') + k2.export_public(pubname) + pk2 = load(pubname) + + # We should be able to export the public key from the loaded + # public key, but not the private key. + pk2.export_public(self.tname('keygen-pub2.pem')) + self.assertRaises(RSAUsageError, pk2.export_private, + self.tname('keygen-priv2.pem')) + + def test_emit(self): + """Basic sanity check on the code emitters.""" + for key_size in RSA_KEY_SIZES: + k = RSA.generate(key_size=key_size) + + ccode = io.StringIO() + k.emit_c_public(ccode) + self.assertIn("rsa_pub_key", ccode.getvalue()) + self.assertIn("rsa_pub_key_len", ccode.getvalue()) + + rustcode = io.StringIO() + k.emit_rust_public(rustcode) + self.assertIn("RSA_PUB_KEY", rustcode.getvalue()) + + def test_emit_pub(self): + """Basic sanity check on the code emitters, from public key.""" + pubname = self.tname("public.pem") + for key_size in RSA_KEY_SIZES: + k = RSA.generate(key_size=key_size) + k.export_public(pubname) + + k2 = load(pubname) + + ccode = io.StringIO() + k2.emit_c_public(ccode) + self.assertIn("rsa_pub_key", ccode.getvalue()) + self.assertIn("rsa_pub_key_len", ccode.getvalue()) + + rustcode = io.StringIO() + k2.emit_rust_public(rustcode) + self.assertIn("RSA_PUB_KEY", rustcode.getvalue()) + + def test_sig(self): + for key_size in RSA_KEY_SIZES: + k = RSA.generate(key_size=key_size) + buf = b'This is the message' + sig = k.sign(buf) + + # The code doesn't have any verification, so verify this + # manually. + k.key.public_key().verify( + signature=sig, + data=buf, + padding=PSS(mgf=MGF1(SHA256()), salt_length=32), + algorithm=SHA256()) + + # Modify the message to make sure the signature fails. + self.assertRaises(InvalidSignature, + k.key.public_key().verify, + signature=sig, + data=b'This is thE message', + padding=PSS(mgf=MGF1(SHA256()), salt_length=32), + algorithm=SHA256()) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/mcuboot/imgtool/imgtool/keys/x25519.py b/scripts/mcuboot/imgtool/imgtool/keys/x25519.py new file mode 100644 index 0000000..a31cb3f --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/keys/x25519.py @@ -0,0 +1,109 @@ +""" +X25519 key management +""" + +# SPDX-License-Identifier: Apache-2.0 + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import x25519 + +from .general import KeyClass + + +class X25519UsageError(Exception): + pass + + +class X25519Public(KeyClass): + def __init__(self, key): + self.key = key + + def shortname(self): + return "x25519" + + def _unsupported(self, name): + raise X25519UsageError("Operation {} requires private key".format(name)) + + def _get_public(self): + return self.key + + def get_public_bytes(self): + # The key is embedded into MBUboot in "SubjectPublicKeyInfo" format + return self._get_public().public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + + def get_private_bytes(self, minimal): + self._unsupported('get_private_bytes') + + def export_private(self, path, passwd=None): + self._unsupported('export_private') + + def export_public(self, path): + """Write the public key to the given file.""" + pem = self._get_public().public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + with open(path, 'wb') as f: + f.write(pem) + + def sig_type(self): + return "X25519" + + def sig_tlv(self): + return "X25519" + + def sig_len(self): + return 32 + + +class X25519(X25519Public): + """ + Wrapper around an X25519 private key. + """ + + def __init__(self, key): + """key should be an instance of EllipticCurvePrivateKey""" + self.key = key + + @staticmethod + def generate(): + pk = x25519.X25519PrivateKey.generate() + return X25519(pk) + + def _get_public(self): + return self.key.public_key() + + def get_private_bytes(self, minimal): + return self.key.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption()) + + def export_private(self, path, passwd=None): + """ + Write the private key to the given file, protecting it with the + optional password. + """ + if passwd is None: + enc = serialization.NoEncryption() + else: + enc = serialization.BestAvailableEncryption(passwd) + pem = self.key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=enc) + with open(path, 'wb') as f: + f.write(pem) + + def sign_digest(self, digest): + """Return the actual signature""" + return self.key.sign(data=digest) + + def verify_digest(self, signature, digest): + """Verify that signature is valid for given digest""" + k = self.key + if isinstance(self.key, x25519.X25519PrivateKey): + k = self.key.public_key() + return k.verify(signature=signature, data=digest) diff --git a/scripts/mcuboot/imgtool/imgtool/main.py b/scripts/mcuboot/imgtool/imgtool/main.py new file mode 100644 index 0000000..941c096 --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/main.py @@ -0,0 +1,398 @@ +#! /usr/bin/env python3 +# +# Copyright 2017-2020 Linaro Limited +# Copyright 2019-2021 Arm Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +import click +import getpass +import imgtool.keys as keys +import sys +from imgtool import image, imgtool_version +from imgtool.version import decode_version +from .keys import ( + RSAUsageError, ECDSAUsageError, Ed25519UsageError, X25519UsageError) + +MIN_PYTHON_VERSION = (3, 6) +if sys.version_info < MIN_PYTHON_VERSION: + sys.exit("Python %s.%s or newer is required by imgtool." + % MIN_PYTHON_VERSION) + + +def gen_rsa2048(keyfile, passwd): + keys.RSA.generate().export_private(path=keyfile, passwd=passwd) + + +def gen_rsa3072(keyfile, passwd): + keys.RSA.generate(key_size=3072).export_private(path=keyfile, + passwd=passwd) + + +def gen_ecdsa_p256(keyfile, passwd): + keys.ECDSA256P1.generate().export_private(keyfile, passwd=passwd) + + +def gen_ecdsa_p224(keyfile, passwd): + print("TODO: p-224 not yet implemented") + + +def gen_ed25519(keyfile, passwd): + keys.Ed25519.generate().export_private(path=keyfile, passwd=passwd) + + +def gen_x25519(keyfile, passwd): + keys.X25519.generate().export_private(path=keyfile, passwd=passwd) + + +valid_langs = ['c', 'rust'] +keygens = { + 'rsa-2048': gen_rsa2048, + 'rsa-3072': gen_rsa3072, + 'ecdsa-p256': gen_ecdsa_p256, + 'ecdsa-p224': gen_ecdsa_p224, + 'ed25519': gen_ed25519, + 'x25519': gen_x25519, +} + + +def load_key(keyfile): + # TODO: better handling of invalid pass-phrase + key = keys.load(keyfile) + if key is not None: + return key + passwd = getpass.getpass("Enter key passphrase: ").encode('utf-8') + return keys.load(keyfile, passwd) + + +def get_password(): + while True: + passwd = getpass.getpass("Enter key passphrase: ") + passwd2 = getpass.getpass("Reenter passphrase: ") + if passwd == passwd2: + break + print("Passwords do not match, try again") + + # Password must be bytes, always use UTF-8 for consistent + # encoding. + return passwd.encode('utf-8') + + +@click.option('-p', '--password', is_flag=True, + help='Prompt for password to protect key') +@click.option('-t', '--type', metavar='type', required=True, + type=click.Choice(keygens.keys()), prompt=True, + help='{}'.format('One of: {}'.format(', '.join(keygens.keys())))) +@click.option('-k', '--key', metavar='filename', required=True) +@click.command(help='Generate pub/private keypair') +def keygen(type, key, password): + password = get_password() if password else None + keygens[type](key, password) + + +@click.option('-l', '--lang', metavar='lang', default=valid_langs[0], + type=click.Choice(valid_langs)) +@click.option('-k', '--key', metavar='filename', required=True) +@click.command(help='Dump public key from keypair') +def getpub(key, lang): + key = load_key(key) + if key is None: + print("Invalid passphrase") + elif lang == 'c': + key.emit_c_public() + elif lang == 'rust': + key.emit_rust_public() + else: + raise ValueError("BUG: should never get here!") + + +@click.option('--minimal', default=False, is_flag=True, + help='Reduce the size of the dumped private key to include only ' + 'the minimum amount of data required to decrypt. This ' + 'might require changes to the build config. Check the docs!' + ) +@click.option('-k', '--key', metavar='filename', required=True) +@click.command(help='Dump private key from keypair') +def getpriv(key, minimal): + key = load_key(key) + if key is None: + print("Invalid passphrase") + try: + key.emit_private(minimal) + except (RSAUsageError, ECDSAUsageError, Ed25519UsageError, + X25519UsageError) as e: + raise click.UsageError(e) + + +@click.argument('imgfile') +@click.option('-k', '--key', metavar='filename') +@click.command(help="Check that signed image can be verified by given key") +def verify(key, imgfile): + key = load_key(key) if key else None + ret, version, digest = image.Image.verify(imgfile, key) + if ret == image.VerifyResult.OK: + print("Image was correctly validated") + print("Image version: {}.{}.{}+{}".format(*version)) + print("Image digest: {}".format(digest.hex())) + return + elif ret == image.VerifyResult.INVALID_MAGIC: + print("Invalid image magic; is this an MCUboot image?") + elif ret == image.VerifyResult.INVALID_TLV_INFO_MAGIC: + print("Invalid TLV info magic; is this an MCUboot image?") + elif ret == image.VerifyResult.INVALID_HASH: + print("Image has an invalid sha256 digest") + elif ret == image.VerifyResult.INVALID_SIGNATURE: + print("No signature found for the given key") + else: + print("Unknown return code: {}".format(ret)) + sys.exit(1) + + +def validate_version(ctx, param, value): + try: + decode_version(value) + return value + except ValueError as e: + raise click.BadParameter("{}".format(e)) + + +def validate_security_counter(ctx, param, value): + if value is not None: + if value.lower() == 'auto': + return 'auto' + else: + try: + return int(value, 0) + except ValueError: + raise click.BadParameter( + "{} is not a valid integer. Please use code literals " + "prefixed with 0b/0B, 0o/0O, or 0x/0X as necessary." + .format(value)) + + +def validate_header_size(ctx, param, value): + min_hdr_size = image.IMAGE_HEADER_SIZE + if value < min_hdr_size: + raise click.BadParameter( + "Minimum value for -H/--header-size is {}".format(min_hdr_size)) + return value + + +def get_dependencies(ctx, param, value): + if value is not None: + versions = [] + images = re.findall(r"\((\d+)", value) + if len(images) == 0: + raise click.BadParameter( + "Image dependency format is invalid: {}".format(value)) + raw_versions = re.findall(r",\s*([0-9.+]+)\)", value) + if len(images) != len(raw_versions): + raise click.BadParameter( + '''There's a mismatch between the number of dependency images + and versions in: {}'''.format(value)) + for raw_version in raw_versions: + try: + versions.append(decode_version(raw_version)) + except ValueError as e: + raise click.BadParameter("{}".format(e)) + dependencies = dict() + dependencies[image.DEP_IMAGES_KEY] = images + dependencies[image.DEP_VERSIONS_KEY] = versions + return dependencies + + +class BasedIntParamType(click.ParamType): + name = 'integer' + + def convert(self, value, param, ctx): + try: + return int(value, 0) + except ValueError: + self.fail('%s is not a valid integer. Please use code literals ' + 'prefixed with 0b/0B, 0o/0O, or 0x/0X as necessary.' + % value, param, ctx) + + +@click.argument('outfile') +@click.argument('infile') +@click.option('--custom-tlv', required=False, nargs=2, default=[], + multiple=True, metavar='[tag] [value]', + help='Custom TLV that will be placed into protected area. ' + 'Add "0x" prefix if the value should be interpreted as an ' + 'integer, otherwise it will be interpreted as a string. ' + 'Specify the option multiple times to add multiple TLVs.') +@click.option('-R', '--erased-val', type=click.Choice(['0', '0xff']), + required=False, + help='The value that is read back from erased flash.') +@click.option('-x', '--hex-addr', type=BasedIntParamType(), required=False, + help='Adjust address in hex output file.') +@click.option('-L', '--load-addr', type=BasedIntParamType(), required=False, + help='Load address for image when it should run from RAM.') +@click.option('-F', '--rom-fixed', type=BasedIntParamType(), required=False, + help='Set flash address the image is built for.') +@click.option('--save-enctlv', default=False, is_flag=True, + help='When upgrading, save encrypted key TLVs instead of plain ' + 'keys. Enable when BOOT_SWAP_SAVE_ENCTLV config option ' + 'was set.') +@click.option('-E', '--encrypt', metavar='filename', + help='Encrypt image using the provided public key. ' + '(Not supported in direct-xip or ram-load mode.)') +@click.option('--encrypt-keylen', default='128', + type=click.Choice(['128','256']), + help='When encrypting the image using AES, select a 128 bit or ' + '256 bit key len.') +@click.option('-e', '--endian', type=click.Choice(['little', 'big']), + default='little', help="Select little or big endian") +@click.option('--overwrite-only', default=False, is_flag=True, + help='Use overwrite-only instead of swap upgrades') +@click.option('--boot-record', metavar='sw_type', help='Create CBOR encoded ' + 'boot record TLV. The sw_type represents the role of the ' + 'software component (e.g. CoFM for coprocessor firmware). ' + '[max. 12 characters]') +@click.option('-M', '--max-sectors', type=int, + help='When padding allow for this amount of sectors (defaults ' + 'to 128)') +@click.option('--confirm', default=False, is_flag=True, + help='When padding the image, mark it as confirmed (implies ' + '--pad)') +@click.option('--pad', default=False, is_flag=True, + help='Pad image to --slot-size bytes, adding trailer magic') +@click.option('-S', '--slot-size', type=BasedIntParamType(), required=True, + help='Size of the slot. If the slots have different sizes, use ' + 'the size of the secondary slot.') +@click.option('--pad-header', default=False, is_flag=True, + help='Add --header-size zeroed bytes at the beginning of the ' + 'image') +@click.option('-H', '--header-size', callback=validate_header_size, + type=BasedIntParamType(), required=True) +@click.option('--pad-sig', default=False, is_flag=True, + help='Add 0-2 bytes of padding to ECDSA signature ' + '(for mcuboot <1.5)') +@click.option('-d', '--dependencies', callback=get_dependencies, + required=False, help='''Add dependence on another image, format: + "(,), ... "''') +@click.option('-s', '--security-counter', callback=validate_security_counter, + help='Specify the value of security counter. Use the `auto` ' + 'keyword to automatically generate it from the image version.') +@click.option('-v', '--version', callback=validate_version, required=True) +@click.option('--align', type=click.Choice(['1', '2', '4', '8']), + required=True) +@click.option('--public-key-format', type=click.Choice(['hash', 'full']), + default='hash', help='In what format to add the public key to ' + 'the image manifest: full key or hash of the key.') +@click.option('-k', '--key', metavar='filename') +@click.option('--use-random-iv', default=False, is_flag=True, + help='Use random Salt and IV (initial vectors) for the image ' + 'encrypting scheme') +@click.command(help='''Create a signed or unsigned image\n + INFILE and OUTFILE are parsed as Intel HEX if the params have + .hex extension, otherwise binary format is used''') +def sign(key, public_key_format, align, version, pad_sig, header_size, + pad_header, slot_size, pad, confirm, max_sectors, overwrite_only, + endian, encrypt_keylen, encrypt, infile, outfile, dependencies, + load_addr, hex_addr, erased_val, save_enctlv, security_counter, + boot_record, custom_tlv, rom_fixed, use_random_iv): + + if confirm: + # Confirmed but non-padded images don't make much sense, because + # otherwise there's no trailer area for writing the confirmed status. + pad = True + img = image.Image(version=decode_version(version), header_size=header_size, + pad_header=pad_header, pad=pad, confirm=confirm, + align=int(align), slot_size=slot_size, + max_sectors=max_sectors, overwrite_only=overwrite_only, + endian=endian, load_addr=load_addr, rom_fixed=rom_fixed, + erased_val=erased_val, save_enctlv=save_enctlv, + security_counter=security_counter) + img.load(infile) + key = load_key(key) if key else None + enckey = load_key(encrypt) if encrypt else None + if enckey and key: + if ((isinstance(key, keys.ECDSA256P1) and + not isinstance(enckey, keys.ECDSA256P1Public)) + or (isinstance(key, keys.RSA) and + not isinstance(enckey, keys.RSAPublic))): + # FIXME + raise click.UsageError("Signing and encryption must use the same " + "type of key") + + if pad_sig and hasattr(key, 'pad_sig'): + key.pad_sig = True + + # Get list of custom protected TLVs from the command-line + custom_tlvs = {} + for tlv in custom_tlv: + tag = int(tlv[0], 0) + if tag in custom_tlvs: + raise click.UsageError('Custom TLV %s already exists.' % hex(tag)) + if tag in image.TLV_VALUES.values(): + raise click.UsageError( + 'Custom TLV %s conflicts with predefined TLV.' % hex(tag)) + + value = tlv[1] + if value.startswith('0x'): + if len(value[2:]) % 2: + raise click.UsageError('Custom TLV length is odd.') + custom_tlvs[tag] = bytes.fromhex(value[2:]) + else: + custom_tlvs[tag] = value.encode('utf-8') + + img.create(key, public_key_format, enckey, dependencies, boot_record, + custom_tlvs, int(encrypt_keylen), use_random_iv=use_random_iv) + img.save(outfile, hex_addr) + + +class AliasesGroup(click.Group): + + _aliases = { + "create": "sign", + } + + def list_commands(self, ctx): + cmds = [k for k in self.commands] + aliases = [k for k in self._aliases] + return sorted(cmds + aliases) + + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + if cmd_name in self._aliases: + return click.Group.get_command(self, ctx, self._aliases[cmd_name]) + return None + + +@click.command(help='Print imgtool version information') +def version(): + print(imgtool_version) + + +@click.command(cls=AliasesGroup, + context_settings=dict(help_option_names=['-h', '--help'])) +def imgtool(): + pass + + +imgtool.add_command(keygen) +imgtool.add_command(getpub) +imgtool.add_command(getpriv) +imgtool.add_command(verify) +imgtool.add_command(sign) +imgtool.add_command(version) + + +if __name__ == '__main__': + imgtool() diff --git a/scripts/mcuboot/imgtool/imgtool/version.py b/scripts/mcuboot/imgtool/imgtool/version.py new file mode 100644 index 0000000..6e38f44 --- /dev/null +++ b/scripts/mcuboot/imgtool/imgtool/version.py @@ -0,0 +1,55 @@ +# Copyright 2017 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Semi Semantic Versioning + +Implements a subset of semantic versioning that is supportable by the image +header. +""" + +from collections import namedtuple +import re + +SemiSemVersion = namedtuple('SemiSemVersion', ['major', 'minor', 'revision', + 'build']) + +version_re = re.compile( + r"""^([1-9]\d*|0)(\.([1-9]\d*|0)(\.([1-9]\d*|0)(\+([1-9]\d*|0))?)?)?$""") + + +def decode_version(text): + """Decode the version string, which should be of the form maj.min.rev+build + """ + m = version_re.match(text) + if m: + result = SemiSemVersion( + int(m.group(1)) if m.group(1) else 0, + int(m.group(3)) if m.group(3) else 0, + int(m.group(5)) if m.group(5) else 0, + int(m.group(7)) if m.group(7) else 0) + return result + else: + msg = "Invalid version number, should be maj.min.rev+build with later " + msg += "parts optional" + raise ValueError(msg) + + +if __name__ == '__main__': + print(decode_version("1.2")) + print(decode_version("1.0")) + print(decode_version("0.0.2+75")) + print(decode_version("0.0.0+00")) diff --git a/scripts/mcuboot/imgtool/jgdb.sh b/scripts/mcuboot/imgtool/jgdb.sh new file mode 100644 index 0000000..dc59020 --- /dev/null +++ b/scripts/mcuboot/imgtool/jgdb.sh @@ -0,0 +1,8 @@ +#! /bin/bash +# +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname $0)/../target.sh + +# Start the jlink gdb server +JLinkGDBServer -if swd -device $SOC -speed auto diff --git a/scripts/mcuboot/imgtool/jl.sh b/scripts/mcuboot/imgtool/jl.sh new file mode 100644 index 0000000..abc6dab --- /dev/null +++ b/scripts/mcuboot/imgtool/jl.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname $0)/../target.sh + +JLinkExe -speed auto -si SWD -device $SOC diff --git a/scripts/mcuboot/imgtool/mcubin.bt b/scripts/mcuboot/imgtool/mcubin.bt new file mode 100644 index 0000000..e2ec361 --- /dev/null +++ b/scripts/mcuboot/imgtool/mcubin.bt @@ -0,0 +1,135 @@ +// Copyright (C) 2019, Linaro Ltd +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file is a Binary Template file for the 010 Editor +// (http://www.sweetscape.com/010editor/) to allow it to show the +// structure of an MCUboot image. + +LittleEndian(); + +struct ENTRY { + uint32 id; + uint32 offset; + uint32 size; + uint32 pad; +}; + +// The simulator writes the partition table at the beginning of the +// image, so that we can tell where the partitions are. If you are +// trying to view an image captured from a device, you can either +// construct a synthetic partition table in the file, or change code +// described below to hardcode one. +struct PTABLE { + uchar pheader[8]; + if (ptable.pheader != "mcuboot\0") { + // NOTE: Put code here to hard code a partition table, and + // continue. + Warning("Invalid magic on ptable header"); + return -1; + } else { + uint32 count; + struct ENTRY entries[count]; + } +}; + +struct PTABLE ptable; + +struct IMAGE_VERSION { + uchar major; + uchar minor; + uint16 revision; + uint32 build_num; +}; + +struct IHDR { + uint32 magic ; + uint32 load_addr ; + uint16 hdr_size ; + uint16 protect_size ; + uint32 img_size ; + uint32 flags; + struct IMAGE_VERSION ver; + uint32 _pad1; +}; + +struct TLV_HDR { + uint16 magic; + uint16 tlv_tot; +}; + +struct TLV { + uchar type ; + uchar pad; + uint16 len; + + switch (type) { + case 0x01: // keyhash + uchar keyhash[len]; + break; + case 0x40: // dependency + if (len != 12) { + Warning("Invalid dependency size"); + return -1; + } + uchar image_id; + uchar pad1; + uint16 pad2; + struct IMAGE_VERSION version; + break; + default: + // Other, just consume the data. + uchar data[len]; + } +}; + +local int i; +local int epos; + +for (i = 0; i < ptable.count; i++) { + FSeek(ptable.entries[i].offset); + switch (ptable.entries[i].id) { + case 1: + case 2: + case 4: + case 5: + struct IMAGE { + struct IHDR ihdr; + + if (ihdr.magic == 0x96f3b83d) { + uchar payload[ihdr.img_size]; + + epos = FTell(); + struct TLV_HDR tlv_hdr; + + if (tlv_hdr.magic == 0x6907) { + epos += tlv_hdr.tlv_tot; + while (FTell() < epos) { + struct TLV tlv; + } + } + } + // uchar block[ptable.entries[i].size]; + } image; + break; + case 3: + struct SCRATCH { + uchar data[ptable.entries[i].size]; + } scratch; + break; + default: + break; + } +} diff --git a/scripts/mcuboot/imgtool/requirements.txt b/scripts/mcuboot/imgtool/requirements.txt new file mode 100644 index 0000000..9481e2c --- /dev/null +++ b/scripts/mcuboot/imgtool/requirements.txt @@ -0,0 +1,4 @@ +cryptography>=2.6 +intelhex +click +cbor>=1.0.0 diff --git a/scripts/mcuboot/imgtool/setup.py b/scripts/mcuboot/imgtool/setup.py new file mode 100644 index 0000000..a228ea3 --- /dev/null +++ b/scripts/mcuboot/imgtool/setup.py @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: Apache-2.0 + +import setuptools +from imgtool import imgtool_version + +setuptools.setup( + name="imgtool", + version=imgtool_version, + author="The MCUboot committers", + author_email="mcuboot@groups.io", + description=("MCUboot's image signing and key management"), + license="Apache Software License", + url="http://github.com/mcu-tools/mcuboot", + packages=setuptools.find_packages(), + python_requires='>=3.6', + install_requires=[ + 'cryptography>=2.4.2', + 'intelhex>=2.2.1', + 'click', + 'cbor>=1.0.0', + ], + entry_points={ + "console_scripts": ["imgtool=imgtool.main:imgtool"] + }, + classifiers=[ + "Programming Language :: Python :: 3", + "Development Status :: 4 - Beta", + "Topic :: Software Development :: Build Tools", + "License :: OSI Approved :: Apache Software License", + ], +) diff --git a/scripts/mcuboot/keys/cypress-test-ec-p256.pem b/scripts/mcuboot/keys/cypress-test-ec-p256.pem new file mode 100644 index 0000000..e1f8e15 --- /dev/null +++ b/scripts/mcuboot/keys/cypress-test-ec-p256.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQguR/Jq6LjMgp8DVtE +7pKguttNo6L239aEcijzGOr5C72hRANCAAT/NroNASdTGo6bS8r0+C+30YcG0WLV +chWs+99DnOr3SZoalv6/pCNIVrwFv3KkJsmsZUbNNmxeMPr+IlfGGPg0 +-----END PRIVATE KEY----- diff --git a/scripts/mcuboot/keys/cypress-test-ec-p256.pub b/scripts/mcuboot/keys/cypress-test-ec-p256.pub new file mode 100644 index 0000000..8174b5d --- /dev/null +++ b/scripts/mcuboot/keys/cypress-test-ec-p256.pub @@ -0,0 +1,16 @@ +/* Autogenerated by imgtool.py, do not edit. */ +const unsigned char ecdsa_pub_key[] = { + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0xff, 0x36, 0xba, 0x0d, 0x01, + 0x27, 0x53, 0x1a, 0x8e, 0x9b, 0x4b, 0xca, 0xf4, + 0xf8, 0x2f, 0xb7, 0xd1, 0x87, 0x06, 0xd1, 0x62, + 0xd5, 0x72, 0x15, 0xac, 0xfb, 0xdf, 0x43, 0x9c, + 0xea, 0xf7, 0x49, 0x9a, 0x1a, 0x96, 0xfe, 0xbf, + 0xa4, 0x23, 0x48, 0x56, 0xbc, 0x05, 0xbf, 0x72, + 0xa4, 0x26, 0xc9, 0xac, 0x65, 0x46, 0xcd, 0x36, + 0x6c, 0x5e, 0x30, 0xfa, 0xfe, 0x22, 0x57, 0xc6, + 0x18, 0xf8, 0x34, +}; +const unsigned int ecdsa_pub_key_len = 91; diff --git a/scripts/mcuboot/policy/policy_CM33_no_secure.json b/scripts/mcuboot/policy/policy_CM33_no_secure.json new file mode 100644 index 0000000..74d8263 --- /dev/null +++ b/scripts/mcuboot/policy/policy_CM33_no_secure.json @@ -0,0 +1,138 @@ +{ + "policy": { + "platform": "cyw20829", + "version": 2.0, + "type": "no_secure" + }, + "device_policy": + { + "debug": + { + "cpu": + { + "ap_cm33": { + "description": "Configures the CM33 debug access port availability in the NORMAL_NO_SECURE LCS", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "listen_window": { + "description": "Configures the listen window time to acquire the CM33 debug access port in the NORMAL_NO_SECURE LCS", + "applicable_conf": "100 ms, 20 ms, 2 ms, 0 ms", + "value": "100 ms" + }, + "cm33_dbg": + { + "description": "Configures the invasive debug of CM33 core", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "cm33_nid": + { + "description": "Configures the non-invasive debug of CM33 core", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "dead_ap_cm33": { + "description": "Configures the CM33 debug access port availability in the DEAD branch", + "applicable_conf": "Enable, Permanently Disable", + "value": "Enable" + }, + "dead_cm33_dbg": + { + "description": "Configures the invasive debug of CM33 core in the DEAD branch", + "applicable_conf": "Enable, Permanently Disable", + "value": "Enable" + }, + "dead_cm33_nid": + { + "description": "Configures the non-invasive debug of CM33 core in the DEAD branch", + "applicable_conf": "Enable, Permanently Disable", + "value": "Enable" + } + }, + "system": + { + "ap": { + "description": "Configures the System debug access port (DAP) availability in the NORMAL_NO_SECURE LCS", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "mpc/ppc": { + "description": "Indicates that the MPC/PPC on the system access port must be programmed and locked according to the settings in the next fields", + "applicable_conf": "Enable, Disable", + "value": "Disable" + }, + "sram": { + "description": "Configures what portion of SRAM macro 0 is accessible through the System debug access port in the NORMAL_NO_SECURE LCS. Only a portion of SRAM starting at the bottom of the area is exposed", + "applicable_conf": "Entire region, 7/8, 3/4, 1/2, 1/4, 1/8, 1/16, Nothing", + "value": "Entire region" + }, + "mmio": { + "description": "Configures what portion of the MMIO region is accessible through the System debug access port in the NORMAL_NO_SECURE LCS", + "applicable_conf": "All, Only IPC, No access", + "value": "All" + }, + "dead_ap": { + "description": "Configures the System debug access port (DAP) availability in the DEAD branch", + "applicable_conf": "Enable, Permanently Disable", + "value": "Enable" + }, + "dead_mpc/ppc": { + "description": "Indicates that the MPC/PPC on the system access port must be programmed and locked in the DEAD branch according to the next fields settings", + "applicable_conf": "Enable, Disable", + "value": "Disable" + }, + "dead_sram": { + "description": "Configures what portion of SRAM macro 0 is accessible through the System debug access port in the DEAD branch. Only a portion of SRAM starting at the bottom of the area is exposed", + "applicable_conf": "Entire region, 7/8, 3/4, 1/2, 1/4, 1/8, 1/16, Nothing", + "value": "Entire region" + }, + "dead_mmio": { + "description": "Configures what portion of the MMIO region is accessible through the system debug access port in the DEAD branch", + "applicable_conf": "All, Only IPC, No access", + "value": "All" + } + } + }, + "smif_config": + { + "smif_configuration": { + "description": "SMIF Configuration", + "applicable_conf": "SFDP 1.5 and above, QER_1, QER_2, QER_3, QER_4, QER_5, QER_6", + "value": "QER_1" + }, + "chip_select": { + "description": "Chip Select", + "applicable_conf": "CS0, CS1", + "value": "CS0" + }, + "data_width": { + "description": "Data Width", + "applicable_conf": "1X, 2X, 4X", + "value": "4X" + }, + "data_select": { + "description": "Data Select", + "applicable_conf": "SEL0, SEL1", + "value": "SEL0" + }, + "addressing_mode": { + "description": "Addressing Mode", + "applicable_conf": "3-byte or 4-byte", + "value": "3-byte" + } + }, + "flow_control": + { + "target_lcs": { + "description": "The device LCS after the device is reset after service application completes execution", + "applicable_conf": "NORMAL, NORMAL_NO_SECURE", + "value": "NORMAL_NO_SECURE" + }, + "program_oem_assets": { + "description": "Programs OEM assets (smif_config and debug) and makes them immutable (this can be done only once)", + "value": true + } + } + } +} diff --git a/scripts/mcuboot/policy/policy_CM33_secure.json b/scripts/mcuboot/policy/policy_CM33_secure.json new file mode 100644 index 0000000..9aa65bb --- /dev/null +++ b/scripts/mcuboot/policy/policy_CM33_secure.json @@ -0,0 +1,194 @@ +{ + "policy": { + "platform": "cyw20829", + "version": 2.1, + "type": "secure" + }, + "device_policy": + { + "debug": + { + "cpu": + { + "ap_cm33": { + "description": "Configures the CM33 debug access port availability in the SECURE LCS", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Disable" + }, + "listen_window": { + "description": "Configures the listen window time to acquire the CM33 debug access port in the SECURE LCS", + "applicable_conf": "100 ms, 20 ms, 2 ms, 0 ms", + "value": "100 ms" + }, + "cm33_dbg": + { + "description": "Configures the invasive debug of CM33 core", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "cm33_nid": + { + "description": "Configures the non-invasive debug of CM33 core", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "dead_ap_cm33": { + "description": "Configures the CM33 debug access port availability in the DEAD branch", + "applicable_conf": "Enable, Permanently Disable", + "value": "Permanently Disable" + }, + "dead_cm33_dbg": + { + "description": "Configures the invasive debug of CM33 core in the DEAD branch", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "dead_cm33_nid": + { + "description": "Configures the non-invasive debug of CM33 core in the DEAD branch", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + } + }, + "system": + { + "ap": { + "description": "Configures the System debug access port (DAP) availability in the SECURE LCS", + "applicable_conf": "Enable, Disable, Permanently Disable", + "value": "Enable" + }, + "mpc/ppc": { + "description": "Indicates that the MPC/PPC on the system access port must be programmed and locked according to the settings in the next fields", + "applicable_conf": "Enable, Disable", + "value": "Disable" + }, + "sram": { + "description": "Configures what portion of SRAM macro 0 is accessible through the System debug access port in the SECURE LCS. Only a portion of SRAM starting at the bottom of the area is exposed", + "applicable_conf": "Entire region, 7/8, 3/4, 1/2, 1/4, 1/8, 1/16, Nothing", + "value": "Entire region" + }, + "mmio": { + "description": "Configures what portion of the MMIO region is accessible through the System debug access port in the SECURE LCS", + "applicable_conf": "All, Only IPC, No access", + "value": "All" + }, + "dead_ap": { + "description": "Configures the System debug access port (DAP) availability in the DEAD branch", + "applicable_conf": "Enable, Permanently Disable", + "value": "Enable" + }, + "dead_mpc/ppc": { + "description": "Indicates that the MPC/PPC on the system access port must be programmed and locked in the DEAD branch according to the next fields settings", + "applicable_conf": "Enable, Disable", + "value": "Disable" + }, + "dead_sram": { + "description": "Configures what portion of SRAM macro 0 is accessible through the System debug access port in the DEAD branch. Only a portion of SRAM starting at the bottom of the area is exposed", + "applicable_conf": "Entire region, 7/8, 3/4, 1/2, 1/4, 1/8, 1/16, Nothing", + "value": "Entire region" + }, + "dead_mmio": { + "description": "Configures what portion of the MMIO region is accessible through the system debug access port in the DEAD branch", + "applicable_conf": "All, Only IPC, No access", + "value": "All" + } + } + }, + "smif_config": + { + "smif_configuration": { + "description": "SMIF Configuration", + "applicable_conf": "SFDP 1.5 and above, QER_1, QER_2, QER_3, QER_4, QER_5, QER_6", + "value": "QER_1" + }, + "chip_select": { + "description": "Chip Select", + "applicable_conf": "CS0, CS1", + "value": "CS0" + }, + "data_width": { + "description": "Data Width", + "applicable_conf": "1X, 2X, 4X", + "value": "4X" + }, + "data_select": { + "description": "Data Select", + "applicable_conf": "SEL0, SEL1", + "value": "SEL0" + }, + "addressing_mode": { + "description": "Addressing Mode", + "applicable_conf": "3-byte or 4-byte", + "value": "3-byte" + }, + "encryption": { + "description": "Enables SMIF encryption", + "value": false + } + }, + "reprovisioning": + { + "nv_counter": { + "description": "Anti-rollback counter. Each item of the 'value' array defines counter for each next application. Each 'bits_per_cnt' item defines number of bits for the next application counter (total bits number 32). IMPORTANT: 'bits_per_cnt' in the provisioning and reprovisioning policy files MUST BE the same", + "value": [0], + "bits_per_cnt": [32] + }, + "revoke_oem_pubkey_0": { + "description": "Revokes OEM public key 0. The OEM public key 1 is used for image verification (this can be done only once). This option is not applicable if SMIF encryption is enabled", + "value": false + } + }, + "flow_control": + { + "target_lcs": { + "description": "The device LCS after the device is reset after service application completes execution", + "applicable_conf": "NORMAL, SECURE", + "value": "SECURE" + }, + "program_oem_assets": { + "description": "Programs OEM assets (smif_config and debug) and makes them immutable (this can be done only once)", + "value": true + }, + "program_oem_key_0_hash": { + "description": "Programs the OEM key 0 hash and makes it immutable (this can be done only once)", + "value": true + }, + "program_oem_key_1_hash": { + "description": "Programs the OEM key 1 hash and makes it immutable (this can be done only once)", + "value": false + } + } + }, + "pre_build": + { + "keys": + { + "oem_pub_key_0": { + "description": "Path to the OEM public key 0", + "value": "../keys/pub_oem_0.pem" + }, + "oem_pub_key_1": { + "description": "Path to the OEM public key 1", + "value": "../keys/pub_oem_1.pem" + }, + "encrypt_key": { + "description": "Path to the AES-128 key for image encryption in external memory", + "value": "../keys/encrypt_key.bin" + } + } + }, + "post_build": + { + "keys": + { + "oem_priv_key_0": { + "description": "Path to the OEM private key 0", + "value": "../keys/priv_oem_0.pem" + }, + "oem_priv_key_1": { + "description": "Path to the OEM private key 1", + "value": "../keys/priv_oem_1.pem" + } + } + } +} diff --git a/scripts/mcuboot/sign_script.bash b/scripts/mcuboot/sign_script.bash new file mode 100755 index 0000000..008e248 --- /dev/null +++ b/scripts/mcuboot/sign_script.bash @@ -0,0 +1,295 @@ +#!/bin/bash +# +# This file is used by make to create the build commands to sign an OTA image +# +# Modify at your peril ! +# +# break immediately on errors +set -e + +# +# Arguments +# We have a lot +# +CY_OUTPUT_PATH=$1 +shift +CY_OUTPUT_NAME=$1 +shift +CY_PYTHON_PATH=$1 +shift +CY_ELF_TO_HEX=$1 +shift +CY_ELF_TO_HEX_OPTIONS=$1 +shift +CY_ELF_TO_HEX_FILE_ORDER=$1 +shift +MCUBOOT_SCRIPT_FILE_DIR=$1 +shift +IMGTOOL_SCRIPT_NAME=$1 +shift +IMGTOOL_COMMAND_ARG=$1 +shift +FLASH_ERASE_VALUE=$1 +shift +MCUBOOT_HEADER_SIZE=$1 +shift +MCUBOOT_MAX_IMG_SECTORS=$1 +shift +APP_BUILD_VERSION=$1 +shift +FLASH_AREA_IMG_1_PRIMARY_START=$1 +shift +FLASH_AREA_IMG_1_PRIMARY_SIZE=$1 +shift +CY_HEX_TO_BIN=$1 +shift +CY_SIGNING_KEY_ARG=$1 +shift + +# When we want to separate the WiFi and BT Firmware, we send more arguments +# POSTBUILD+=FW_DATBLOCK_SEPARATE_FROM_APPLICATION $(FW_DATA_BLOCK_BUILDER)\ +# $(FW_DATA_BLOCK_WIFI_FW_SOURCE) $(FW_DATA_BLOCK_CLM_BLOB_SOURCE) $(FW_DATA_BLOCK_BT_FW_SOURCE)\ +# $(FW_DATA_BLOCK_OUTPUT_FILE_NAME) $(CY_EXTERNAL_FLASH_ERASE_VALUE) $(CY_EXT_MCUBOOT_HEADER_SIZE)\ +# $(CY_BOOT_PRIMARY_1_IMAGE_2_START) $(CY_BOOT_PRIMARY_1_IMAGE_2_SIZE) + +CY_BUILD_SEPARATE_FW=$1 +if [ "$CY_BUILD_SEPARATE_FW" == "FW_DATBLOCK_SEPARATE_FROM_APPLICATION" ] +then + shift + FW_DATA_BLOCK_BUILDER=$1 + shift + FW_DATA_BLOCK_WIFI_FW_SOURCE=$1 + shift + FW_DATA_BLOCK_CLM_BLOB_SOURCE=$1 + shift + FW_DATA_BLOCK_BT_FW_SOURCE=$1 + shift + FW_DATA_BLOCK_OUTPUT_FILE_NAME=$1 + shift + CY_EXTERNAL_FLASH_ERASE_VALUE=$1 + shift + CY_EXT_MCUBOOT_HEADER_SIZE=$1 + shift + CY_BOOT_PRIMARY_1_IMAGE_2_START=$1 + shift + CY_BOOT_PRIMARY_1_IMAGE_2_SIZE=$1 + shift + MCUBOOT_MAX_FW_IMG_SECTORS=$1 + +FW_DATA_BLOCK_OUTPUT_FILE_WILD=$FW_DATA_BLOCK_OUTPUT_FILE_NAME.* +FW_DATA_BLOCK_OUTPUT_FILE_BIN=$FW_DATA_BLOCK_OUTPUT_FILE_NAME".bin" +FW_DATA_BLOCK_OUTPUT_FILE_UNSIGNED_HEX=$FW_DATA_BLOCK_OUTPUT_FILE_NAME".unsigned.hex" +FW_DATA_BLOCK_OUTPUT_FILE_HEX=$FW_DATA_BLOCK_OUTPUT_FILE_NAME".hex" + +echo "FW_DATA_BLOCK_BUILDER = $FW_DATA_BLOCK_BUILDER" +echo "FW_DATA_BLOCK_WIFI_FW_SOURCE = $FW_DATA_BLOCK_WIFI_FW_SOURCE" +echo "FW_DATA_BLOCK_CLM_BLOB_SOURCE = $FW_DATA_BLOCK_CLM_BLOB_SOURCE" +echo "FW_DATA_BLOCK_BT_FW_SOURCE = $FW_DATA_BLOCK_BT_FW_SOURCE" +echo "FW_DATA_BLOCK_OUTPUT_FILE_NAME = $FW_DATA_BLOCK_OUTPUT_FILE_NAME" +echo "CY_EXTERNAL_FLASH_ERASE_VALUE = $CY_EXTERNAL_FLASH_ERASE_VALUE" +echo "CY_BOOT_PRIMARY_1_IMAGE_2_START = $CY_BOOT_PRIMARY_1_IMAGE_2_START" +echo "CY_BOOT_PRIMARY_1_IMAGE_2_SIZE = $CY_BOOT_PRIMARY_1_IMAGE_2_SIZE" + +fi + + +# Export these values for python3 click module +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +CY_OUTPUT_BIN=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin +CY_OUTPUT_ELF=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.elf +CY_OUTPUT_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex +CY_OUTPUT_SIGNED_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.hex +CY_OUTPUT_FILE_WILD=$CY_OUTPUT_NAME.* +CY_OUTPUT_FILE_NAME_BIN=$CY_OUTPUT_NAME.bin +CY_OUTPUT_FILE_NAME_TAR=$CY_OUTPUT_NAME.tar +CY_COMPONENTS_JSON_NAME=components.json +# +# For elf -> hex conversion +# +if [ "$CY_ELF_TO_HEX_FILE_ORDER" == "elf_first" ] +then + CY_ELF_TO_HEX_FILE_1=$CY_OUTPUT_ELF + CY_ELF_TO_HEX_FILE_2=$CY_OUTPUT_HEX +else + CY_ELF_TO_HEX_FILE_1=$CY_OUTPUT_HEX + CY_ELF_TO_HEX_FILE_2=$CY_OUTPUT_ELF +fi + +# +# Leave here for debugging +#echo " CY_OUTPUT_NAME $CY_OUTPUT_NAME" +#echo " CY_OUTPUT_BIN $CY_OUTPUT_BIN" +#echo " CY_OUTPUT_ELF $CY_OUTPUT_ELF" +#echo " CY_OUTPUT_HEX $CY_OUTPUT_HEX" +#echo " CY_OUTPUT_SIGNED_HEX $CY_OUTPUT_SIGNED_HEX" +#echo " MCUBOOT_SCRIPT_FILE_DIR $MCUBOOT_SCRIPT_FILE_DIR" +#echo " IMGTOOL_SCRIPT_NAME $IMGTOOL_SCRIPT_NAME" +#echo " FLASH_ERASE_VALUE $FLASH_ERASE_VALUE" +#echo " MCUBOOT_HEADER_SIZE $MCUBOOT_HEADER_SIZE" +#echo " MCUBOOT_MAX_IMG_SECTORS $MCUBOOT_MAX_IMG_SECTORS" +#echo " APP_BUILD_VERSION $APP_BUILD_VERSION" +#echo " FLASH_AREA_IMG_1_PRIMARY_START $FLASH_AREA_IMG_1_PRIMARY_START" +#echo " FLASH_AREA_IMG_1_PRIMARY_SIZE $FLASH_AREA_IMG_1_PRIMARY_SIZE" +#echo " SIGNING_KEY_PATH $SIGNING_KEY_PATH" +# +# For FLASH_ERASE_VALUE +# If value is 0x00, we need to specify "-R 0" +# If value is 0xFF, we do not specify anything! +# +FLASH_ERASE_ARG= +if [ "$FLASH_ERASE_VALUE" == "0x00" ] +then +FLASH_ERASE_ARG="-R 0" +fi + +EXT_FLASH_ERASE_ARG= +if [ "$CY_EXTERNAL_FLASH_ERASE_VALUE" == "0x00" ] +then +EXT_FLASH_ERASE_ARG="-R 0" +fi + + +echo "" +echo "Create unsigned.hex" +# echo "$CY_ELF_TO_HEX $CY_ELF_TO_HEX_OPTIONS $CY_ELF_TO_HEX_FILE_1 $CY_ELF_TO_HEX_FILE_2" +"$CY_ELF_TO_HEX" $CY_ELF_TO_HEX_OPTIONS $CY_ELF_TO_HEX_FILE_1 $CY_ELF_TO_HEX_FILE_2 + +# If +if [[ "$IMGTOOL_COMMAND_ARG" != "do_not_sign" ]]; then + echo "imgtool $IMGTOOL_COMMAND_ARG signed .hex." + echo "$IMGTOOL_SCRIPT_NAME $IMGTOOL_COMMAND_ARG $FLASH_ERASE_ARG -e little --pad-header --align 8 -H $MCUBOOT_HEADER_SIZE -M $MCUBOOT_MAX_IMG_SECTORS -v $APP_BUILD_VERSION -L $FLASH_AREA_IMG_1_PRIMARY_START -S $FLASH_AREA_IMG_1_PRIMARY_SIZE $CY_SIGNING_KEY_ARG $CY_OUTPUT_HEX $CY_OUTPUT_SIGNED_HEX" + $CY_PYTHON_PATH $MCUBOOT_SCRIPT_FILE_DIR/$IMGTOOL_SCRIPT_NAME $IMGTOOL_COMMAND_ARG $FLASH_ERASE_ARG -e little --pad-header --align 8 -H $MCUBOOT_HEADER_SIZE -M $MCUBOOT_MAX_IMG_SECTORS -v $APP_BUILD_VERSION -L $FLASH_AREA_IMG_1_PRIMARY_START -S $FLASH_AREA_IMG_1_PRIMARY_SIZE $CY_SIGNING_KEY_ARG $CY_OUTPUT_HEX $CY_OUTPUT_SIGNED_HEX +fi +# +# Convert signed hex file to Binary +echo "Signed .hex to .bin" +"$CY_HEX_TO_BIN" --input-target=ihex --output-target=binary $CY_OUTPUT_SIGNED_HEX $CY_OUTPUT_BIN + +# get size of binary file for components.json +BIN_SIZE=$(ls -g -o $CY_OUTPUT_BIN | awk '{printf $3}') + +# Navigate to build directory + +pushd $CY_OUTPUT_PATH + +# create "components.json" file +echo "{\"numberOfComponents\":\"2\",\"version\":\"$APP_BUILD_VERSION\",\"files\":[" > $CY_COMPONENTS_JSON_NAME +echo "{\"fileName\":\"components.json\",\"fileType\": \"component_list\"}," >> $CY_COMPONENTS_JSON_NAME +echo "{\"fileName\":\"$CY_OUTPUT_FILE_NAME_BIN\",\"fileType\": \"NSPE\",\"fileSize\":\"$BIN_SIZE\"}]}" >> $CY_COMPONENTS_JSON_NAME + +# create tarball for OTA +echo "Create tarball" +tar -cf $CY_OUTPUT_FILE_NAME_TAR $CY_COMPONENTS_JSON_NAME $CY_OUTPUT_FILE_NAME_BIN + +# +# +# When we build WiFi & BT FW into separate block +# +# +popd + +if [ "$CY_BUILD_SEPARATE_FW" == "FW_DATBLOCK_SEPARATE_FROM_APPLICATION" ] +then + # Build the FW Data Block + if [ "$FW_DATA_BLOCK_WIFI_FW_SOURCE" == "NONE" ] + then + WIFI_ARGUMENT=" " + else + WIFI_ARGUMENT="-wifi_src $FW_DATA_BLOCK_WIFI_FW_SOURCE" + fi + + if [ "$FW_DATA_BLOCK_CLM_BLOB_SOURCE" == "NONE" ] + then + CLM_ARGUMENT=" " + else + CLM_ARGUMENT="-clm_src $FW_DATA_BLOCK_CLM_BLOB_SOURCE" + fi + + if [ "$FW_DATA_BLOCK_BT_FW_SOURCE" == "NONE" ] + then + BT_ARGUMENT=" " + else + BT_ARGUMENT="-bt_src $FW_DATA_BLOCK_BT_FW_SOURCE" + fi + + echo "" + echo "WIFI_ARGUMENT $WIFI_ARGUMENT" + echo "CLM_ARGUMENT $CLM_ARGUMENT" + echo "BT_ARGUMENT $BT_ARGUMENT" + echo "" + + echo "$CY_PYTHON_PATH $FW_DATA_BLOCK_BUILDER -l $WIFI_ARGUMENT $CLM_ARGUMENT $BT_ARGUMENT -out_file $FW_DATA_BLOCK_OUTPUT_FILE_BIN" + $CY_PYTHON_PATH $FW_DATA_BLOCK_BUILDER -l $WIFI_ARGUMENT $CLM_ARGUMENT $BT_ARGUMENT -out_file $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_BIN + + # Convert to Hex + echo "$CY_PYTHON_PATH $CY_PYTHON_PATH/../Scripts/bin2hex.py $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_BIN $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_UNSIGNED_HEX" + $CY_PYTHON_PATH $CY_PYTHON_PATH/../Scripts/bin2hex.py $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_BIN $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_UNSIGNED_HEX + ls -l $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_WILD + + # sign the hex file and place at Primary image 2 start + echo "$CY_PYTHON_PATH $MCUBOOT_SCRIPT_FILE_DIR/$IMGTOOL_SCRIPT_NAME $IMGTOOL_COMMAND_ARG $EXT_FLASH_ERASE_ARG -e little --pad-header --align 8 -H $CY_EXT_MCUBOOT_HEADER_SIZE -M $MCUBOOT_MAX_FW_IMG_SECTORS -v $APP_BUILD_VERSION -x $CY_BOOT_PRIMARY_1_IMAGE_2_START -S $CY_BOOT_PRIMARY_1_IMAGE_2_SIZE $CY_SIGNING_KEY_ARG $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_UNSIGNED_HEX $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_HEX" + $CY_PYTHON_PATH $MCUBOOT_SCRIPT_FILE_DIR/$IMGTOOL_SCRIPT_NAME $IMGTOOL_COMMAND_ARG $EXT_FLASH_ERASE_ARG -e little --pad-header --align 8 -H $CY_EXT_MCUBOOT_HEADER_SIZE -M $MCUBOOT_MAX_FW_IMG_SECTORS -v $APP_BUILD_VERSION -x $CY_BOOT_PRIMARY_1_IMAGE_2_START -S $CY_BOOT_PRIMARY_1_IMAGE_2_SIZE $CY_SIGNING_KEY_ARG $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_UNSIGNED_HEX $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_HEX + + # Convert signed hex file to Binary + echo "Signed $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_HEX $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_BIN" + "$CY_HEX_TO_BIN" --input-target=ihex --output-target=binary $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_HEX $CY_OUTPUT_PATH/$FW_DATA_BLOCK_OUTPUT_FILE_BIN + + pushd $CY_OUTPUT_PATH + + # Make tar archive + # get size of binary file for components.json + FW_DATA_BLOCK_SIZE=$(ls -g -o $FW_DATA_BLOCK_OUTPUT_FILE_BIN | awk '{printf $3}') + + # create "components.json" file + echo "{\"numberOfComponents\":\"3\",\"version\":\"$APP_BUILD_VERSION\",\"files\":[" > $CY_COMPONENTS_JSON_NAME + echo "{\"fileName\":\"components.json\",\"fileType\": \"component_list\"}," >> $CY_COMPONENTS_JSON_NAME + echo "{\"fileName\":\"$CY_OUTPUT_FILE_NAME_BIN\",\"fileType\": \"NSPE\",\"fileSize\":\"$BIN_SIZE\"}," >> $CY_COMPONENTS_JSON_NAME + echo "{\"fileName\":\"$FW_DATA_BLOCK_OUTPUT_FILE_BIN\",\"fileType\": \"FWDB\",\"fileSize\":\"$FW_DATA_BLOCK_SIZE\"}]}" >> $CY_COMPONENTS_JSON_NAME + + # create tarball for OTA + echo "Create tarball" + tar -cf $CY_OUTPUT_FILE_NAME_TAR $CY_COMPONENTS_JSON_NAME $CY_OUTPUT_FILE_NAME_BIN $FW_DATA_BLOCK_OUTPUT_FILE_BIN + + popd +fi + +pushd $CY_OUTPUT_PATH +echo "" +echo "Application Name : $CY_OUTPUT_NAME" +echo "Application Version : $APP_BUILD_VERSION" +echo "Cypress MCUBoot Header size : $MCUBOOT_HEADER_SIZE" +if [ "$CY_BUILD_SEPARATE_FW" == "FW_DATBLOCK_SEPARATE_FROM_APPLICATION" ] +then +echo "Primary 1 Slot Image 1 Start : $FLASH_AREA_IMG_1_PRIMARY_START" +echo "Primary 1 Slot Image 1 Size : $FLASH_AREA_IMG_1_PRIMARY_SIZE" +echo "Primary 1 Slot Image 2 Start : $CY_BOOT_PRIMARY_1_IMAGE_2_START" +echo "Primary 1 Slot Image 2 Size : $CY_BOOT_PRIMARY_1_IMAGE_2_SIZE" +echo "FLASH ERASE Value : $FLASH_ERASE_VALUE" +echo "EXT FLASH ERASE Value : $CY_EXTERNAL_FLASH_ERASE_VALUE" +echo "CY_EXT_MCUBOOT_HEADER_SIZE : $CY_EXT_MCUBOOT_HEADER_SIZE" +else +echo "Primary 1 Slot Start : $FLASH_AREA_IMG_1_PRIMARY_START" +echo "Primary 1 Slot Size : $FLASH_AREA_IMG_1_PRIMARY_SIZE" +echo "FLASH ERASE Value : $FLASH_ERASE_VALUE" +fi +echo "Max 512 bytes sectors for Application : $MCUBOOT_MAX_IMG_SECTORS" +if [ "$SIGNING_KEY_PATH" != "" ] +then + echo "Signing key: $SIGNING_KEY_PATH" +fi +echo "" + +ls -l $CY_OUTPUT_FILE_WILD +if [ "$CY_BUILD_SEPARATE_FW" == "FW_DATBLOCK_SEPARATE_FROM_APPLICATION" ] +then +ls -l $FW_DATA_BLOCK_OUTPUT_FILE_WILD +fi +echo "" + +echo "$CY_OUTPUT_FILE_NAME_TAR File List" +# print tar file list +tar -t -f $CY_OUTPUT_FILE_NAME_TAR + +echo "" diff --git a/scripts/mcuboot/sign_script_20829.bash b/scripts/mcuboot/sign_script_20829.bash new file mode 100755 index 0000000..423418c --- /dev/null +++ b/scripts/mcuboot/sign_script_20829.bash @@ -0,0 +1,213 @@ +#!/bin/bash +# +# This file is used by make to create the build commands to sign an OTA image +# +# Modify at your peril ! +# +# break immediately on errors +set -e + +# +# Arguments +# We have a lot +# +GCC_ARM_TOOLCHAIN_PATH=$1 +shift +CY_PYTHON_PATH=$1 +shift +CY_OUTPUT_PATH=$1 +shift +CY_OUTPUT_NAME=$1 +shift +CY_ELF_TO_HEX=$1 +shift +CY_ELF_TO_HEX_OPTIONS=$1 +shift +CY_ELF_TO_HEX_FILE_ORDER=$1 +shift +CY_HEX_TO_BIN=$1 +shift +FLASH_ERASE_VALUE=$1 +shift +MCUBOOT_HEADER_SIZE=$1 +shift +APP_BUILD_VERSION=$1 +shift +FLASH_BASE_ADDRESS=$1 +shift +FLASH_AREA_IMG_1_PRIMARY_START=$1 +shift +FLASH_AREA_IMG_1_PRIMARY_SIZE=$1 +shift +FLASH_AREA_IMG_1_SECONDARY_START=$1 +shift +MCUBOOT_KEY_DIR=$1 +shift +MCUBOOT_KEY_FILE=$1 +shift +CY_TOC2_GENERATOR=$1 +shift +CY_LCS=$1 +shift +MTB_TOOLS__OUTPUT_CONFIG_DIR=$1 +shift +APPNAME=$1 +shift +APPTYPE=$1 +shift +current_dir=$1 +shift +SMIF_CRYPTO_CONFIG=$1 +shift +MTB_TOOLCHAIN_GCC_ARM__BASE_DIR=$1 +shift +OTA_APP_POLICY_PATH=$1 +shift +CY_SLOT_SIZE=$1 +shift +CY_ENCRYPTION=$1 +shift +CY_SERVICE_APP_DESCR_ADDR=$1 +shift +BOOTSTRAP_SIZE=$1 +shift +DEVICE_SRAM_SIZE_KB=$1 + +# Export these values for python3 click module +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +CY_OUTPUT_ELF=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.elf +CY_OUTPUT_BIN=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin +CY_OUTPUT_FINAL_BIN=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin +CY_OUTPUT_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex +CY_OUTPUT_FINAL_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.hex +# Copy final to .final.hex for MTB +CY_OUTPUT_FINAL_FINAL_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.hex +CY_OUTPUT_FILE_WILD=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.* +CY_OUTPUT_FILE_NAME_BIN=$CY_OUTPUT_NAME.bin +CY_OUTPUT_FILE_NAME_TAR=$CY_OUTPUT_NAME.tar +CY_COMPONENTS_JSON_NAME=components.json +# +# For elf -> hex conversion +# +if [ "$CY_ELF_TO_HEX_FILE_ORDER" == "elf_first" ] +then + CY_ELF_TO_HEX_FILE_1=$CY_OUTPUT_ELF + CY_ELF_TO_HEX_FILE_2=$CY_OUTPUT_HEX +else + CY_ELF_TO_HEX_FILE_1=$CY_OUTPUT_HEX + CY_ELF_TO_HEX_FILE_2=$CY_OUTPUT_ELF +fi + +# Add base address to offset for PRIMARY slot +FLASH_AREA_IMG_1_PRIMARY_START_ABS=`printf "0x%x\n" $(($FLASH_BASE_ADDRESS + $FLASH_AREA_IMG_1_PRIMARY_START))` + +# +# Leave here for debugging +echo "--------------------- MCUBOOT SIGN Vars ----------------------------------------------------------------------" +echo "GCC_ARM_TOOLCHAIN_PATH =$GCC_ARM_TOOLCHAIN_PATH" +echo "CY_PYTHON_PATH =$CY_PYTHON_PATH" +echo "CY_OUTPUT_PATH =$CY_OUTPUT_PATH" +echo "CY_OUTPUT_NAME =$CY_OUTPUT_NAME" +echo "CY_ELF_TO_HEX =$CY_ELF_TO_HEX" +echo "CY_ELF_TO_HEX_OPTIONS =$CY_ELF_TO_HEX_OPTIONS" +echo "CY_ELF_TO_HEX_FILE_ORDER =$CY_ELF_TO_HEX_FILE_ORDER" +echo "CY_HEX_TO_BIN =$CY_HEX_TO_BIN" +echo "FLASH_ERASE_VALUE =$FLASH_ERASE_VALUE" +echo "MCUBOOT_HEADER_SIZE =$MCUBOOT_HEADER_SIZE" +echo "APP_BUILD_VERSION =$APP_BUILD_VERSION" +echo "FLASH_BASE_ADDRESS =$FLASH_BASE_ADDRESS" +echo "FLASH_AREA_IMG_1_PRIMARY_START =$FLASH_AREA_IMG_1_PRIMARY_START" +echo "FLASH_AREA_IMG_1_PRIMARY_START_ABS =$FLASH_AREA_IMG_1_PRIMARY_START_ABS" +echo "FLASH_AREA_IMG_1_PRIMARY_SIZE =$FLASH_AREA_IMG_1_PRIMARY_SIZE" +echo "FLASH_AREA_IMG_1_SECONDARY_START =$FLASH_AREA_IMG_1_SECONDARY_START" +echo "MCUBOOT_KEY_DIR =$MCUBOOT_KEY_DIR" +echo "MCUBOOT_KEY_FILE =$MCUBOOT_KEY_FILE" +echo "CY_TOC2_GENERATOR =$CY_TOC2_GENERATOR" +echo "CY_LCS =$CY_LCS" +echo "MTB_TOOLS__OUTPUT_CONFIG_DIR =$MTB_TOOLS__OUTPUT_CONFIG_DIR" +echo "APPNAME =$APPNAME" +echo "APPTYPE =$APPTYPE" +echo "current_dir =$current_dir" +echo "SMIF_CRYPTO_CONFIG =$SMIF_CRYPTO_CONFIG" +echo "MTB_TOOLCHAIN_GCC_ARM__BASE_DIR =$MTB_TOOLCHAIN_GCC_ARM__BASE_DIR" +echo "OTA_APP_POLICY_PATH =$OTA_APP_POLICY_PATH" +echo "CY_SLOT_SIZE =$CY_SLOT_SIZE" +echo "CY_ENCRYPTION =$CY_ENCRYPTION" +echo "CY_SERVICE_APP_DESCR_ADDR =$CY_SERVICE_APP_DESCR_ADDR" +echo "BOOTSTRAP_SIZE =$BOOTSTRAP_SIZE" +echo "DEVICE_SRAM_SIZE_KB =$DEVICE_SRAM_SIZE_KB" + +# For FLASH_ERASE_VALUE +# If value is 0x00, we need to specify "-R 0" +# If value is 0xFF, we do not specify anything! +# +FLASH_ERASE_ARG= +if [ "$FLASH_ERASE_VALUE" == "0x00" ] +then +FLASH_ERASE_ARG="-R 0" +fi + +PRJ_DIR=. + +echo "" +echo "[Bin to Hex for debug (unsigned)]" +#echo "$CY_HEX_TO_BIN -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex" +#$CY_HEX_TO_BIN -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex + +echo "" +echo "[TOC2_Generate] Execute toc2 generator script for $CY_OUTPUT_NAME" +echo "source $CY_TOC2_GENERATOR $CY_LCS $MTB_TOOLS__OUTPUT_CONFIG_DIR $APPNAME $APPTYPE $current_dir $SMIF_CRYPTO_CONFIG $MTB_TOOLCHAIN_GCC_ARM__BASE_DIR $OTA_APP_POLICY_PATH $CY_SLOT_SIZE $CY_ENCRYPTION $CY_SERVICE_APP_DESCR_ADDR $BOOTSTRAP_SIZE $DEVICE_SRAM_SIZE_KB" +source $CY_TOC2_GENERATOR $CY_LCS $MTB_TOOLS__OUTPUT_CONFIG_DIR $APPNAME $APPTYPE $current_dir $SMIF_CRYPTO_CONFIG $MTB_TOOLCHAIN_GCC_ARM__BASE_DIR $OTA_APP_POLICY_PATH $CY_SLOT_SIZE $CY_ENCRYPTION $CY_SERVICE_APP_DESCR_ADDR $BOOTSTRAP_SIZE $DEVICE_SRAM_SIZE_KB; + +echo "" +echo "Checking for TOC2 output file" +ls -l $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin + +#################################################### SIGNING BOOT IMAGE ###################################################### +echo "" +echo "[SIGNING BOOT using cysecuretools]" +echo "cysecuretools -q -t cyw20829 -p $OTA_APP_POLICY_PATH sign-image -H $MCUBOOT_HEADER_SIZE --align 8 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE --overwrite-only -R 0xff --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin --output $CY_OUTPUT_BIN --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image-id 1" +cysecuretools -q -t cyw20829 -p $OTA_APP_POLICY_PATH sign-image -H $MCUBOOT_HEADER_SIZE --align 1 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE --overwrite-only -R 0xff --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin --output $CY_OUTPUT_BIN --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image-id 1 + +echo "" +echo "[Bin to Hex for PRIMARY (BOOT) Slot]" +echo "$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_PRIMARY_START_ABS -I binary -O ihex $CY_OUTPUT_BIN $CY_OUTPUT_FINAL_HEX" +$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_PRIMARY_START_ABS -I binary -O ihex $CY_OUTPUT_BIN $CY_OUTPUT_FINAL_HEX +echo "Copy $CY_OUTPUT_FINAL_HEX to $CY_OUTPUT_FINAL_FINAL_HEX for MTB" +cp $CY_OUTPUT_FINAL_HEX $CY_OUTPUT_FINAL_FINAL_HEX + +#################################################### SIGNING UPGRADE IMAGE ###################################################### +echo "" +echo "[SIGNING UPGRADE using cysecuretools]" +echo "cysecuretools -q -t cyw20829 -p $OTA_APP_POLICY_PATH sign-image -H $MCUBOOT_HEADER_SIZE --align 8 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE --overwrite-only -R 0xff --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin --output $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.signed.bin --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image-id 1" +cysecuretools -q -t cyw20829 -p $OTA_APP_POLICY_PATH sign-image -H $MCUBOOT_HEADER_SIZE --align 1 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE --overwrite-only -R 0xff --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin --output $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.signed.bin --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image-id 1 + +echo "" +echo "[Bin to Hex for SECONDARY (UPDATE) Slot]" +echo "$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_SECONDARY_START -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.signed.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.hex" +$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_SECONDARY_START -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.signed.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.hex + +# clean up temp files +rm $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin + +# get size of binary file for components.json +BIN_SIZE=$(ls -g -o $CY_OUTPUT_BIN | awk '{printf $3}') + +# Navigate to build directory + +pushd $CY_OUTPUT_PATH + +# create "components.json" file +echo "{\"numberOfComponents\":\"2\",\"version\":\"$APP_BUILD_VERSION\",\"files\":[" > $CY_COMPONENTS_JSON_NAME +echo "{\"fileName\":\"components.json\",\"fileType\": \"component_list\"}," >> $CY_COMPONENTS_JSON_NAME +echo "{\"fileName\":\"$CY_OUTPUT_FILE_NAME_BIN\",\"fileType\": \"NSPE\",\"fileSize\":\"$BIN_SIZE\"}]}" >> $CY_COMPONENTS_JSON_NAME + +# create tarball for OTA +echo "Create tarball" +tar -cf $CY_OUTPUT_FILE_NAME_TAR $CY_COMPONENTS_JSON_NAME $CY_OUTPUT_FILE_NAME_BIN + +echo "" +ls -l $CY_OUTPUT_FILE_WILD +echo "" diff --git a/scripts/mcuboot/sign_script_xmc7200.bash b/scripts/mcuboot/sign_script_xmc7200.bash new file mode 100755 index 0000000..1ef0ea6 --- /dev/null +++ b/scripts/mcuboot/sign_script_xmc7200.bash @@ -0,0 +1,164 @@ +#!/bin/bash +# +# This file is used by make to create the build commands to sign an OTA image +# +# Modify at your peril ! +# +# break immediately on errors +set -e + +# +# Arguments +# We have a lot +# +GCC_ARM_TOOLCHAIN_PATH=$1 +shift +CY_PYTHON_PATH=$1 +shift +CY_OUTPUT_PATH=$1 +shift +CY_OUTPUT_NAME=$1 +shift +CY_ELF_TO_HEX=$1 +shift +CY_ELF_TO_HEX_OPTIONS=$1 +shift +CY_ELF_TO_HEX_FILE_ORDER=$1 +shift +CY_HEX_TO_BIN=$1 +shift +FLASH_ERASE_VALUE=$1 +shift +MCUBOOT_HEADER_SIZE=$1 +shift +APP_BUILD_VERSION=$1 +shift +FLASH_BASE_ADDRESS=$1 +shift +FLASH_AREA_IMG_1_PRIMARY_START=$1 +shift +FLASH_AREA_IMG_1_PRIMARY_SIZE=$1 +shift +FLASH_AREA_IMG_1_SECONDARY_START=$1 +shift +MCUBOOT_KEY_DIR=$1 +shift +MCUBOOT_KEY_FILE=$1 + +# Export these values for python3 click module +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +CY_OUTPUT_ELF=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.elf +CY_OUTPUT_BIN=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin +CY_OUTPUT_FINAL_BIN=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.bin +CY_OUTPUT_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex +CY_OUTPUT_FINAL_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.hex +# Copy final to .final.hex for MTB +CY_OUTPUT_FINAL_FINAL_HEX=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.final.hex +CY_OUTPUT_FILE_WILD=$CY_OUTPUT_PATH/$CY_OUTPUT_NAME.* +CY_OUTPUT_FILE_NAME_BIN=$CY_OUTPUT_NAME.bin +CY_OUTPUT_FILE_NAME_TAR=$CY_OUTPUT_NAME.tar +CY_COMPONENTS_JSON_NAME=components.json +# +# For elf -> hex conversion +# +if [ "$CY_ELF_TO_HEX_FILE_ORDER" == "elf_first" ] +then + CY_ELF_TO_HEX_FILE_1=$CY_OUTPUT_ELF + CY_ELF_TO_HEX_FILE_2=$CY_OUTPUT_HEX +else + CY_ELF_TO_HEX_FILE_1=$CY_OUTPUT_HEX + CY_ELF_TO_HEX_FILE_2=$CY_OUTPUT_ELF +fi + +# Add base address to offset for PRIMARY slot +FLASH_AREA_IMG_1_PRIMARY_START_ABS=`printf "0x%x\n" $(($FLASH_BASE_ADDRESS + $FLASH_AREA_IMG_1_PRIMARY_START))` + +# +# Leave here for debugging +echo "--------------------- MCUBOOT SIGN Vars ----------------------------------------------------------------------" +echo "GCC_ARM_TOOLCHAIN_PATH =$GCC_ARM_TOOLCHAIN_PATH" +echo "CY_PYTHON_PATH =$CY_PYTHON_PATH" +echo "CY_OUTPUT_PATH =$CY_OUTPUT_PATH" +echo "CY_OUTPUT_NAME =$CY_OUTPUT_NAME" +echo "CY_ELF_TO_HEX =$CY_ELF_TO_HEX" +echo "CY_ELF_TO_HEX_OPTIONS =$CY_ELF_TO_HEX_OPTIONS" +echo "CY_ELF_TO_HEX_FILE_ORDER =$CY_ELF_TO_HEX_FILE_ORDER" +echo "CY_HEX_TO_BIN =$CY_HEX_TO_BIN" +echo "FLASH_ERASE_VALUE =$FLASH_ERASE_VALUE" +echo "MCUBOOT_HEADER_SIZE =$MCUBOOT_HEADER_SIZE" +echo "APP_BUILD_VERSION =$APP_BUILD_VERSION" +echo "FLASH_BASE_ADDRESS =$FLASH_BASE_ADDRESS" +echo "FLASH_AREA_IMG_1_PRIMARY_START =$FLASH_AREA_IMG_1_PRIMARY_START" +echo "FLASH_AREA_IMG_1_PRIMARY_START_ABS =$FLASH_AREA_IMG_1_PRIMARY_START_ABS" +echo "FLASH_AREA_IMG_1_PRIMARY_SIZE =$FLASH_AREA_IMG_1_PRIMARY_SIZE" +echo "FLASH_AREA_IMG_1_SECONDARY_START =$FLASH_AREA_IMG_1_SECONDARY_START" +echo "MCUBOOT_KEY_DIR =$MCUBOOT_KEY_DIR" +echo "MCUBOOT_KEY_FILE =$MCUBOOT_KEY_FILE" + +# For FLASH_ERASE_VALUE +# If value is 0x00, we need to specify "-R 0" +# If value is 0xFF, we do not specify anything! +# +FLASH_ERASE_ARG= +if [ "$FLASH_ERASE_VALUE" == "0x00" ] +then +FLASH_ERASE_ARG="-R 0" +fi + +PRJ_DIR=. + +echo "" +echo "[Bin to Hex for debug (unsigned)]" +echo "$CY_HEX_TO_BIN -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex" +$CY_HEX_TO_BIN -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.hex + + +#################################################### SIGNING BOOT IMAGE ###################################################### +echo "" +echo "[SIGNING BOOT using cysecuretools]" +echo "cysecuretools -t XMC7200 sign-image --header-size $MCUBOOT_HEADER_SIZE --align 8 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE -R 0xff --overwrite-only --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.bin --output $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.signed.bin --hex-addr=$FLASH_AREA_IMG_1_PRIMARY_START_ABS" +cysecuretools -t XMC7200 sign-image --header-size $MCUBOOT_HEADER_SIZE --align 8 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE -R 0xff --overwrite-only --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.bin --output $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.signed.bin --hex-addr=$FLASH_AREA_IMG_1_PRIMARY_START_ABS + +echo "" +echo "[Bin to Hex for PRIMARY (BOOT) Slot]" +echo "$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_PRIMARY_START_ABS -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.signed.bin $CY_OUTPUT_FINAL_HEX" +$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_PRIMARY_START_ABS -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.signed.bin $CY_OUTPUT_FINAL_HEX +echo "Copy $CY_OUTPUT_FINAL_HEX to $CY_OUTPUT_FINAL_FINAL_HEX for MTB" +cp $CY_OUTPUT_FINAL_HEX $CY_OUTPUT_FINAL_FINAL_HEX + +# #################################################### SIGNING UPGRADE IMAGE ###################################################### +echo "" +echo "[SIGNING UPGRADE using cysecuretools]" +echo "cysecuretools -t XMC7200 sign-image --header-size $MCUBOOT_HEADER_SIZE --align 8 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE -R 0xff --overwrite-only --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.bin --output $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin --hex-addr=$FLASH_AREA_IMG_1_SECONDARY_START" +cysecuretools -t XMC7200 sign-image --header-size $MCUBOOT_HEADER_SIZE --align 8 -v $APP_BUILD_VERSION -S $FLASH_AREA_IMG_1_PRIMARY_SIZE -R 0xff --overwrite-only --key-path $MCUBOOT_KEY_DIR/$MCUBOOT_KEY_FILE --image $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.unsigned.bin --output $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin --hex-addr=$FLASH_AREA_IMG_1_SECONDARY_START + +echo "" +echo "[Bin to Hex for SECONDARY (UPDATE) Slot]" +echo "$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_SECONDARY_START -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.hex" +$CY_HEX_TO_BIN --change-address=$FLASH_AREA_IMG_1_SECONDARY_START -I binary -O ihex $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.bin $CY_OUTPUT_PATH/$CY_OUTPUT_NAME.update.hex + +# clean up temp files +# rm $CY_OUTPUT_PATH/($CY_OUTPUT_NAME).unsigned.bin + +# get size of binary file for components.json +BIN_SIZE=$(ls -g -o $CY_OUTPUT_BIN | awk '{printf $3}') + +# Navigate to build directory + +pushd $CY_OUTPUT_PATH + +# create "components.json" file +echo "{\"numberOfComponents\":\"2\",\"version\":\"$APP_BUILD_VERSION\",\"files\":[" > $CY_COMPONENTS_JSON_NAME +echo "{\"fileName\":\"components.json\",\"fileType\": \"component_list\"}," >> $CY_COMPONENTS_JSON_NAME +echo "{\"fileName\":\"$CY_OUTPUT_FILE_NAME_BIN\",\"fileType\": \"NSPE\",\"fileSize\":\"$BIN_SIZE\"}]}" >> $CY_COMPONENTS_JSON_NAME + +# create tarball for OTA +echo "Create tarball" +tar -cf $CY_OUTPUT_FILE_NAME_TAR $CY_COMPONENTS_JSON_NAME $CY_OUTPUT_FILE_NAME_BIN + + +echo "" +ls -l $CY_OUTPUT_FILE_WILD +echo "" diff --git a/source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md b/source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md new file mode 100644 index 0000000..f2dd086 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md @@ -0,0 +1,117 @@ +# MCUBootApp Usage Instructions + + +## 1. Clone MCUBoot + +- You need to first build and program the bootloader app *MCUBootApp* that is available in the [MCUBoot GitHub repo](https://github.com/mcu-tools/mcuboot) before using an MCUBootloader based OTA application. + + - MCUBootApp runs on the CM0+ CPU and starts any OTA enabled application on CM4 core in case of multicore Psoc6 devices. + - MCUBootApp runs on the CM0+ CPU and starts any OTA enabled application on CM7 core in case of multicore XMC7200 devices. + - MCUBootApp runs on CM33 CPU along with the OTA enabled applications in the case of 20829 devices. + +- Clone the MCUBoot repository onto your local machine, **outside of your application directory.** + +- Open a CLI terminal and run the following command: + + ``` + git clone https://github.com/JuulLabs-OSS/mcuboot.git + ``` + +- Navigate to the cloned *mcuboot* folder: + ``` + cd mcuboot + ``` + +- Change the branch to get the appropriate version: + + ``` + git checkout v1.9.1-cypress + ``` + +- Pull in sub-modules to build mcuboot: + + ``` + git submodule update --init --recursive + ``` + +- Install the required Python packages mentioned in *mcuboot/scripts/requirements.txt*. Be sure to use the python instance in ModusToolbox/tools_XX/python: + ``` + cd mcuboot/scripts + + pip install -r requirements.txt + ``` + +Note: +- The **CY8CKIT-064B0S2-4343W** is a special kit that uses cysecureboot. See [cysecuretools for PSoC™ 64 and CYW20829 devices](#5-cysecuretools-for-psoc-64-and-cyw20829-devices) information section below. + +## 2. UART differences + +The UART Tx and Rx pins are common across most TARGET boards. However, there are exceptions. If "printf()" output are not seen on the terminal, check the UART settings. The default UART Tx and Rx can be changed for your device. + +To change default UART Tx and Rx, pass the `UART_RX_DEFAULT=XX` and `UART_TX_DEFAULT=xx` parameters to the MCUBootApp `make` command. +``` + make clean app APP_NAME=MCUBootApp PLATFORM=XXXX FLASH_MAP=XXXX UART_TX_DEFAULT?=P10_1 UART_RX_DEFAULT?=P10_0 + `UART_RX_DEFAULT` - Sets the pin number in the GPIO port used as RX of the debug serial port. + `UART_TX_DEFAULT` - Sets the pin number in the GPIO port used as TX of the debug serial port. +``` + +## 3. Build MCUBoot + +MCUBootApp supports using a JSON document to define the flash regions used for updating the application. + +Read **[MCUBoot Build Commands](./MCUBOOT_BUILD_COMMANDS.md)** to see the flashmaps and build command to use. This ****must**** be the same flashmap used to buid your OTA application. + +Notes: +- The JSON files use ABSOLUTE address, which indicate which flash part is to be used for the particular section. The usage in MCUBootApp and OTA Bootloader Support library defines the location by device_id and RELATIVE address. You do not need to do anything, this information is to reduce confusion. + +- Watch the MCUBootApp build output. If the python script flashmap.py detects errors in the flash layout, it will report them to stderr and stop the build. + +## 4. Program MCUBootApp + +- Connect the board to your PC using the provided USB cable through the USB connector. + +- Erase flash area before programming MCUBootApp. + +- From the terminal, execute the make program command to program the application using the default toolchain to the default target. + ``` + make program TARGET= TOOLCHAIN= + ``` + +- Alternatively, the board can be programmed using CyProgrammer, OpenOCD commands or the instructions in your Customer Example Application notes. + - [OpenOCD commands for PSOC6 devices](https://github.com/mcu-tools/mcuboot/blob/v1.9.1-cypress/boot/cypress/platforms/PSOC6.md#using-openocd-from-command-line) + - [OpenOCD commands for 20829 devices](https://github.com/mcu-tools/mcuboot/blob/v1.9.1-cypress/boot/cypress/platforms/CYW20829.md#using-openocd-from-command-line) + - [OpenOCD commands for XMC7200 devices](https://github.com/mcu-tools/mcuboot/blob/v1.9.1-cypress/boot/cypress/platforms/XMC7000.md#xmc7000-secure-boot-configuration-description) + +Notes: +- For XMC7200 devices, once the 'status_area' of the MCUBootApp has been erased, this flash area should be filled with the value '0xFF'. + ``` + flash fillb 0x14030000 0xFF 0x2800 + ``` + +## 5. cysecuretools for PSoC™ 64 and CYW20829 devices + +For CY8CKIT-062B0S2-4343W kit and CYW20829 devices (SECURE), we use a procedure called "provisioning" to put the CyBootloader into the device. Please refer to the following cysecuretools documents for this procedure. + +[Provisioning Steps for CY8CKIT-064B0S2-4343W](https://github.com/Infineon/cysecuretools/blob/master/docs/README_PSOC64.md) + +[Provisioning Steps for CYW20829 devices](https://github.com/Infineon/cysecuretools/blob/master/docs/README_CYW20829.md) + +Note: +- For 20829 NORMAL_NO_SECURE mode, MCUBootApp should be built and programmed separately. + +- Windows version of ModusToolbox 3.1 contains a Python package with CySecureTools 5.0.0. mcuboot v1.9.1-cypress requires the CySecureTools v5.0.0 or greater for 20829 and XMC7200 platforms. + +- The following command can be used in the modus-shell terminal to find the current version of CySecureTools. + ```` + cysecuretools version + ```` + +- If the current CySecureTools is not the required version, the following command can be used in modus-shell terminal to update it. + ```` + pip install --upgrade --force-reinstall cysecuretools + ```` + +- Additionally, the following command can be used to view the supported targets and families of devices. + ```` + cysecuretools device-list + ```` diff --git a/source/COMPONENT_MCUBOOT/MCUBOOT_BUILD_COMMANDS.md b/source/COMPONENT_MCUBOOT/MCUBOOT_BUILD_COMMANDS.md new file mode 100644 index 0000000..2e19510 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/MCUBOOT_BUILD_COMMANDS.md @@ -0,0 +1,141 @@ +# MCUBoot Build Commands + +The JSON flash maps were verified to work with MCUBoot v1.9.1-cypress. The JSON flash map files are available in [flashmap](./../../configs/COMPONENT_MCUBOOT/flashmap/) folder. + +Choose the configuration to use from the information below and copy the flash map file to your **\/boot/cypress/** directory before building MCUBootApp. + +## 1. PSoC™ 62 2M Internal Flash Platforms +- CY8CKIT-062S2-43012 +- CY8CPROTO-062-4343W +- CY8CEVAL-062S2-MUR-43439M2 +- CY8CEVAL-062S2-LAI-4373M2 + +There are flash maps for the upgrade slot in internal flash and in external flash. There are also versions for SWAP and OVERWRITE upgrade methods. + +Building MCUBoot + +To build MCUBoot for internal only flash SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M FLASH_MAP=./psoc62_2m_int_swap_single.json +``` + +To build MCUBoot for internal only flash OVERWRITE configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M FLASH_MAP=./psoc62_2m_int_overwrite_single.json +``` + +To build MCUBoot for internal + external flash SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M FLASH_MAP=./psoc62_2m_ext_swap_single.json +``` + +To build MCUBoot for internal + external flash OVERWRITE configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M FLASH_MAP=./psoc62_2m_ext_overwrite_single.json +``` + +## 2. PSoC™ 62 1M Internal Flash Platforms +- CY8CKIT-062-BLE + +Building MCUBoot + +To build MCUBoot for internal + internal flash SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_1M USE_CUSTOM_DEBUG_UART=1 FLASH_MAP=./psoc62_1m_cm0_int_swap_single.json +``` + +## 3. PSoC™ 62 512K Internal Flash Platforms +- CY8CPROTO-062S3-4343W + +Building MCUBoot + +To build MCUBoot for internal + external flash OVERWRITE configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_512K USE_CUSTOM_DEBUG_UART=1 FLASH_MAP=./psoc62_512k_ext_overwrite_single.json +``` + +To build MCUBoot for internal + external flash SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_512K USE_CUSTOM_DEBUG_UART=1 FLASH_MAP=./psoc62_512k_ext_swap_single.json +``` + +To build MCUBoot for external flash execute (XIP) SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_512K USE_CUSTOM_DEBUG_UART=1 FLASH_MAP=./psoc62_512k_xip_swap_single.json +``` + +## 4. PSoC™ 63 1M Internal Flash Platforms +- CY8CPROTO-063-BLE +- CYBLE-416045-EVAL + +Building MCUBoot + +To build MCUBoot for internal + internal flash SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_063_1M USE_CUSTOM_DEBUG_UART=1 FLASH_MAP=./psoc63_1m_cm0_int_swap_single.json +``` + +## 5. PSoC™ 64 Platform +- CY8CKIT-064B0S2-4343W + +Building MCUBoot + +There are no flash maps for this device, the parameters are in the Makefile. We use cysecuretools to provision CY8CPROTO-064B0S2-4343W targets. Please see MCUBOOT_APP_README.md for more details. + + +## 6. CYW20829 Platforms + +The CYW920829M2EVK-02 platform only supports an external flash execution(XIP) configuration. + +Building MCUBoot + +To build MCUBoot for external flash execute (XIP) SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=CYW20829 USE_CUSTOM_DEBUG_UART=1 USE_EXTERNAL_FLASH=1 USE_XIP=1 FLASH_MAP=./cyw20829_xip_swap_single.json +``` + +To build MCUBoot for external flash execute (XIP) OVERWRITE configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=CYW20829 USE_CUSTOM_DEBUG_UART=1 USE_EXTERNAL_FLASH=1 USE_XIP=1 FLASH_MAP=./cyw20829_xip_overwrite_single.json +``` + +## 7. XMC7200 Evaluation Kit +- KIT_XMC72_EVK + +The XMC7200 platform currently supports only an internal flash configuration. + +Building MCUBoot + +To build MCUBoot for internal only flash SWAP configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=XMC7200 BUILDCFG=Debug FLASH_MAP=./xmc7200_int_swap_single.json PLATFORM_CONFIG=platforms/memory/XMC7000/flashmap/xmc7200_platform.json CORE=CM0P APP_CORE=CM7 APP_CORE_ID=0 +``` + +To build MCUBoot for internal only flash OVERWRITE configuration: + +``` +make clean app APP_NAME=MCUBootApp PLATFORM=XMC7200 BUILDCFG=Debug FLASH_MAP=./xmc7200_int_swap_single.json PLATFORM_CONFIG=platforms/memory/XMC7000/flashmap/xmc7200_platform.json CORE=CM0P APP_CORE=CM7 APP_CORE_ID=0 +``` + +# UART differences + +The UART Tx and Rx pins are common across most TARGET boards. However, there are exceptions. If "printf()" output are not seen on the terminal, check the UART settings. The default UART Tx and Rx can be changed for your device. + +To change default UART Tx and Rx, pass the `UART_RX_DEFAULT=XX` and `UART_TX_DEFAULT=xx` parameters to the MCUBootApp `make` command. +``` + make clean app APP_NAME=MCUBootApp PLATFORM=XXXX FLASH_MAP=XXXX UART_TX_DEFAULT?=P10_1 UART_RX_DEFAULT?=P10_0 + `UART_RX_DEFAULT` - Sets the pin number in the GPIO port used as RX of the debug serial port. + `UART_TX_DEFAULT` - Sets the pin number in the GPIO port used as TX of the debug serial port. +``` diff --git a/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_FLASH_LAYOUT_README.md b/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_FLASH_LAYOUT_README.md new file mode 100644 index 0000000..977e012 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_FLASH_LAYOUT_README.md @@ -0,0 +1,133 @@ +# Flash Layout for MCUBootloader based OTA + +## 1. Introduction + +MCUBootloader based OTA, in concert with MCUBootApp, uses 2 "Slots" in order to update a device. The Primary Slot (also called "boot") is where the currently executing application is located. The Secondary Slot (also called "upgrade") is where we store the new application as it is being downloaded. + +| Flash Area Name | Purpose | +|-------------------| ---------------------------- | +| Primary Slot | Location of executing code | +| Secondary Slot| Location to store the updating code | +| Status Area | MCUBootApp uses this area for keeping track of the SWAP process | +| Scratch Area | MCUBootApp uses this area as a temporary location when swapping Primary and Secondary Slots | + +The location of the flash slots is based on the flash available in the system. The layout is defined at application build time and is never changed during the lifetime of the device. The flash layout of the application **must** match the flash layout in MCUBootApp. + +In order to get these areas to match, we use a common JSON formatted file to define the flash areas. When building MCUBootApp, use the same JSON file as is used for building the User Application. The python script [flashmap.py](./../../scripts/mcuboot/flashmap.py) is executed as part of the build. It will check for some common mistakes in JSON files. + +All flash erase operations (ex: erasing a slot for a new download) will erase full sectors at a time. PSoC™ 6 MCUs have internal flash that use 512 byte sector sizes. External flash devices will have different sector sizes, from 4k to 256k. If you are going to modify a flash layout, be aware of the sector sizes. + +For CAT1C devices (XMC7200 MCUs), Flash memory controller has logical banks feature and flash memory region is split into two banks. These banks are referred as Logical Bank 0 and Logical Bank 1. User needs to be aware of the following : +- Primary and Secondary slots should be kept in different logical banks. +- While executing from one logical bank, we cannot erase sectors of the same logical bank. + +For more detailed information regarding CAT1C flash system, refer to [PDL API Reference Manual](https://infineon.github.io/mtb-pdl-cat1/pdl_api_reference_manual/html/group__group__flash.html) + + +## 2. Internal Flash Only Layout + +When the device only has internal flash, all the flash areas must reside in the internal flash. This restricts the size of the application to what can fit in the internal flash space. + +Example :
+Target : CY8CPROTO-062-4343W
+Flashmap : [psoc62_2m_int_swap_single.json](./../../configs/COMPONENT_MCUBOOT/flashmap/psoc62_2m_int_swap_single.json) + +**Internal Flash Layout for 2M internal flash** +
Note: Internal flash sector size is 512 bytes. +| Address Range | Size | Description | +| --------------|------| -----------| +| 0x10000000-0x10017FFF | 0x00018000 | MCUBootApp code | +| 0x10018000-0x100183FF | 0x00000400 | Primary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x10018400-0x101063FF | 0x000EDC00 | Primary Slot User Application (951k) | +| 0x10106000-0x101063FF | 0x00000400 | Secondary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x10106400-0x101F3FFF | 0x000EDC00 | Secondary Slot User Application (951k)| +| 0x101f4000-0x101F7BFF | 0x00003c00 | MCUBootApp Status Area | +| 0x101f7C00-0x101F8BFF | 0x00001000 | MCUBootApp Scratch Area (4k) | +| 0x101F9C00-0x10200000 | 0x00006400 | Unused (25k) | + + +## 3. Internal Flash + External Flash Layout + +When the device has both internal and external flash, the Secondary Slot and the Swap Area can be moved to external flash, leaving more internal flash for the application code. + +Example :
+Target : CY8CPROTO-062S3-4343W
+Flashmap : [psoc62_512k_ext_swap_single.json](./../../configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_ext_swap_single.json) + +**Internal Flash + External Flash Layout for 512k Internal Flash** + +**Internal Flash** +
Note: Internal flash sector size is 512 bytes. +| Address Range | Size | Description | +| --------------|------| -----------| +| 0x10000000-0x10017FFF | 0x00018000 | MCUBootApp code | +| 0x10018000-0x100183FF | 0x00000400 | Primary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x10018400-0x100743FF | 0x0005C000 | Primary Slot User Application (368k) | +| 0x10074400-0x10073E00 | 0x00003c00 | MCUBootApp Status Area | +| 0x10078000-0x10080000 | 0x00008000 | Unused (32k) + +**External Flash** +
Note: External flash sector size is 256k bytes. +| Address Range | Size | Description | +| --------------|------| -----------| +| 0x18000000-0x180003FF | 0x00000400 | Secondary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x18000400-0x1805C3FF | 0x0005C000 | Secondary Slot User Application (368k)| +| 0x18080000-0x180FFFFF | 0x00080000 | MCUBootApp Scratch Area (512k) | + + +## 4. Internal Flash + External Flash, XIP from External Flash Layout + +When the device has both internal and external flash, and the Primary Slot can reside in external flash, the User Application will run in **XIP** mode (e**X**ecute **I**n **P**lace). The Primary Slot moves into external flash and can have a larger slot size. + +Example :
+Target : CY8CPROTO-062S3-4343W
+Flashmap : [psoc62_512k_xip_swap_single.json](./../../configs/COMPONENT_MCUBOOT/flashmap/psoc62_512k_xip_swap_single.json) + +**Internal Flash + External Flash Layout for 512k Internal Flash using XIP** + +**Internal Flash** +
Note: Internal flash sector size is 512 bytes. +| Address Range | Size | Description | +| --------------|------| -----------| +| 0x10000000-0x10017FFF | 0x00018000 | MCUBootApp code | +| 0x10018000-0x1001BBFF | 0x00003c00 | MCUBootApp Status Area | +| 0x1001BC00-0x10080000 | 0x00064400 | Unused (401k) + +**External Flash** +
Note: External flash sector size is 256k bytes. +| Address Range | Size | Description | +| --------------|------| -----------| +| 0x18000000-0x100003FF | 0x00000400 | Primary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x18000400-0x1813FF00 | 0x0013FF00 | Primary Slot User Application (1.25M) | +| 0x18180000-0x181803FF | 0x00000400 | Secondary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x18180400-0x1805C3FF | 0x0013FF00 | Secondary Slot User Application (1.25M)| +| 0x18440000-0x184BFFFF | 0x00080000 | MCUBootApp Scratch Area (512k) | + + +## 5. External Flash Only Layout + +When the device has only external flash, all flash areas must reside in external flash. MCUBootApp and the User Application execute from external flash. The size of the external flash will determine the size of the application. + +Example :
+Target : CYW920829M2EVK-02
+Flashmap : [cyw20829_xip_swap_single.json](./../../configs/COMPONENT_MCUBOOT/flashmap/cyw20829_xip_swap_single.json) + +**External Flash Layout for device without Internal Flash** + +
Note: External flash sector size is 4k bytes. +| Address Range | Size | Description | +| --------------|------| -----------| +| 0x60000000-0x6001FFFF | 0x00020000 | MCUBootApp code | +| 0x60020000-0x600003FF | 0x00000400 | Primary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x60020400-0x6007FFFF | 0x0005FC00 | Primary Slot User Application (368k) | +| 0x60080000-0x608043FF | 0x00000400 | Secondary Slot Required MCUBootHeader (added in signing step of User App) | +| 0x60080400-0x600DFFFF | 0x0005FC00 | Secondary Slot User Application (368k)| +| 0x600E0000-0x600EBFFF | 0x0000C000 | MCUBootApp Status Area | +| 0x600EC000-0x600EDFFF | 0x00002000 | MCUBootApp Scratch Area (512k) | + + +## 6. Sample Flash Layout(JSON) + +Sample flash layout (JSON) available in [flashmap](./../../configs/COMPONENT_MCUBOOT/flashmap/) folder. + +For a given target, the same flashmap should be used for [MCUBootApp](./MCUBOOT_BUILD_COMMANDS.md) and user ota applications. diff --git a/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md b/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md new file mode 100644 index 0000000..2d9c876 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md @@ -0,0 +1,42 @@ +# Bootloader Support Makefile Settings for a User OTA Application + +## 1. Introduction + +This guide shows Makefile variables and build DEFINES used when building an application with ota-bootloader-abstraction library along with ota-update library support. + + +## 2. Standard MCUBootloader based OTA Application Makefile Defines + + +| Makefile Variable | Example | Description | +| ----------------- | ------- | ----------- | +| TARGET?=\ | TARGET?=CY8CPROTO-062-4343W | Target Kit for build | +| CORE?=\ | CORE?=CM4 | Core CPU for Application
(CM33, CM4) | +| APPNAME?=\ | APPNAME=ota-test | Name of Application | +| TOOLCHAIN?=\ | TOOLCHAIN?=GCC_ARM | GCC_ARM (default)
ARM
IAR | +| CONFIG?=\ | CONFIG?=Debug | Build level
- Debug
- Release | + +## 3. MCUBootloader based OTA Specific Makefile Defines + +| Makefile addition | Required | Default if not defined | Description | +| ----------------- | -------- | ---------------------- | ----------- | +| CY_BUILD_LOCATION=\ | Yes | Error | Required by flashmap.py for setting output directory for use in sign_script.bash script. | +| APP_VERSION_MAJOR=\ | Yes | Error | Application Major version number X.y.z| +| APP_VERSION_MINOR=\ | Yes | Error | Application Minor version number x.Y.z| +| APP_VERSION_BUILD=\ | Yes | Error | Application Build version number x.y.Z | +| OTA_PLATFORM= | No | Depends on Target Support | must be one of:
XMC7200 - ex: KIT_XMC72_EVK
CYW20829 - ex: CYW920829-KEYBOARD and CYW920829-MOUSE
PSOC_062_512K - ex: CY8CPROTO-062S3-4343W
PSOC_062_1M - ex: CY8CKIT-062-BLE
PSOC_062_2M - ex: CY8CPROTO-062-4343W CY8CEVAL-062S2-LAI-4373M2 CY8CEVAL-062S2-CYW943439M2IPA1 CY8CKIT-062S2-43012
PSOC_063_1M - ex: CY8CPROTO-063-BLE
PSOC_064_2M - ex: CY8CKIT-064B0S2-4343W
Default value is set for officially supported kits. For reference kit value should be set. | +| OTA_FLASH_MAP= | No | Depends on Target Support | Default flash_maps are available [here](./../../configs/COMPONENT_MCUBOOT/flashmap) for supported targets.
If this makefile entry is empty then ota-bootloader-abstraction library uses target default flash map for generating flashmap.mk.
JSON file passed to flashmap.py that generates flashmap.mk.
For XMC7200, new flashmap format is used and it is parsed using flashmap_xmc.py.
The JSON file defines:
- Internal / external flash usage
- Flash area location and sizes
- Number of images / slots
- XIP (from external flash) if defined | +| OTA_LINKER_FILE= | Yes | Error | Based on selected target, Create OTA linker file for XIP or Non XIP mode.
Template linkers for supported platforms are available [here](./../../template_linkers/COMPONENT_MCUBOOT/). | +| CY_TEST_APP_VERSION_IN_TAR=\<0,1\> | No | 0 | Set to 1 to enable checking application version in TAR file in OTA library when updating using a TAR file. | +| CY_PYTHON_PATH=\ | Yes | Error | MCUBootloader based OTA Pre-build and Post-build scripts uses python.
Users is expected to use this Makefile entry to provide Python path. | +| CY_SIGN_KEY_PATH=\ | No | Test key 'cypress-test-ec-p256.pem' is used for signing. | MCUBootloader uses the default key for validating images.
Users can use this Makefile entry to use their own key for signing BOOT/UPGRADE images. | +| IMG_SIGNING_SCRIPT_TOOL_PATH=\ | No | For PSoC6 - Image Signing Tool provided by MCUBootloader.
For 20829 - cysecuretools v4.2
For XMC7200 - cysecuretools 5.0 | Users can use this Makefile entry to use a tool of their choice for signing update images.
If this makefile entry is empty, ota-bootloader-abstraction library uses the default Image signing tools depending on the Target device. | +| OTA_POLICY_FILE_PATH=\ | No | Depends on Target Support | User needs to define this Makefile entry to provide the policy file path for 20829 devices which use cysecuretools for signing update images.
Refer to [MCUBoot App Readme](./MCUBOOT_APP_README.md).
This is not required for PSoC6 non-secure devices. | +| OTA_APP_POSTBUILD=\ | No | Post-build commands for generating Signed BOOT and UPGRADE images. | Users can use this Makefile entry to provide their own post-build commands.
If this makefile entry is empty, the ota-bootloader-abstraction library uses the default POSTBUILD commands which create signed BOOT and UPGRADE images.| + +Notes: +- ota-bootloader-abstraction repo provides makefiles/mcuboot/mcuboot_support.mk file for simplifying the ota-bootloader-abstraction library integration with the applications. +- Application Makefile needs to include mcuboot_support.mk file from the ota-bootloader-abstraction library for the Target dependent Flashmap Configurations and pre/post build scripts. + ``` + include ../mtb_shared/ota-bootloader-abstraction//makefiles/mcuboot/mcuboot_support.mk + ``` diff --git a/source/COMPONENT_MCUBOOT/cy_flash_map.c b/source/COMPONENT_MCUBOOT/cy_flash_map.c new file mode 100644 index 0000000..c3784c2 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_flash_map.c @@ -0,0 +1,658 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * This is the source file of flash driver adaptation layer between PSoC6 + * and standard MCUBoot code. + */ + +/***************************************************************************** + * + * This is a modified version that only includes minimal functionality needed by + * Infineon ota-update library. + * +******************************************************************************/ + +/* + * The defines used can be generated by a JSON file, the files are located in configs/COMPONENT_MCUBOOT/flashmap/. + * Add to the make command line + * make build FLASH_MAP=$(SEARCH_ota-bootloader-abstraction/configs/COMPONENT_MCUBOOT/flashmap/ + * + * FLASH_AREA_BOOTLOADER_DEV_ID + * FLASH_AREA_BOOTLOADER_START + * FLASH_AREA_BOOTLOADER_SIZE + * FLASH_AREA_IMG_1_PRIMARY_DEV_ID + * FLASH_AREA_IMG_1_PRIMARY_START + * FLASH_AREA_IMG_1_PRIMARY_SIZE + * FLASH_AREA_IMG_1_SECONDARY_DEV_ID + * FLASH_AREA_IMG_1_SECONDARY_START + * FLASH_AREA_IMG_1_SECONDARY_SIZE + * FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID + * FLASH_AREA_IMAGE_SWAP_STATUS_START + * FLASH_AREA_IMAGE_SWAP_STATUS_SIZE + * FLASH_AREA_IMAGE_SCRATCH_DEV_ID + * FLASH_AREA_IMAGE_SCRATCH_START + * FLASH_AREA_IMAGE_SCRATCH_SIZE + * MCUBOOT_IMAGE_NUMBER + * MCUBOOT_MAX_IMG_SECTORS + */ + +#include +#include +#include +#include +#include +#include "cy_pdl.h" + +#include "flash_map_backend.h" +#include "cy_ota_api.h" +#include "cy_ota_bootloader_abstraction_log.h" +#include "cy_ota_flash.h" + +#ifdef PSOC_064_2M +/* Include flashmap header for PSoC64 kit */ +#include "cy_flash_map_psoc64.h" +#else +/* This header file will get generated during building depending on flashmap choosen. */ +#include "cy_flash_map.h" +#endif + +/* This is the value of internal flash bytes after an erase */ +#define CY_BOOT_INTERNAL_FLASH_ERASE_VALUE (0x00) +/* This is the value of external flash bytes after an erase */ +#define CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE (0xff) + +/* For CYW20829 this needs to be 256. Tested OK */ +#if defined(CYW20829) + #define BOOT_MAX_ALIGN 256u +#endif + +#if defined(XMC7200) + #define BOOT_MAX_ALIGN 8u +#endif + +#if defined(PSOC_062_2M) || defined(PSOC_062_1M) || defined(PSOC_062_512K) || defined(PSOC_063_1M) || defined(PSOC_064_2M) + #define BOOT_MAX_ALIGN 512u +#endif + +#ifndef BOOT_MAX_ALIGN +#warning "No MAX_BOOT_ALIGN set, defaulting to 8" +#define BOOT_MAX_ALIGN 8u +#endif + +/* alignment within the MCUBoot Trailer */ +#define BOOT_TRAILER_ALIGN 8u + + +/* This is not actually used by mcuboot's code but can be used by apps + * when attempting to read/write a trailer. + struct image_trailer { + uint8_t swap_type; + uint8_t pad1[BOOT_TRAILER_ALIGN - 1]; + uint8_t copy_done; + uint8_t pad2[BOOT_TRAILER_ALIGN - 1]; + uint8_t image_ok; + uint8_t pad3[BOOT_TRAILER_ALIGN - 1]; + uint8_t magic[16]; + }; +*/ + + +/* Construct the swap_info field from swap type and image number */ +#define BOOT_SET_SWAP_INFO(swap_info, image, type) { \ + assert((image) < 0xF); \ + assert((type) < 0xF); \ + (swap_info) = ((image) << 4) \ + | (type); \ + } + +static const uint32_t boot_img_magic[] = { + 0xf395c277u, + 0x7fefd260u, + 0x0f505235u, + 0x8079b62cu, +}; + +/* size of the boot_image_magic in mcuboot slot */ +#define BOOT_MAGIC_SZ (sizeof(boot_img_magic)) + +uint8_t flash_area_erased_val(const struct flash_area *fap); + +/* Define DEBUG_PRINT_OPEN_AREA to print flash area info when area is opened */ + +#ifndef DEBUG_PRINT_OPEN_AREA +#define DEBUG_PRINT_FLASH_AREA(fa) +#else +void print_flash_area_desc(const struct flash_area *fa) +{ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, "\nMCUBoot flash area:\n"); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, " fa_id: %d\r\n", fa->fa_id); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, " device_id: %d\r\n", fa->fa_device_id); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, " fa_off: 0x%08lx\r\n", fa->fa_off); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, " fa_size: 0x%08lx\r\n", fa->fa_size); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, " erase_val: 0x%02x\r\n", flash_area_erased_val(fa)); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, "\r\n"); +} + +void print_all_flash_area_descs(void) +{ + int i; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "\r\nMCUBoot flash areas:\r\n"); + for (i = 0; boot_area_descs[i] != NULL; i++) + { + print_flash_area_desc(boot_area_descs[i]); + } +} + +#define DEBUG_PRINT_FLASH_AREA(fa) print_flash_area_desc(fa) +#define DEBUG_PRINT_FLASH_AREAS() print_all_flash_area_descs +#endif + +uint8_t flash_area_erased_val(const struct flash_area *fap) +{ + uint8_t ret = 0; + + if(fap->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) + { + ret = CY_BOOT_INTERNAL_FLASH_ERASE_VALUE ; + } + #ifdef OTA_USE_EXTERNAL_FLASH + else if((fap->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) + { + ret = CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE; + } + #endif + else + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "\nInvalid memory device ID"); + assert(false) ; + } + + return ret; +} + + /* +* Opens the area for use. id is one of the `fa_id`s +*/ +int8_t flash_area_open(uint8_t id, const struct flash_area **fa) +{ + int8_t ret = -1; + uint32_t i = 0; + + if(NULL != fa) + { + while(NULL != boot_area_descs[i]) + { + if(id == boot_area_descs[i]->fa_id) + { + *fa = boot_area_descs[i]; + ret = 0; + DEBUG_PRINT_FLASH_AREA(*fa); /* enable above for debugging */ + break; + } + i++; + } + } + + return ret; +} + +/* +* Clear pointer to flash area fa +*/ +void flash_area_close(const struct flash_area *fa) +{ + (void)fa; /* Nothing to do there */ +} + +/* +* Reads `len` bytes of flash memory at `off` to the buffer at `dst` +*/ +int8_t flash_area_read(const struct flash_area *fa, uint32_t off, void *dst, uint32_t len) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + size_t addr = 0; + + /* check if requested offset not less then flash area (fa) start */ + if((NULL == fa) || (NULL == dst) || ((off > fa->fa_size) || (len > fa->fa_size) || ((off + len) > fa->fa_size))) + { + return BOOT_EBADARGS; + } + + /* Add base of flash area and offset within the flash area */ + addr = fa->fa_off + off; + + if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) + { +#if defined(CYW20829) + /* CYW20829 does not have internal flash - check your flash layout JSON file!*/ + return BOOT_EBADARGS; +#endif +#if defined(PSOC_062_2M) || defined(PSOC_062_1M) || defined(PSOC_062_512K) || defined(PSOC_063_1M) || defined(PSOC_064_2M) || defined(XMC7200) + result = cy_ota_mem_read(CY_OTA_MEM_TYPE_INTERNAL_FLASH, addr, dst, len); +#endif + } +#ifdef OTA_USE_EXTERNAL_FLASH + else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) + { + result = cy_ota_mem_read(CY_OTA_MEM_TYPE_EXTERNAL_FLASH, addr, dst, len); + } +#endif + else + { + /* incorrect/non-existing flash device id */ + result = CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED; + } + + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Flash area read error, result = [0x%X]", (uint32_t)result); + return -1; + } + + return 0; +} + +/*< Writes `len` bytes of flash memory at `off` from the buffer at `src` */ +int8_t flash_area_write(const struct flash_area *fa, uint32_t off, const void *src, uint32_t len) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + size_t addr = 0; + + /* check if requested offset not less then flash area (fa) start */ + if((NULL == fa) || (NULL == src) || ((off > fa->fa_size) || (len > fa->fa_size) || ((off + len) > fa->fa_size))) + { + return BOOT_EBADARGS; + } + + /* Add base of flash area and offset within the flash area */ + addr = fa->fa_off + off; + + if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) + { +#if defined(CYW20829) + /* CYW20829 does not have internal flash - check your flash layout JSON file!*/ + return BOOT_EBADARGS; +#endif +#if defined(PSOC_062_2M) || defined(PSOC_062_1M) || defined(PSOC_062_512K) || defined(PSOC_063_1M) || defined(PSOC_064_2M) || defined(XMC7200) + result = cy_ota_mem_write(CY_OTA_MEM_TYPE_INTERNAL_FLASH, addr, (void *)src, len); +#endif + } +#ifdef OTA_USE_EXTERNAL_FLASH + else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) + { + result = cy_ota_mem_write(CY_OTA_MEM_TYPE_EXTERNAL_FLASH, addr, (void *)src, len); + } +#endif + else + { + /* incorrect/non-existing flash device id */ + result = CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED; + } + + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Flash area write error, result = [0x%X]", (uint32_t)result); + return -1; + } + + return 0; +} + +/*< Erases `len` bytes of flash memory at `off` */ +int8_t flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + size_t addr = 0; + + /* check if requested offset not less then flash area (fa) start */ + if(NULL == fa) + { + return BOOT_EBADARGS; + } + + assert(off < fa->fa_off); + assert(off + len < fa->fa_off + fa->fa_size); + + /* Add base of flash area and offset within the flash area */ + addr = fa->fa_off + off; + + if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) + { +#if defined(CYW20829) + /* CYW20829 does not have internal flash - check your flash layout JSON file!*/ + return BOOT_EBADARGS; +#endif +#if defined(PSOC_062_2M) || defined(PSOC_062_1M) || defined(PSOC_062_512K) || defined(PSOC_063_1M) || defined(PSOC_064_2M) || defined(XMC7200) + result = cy_ota_mem_erase(CY_OTA_MEM_TYPE_INTERNAL_FLASH, addr, len); +#endif + } +#ifdef OTA_USE_EXTERNAL_FLASH + else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) + { + result = cy_ota_mem_erase(CY_OTA_MEM_TYPE_EXTERNAL_FLASH, addr, len); + } +#endif /* OTA_USE_EXTERNAL_FLASH */ + else + { + /* incorrect/non-existing flash device id */ + result = CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED; + } + + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Flash area erase error, result = [0x%X]", (uint32_t)result); + return -1; + } + + return 0; +} + +static inline uint32_t boot_magic_off(const struct flash_area *fap) +{ + return fap->fa_size - BOOT_MAGIC_SZ; +} + +static inline uint32_t boot_image_ok_off(const struct flash_area *fap) +{ + return boot_magic_off(fap) - BOOT_TRAILER_ALIGN; +} + +static inline uint32_t boot_copy_done_off(const struct flash_area *fap) +{ + return boot_image_ok_off(fap) - BOOT_TRAILER_ALIGN; +} + +static inline uint32_t boot_swap_info_off(const struct flash_area *fap) +{ + return boot_copy_done_off(fap) - BOOT_TRAILER_ALIGN; +} + +/*< Returns this `flash_area`s alignment */ +size_t flash_area_align(const struct flash_area *fa) +{ + size_t rc = 0u; /* error code (alignment cannot be zero) */ + + if(NULL != fa) + { + if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) + { +#ifdef XMC7200 + rc = BOOT_MAX_ALIGN; +#else + rc = cy_ota_mem_get_prog_size(CY_OTA_MEM_TYPE_INTERNAL_FLASH, 0); +#endif + } +#ifdef OTA_USE_EXTERNAL_FLASH + else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) + { + rc = cy_ota_mem_get_prog_size(CY_OTA_MEM_TYPE_EXTERNAL_FLASH, 0); + } +#endif /* OTA_USE_EXTERNAL_FLASH */ + else + { + /* Not valid - alignment cannot be 0 */ + } + } + + return rc; +} + +/** + * Write trailer data; status bytes, swap_size, etc + * + * @returns 0 on success, != 0 on error. + */ +int8_t boot_write_trailer(const struct flash_area *fap, uint32_t off, const uint8_t *inbuf, uint8_t inlen) +{ + uint8_t buf[BOOT_MAX_ALIGN]; + size_t align; + uint8_t erased_val; + int8_t rc; + + align = flash_area_align(fap); + if(align == 0u) + { + return BOOT_EFLASH; + } + + align = ((inlen + align - 1) & (~(align - 1))); + if(align > BOOT_MAX_ALIGN) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() align 0x%x > 0x%x BOOT_MAX_ALIGN , ret -1\n", __LINE__, __func__, align, BOOT_MAX_ALIGN); + return -1; + } + erased_val = flash_area_erased_val(fap); + + memcpy(buf, inbuf, inlen); + memset(&buf[inlen], erased_val, (align - inlen)); + + if((off + align) > fap->fa_size) + { + align = fap->fa_size - off; + } + + rc = flash_area_write(fap, off, buf, align); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() flash_area_write(fap, 0x%lx, %p, 0x%lx) , ret %d\n", __LINE__, __func__, off, buf, align, rc); + if(rc != 0) + { + return BOOT_EFLASH; + } + + return 0; +} + +int8_t boot_write_magic(const struct flash_area *fap) +{ + uint8_t magic[BOOT_MAGIC_SZ]; + uint32_t off; + int8_t rc; + + /* + * For XIP builds, boot_img_magic may end up stored in external flash. + * Copy the data to a temporary buffer to avoid trying to access + * an external flash buffer while using ram SMIF write routines.. + */ + + memcpy(&(magic[0]), &(boot_img_magic[0]), BOOT_MAGIC_SZ); + + off = boot_magic_off(fap); + rc = flash_area_write(fap, off, magic, BOOT_MAGIC_SZ); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() fap->off 0x%lx off 0x%lx rc %d\n", __func__, fap->fa_off, off, rc); + if(rc != 0) + { + return BOOT_EFLASH; + } + + return 0; +} + +int8_t boot_write_image_ok(const struct flash_area *fap) +{ + uint32_t off; + uint8_t buff[2]; + int8_t rc; + + off = boot_image_ok_off(fap); + buff[0] = BOOT_FLAG_SET; + rc = flash_area_write(fap, off, buff, 1); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() fap->off 0x%lx off 0x%lx rc %d\n", __func__, fap->fa_off, off, rc); + if(rc != 0) + { + return BOOT_EFLASH; + } + + return 0; +} + +/** + * Writes the specified value to the `swap-type` field of an image trailer. + * This value is persisted so that the boot loader knows what swap operation to + * resume in case of an unexpected reset. + */ +int8_t boot_write_swap_info(const struct flash_area *fap, uint8_t swap_type, uint8_t image_num) +{ + uint32_t off; + uint8_t swap_info; + int8_t rc = 0; + + BOOT_SET_SWAP_INFO(swap_info, image_num, swap_type); + off = boot_swap_info_off(fap); + rc = boot_write_trailer(fap, off, (const uint8_t *) &swap_info, 1); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() fap->off 0x%lx off 0x%lx rc %d\n", __func__, fap->fa_off, off, rc); + if(rc != 0) + { + return BOOT_EFLASH; + } + + return 0; +} + +/** + * Marks the image in the secondary slot as pending. On the next reboot, + * the system will perform a one-time boot of the the secondary slot image. + * + * @param image 0 = Secondary_Slot_1, 1 = Secondary_Slot_2 + * @param permanent Whether the image should be used permanently or only tested once: + * 0=run image once, then confirm or revert. + * 1=run image forever. + * + * @return 0 on success; nonzero on failure. + */ +int8_t flash_area_boot_set_pending(uint8_t image, uint8_t permanent) +{ + const struct flash_area *fap; + int8_t rc = 0; + + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image), &fap); + if(rc == 0) + { + rc = boot_write_magic(fap); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() boot_write_magic(fap) returned %d\n", __func__, rc); + + /* + * Writing trailer flags doesn't work properly for internal flash. That's OK + * because writing the magic does work and that's enough to trigger the update. + */ + if( (fap->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) + { + uint8_t swap_type; + if((rc == 0) && permanent) + { + rc = boot_write_image_ok(fap); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() boot_write_image_ok(fap) returned %d\n", __func__, rc); + } + + if(rc == 0) + { + if(permanent) + { + swap_type = BOOT_SWAP_TYPE_PERM; + } + else + { + swap_type = BOOT_SWAP_TYPE_TEST; + } + rc = boot_write_swap_info(fap, swap_type, 0); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() boot_write_swap_info(fap) returned %d\n", __func__, rc); + } + } + + flash_area_close(fap); + } + + return rc; +} + +/** + * Marks the image in the secondary slot as Invalidated, once the Primary Image is set as Confirmed. + * + * @param image 0 = Secondary_Slot_1, 1 = Secondary_Slot_2 + * + * @return 0 on success; nonzero on failure. + */ +int8_t flash_area_boot_unset_pending(uint8_t image) +{ + const struct flash_area *fap; + int8_t rc = 0; + + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image), &fap); + if(rc == 0) + { + uint8_t magic[BOOT_MAGIC_SZ]; + uint32_t off; + + memset(&(magic[0]), 0x00, BOOT_MAGIC_SZ); + + off = boot_magic_off(fap); + rc = flash_area_write(fap, off, magic, BOOT_MAGIC_SZ); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() fap->off 0x%lx off 0x%lx rc %d\n", __func__, fap->fa_off, off, rc); + if(rc != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() flash_area_write() failed, returned rc = %d\n", __func__, rc); + return BOOT_EFLASH; + } + flash_area_close(fap); + } + + return rc; +} + +/** + * Marks the image in the primary slot as confirmed. The system will continue + * booting into the image in the primary slot until told to boot from a + * different slot. + * + * @return 0 on success; nonzero on failure. + */ +int8_t flash_area_boot_set_confirmed(void) +{ + const struct flash_area *fap; + int8_t rc = 0; + + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &fap); + if(rc == 0) + { + rc = boot_write_magic(fap); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() boot_write_magic() returned %d\n", __func__, rc); + if(rc == 0) + { + rc = boot_write_image_ok(fap); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "boot_write_image_ok() returned %d\n", rc); + } + flash_area_close(fap); + } + + return rc; +} diff --git a/source/COMPONENT_MCUBOOT/cy_flash_map_psoc64.h b/source/COMPONENT_MCUBOOT/cy_flash_map_psoc64.h new file mode 100644 index 0000000..52945af --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_flash_map_psoc64.h @@ -0,0 +1,92 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Flashmap header for PSOC_064_2M. + */ + +#ifndef CY_FLASH_MAP_PSOC_64_H +#define CY_FLASH_MAP_PSOC_64_H + +static struct flash_area flash_areas[] = { + { + .fa_id = FLASH_AREA_BOOTLOADER, + .fa_device_id = FLASH_AREA_BOOTLOADER_DEV_ID, + .fa_off = FLASH_AREA_BOOTLOADER_START, + .fa_size = FLASH_AREA_BOOTLOADER_SIZE, + }, + { + .fa_id = FLASH_AREA_IMG_1_PRIMARY, + .fa_device_id = FLASH_AREA_IMG_1_PRIMARY_DEV_ID, + .fa_off = FLASH_AREA_IMG_1_PRIMARY_START, + .fa_size = FLASH_AREA_IMG_1_PRIMARY_SIZE, + }, + { + .fa_id = FLASH_AREA_IMG_1_SECONDARY, + .fa_device_id = FLASH_AREA_IMG_1_SECONDARY_DEV_ID, + .fa_off = FLASH_AREA_IMG_1_SECONDARY_START, + .fa_size = FLASH_AREA_IMG_1_SECONDARY_SIZE, + } +#ifdef FLASH_AREA_IMAGE_SCRATCH_DEV_ID + ,{ + .fa_id = FLASH_AREA_IMAGE_SCRATCH, + .fa_device_id = FLASH_AREA_IMAGE_SCRATCH_DEV_ID, + .fa_off = FLASH_AREA_IMAGE_SCRATCH_START, + .fa_size = FLASH_AREA_IMAGE_SCRATCH_SIZE, + } +#endif +#ifdef FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID + ,{ + .fa_id = FLASH_AREA_IMAGE_SWAP_STATUS, + .fa_device_id = FLASH_AREA_IMAGE_SWAP_STATUS_DEV_ID, + .fa_off = FLASH_AREA_IMAGE_SWAP_STATUS_START, + .fa_size = FLASH_AREA_IMAGE_SWAP_STATUS_SIZE, + } +#endif +}; + +/* These are indexes into the above table and do not directly correspond with the fa_id */ +struct flash_area *boot_area_descs[] = { + &flash_areas[0U], + &flash_areas[1U], + &flash_areas[2U], +#ifdef FLASH_AREA_IMAGE_SCRATCH_START + &flash_areas[3U], +#endif +#ifdef FLASH_AREA_IMAGE_SWAP_STATUS_START + &flash_areas[4U], +#endif + NULL +}; + +#endif /* CY_FLASH_MAP_PSOC_64_H */ diff --git a/source/COMPONENT_MCUBOOT/cy_ota_flash.h b/source/COMPONENT_MCUBOOT/cy_ota_flash.h new file mode 100644 index 0000000..8ce8a47 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_ota_flash.h @@ -0,0 +1,185 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +#ifndef CY_OTA_FLASH_H_ +#define CY_OTA_FLASH_H_ + +#include "cy_result_mw.h" + +/* OTA API */ +#include "cy_pdl.h" +#include "cyhal.h" + +/** + * \addtogroup group_ota_bootsupport + * \{ + */ + +/*********************************************************************** + * + * Defines & Enums + * + **********************************************************************/ + /** + * \addtogroup group_ota_bootsupport_macros + * \{ + */ +/** The function or operation is not supported on the target or the memory */ +#define CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 1)) +/** The Serial Flash not initialized */ +#define CY_RSLT_SERIAL_FLASH_ERR_NOT_INITED (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 2)) +/** Parameters passed to a function are invalid */ +#define CY_RSLT_SERIAL_FLASH_ERR_BAD_PARAM (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 3)) +/** A previously initiated read operation is not yet complete */ +#define CY_RSLT_SERIAL_FLASH_ERR_READ_BUSY (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 4)) +/** A DMA error occurred during read transfer */ +#define CY_RSLT_SERIAL_FLASH_ERR_DMA (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 5)) +/** Read abort failed. QSPI block is busy. */ +#define CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY (cy_rslt_t)(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 6)) + +/** \} group_ota_macros */ + + +/** + * \addtogroup group_ota_bootsupport_typedefs + * \{ + */ + +/** + * @brief Enumeration of OTA storage types. + */ +typedef enum +{ + CY_OTA_MEM_TYPE_INTERNAL_FLASH = 0, /**< For internal flash type. */ + CY_OTA_MEM_TYPE_EXTERNAL_FLASH, /**< For external flash type. */ + CY_OTA_MEM_TYPE_RRAM, /**< For RRAM type. */ + CY_OTA_MEM_TYPE_NONE /**< Default value. */ +} cy_ota_mem_type_t; + +/** \} group_ota_typedefs */ + +/*********************************************************************** + * + * Functions + * + **********************************************************************/ +/** + * \addtogroup group_ota_bootsupport_functions + * \{ + * OTA Bootloader support library flash operation APIs. Storage Interface APIs call these flash operation APIs + * to store downloaded UPGRADE image on Internal or External Flash based on target platforms. + */ + +/** + * @brief Initializes flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +cy_rslt_t cy_ota_mem_init(void); + +/** + * @brief Read from flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to read from. + * @param[out] data Pointer to the buffer to store the data read from the memory. + * @param[in] len Number of data bytes to read. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +cy_rslt_t cy_ota_mem_read(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len); + +/** + * @brief Write to flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to write to. + * @param[in] data Pointer to the buffer containing the data to be written. + * @param[in] len Number of bytes to write. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +cy_rslt_t cy_ota_mem_write(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len); + +/** + * @brief Erase flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to begin erasing. + * @param[in] len Number of bytes to erase. + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_TYPE_ERROR + */ +cy_rslt_t cy_ota_mem_erase(cy_ota_mem_type_t mem_type, uint32_t addr, size_t len); + +/** + * @brief To get page size for programming flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Address that belongs to the sector for which programming page size needs to be returned. + * + * @return Page size in bytes. + */ +size_t cy_ota_mem_get_prog_size(cy_ota_mem_type_t mem_type, uint32_t addr); + +/** + * @brief To get sector size of flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Address that belongs to the sector for which sector erase size needs to be returned. + * + * @return Sector size in bytes. + */ +size_t cy_ota_mem_get_erase_size(cy_ota_mem_type_t mem_type, uint32_t addr); + +/** \} group_ota_bootsupport_functions */ + +/** \} group_ota_bootsupport */ + +#endif /* CY_OTA_FLASH_H_ */ diff --git a/source/COMPONENT_MCUBOOT/cy_ota_flash_weak.c b/source/COMPONENT_MCUBOOT/cy_ota_flash_weak.c new file mode 100644 index 0000000..049f9b1 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_ota_flash_weak.c @@ -0,0 +1,235 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Weak functions for ota flash APIs + * + */ + +#include +#include +#include +#include + +#include "cy_ota_flash.h" + +/*********************************************************************** + * + * defines & enums + * + * For more info on locations within slots, please see MCUBootApp + * bootutils_misc.c, bootutils_private.h, bootutils.h + * + **********************************************************************/ + +/*********************************************************************** + * + * Macros + * + **********************************************************************/ +#if defined(__ICCARM__) +#define OTA_WEAK_FUNCTION __WEAK +#define TLS_ATTR_PACKED(struct) __packed struct +#elif defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) +#define OTA_WEAK_FUNCTION __attribute__((weak)) +#define TLS_ATTR_PACKED(struct) struct __attribute__((packed)) +#else +#define OTA_WEAK_FUNCTION __attribute__((weak)) +#define TLS_ATTR_PACKED(struct) struct __attribute__((packed)) +#endif /* defined(__ICCARM__) */ + +#define UNUSED_ARG(arg) (void)(arg) + +/*********************************************************************** + * + * Structures + * + **********************************************************************/ + +/*********************************************************************** + * + * Variables + * + **********************************************************************/ + +/*********************************************************************** + * + * functions + * + **********************************************************************/ +/** + * @brief Initializes flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +OTA_WEAK_FUNCTION cy_rslt_t cy_ota_mem_init(void) +{ + /* + * This function does nothing, weak implementation. + * The purpose of this code is to disable compiler warnings for Non-optimized + * builds which do not remove unused functions and require them for the + * completeness of the linking step. + */ + return CY_RSLT_SUCCESS; +} + +/** + * @brief Read from flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to read from. + * @param[out] data Pointer to the buffer to store the data read from the memory. + * @param[in] len Number of data bytes to read. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +OTA_WEAK_FUNCTION cy_rslt_t cy_ota_mem_read(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len) +{ + /* + * This function does nothing, weak implementation. + * The purpose of this code is to disable compiler warnings for Non-optimized + * builds which do not remove unused functions and require them for the + * completeness of the linking step. + */ + UNUSED_ARG(mem_type); + UNUSED_ARG(addr); + UNUSED_ARG(data); + UNUSED_ARG(len); + return CY_RSLT_SUCCESS; +} + +/** + * @brief Write to flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to write to. + * @param[in] data Pointer to the buffer containing the data to be written. + * @param[in] len Number of bytes to write. + * + * @return CY_RSLT_SUCCESS on success + * CY_RSLT_TYPE_ERROR on failure + */ +OTA_WEAK_FUNCTION cy_rslt_t cy_ota_mem_write(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len) +{ + /* + * This function does nothing, weak implementation. + * The purpose of this code is to disable compiler warnings for Non-optimized + * builds which do not remove unused functions and require them for the + * completeness of the linking step. + */ + UNUSED_ARG(mem_type); + UNUSED_ARG(addr); + UNUSED_ARG(data); + UNUSED_ARG(len); + return CY_RSLT_SUCCESS; +} + +/** + * @brief Erase flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Starting address to begin erasing. + * @param[in] len Number of bytes to erase. + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_TYPE_ERROR + */ +OTA_WEAK_FUNCTION cy_rslt_t cy_ota_mem_erase(cy_ota_mem_type_t mem_type, uint32_t addr, size_t len) +{ + /* + * This function does nothing, weak implementation. + * The purpose of this code is to disable compiler warnings for Non-optimized + * builds which do not remove unused functions and require them for the + * completeness of the linking step. + */ + UNUSED_ARG(mem_type); + UNUSED_ARG(addr); + UNUSED_ARG(len); + return CY_RSLT_SUCCESS; +} + +/** + * @brief To get page size for programming flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Address that belongs to the sector for which programming page size needs to be returned. + * + * @return Page size in bytes. + */ +OTA_WEAK_FUNCTION size_t cy_ota_mem_get_prog_size(cy_ota_mem_type_t mem_type, uint32_t addr) +{ + /* + * This function does nothing, weak implementation. + * The purpose of this code is to disable compiler warnings for Non-optimized + * builds which do not remove unused functions and require them for the + * completeness of the linking step. + */ + UNUSED_ARG(mem_type); + UNUSED_ARG(addr); + return CY_RSLT_SUCCESS; +} + +/** + * @brief To get sector size of flash, QSPI flash, or any other external memory type + * + * NOTE: This function must be implemented in the user's code. + * + * @param[in] mem_type Memory type @ref cy_ota_mem_type_t + * @param[in] addr Address that belongs to the sector for which sector erase size needs to be returned. + * + * @return Sector size in bytes. + */ +OTA_WEAK_FUNCTION size_t cy_ota_mem_get_erase_size(cy_ota_mem_type_t mem_type, uint32_t addr) +{ + /* + * This function does nothing, weak implementation. + * The purpose of this code is to disable compiler warnings for Non-optimized + * builds which do not remove unused functions and require them for the + * completeness of the linking step. + */ + UNUSED_ARG(mem_type); + UNUSED_ARG(addr); + return CY_RSLT_SUCCESS; +} diff --git a/source/COMPONENT_MCUBOOT/cy_ota_storage_api.c b/source/COMPONENT_MCUBOOT/cy_ota_storage_api.c new file mode 100644 index 0000000..b6d291b --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_ota_storage_api.c @@ -0,0 +1,296 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Cypress OTA Download Storage abstraction + */ + +#include +#include +#include +#include + +#include "cy_ota_api.h" +#include "cy_ota_internal.h" + +#include "flash_map_backend.h" +#include "cy_ota_storage_api.h" +#include "cy_ota_flash.h" +#include "cy_ota_bootloader_abstraction_log.h" + +/*********************************************************************** + * + * defines & enums + * + * For more info on locations within slots, please see MCUBootApp + * bootutils_misc.c, bootutils_private.h, bootutils.h + * + **********************************************************************/ + +/*********************************************************************** + * + * Macros + * + **********************************************************************/ + +/*********************************************************************** + * + * Structures + * + **********************************************************************/ + +/*********************************************************************** + * + * Variables + * + **********************************************************************/ + +/*********************************************************************** + * + * functions + * + **********************************************************************/ +/** + * @brief Initialize Storage area + * + * NOTE: Typically, this initializes Secondary Slot storage area + * + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_TYPE_ERROR + */ +cy_rslt_t cy_ota_storage_init(void) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s()\n", __func__); + result = cy_ota_mem_init(); + return result; +} + +/** + * @brief Open Storage area for download + * + * NOTE: Typically, this erases Secondary Slot + * + * @param[in] storage_ptr - Pointer to the OTA Agent storage context @ref cy_ota_storage_context_t + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_OPEN_STORAGE + */ +cy_rslt_t cy_ota_storage_open(cy_ota_storage_context_t *storage_ptr) +{ + const struct flash_area *fap; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s()\n", __func__); + if(storage_ptr == NULL) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Storage context pointer for %s() is invalid\n", __func__); + return CY_RSLT_OTA_ERROR_OPEN_STORAGE; + } + + /* clear out the stats */ + storage_ptr->total_image_size = 0; + storage_ptr->total_bytes_written = 0; + storage_ptr->last_offset = 0; + storage_ptr->last_size = 0; + storage_ptr->storage_loc = NULL; + + if(flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0), &fap) != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0) ) failed\n"); + return CY_RSLT_OTA_ERROR_OPEN_STORAGE; + } + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_NOTICE, "Erase secondary image slot fap->fa_off: 0x%08lx, size: 0x%08lx\n", fap->fa_off, fap->fa_size); + if(flash_area_erase(fap, 0, fap->fa_size) != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "flash_area_erase(fap, 0) failed\r\n"); + return CY_RSLT_OTA_ERROR_OPEN_STORAGE; + } + + storage_ptr->storage_loc = (void *)fap; + + return CY_RSLT_SUCCESS; +} + +/** + * @brief Read from storage area + * + * @param[in] storage_ptr - Pointer to the OTA Agent storage context @ref cy_ota_storage_context_t + * @param[in][out] chunk_info - Pointer to chunk information, buffer pointer used for the read + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_READ_STORAGE + */ +cy_rslt_t cy_ota_storage_read(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_read_info_t *chunk_info) +{ + const struct flash_area *fap; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s()\n", __func__); + if(storage_ptr == NULL) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Storage context pointer is invalid\n"); + return CY_RSLT_OTA_ERROR_READ_STORAGE; + } + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_INFO, "buf:%p len:%ld off: 0x%lx (%ld)\n", + chunk_info->buffer, chunk_info->size, + chunk_info->offset, chunk_info->offset); + + /* Always read from secondary slot */ + fap = (const struct flash_area *)storage_ptr->storage_loc; + if(fap != NULL) + { + /* read into the chunk_info buffer */ + if(flash_area_read(fap, chunk_info->offset, chunk_info->buffer, chunk_info->size) != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "flash_area_read() failed \n"); + return CY_RSLT_OTA_ERROR_READ_STORAGE; + } + return CY_RSLT_SUCCESS; + } + else + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() flash_area invalid\r\n", __func__); + return CY_RSLT_OTA_ERROR_READ_STORAGE; + } +} + +/** + * @brief Close Storage area for download + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context @ref cy_ota_storage_context_t + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_CLOSE_STORAGE + */ +cy_rslt_t cy_ota_storage_close(cy_ota_storage_context_t *storage_ptr) +{ + const struct flash_area *fap; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s()\n", __func__); + if(storage_ptr == NULL) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Storage context pointer is invalid\n"); + return CY_RSLT_OTA_ERROR_CLOSE_STORAGE; + } + + /* close secondary slot */ + fap = (const struct flash_area *)storage_ptr->storage_loc; + if(fap == NULL) + { + return CY_RSLT_OTA_ERROR_CLOSE_STORAGE; + } + flash_area_close(fap); + + return CY_RSLT_SUCCESS; +} + +/** + * @brief Verify download signature + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context @ref cy_ota_storage_context_t + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_GENERAL + */ +cy_rslt_t cy_ota_storage_verify(cy_ota_storage_context_t *storage_ptr) +{ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s()\n", __func__); + if(storage_ptr == NULL) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Storage context pointer is invalid\n"); + return CY_RSLT_OTA_ERROR_VERIFY; + } + + if(flash_area_boot_set_pending(0, (storage_ptr->validate_after_reboot == 0)) != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "VERIFY flash_area_boot_set_pending() Failed \n"); + return CY_RSLT_OTA_ERROR_VERIFY; + } + else + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "VERIFY flash_area_boot_set_pending() completed \n"); + return CY_RSLT_SUCCESS; + } +} + +/** + * @brief App has validated the new OTA Image + * + * This call needs to be after reboot and MCUBoot has copied the new Application + * to the Primary Slot. + * + * @param N/A + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_GENERAL + */ +cy_rslt_t cy_ota_storage_image_validate(uint16_t app_id) +{ + /* Mark Image in Primary Slot as valid */ + cy_rslt_t result = CY_RSLT_SUCCESS; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s()\n", __func__); + (void)app_id; + +#ifndef XMC7200 + /* we copy this to a RAM buffer so that if we are running in XIP from external flash, the write routine won't fail */ + result = flash_area_boot_set_confirmed(); + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "VERIFY flash_area_boot_set_confirmed() Failed \n"); + result = CY_RSLT_OTA_ERROR_GENERAL; + } +#else + /* For XMC7200 platform, Remove the Boot Magic from the Image in the Secondary slot to mark the Image in the primary as permanent. */ + if((flash_area_boot_unset_pending(0)) != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "VALIDATE Primary Image: flash_area_boot_unset_pending() Failed \n"); + result = CY_RSLT_OTA_ERROR_GENERAL; + } +#endif + return result; +} + +cy_rslt_t cy_ota_storage_get_app_info(void* file_des, cy_ota_app_info_t *app_info) +{ + cy_rslt_t result = CY_RSLT_OTA_ERROR_UNSUPPORTED; + (void)(file_des); + (void)(app_info); + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s \n", __func__); + + return result; +} diff --git a/source/COMPONENT_MCUBOOT/cy_ota_storage_api.h b/source/COMPONENT_MCUBOOT/cy_ota_storage_api.h new file mode 100644 index 0000000..bf472cb --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_ota_storage_api.h @@ -0,0 +1,175 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Cypress OTA platform storage API header file + */ + +/** @file + * + * Bootloader based OTA platform storage API header file. + * + */ + +#ifndef CY_OTA_STORAGE_API_H_ +#define CY_OTA_STORAGE_API_H_ + +#include "cy_ota_api.h" + +/** + * \addtogroup group_ota_bootsupport Infineon OTA Bootloader Support API + * \{ + * OTA Bootloader support for handling and installing firmware updates. + * + * \defgroup group_ota_bootsupport_macros OTA Bootloader Support Macros + * Macros used to define the OTA Bootloader Support behavior. + * + * \defgroup group_ota_bootsupport_typedefs Bootloader Support Typedefs + * Typedefs used by the OTA Bootloader Support. + * + * \defgroup group_ota_bootsupport_functions Bootloader Support Functions + * Functions for handling and installing firmware updates. + * + */ + +/*********************************************************************** + * + * Functions + * + **********************************************************************/ +/** + * \addtogroup group_ota_bootsupport_functions + * \{ + * Bootloader based storage interface APIs for handling downloaded UPGRADE image of OTA application. + * These callbacks are defind in ota-update library and expected to register these callbacks during OTA agent start. + * ota-bootloader-abstraction library has implementation of these bootloader specific storage interface APIs. + * + */ + +/** + * @brief Initialize Storage area + * + * NOTE: Typically, this initializes flash hardware and Application is expected to call this API + * once before any other flash operation. + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_TYPE_ERROR + */ +cy_rslt_t cy_ota_storage_init(void); + +/** + * @brief Open storage area for storing OTA UPGRADE images. + * + * NOTE: Typically, This erases UPGRADE Slots. + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context 'cy_ota_storage_context_t' + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_OPEN_STORAGE + */ +cy_rslt_t cy_ota_storage_open(cy_ota_storage_context_t *storage_ptr); + +/** + * @brief Read data from storage area + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context 'cy_ota_storage_context_t' + * @param[in] chunk_info Pointer to read chunk information, buffer pointer used for the read + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_READ_STORAGE + */ +cy_rslt_t cy_ota_storage_read(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_read_info_t *chunk_info); + +/** + * @brief Write data to configured storage area + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context 'cy_ota_storage_context_t' + * @param[in] chunk_info Pointer to write data chunk information + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_rslt_t cy_ota_storage_write(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_write_info_t *chunk_info); + +/** + * @brief Close Storage area for download + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context 'cy_ota_storage_context_t' + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_CLOSE_STORAGE + */ +cy_rslt_t cy_ota_storage_close(cy_ota_storage_context_t *storage_ptr); + +/** + * @brief Verify downloaded UPGRADE OTA image + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context 'cy_ota_storage_context_t' + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_GENERAL + */ +cy_rslt_t cy_ota_storage_verify(cy_ota_storage_context_t *storage_ptr); + +/** + * @brief Application has validated the new OTA Image + * + * This call needs to be after reboot and Bootloader has started the upgrade version of Application. + * to the Primary Slot. + * + * @param[in] app_id Application ID. + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_GENERAL + */ +cy_rslt_t cy_ota_storage_image_validate(uint16_t app_id); + +/** + * @brief Get Application image information + * + * This call needs to be after reboot and Bootloader has started the upgrade version of Application. + * to the Primary Slot. + * + * @param[in] file_des Pointer to the storage context. + * @param[in] app_info Pointer to the OTA Application information structure. + * + * @return CY_RSLT_SUCCESS + * CY_RSLT_OTA_ERROR_GENERAL + */ +cy_rslt_t cy_ota_storage_get_app_info(void* file_des, cy_ota_app_info_t *app_info); + +/** \} group_ota_bootsupport_functions */ + +/** \} group_ota_bootsupport */ + +#endif /* CY_OTA_STORAGE_API_H_ */ diff --git a/source/COMPONENT_MCUBOOT/cy_ota_untar.c b/source/COMPONENT_MCUBOOT/cy_ota_untar.c new file mode 100644 index 0000000..9024072 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/cy_ota_untar.c @@ -0,0 +1,485 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Cypress OTA Agent network abstraction un-tar archive + */ + +#include +#include +#include +#include + +#include "cy_ota_api.h" +#include "cy_ota_internal.h" +#include "cy_ota_storage_api.h" +#include "cy_ota_bootloader_abstraction_log.h" + +#include "cyabs_rtos.h" + +#include "untar.h" +#include "flash_map_backend.h" + +/* define CY_TEST_APP_VERSION_IN_TAR to test the application version in the + * TAR archive at start of OTA image download. + * + * NOTE: This requires that the user set the version number in the Makefile + * APP_VERSION_MAJOR + * APP_VERSION_MINOR + * APP_VERSION_BUILD + */ + +/*********************************************************************** + * + * OTA wrappers and callbacks for untar.c + * + **********************************************************************/ + +/*********************************************************************** + * + * defines & enums + * + **********************************************************************/ + +/** + * @brief Tarball support file types recognized in components.json file + * + * The file type in the tarball + */ +#define CY_FILE_TYPE_SPE "SPE" /**< Secure Programming Environment (TFM) code type */ +#define CY_FILE_TYPE_NSPE "NSPE" /**< Non-Secure Programming Environment (application) code type */ + +/*********************************************************************** + * + * Macros + * + **********************************************************************/ + +/*********************************************************************** + * + * Structures + * + **********************************************************************/ + +/*********************************************************************** + * + * Data & Variables + * + **********************************************************************/ + +/** + * @brief Context structure for parsing the tar file + */ +static cy_untar_context_t ota_untar_context; + +/** + * @brief Structure for handling TAR Header for MTU Sizes less than 512 + */ +typedef struct update_file_header +{ + /* Temporary Buffer to handle TAR Header */ + uint8_t *buffer; + + /* Size of data in temporary Buffer */ + uint32_t buffer_size; + + /* Indicates if the TAR header check is completed */ + bool is_tar_header_checked; + +} update_file_header_t; + +static update_file_header_t file_header; + +/*********************************************************************** + * + * Forward declarations + * + **********************************************************************/ + +/*********************************************************************** + * + * Functions + * + **********************************************************************/ + +/** + * @brief callback to handle tar data + * + * @param ctxt untar context + * @param file_index index into ctxt->files for the data + * @param buffer data to use + * @param file_offset offset into the file to store data + * @param chunk_size amount of data in buffer to use + * @param cb_arg argument passed into initialization + * + * return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +static cy_untar_result_t ota_untar_write_callback(cy_untar_context_ptr ctxt, uint16_t file_index, + uint8_t *buffer, uint32_t file_offset, + uint32_t chunk_size, void *cb_arg) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + uint16_t image = 0; + const struct flash_area *fap; + cy_ota_storage_context_t *storage_ptr = (cy_ota_storage_context_t *)cb_arg; + + if((ctxt == NULL) || (buffer == NULL) || (storage_ptr == NULL)) + { + return CY_UNTAR_ERROR; + } + + if(strncmp(ctxt->files[file_index].type, CY_FILE_TYPE_SPE, strlen(CY_FILE_TYPE_SPE)) == 0) + { + image = 1; /* The TFM code, cm0 */ + if((file_offset + chunk_size) > ctxt->files[file_index].size) + { + chunk_size = ctxt->files[file_index].size - file_offset; + } + } + else if(strncmp(ctxt->files[file_index].type, CY_FILE_TYPE_NSPE, strlen(CY_FILE_TYPE_NSPE)) == 0) + { + image = 0; /* The application code, cm4 */ + if((file_offset + chunk_size) > ctxt->files[file_index].size) + { + chunk_size = ctxt->files[file_index].size - file_offset; + } + } + else + { + /* unknown file type */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG2, "%d:%s Unknown File Type: >%s<\n", __LINE__, __func__, ctxt->files[file_index].type); + return CY_UNTAR_ERROR; + } + + if(flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image), &fap) != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() flash_area_open(%d) failed\n", __func__, image); + return CY_UNTAR_ERROR; + } + + if(flash_area_write(fap, file_offset, buffer, chunk_size) != 0) + { + result = CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() failed\n", __func__); + flash_area_close(fap); + return CY_UNTAR_ERROR; + } + + flash_area_close(fap); + + return CY_UNTAR_SUCCESS; +} + +/** + * @brief Initialization routine for handling tarball OTA file + * + * @param ctx_ptr Pointer to OTA agent context + * @param ctx_untar[in,out] pointer to untar context to be initialized + * + * return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +static cy_untar_result_t cy_ota_untar_init_context(cy_ota_storage_context_t *storage_ptr, cy_untar_context_t* ctx_untar ) +{ + if(cy_untar_init( ctx_untar, ota_untar_write_callback, storage_ptr ) == CY_RSLT_SUCCESS) + { + storage_ptr->ota_is_tar_archive = 1; + return CY_UNTAR_SUCCESS; + } + return CY_UNTAR_ERROR; +} + +#if 0 /* keep if needed later */ +/** + * @brief - set pending for the files contained in the TAR archive we just validated. + * + * return CY_UNTAR_SUCCESS + */ +cy_untar_result_t cy_ota_untar_set_pending(void) +{ + uint16_t i; + uint16_t image = 0; + for (i = 0; i < ota_untar_context.num_files_in_json; i++ ) + { + if(strncmp(ota_untar_context.files[i].type, CY_FILE_TYPE_SPE, strlen(CY_FILE_TYPE_SPE)) == 0) + { + image = 1; /* The TFM code, cm0 */ + } + else if(strncmp(ota_untar_context.files[i].type, CY_FILE_TYPE_NSPE, strlen(CY_FILE_TYPE_NSPE)) == 0) + { + image = 0; /* The application code, cm4 */ + } + else + { + /* unknown file type */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s BAD FILE TYPE %d: >%s<\n", __LINE__, __func__, i, ota_untar_context.files[i].type); + continue; + } + boot_set_pending(image, 0); + } + + return CY_UNTAR_SUCCESS; + +} +#endif + +/** + * @brief Determine if tar or non-tar and call correct write function + * + * @param[in] storage_ptr Pointer to the OTA Agent storage context @ref cy_ota_storage_context_t + * @param[in] chunk_info Pointer to chunk information + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_rslt_t cy_ota_storage_write(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_write_info_t * const chunk_info) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + uint16_t copy_offset = 0; + + if((storage_ptr == NULL) || (chunk_info == NULL)) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "Storage context pointer for %s() is invalid\n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + if(chunk_info->offset == 0UL) + { + file_header.is_tar_header_checked = false; + file_header.buffer_size = 0; + } + + if(!file_header.is_tar_header_checked) + { + /* we need to check some things when we receive the first 512 Bytes data */ + if((chunk_info->offset == 0UL) && (chunk_info->size >= TAR_BLOCK_SIZE)) + { + /* + * Check for incoming tarball (as opposed to a single file OTA) + */ + if(cy_is_tar_header(chunk_info->buffer, chunk_info->size) == CY_UNTAR_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_NOTICE, "%d:%s() TAR ARCHIVE\n", __LINE__, __func__); + if(cy_ota_untar_init_context(storage_ptr, &ota_untar_context) != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() cy_ota_untar_init_context() FAILED! \n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + } + else + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_NOTICE, "%d:%s() Non TAR file\n", __LINE__, __func__); + } + file_header.is_tar_header_checked = true; + } + else + { + if(file_header.buffer == NULL) + { + file_header.buffer = (uint8_t *)malloc(TAR_BLOCK_SIZE); + if(file_header.buffer == NULL) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() malloc() for file_header Buffer FAILED! \n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + memset(file_header.buffer, 0x00, TAR_BLOCK_SIZE); + } + + if((file_header.buffer_size + chunk_info->size) < TAR_BLOCK_SIZE) + { + memcpy((file_header.buffer + file_header.buffer_size), chunk_info->buffer, (chunk_info->size)); + file_header.buffer_size += chunk_info->size; + + return CY_RSLT_SUCCESS; + } + else + { + copy_offset = TAR_BLOCK_SIZE - file_header.buffer_size; + memcpy((file_header.buffer + file_header.buffer_size), chunk_info->buffer, copy_offset); + file_header.buffer_size = TAR_BLOCK_SIZE; + + chunk_info->offset = TAR_BLOCK_SIZE; + chunk_info->size -= copy_offset; + } + + if(cy_is_tar_header(file_header.buffer, file_header.buffer_size) == CY_UNTAR_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() TAR ARCHIVE\n", __LINE__, __func__); + if(cy_ota_untar_init_context(storage_ptr, &ota_untar_context) != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() cy_ota_untar_init_context() FAILED! \n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + } + else + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() Non TAR\n", __LINE__, __func__); + } + file_header.is_tar_header_checked = true; + } + } + + /* treat a tar file differently from a "normal" OTA */ + if(storage_ptr->ota_is_tar_archive != 0) + { + uint32_t consumed = 0; + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() TAR ARCHIVE\n", __LINE__, __func__); + + if(file_header.buffer_size) + { + cy_untar_result_t result; + + while (consumed < file_header.buffer_size) + { + result = cy_untar_parse(&ota_untar_context, (consumed), (file_header.buffer + consumed), + (file_header.buffer_size - consumed), &consumed); + if((result == CY_UNTAR_ERROR) || (result == CY_UNTAR_INVALID)) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() cy_untar_parse() FAIL consumed: %ld sz:%ld result:%ld)!\n", __func__, consumed, chunk_info->size, result); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + /* Yield for a bit */ + cy_rtos_delay_milliseconds(1); + } + free(file_header.buffer); + file_header.buffer = NULL; + file_header.buffer_size = 0; + + consumed = 0; + } + + while (consumed < chunk_info->size) + { + cy_untar_result_t result; + result = cy_untar_parse(&ota_untar_context, (chunk_info->offset + consumed), &chunk_info->buffer[consumed + copy_offset], + (chunk_info->size - consumed), &consumed); + if((result == CY_UNTAR_ERROR) || (result == CY_UNTAR_INVALID)) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() cy_untar_parse() FAIL consumed: %ld sz:%ld result:%ld)!\n", __func__, consumed, chunk_info->size, result); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + /* Yield for a bit */ + cy_rtos_delay_milliseconds(1); + } + + /* with the tarball we get a version - check if it is > current so we can bail early */ +#ifdef CY_TEST_APP_VERSION_IN_TAR + if(ota_untar_context.version[0] != 0) + { + /* example version string ".." */ + uint16_t major = 0; + uint16_t minor = 0; + uint16_t build = 0; + char *dot; + major = atoi(ota_untar_context.version); + dot = strstr(ota_untar_context.version, "."); + if(dot != NULL) + { + dot++; + minor = atoi(dot); + dot = strstr(dot, "."); + if(dot != NULL) + { + dot++; + build = atoi(dot); + + if((major < APP_VERSION_MAJOR) || + ( (major == APP_VERSION_MAJOR) && + (minor < APP_VERSION_MINOR)) || + ( (major == APP_VERSION_MAJOR) && + (minor == APP_VERSION_MINOR) && + (build <= APP_VERSION_BUILD))) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() OTA image version %d.%d.%d <= current %d.%d.%d-- bail!\r\n", __func__, + major, minor, build, + APP_VERSION_MAJOR, APP_VERSION_MINOR, APP_VERSION_BUILD); + + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + } + } + } +#endif /* CY_TEST_APP_VERSION_IN_TAR */ + } + else + { + /* non-tarball OTA here, always image 0x00 */ + const struct flash_area *fap; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() NON-TAR file\n", __func__); + if(flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0), &fap) != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() flash_area_open()\n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + if(file_header.buffer_size) + { + if(flash_area_write(fap, 0, file_header.buffer, file_header.buffer_size) != 0) + { + result = CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + free(file_header.buffer); + file_header.buffer = NULL; + file_header.buffer_size = 0; + + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() WRITE FAILED\n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + } + + if(flash_area_write(fap, chunk_info->offset, (chunk_info->buffer + copy_offset), chunk_info->size) != 0) + { + result = CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + if(result != CY_RSLT_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() WRITE FAILED\n", __func__); + return CY_RSLT_OTA_ERROR_WRITE_STORAGE; + } + + flash_area_close( fap); + } + + return CY_RSLT_SUCCESS; +} diff --git a/source/COMPONENT_MCUBOOT/flash_map_backend.h b/source/COMPONENT_MCUBOOT/flash_map_backend.h new file mode 100644 index 0000000..21667d3 --- /dev/null +++ b/source/COMPONENT_MCUBOOT/flash_map_backend.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * Copyright (c) 2015 Runtime Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /******************************************************************************* +* \copyright +* +* (c) 2019, Cypress Semiconductor Corporation +* or a subsidiary of Cypress Semiconductor Corporation. All rights +* reserved. +* +* This software is a port of the open source MCUBoot project. +* +* This file was modified to fit PSoC6-based MCUBoot applications. +* +* Portions of this software, including source code, documentation and related +* materials ("Software"), are owned by Cypress Semiconductor +* Corporation or one of its subsidiaries ("Cypress") and is protected by +* and subject to worldwide patent protection (United States and foreign), +* United States copyright laws and international treaty provisions. +* Therefore, you may use this Software only as provided in the license +* agreement accompanying the software package from which you +* obtained this Software ("EULA"). +* +* If no EULA applies, Cypress hereby grants you a personal, non- +* exclusive, non-transferable license to copy, modify, and compile the +* Software source code solely for use in connection with Cypress's +* integrated circuit products. Any reproduction, modification, translation, +* compilation, or representation of this Software except as specified +* above is prohibited without the express written permission of Cypress. +* +* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO +* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, +* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +* PARTICULAR PURPOSE. Cypress reserves the right to make +* changes to the Software without notice. Cypress does not assume any +* liability arising out of the application or use of the Software or any +* product or circuit described in the Software. Cypress does not +* authorize its products for use in any products where a malfunction or +* failure of the Cypress product may reasonably be expected to result in +* significant property damage, injury or death ("High Risk Product"). By +* including Cypress's product in a High Risk Product, the manufacturer +* of such system or application assumes all risk of such use and in doing +* so agrees to indemnify Cypress against all liability. +* +********************************************************************************/ +#ifndef __FLASH_MAP_BACKEND_H__ +#define __FLASH_MAP_BACKEND_H__ + +#include "sysflash.h" + +#define BOOT_EFLASH 1 +#define BOOT_EFILE 2 +#define BOOT_EBADIMAGE 3 +#define BOOT_EBADVECT 4 +#define BOOT_EBADSTATUS 5 +#define BOOT_ENOMEM 6 +#define BOOT_EBADARGS 7 +#define BOOT_EBADVERSION 8 + +/* + * Swap type values from mcuboot + */ + +/** Attempt to boot the contents of the primary slot. */ +#define BOOT_SWAP_TYPE_NONE 1 + +/* + * Swap to the secondary slot. + * Absent a confirm command, revert back on next boot. + */ +#define BOOT_SWAP_TYPE_TEST 2 + +/* + * Swap to the secondary slot and permanently switch to booting its contents. + */ +#define BOOT_SWAP_TYPE_PERM 3 + +/* Swap back to alternate slot. A confirm changes this state to NONE. */ +#define BOOT_SWAP_TYPE_REVERT 4 + +/* Swap failed because image to be run is not valid */ +#define BOOT_SWAP_TYPE_FAIL 5 + +/* Swapping encountered an unrecoverable error */ +#define BOOT_SWAP_TYPE_PANIC 0xff + +/* For setting the image_ok flag */ +#define BOOT_FLAG_SET 1 + +#define FLASH_DEVICE_INDEX_MASK (0x7F) +#define FLASH_DEVICE_GET_EXT_INDEX(n) ((n) & FLASH_DEVICE_INDEX_MASK) +#define FLASH_DEVICE_EXTERNAL_FLAG (0x80) +#define FLASH_DEVICE_INTERNAL_FLASH (0x7F) +#define FLASH_DEVICE_EXTERNAL_FLASH(index) (FLASH_DEVICE_EXTERNAL_FLAG | index) + +/* Code and Work flash regions for XMC */ +#ifdef XMC7200 +/* Internal Code flash */ +#define INTERNAL_FLASH_CODE_LARGE FLASH_DEVICE_INTERNAL_FLASH +#define INTERNAL_FLASH_CODE_SMALL FLASH_DEVICE_INTERNAL_FLASH +/* Internal Work flash */ +#define INTERNAL_FLASH_WORK_LARGE FLASH_DEVICE_INTERNAL_FLASH +#define INTERNAL_FLASH_WORK_SMALL FLASH_DEVICE_INTERNAL_FLASH +#endif + +#ifndef CY_BOOT_EXTERNAL_DEVICE_INDEX +/* assume first(one) SMIF0 device is used */ +#define CY_BOOT_EXTERNAL_DEVICE_INDEX (0) +#endif + +/* multi-image ? */ +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \ + FLASH_AREA_IMG_1_PRIMARY : \ + FLASH_AREA_IMG_1_PRIMARY) + +#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \ + FLASH_AREA_IMG_1_SECONDARY : \ + FLASH_AREA_IMG_1_SECONDARY) + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \ + FLASH_AREA_IMG_1_PRIMARY : \ + ((x) == 1) ? \ + FLASH_AREA_IMG_2_PRIMARY : \ + 255) +#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \ + FLASH_AREA_IMG_1_SECONDARY : \ + ((x) == 1) ? \ + FLASH_AREA_IMG_2_SECONDARY : \ + 255) + +#else +#warning "Image slot and flash area mapping is not defined" +#endif + + +#if ( (defined (CYW20829B0LKML)) && (MCUBOOT_IMAGE_NUMBER > 1) ) +#error Multi-image configuration is NOT supported on this platform! +#endif /* (defined(CYW20829) && MCUBOOT_IMAGE_NUMBER > 1) */ + +/** + * + * Provides abstraction of flash regions for type of use. + * I.e. dude where's my image? + * + * System will contain a map which contains flash areas. Every + * region will contain flash identifier, offset within flash and length. + * + * 1. This system map could be in a file within filesystem (Initializer + * must know/figure out where the filesystem is at). + * 2. Map could be at fixed location for project (compiled to code) + * 3. Map could be at specific place in flash (put in place at mfg time). + * + * Note that the map you use must be valid for BSP it's for, + * match the linker scripts when platform executes from flash, + * and match the target offset specified in download script. + */ +#include + +/** + * @brief Structure describing an area on a flash device. + * + * Multiple flash devices may be available in the system, each of + * which may have its own areas. For this reason, flash areas track + * which flash device they are part of. + */ +struct flash_area { + /** + * This flash area's ID; unique in the system. + */ + uint8_t fa_id; + + /** + * ID of the flash device this area is a part of. + */ + uint8_t fa_device_id; + + /** + * Pad for Word length(32 Bytes). + */ + uint16_t pad16; + + /** + * This area's offset, relative to the beginning of its flash + * device's storage. + */ + uint32_t fa_off; + + /** + * This area's size, in bytes. + */ + uint32_t fa_size; +}; + +/*< Opens the area for use. id is one of the `fa_id`s */ +int8_t flash_area_open(uint8_t id, const struct flash_area **fa); + +/*< Closes the area for use. id is one of the `fa_id`s */ +void flash_area_close(const struct flash_area *fa); + +/*< Reads `len` bytes of flash memory at `off` to the buffer at `dst` */ +int8_t flash_area_read(const struct flash_area *fa, uint32_t off, void *dst, uint32_t len); + +/*< Writes `len` bytes of flash memory at `off` from the buffer at `src` */ +int8_t flash_area_write(const struct flash_area *fa, uint32_t off, const void *src, uint32_t len); + +/*< Erases `len` bytes of flash memory at `off` */ +int8_t flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len); + +/* writes MAGIC, OK and swap_type */ +int8_t flash_area_boot_set_pending(uint8_t image, uint8_t permanent); + +/* writes MAGIC and OK */ +int8_t flash_area_boot_set_confirmed(void); + +/* Removes the Boot Magic of the image in the secondary slot. */ +int8_t flash_area_boot_unset_pending(uint8_t image); + +#endif /* __FLASH_MAP_BACKEND_H__ */ diff --git a/source/COMPONENT_MCUBOOT/sysflash.h b/source/COMPONENT_MCUBOOT/sysflash.h new file mode 100644 index 0000000..61f80fc --- /dev/null +++ b/source/COMPONENT_MCUBOOT/sysflash.h @@ -0,0 +1,77 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +#ifndef SYSFLASH_H +#define SYSFLASH_H + +#include +#include "cy_syslib.h" + +#ifndef MCUBOOT_IMAGE_NUMBER +#ifdef MCUBootApp +#warning Undefined MCUBOOT_IMAGE_NUMBER. Assuming 1 (single-image). +#endif /* MCUBootApp */ +#define MCUBOOT_IMAGE_NUMBER 1 +#endif /* MCUBOOT_IMAGE_NUMBER */ + +#if ((MCUBOOT_IMAGE_NUMBER < 1) || (MCUBOOT_IMAGE_NUMBER > 4)) +#error Unsupported MCUBOOT_IMAGE_NUMBER. Set it to between 1 and 4. +#endif /* ((MCUBOOT_IMAGE_NUMBER < 1) || (MCUBOOT_IMAGE_NUMBER > 4)) */ + +#define FLASH_AREA_BOOTLOADER (0u) + +#define FLASH_AREA_IMG_1_PRIMARY (1u) +#define FLASH_AREA_IMG_1_SECONDARY (2u) + +#define FLASH_AREA_IMAGE_SCRATCH (3u) + +#if MCUBOOT_IMAGE_NUMBER >= 2 +#define FLASH_AREA_IMG_2_PRIMARY (4u) +#define FLASH_AREA_IMG_2_SECONDARY (5u) +#endif /* MCUBOOT_IMAGE_NUMBER >= 2 */ + +#define FLASH_AREA_IMAGE_SWAP_STATUS (7u) + +#if MCUBOOT_IMAGE_NUMBER >= 3 +#define FLASH_AREA_IMG_3_PRIMARY (8u) +#define FLASH_AREA_IMG_3_SECONDARY (9u) +#endif /* MCUBOOT_IMAGE_NUMBER >= 3 */ + +#if MCUBOOT_IMAGE_NUMBER == 4 +#define FLASH_AREA_IMG_4_PRIMARY (10u) +#define FLASH_AREA_IMG_4_SECONDARY (11u) +#endif /* MCUBOOT_IMAGE_NUMBER == 4 */ + +#define FLASH_AREA_ERROR 255u /* Invalid flash area */ + +#endif /* SYSFLASH_H */ diff --git a/source/untar/untar.c b/source/untar/untar.c new file mode 100644 index 0000000..a097254 --- /dev/null +++ b/source/untar/untar.c @@ -0,0 +1,707 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +/* + * Parse incoming TAR archive + * + * NOTE: Since the data we expect is coming over WiFi we possiblky + * won't be getting anything on a reasonable TAR_BLOCK_SIZE boundary. + * + * We will need to store the last chunk we received that we didn't consume + * or have the caller do that for us in order to find the ustar headers + * nicely. + * + */ +#include +#include +#include +#include +#include +#include +#include "untar.h" +#include "cy_utils.h" +#include "cy_result.h" +#include "cy_json_parser.h" +#include "cy_ota_bootloader_abstraction_log.h" + +/************************************************************* + * Defines and enums + ************************************************************/ +#define CY_FILENAME_COMPONENT_JSON "components.json" +#define CY_UNTAR_COMPONENTS_JSON_INDEX (0) + +/* components.json key strings */ +#define CY_KEY_NUM_COMPONENTS "numberOfComponents" +#define CY_KEY_VERSION "version" +#define CY_KEY_FILES "files" +#define CY_KEY_FILE_NAME "fileName" +#define CY_KEY_FILE_TYPE "fileType" +#define CY_KEY_FILE_SIZE "fileSize" + +/************************************************************* + * Structures + ************************************************************/ + +/************************************************************* + * Data + ************************************************************/ + +/************************************************************* + * Function declarations + ************************************************************/ + +/************************************************************* + * Static Functions + ************************************************************/ +static uint8_t cy_untar_block_of_zeros( uint8_t *buffer, uint32_t size) +{ + while(size > 0) + { + if (*buffer != 0x00) + { + return 1; + } + buffer++; + size--; + } + + return 0; +} + +static uint32_t cy_octal_string_to_u32(const char *octal_string) +{ + uint32_t value = 0; + + if (octal_string == NULL) + { + return value; + } + + while( isdigit((unsigned char)*octal_string) ) + { + value <<= 3; + value |= (uint32_t)(*octal_string - '0'); + octal_string++; + } + + return value; +} + +static cy_rslt_t ota_untar_json_callback( cy_JSON_object_t *obj, void*cb_arg ) +{ + cy_untar_context_t *ctxt = (cy_untar_context_t *)cb_arg; + if (ctxt == NULL) + { + return CY_RSLT_TYPE_ERROR; + } + + if (strncmp(CY_KEY_NUM_COMPONENTS, obj->object_string, obj->object_string_length) == 0) + { + ctxt->num_files_in_json = (uint16_t)atoi(obj->value); + } + if (strncmp(CY_KEY_VERSION, obj->object_string, obj->object_string_length) == 0) + { + memcpy(ctxt->app_version, obj->value, obj->value_length); + } + if (strncmp(CY_KEY_FILES, obj->object_string, obj->object_string_length) == 0) + { + ctxt->curr_file_in_json = 0; + } + else if (strncmp(CY_KEY_FILE_NAME, obj->object_string, obj->object_string_length) == 0) + { + /* if we already have an entry for curr file, increment curr file */ + if (strncmp(CY_FILENAME_COMPONENT_JSON, obj->value, obj->value_length) == 0 ) + { + /* components.json here - don't increment current file */ + } + else if ( (ctxt->files[ctxt->curr_file_in_json].name[0] != 0) || + (ctxt->files[ctxt->curr_file_in_json].size != 0) ) + { + ctxt->curr_file_in_json++; + } + else + { + /* Nothing to do here - Needed for Coverity (MISRA C 2012 Rule 15.7) */ + } + memcpy(ctxt->files[ctxt->curr_file_in_json].name, obj->value, obj->value_length); + } + else if (strncmp(CY_KEY_FILE_SIZE, obj->object_string, obj->object_string_length) == 0) + { + ctxt->files[ctxt->curr_file_in_json].size = (uint32_t)atoi(obj->value); + } + else if (strncmp(CY_KEY_FILE_TYPE, obj->object_string, obj->object_string_length) == 0) + { + memcpy(ctxt->files[ctxt->curr_file_in_json].type, obj->value, obj->value_length); + } + else + { + /* Nothing to do here - Needed for Coverity (MISRA C 2012 Rule 15.7) */ + } + + return CY_RSLT_SUCCESS; +} + +static cy_untar_result_t cy_parse_component_json_data(cy_untar_context_t *ctxt, uint8_t *buffer, uint32_t size) +{ + cy_rslt_t result; + const char *file_start; + + if ( (ctxt == NULL) || (buffer == NULL) || (size == 0)) + { + return CY_UNTAR_ERROR; + } + + if (size < ctxt->files[0].size ) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() Not enough data for components.json parse need: %ld\n", __func__, ctxt->files[0].size); + /* still waiting for all of the json, still good */ + return CY_UNTAR_NOT_ENOUGH_DATA; + } + + /* initialize info for start of parsing components.json */ + file_start = (char *)buffer; + ctxt->curr_file_in_json = 0; + ctxt->num_files_in_json = 0; + cy_JSON_parser_register_callback( ota_untar_json_callback, ctxt ); + result = cy_JSON_parser( file_start, ctxt->files[0].size ); + if (result != CY_RSLT_SUCCESS) + { + return CY_UNTAR_ERROR; + } + return CY_UNTAR_SUCCESS; +} + +/** + * @brief process a ustar header + * + * NOTE: always consumes TAR_BLOCK_SIZE bytes + * + * @param ctxt[in,out] ptr to context structure, gets updated + * @param stream_offset[in] offset into entire stream + * @param buffer[in] ptr to the next buffer of input + * @param size[in] bytes in tar_buffer + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +static cy_untar_result_t cy_untar_parse_process_header(cy_untar_context_t *ctxt, uint32_t stream_offset, uint8_t *buffer, uint32_t size) +{ + uint16_t i; + uint32_t component_size; + ustar_header_t *hdr = (ustar_header_t *)buffer; + + /* make sure this is a valid header */ + if (cy_is_tar_header( buffer, size ) != CY_UNTAR_SUCCESS) + { + + if (cy_untar_block_of_zeros(buffer, size) == 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s() is_tar_header() ZEROs, ignore\n" , __func__); + /* full TAR_BLOCK_SIZE of 0x00 - ignore */ + return CY_UNTAR_SUCCESS; + } + + /* expected a header but NOT A HEADER. */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() is_tar_header() failed\n" , __func__); + return CY_UNTAR_ERROR; + } + + /* special case for our components.json file */ + if ( strcmp((char*)hdr->name, CY_FILENAME_COMPONENT_JSON) == 0) + { + if (ctxt->num_files > 0 ) + { + /* error - components.json must be first! */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() missing components.json!\n" , __func__); + return CY_UNTAR_ERROR; + } + ctxt->current_file = CY_UNTAR_COMPONENTS_JSON_INDEX; + ctxt->files[ctxt->current_file].size = cy_octal_string_to_u32((char*)hdr->size); + } + else + { + /* not components.json - find file in the list parsed from components.json */ + for (i = 0; i < ctxt->num_files_in_json ; i++) + { + if (strcmp((char*)hdr->name, ctxt->files[i].name) == 0) + { + /* is the file size the same as in components.json? */ + component_size = cy_octal_string_to_u32((char *)hdr->size); + if (component_size != ctxt->files[i].size) + { + /* data in tar and components.json do not match */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() components.json faulty file size %ld != %ld!\n" , __func__, component_size, ctxt->files[i].size); + return CY_UNTAR_ERROR; + } + /* we found a file */ + ctxt->current_file = i; + break; + } + } + if (i >= ctxt->num_files_in_json) + { + /* File not found in components.json - data in tar and components.json do not match */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() components.json faulty could not find %s!\n" , __func__, (char*)hdr->name); + return CY_UNTAR_ERROR; + } + } + + /* we found a valid file header */ + strcpy(ctxt->files[ctxt->current_file].name, (char *)hdr->name); /* NUL terminated string */ + ctxt->files[ctxt->current_file].header_offset = stream_offset; + ctxt->files[ctxt->current_file].found_in_tar = 1; + ctxt->files[ctxt->current_file].processed = 0; + + /* increment # file headers found, change state to DATA */ + ctxt->num_files++; + ctxt->tar_state = CY_TAR_PARSE_DATA; + return CY_UNTAR_SUCCESS; +} + +/** + * @brief process tar file data + * + * NOTE: always consumes size bytes + * + * @param ctxt[in,out] ptr to context structure, gets updated +* @param stream_offset[in] offset into entire stream + * @param buffer[in] ptr to the next buffer of input + * @param size[in] bytes in tar_buffer + * @param consumed[out] ptr to save bytes used in callbacks (or skipped at end of file) + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +static cy_untar_result_t cy_untar_parse_process_data(cy_untar_context_t *ctxt, uint32_t stream_offset, uint8_t *buffer, uint32_t size, uint32_t *consumed) +{ + cy_untar_result_t result = CY_UNTAR_SUCCESS; + + /* data chunk here */ + /* check for special case of components.json */ + *consumed = 0; + if (ctxt->already_parsed_components_json == 0) + { + result = cy_parse_component_json_data(ctxt, buffer, size); + if (result == CY_UNTAR_SUCCESS) + { + *consumed = ctxt->files[CY_UNTAR_COMPONENTS_JSON_INDEX].size; + ctxt->already_parsed_components_json = 1; + ctxt->tar_state = CY_TAR_PARSE_FIND_HEADER; +#ifdef CY_OTA_UNTAR_DEBUG + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s() parsed components.json done \n", __LINE__, __func__); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, " version : %s\n", ctxt->app_version); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, " num files : %d\n", ctxt->num_files_in_json); + int i; + for (i = 0; i < ctxt->num_files_in_json; i++) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, " file %d : %s\n", i, ctxt->files[i].name); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, " : %s\n", ctxt->files[i].type); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, " : %ld\n", ctxt->files[i].size); + } + } +#endif + return CY_UNTAR_SUCCESS; + } + else if (result == CY_UNTAR_NOT_ENOUGH_DATA) + { + /* Data is not enough for components.json to be parsed + * Signal for buffer to coalesce data until we have enough to parse. + */ + ctxt->coalesce_needs = ( (ctxt->files[ctxt->current_file].size + (TAR_BLOCK_SIZE - 1)) / TAR_BLOCK_SIZE) * TAR_BLOCK_SIZE; + CY_ASSERT(ctxt->coalesce_needs < sizeof(ctxt->coalesce_buffer)); + if (ctxt->coalesce_needs > sizeof(ctxt->coalesce_buffer)) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%s() Buffer needs > coalesce buffer. Reduce size of components.json or increase buffer size.\n",__func__); + return CY_UNTAR_ERROR; + } + /* this is normal when coalescing data */ + return CY_UNTAR_NOT_ENOUGH_DATA; + } + else + { + /* components.json parse failure */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s PARSE FAILURE\n", __LINE__, __func__); + return CY_UNTAR_COMPONENTS_JSON_PARSE_FAIL; + } + } + else + { + /* check to see if this is data for the current file */ + uint32_t stream_file_start = ctxt->files[ctxt->current_file].header_offset + TAR_BLOCK_SIZE; + uint32_t file_offset = stream_offset - stream_file_start; + uint32_t data_for_file = ctxt->files[ctxt->current_file].size - file_offset; + + if ( data_for_file > size ) + { + data_for_file = size; + } + + if (data_for_file != 0) + { + if (ctxt->cb_func != NULL) + { + cy_untar_result_t cb_result; + file_offset = stream_offset - ctxt->files[ctxt->current_file].header_offset - TAR_BLOCK_SIZE; + /* pass along data to be written */ + cb_result = ctxt->cb_func(ctxt, ctxt->current_file, buffer, file_offset, data_for_file, ctxt->cb_arg); + if (cb_result != CY_UNTAR_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s CALBACK returned FAILURE 0x%x\n", __LINE__, __func__, cb_result); + return result; + } + } + ctxt->files[ctxt->current_file].processed += data_for_file; + *consumed = data_for_file; + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, " file %d : %s\n", ctxt->current_file, ctxt->files[ctxt->current_file].name); + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, " : %ld of %ld\n", ctxt->files[ctxt->current_file].processed, ctxt->files[ctxt->current_file].size); + } + + if (ctxt->files[ctxt->current_file].processed >= ctxt->files[ctxt->current_file].size) + { + /* change state to look for next header */ + ctxt->tar_state = CY_TAR_PARSE_FIND_HEADER; + } + } + return CY_UNTAR_SUCCESS; +} + +/************************************************************* + * Functions + ************************************************************/ +/** + * @brief Determine if this is a tar header + * + * @param buffer[in] ptr to data buffer + * @param size[in] size of buffer + * + * @return CY_UNTAR_INVALID + * CY_UNTAR_SUCCESS + * CY_UNTAR_NOT_ENOUGH_DATA + */ +cy_untar_result_t cy_is_tar_header( uint8_t *buffer, uint32_t size ) +{ + ustar_header_t *hdr = (ustar_header_t *)buffer; + if ( (hdr == NULL) || (size < sizeof(ustar_header_t))) + { + return CY_UNTAR_NOT_ENOUGH_DATA; + } + /* MAGIC is "ustar". + * On Mac tar archiver, ustar" is followed by a NULL char (0x00). + * On Win/Linux tar archiver, "ustar" is followed by a (0x20). + */ + if (memcmp((void const *)hdr->magic, (void const *)TMAGIC, (TMAGLEN - 1)) != 0) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "is_tar_header() invalid ustar magic:%s\n", hdr->magic); + return CY_UNTAR_INVALID; + } + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "is_tar_header(), hdr->magic: %s, TMAGIC: %s, TMAGLEN: %d\n", hdr->magic, TMAGIC, TMAGLEN); + return CY_UNTAR_SUCCESS; +} + +/** + * @brief Initialize our tar context + * + * @param ctxt[in,out] ptr to context structure + * @param cb_func[in] callback function + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_untar_result_t cy_untar_init( cy_untar_context_t *ctxt, untar_write_callback_t cb_func, void *cb_arg ) +{ + if ( (ctxt == NULL) || (cb_func == NULL) ) + { + return CY_UNTAR_ERROR; + } + memset (ctxt, 0x00, sizeof(cy_untar_context_t)); + ctxt->tar_state = CY_TAR_PARSE_FIND_HEADER; + ctxt->cb_func = cb_func; + ctxt->cb_arg = cb_arg; + ctxt->magic = CY_UNTAR_CONTEXT_MAGIC; + + return CY_UNTAR_SUCCESS; +} + +/** + * @brief De-Initialize our tar context + * + * @param ctxt[in,out] ptr to context structure + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_untar_result_t cy_untar_deinit( cy_untar_context_t *ctxt ) +{ + if (ctxt == NULL) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s BAD ARGS\n", __LINE__, __func__); + return CY_UNTAR_ERROR; + } + memset (ctxt, 0x00, sizeof(cy_untar_context_t)); + return CY_UNTAR_SUCCESS; +} + +/** + * @brief Parse the tar data + * + * NOTE: This is meant to be called for each chunk of data received + * callback will be invoked when there is data to write + * + * @param ctxt[in,out] ptr to context structure, gets updated + * @param in_stream_offset[in] offset into entire stream + * @param in_tar_buffer[in] ptr to the next buffer of input + * @param in_size[in] bytes in tar_buffer + * @param consumed[out] ptr to save bytes used in callbacks (or skipped at end of file) + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_untar_result_t cy_untar_parse( cy_untar_context_t *ctxt, uint32_t in_stream_offset, uint8_t *in_buffer, uint32_t in_size, uint32_t *consumed) +{ + cy_untar_result_t result; + + uint8_t *curr_buffer = in_buffer; + uint32_t curr_stream_offset = in_stream_offset; + uint32_t curr_size = in_size; + + if ( (ctxt == NULL) || (in_buffer == NULL) || (in_size == 0) || (consumed == NULL)) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s BAD ARGUMENTS\n", __LINE__, __func__); + return CY_UNTAR_ERROR; + } + + /* we haven't consumed any data yet */ + *consumed = 0; + if (ctxt->magic != CY_UNTAR_CONTEXT_MAGIC) + { + /* our untar context not initialized! */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s BAD UNTAR context MAGIC\n", __LINE__, __func__); + return CY_UNTAR_ERROR; + } + + /* TAR is organized in TAR_BLOCK_SIZE chunks + * a ustar_header is < TAR_BLOCK_SIZE + * "components.json" *may* be larger than TAR_BLOCK_SIZE + * but we constrain the sie to less than (TAR_BLOCK_SIZE * 2) + * */ + + while (curr_size > 0) + { + uint8_t used_coalesce; + uint8_t *buff_to_use; + uint32_t size_to_use; + uint32_t stream_offset_to_use; + uint32_t bytes_consumed; + + /* Have we indicated that we need to coalesce data ? + * We will try to use this sparingly as it takes an extra copy of data. + * + * At start, ctxt->coalesce_needs = 0x00 so we do not trigger this. + */ + if (ctxt->coalesce_bytes < ctxt->coalesce_needs) + { + /* copy data to fill the coalesce needs + * coalesce_needs shall never be larger than the coalesce_buffer! + */ + uint32_t copy_size = (ctxt->coalesce_needs - ctxt->coalesce_bytes); + if (copy_size > curr_size) + { + copy_size = curr_size; + } + memcpy(&ctxt->coalesce_buffer[ctxt->coalesce_bytes], curr_buffer, copy_size); + + if (ctxt->coalesce_bytes == 0 ) + { + ctxt->coalesce_stream_offset = curr_stream_offset; + } + ctxt->coalesce_bytes += copy_size; + curr_size -= copy_size; + curr_buffer += copy_size; + *consumed += copy_size; + curr_stream_offset += copy_size; + + if (*consumed == in_size) + { + /* we consumed all the data for the coalesce buffer, return */ + return CY_UNTAR_SUCCESS; + } + /* we can fall through to the next tests as we have set the pertinent variables */ + } + + /* assume we will use the direct buffer rather than the coalesce buffer + * We set these here after the coalesce check in case we copied into the buffer + */ + bytes_consumed = 0; + used_coalesce = 0; + buff_to_use = curr_buffer; + size_to_use = curr_size; + stream_offset_to_use = curr_stream_offset; + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() ctxt->tar_state: %d consumed: %ld\n", __LINE__, __func__, ctxt->tar_state, *consumed); + if (ctxt->tar_state == CY_TAR_PARSE_FIND_HEADER) + { + /* + * NOTES: + * ustar header always fits in one TAR_BLOCK_SIZE + * ustar header always stars on TAR_BLOCK_SIZE boundary + */ + + if ( (ctxt->coalesce_needs > 0) && + (ctxt->coalesce_bytes >= ctxt->coalesce_needs) ) + { + /* we have data in the coalesce buffer - use it? */ + if (ctxt->coalesce_bytes < TAR_BLOCK_SIZE) + { + /* we need to fill the coalesce buffer before we can parse */ + ctxt->coalesce_needs = TAR_BLOCK_SIZE; + continue; + } + buff_to_use = ctxt->coalesce_buffer; + size_to_use = ctxt->coalesce_bytes; + stream_offset_to_use = ctxt->coalesce_stream_offset; + used_coalesce = 1; + } + + if (size_to_use < TAR_BLOCK_SIZE) + { + /* we need to fill the coalesce buffer before we can parse */ + ctxt->coalesce_needs = TAR_BLOCK_SIZE; + continue; + } + + if ( (stream_offset_to_use % TAR_BLOCK_SIZE) != 0) + { + bytes_consumed = TAR_BLOCK_SIZE - (stream_offset_to_use % TAR_BLOCK_SIZE); + if ( (used_coalesce == 1) && (bytes_consumed > ctxt->coalesce_bytes) ) + { + /* just skip the bytes in coalesce buffer */ + bytes_consumed = ctxt->coalesce_bytes; + } + } + else + { + /* A ustar header is always TAR_BLOCK_SIZE */ + result = cy_untar_parse_process_header(ctxt, stream_offset_to_use, buff_to_use, size_to_use); + if (result != CY_UNTAR_SUCCESS) + { + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s() cy_untar_parse_process_header() fail return %d\n", __LINE__, __func__, result); + return result; + } + bytes_consumed = TAR_BLOCK_SIZE; /* always 1 TAR_BLOCK_SIZE for ustar header */ + } + } + else if(ctxt->tar_state == CY_TAR_PARSE_DATA) + { + /* + * NOTES: + * "components.json" data may require more than one TAR_BLOCK_SIZE of data + */ + + if (ctxt->coalesce_needs > 0) + { + /* we have data in the coalesce buffer - use it */ + if (ctxt->coalesce_bytes < ctxt->coalesce_needs) + { + /* we need to fill the coalesce buffer more before we can parse */ + continue; + } + buff_to_use = ctxt->coalesce_buffer; + size_to_use = ctxt->coalesce_bytes; + stream_offset_to_use = ctxt->coalesce_stream_offset; + used_coalesce = 1; + } + + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%d:%s() offset: %ld sz: %ld\n", __LINE__, __func__, stream_offset_to_use, size_to_use); + result = cy_untar_parse_process_data(ctxt, stream_offset_to_use, buff_to_use, size_to_use, &bytes_consumed); + if (result == CY_UNTAR_NOT_ENOUGH_DATA) + { + /* continue will put data into coalesce buffer and consume the data + */ + continue; + } + if (result != CY_UNTAR_SUCCESS) + { + /* data parse fail */ + cy_ota_bootloader_abstraction_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "%d:%s() cy_untar_parse_process_data() fail return %d\n", __LINE__, __func__, result); + return result; + } + } + else + { + /* Nothing to do here - Needed for Coverity (MISRA C 2012 Rule 15.7) */ + } + + /* handle use of coalesce buffer here */ + if (used_coalesce == 1) + { + if ( (bytes_consumed != 0) && (bytes_consumed < ctxt->coalesce_bytes) ) + { + /* remove skipped data */ + uint32_t copy_size = ctxt->coalesce_bytes - bytes_consumed; + memcpy(ctxt->coalesce_buffer, &ctxt->coalesce_buffer[bytes_consumed], copy_size); + ctxt->coalesce_bytes -= bytes_consumed; + /* If there are no more bytes in the coalesce buffer, clear out the starting stream offset. + * We will see it is zero when we add bytes to the buffer and set the stream offset correctly. + */ + if (ctxt->coalesce_bytes == 0) + { + ctxt->coalesce_stream_offset = 0; + } + else + { + ctxt->coalesce_stream_offset += bytes_consumed; + } + } + else + { + /* we used it all, clear it */ + ctxt->coalesce_bytes = 0; + ctxt->coalesce_needs = 0; + ctxt->coalesce_stream_offset = 0; + memset(ctxt->coalesce_buffer, 0xFF, sizeof(ctxt->coalesce_buffer)); + } + } + else + { + /* keep track of consumed input data */ + *consumed += bytes_consumed; + curr_buffer += bytes_consumed; + curr_size -= bytes_consumed; + curr_stream_offset += bytes_consumed; + } + } /* while we haven't consumed all the data */ + + ctxt->bytes_processed += *consumed; + return CY_UNTAR_SUCCESS; +} diff --git a/source/untar/untar.h b/source/untar/untar.h new file mode 100644 index 0000000..93d3fb6 --- /dev/null +++ b/source/untar/untar.h @@ -0,0 +1,271 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation. All rights reserved. + * + * This software, including source code, documentation and related + * materials ("Software") is owned by Cypress Semiconductor Corporation + * or one of its affiliates ("Cypress") and is protected by and subject to + * worldwide patent protection (United States and foreign), + * United States copyright laws and international treaty provisions. + * Therefore, you may use this Software only as provided in the license + * agreement accompanying the software package from which you + * obtained this Software ("EULA"). + * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, + * non-transferable license to copy, modify, and compile the Software + * source code solely for use in connection with Cypress's + * integrated circuit products. Any reproduction, modification, translation, + * compilation, or representation of this Software except as specified + * above is prohibited without the express written permission of Cypress. + * + * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress + * reserves the right to make changes to the Software without notice. Cypress + * does not assume any liability arising out of the application or use of the + * Software or any product or circuit described in the Software. Cypress does + * not authorize its products for use in any products where a malfunction or + * failure of the Cypress product may reasonably be expected to result in + * significant property damage, injury or death ("High Risk Product"). By + * including Cypress's product in a High Risk Product, the manufacturer + * of such system or application assumes all risk of such use and in doing + * so agrees to indemnify Cypress against all liability. + */ + +#ifndef UNTAR_H__ +#define UNTAR_H__ 1 + +#include +#include "cy_result.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @ Unix Standard Tar header format + * + * The Open Group Base Specifications Issue 7, 2018 edition + * IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008) + * Copyright � 2001-2018 IEEE and The Open Group + * + * ustar Interchange Format + * A ustar archive tape or file shall contain a series of logical records. + * Each logical record shall be a fixed-size logical record of 512 octets (see below). + * Although this format may be thought of as being stored on 9-track industry-standard + * 12.7 mm (0.5 in) magnetic tape, other types of transportable media are not excluded. + * Each file archived shall be represented by a header logical record that describes + * the file, followed by zero or more logical records that give the contents of the file. + * At the end of the archive file there shall be two 512-octet logical records filled with + * binary zeros, interpreted as an end-of-archive indicator. + * The logical records may be grouped for physical I/O operations, as described under the + * -b blocksize and -x ustar options. Each group of logical records may be written with a + * single operation equivalent to the write() function. On magnetic tape, the result of + * this write shall be a single tape physical block. The last physical block shall always + * be the full size, so logical records after the two zero logical records may contain undefined data. + * + */ + +#define TAR_BLOCK_SIZE 512 + +/* General definitions. */ +#define TNAMELEN 100 /**< Name field length. */ +#define TMAGIC "ustar" /**< "ustar". On Mac, it is followed by a NULL char (0x00), on Windows it is followed by a \ (0x20). */ +#define TMAGLEN 6 /**< Length of the above. Must leave space in the structure buffer for NULL or \! */ +#define TVERSION "00" /**< 00 without a null byte. */ +#define TVERSLEN 2 /**< Length of the above. */ + +/* Typeflag field definitions. */ +#define REGTYPE '0' /**< Regular file. */ +#define AREGTYPE '\0' /**< Regular file. */ +#define LNKTYPE '1' /**< Link. */ +#define SYMTYPE '2' /**< Symbolic link. */ +#define CHRTYPE '3' /**< Character special. */ +#define BLKTYPE '4' /**< Block special. */ +#define DIRTYPE '5' /**< Directory. */ +#define FIFOTYPE '6' /**< FIFO special. */ +#define CONTTYPE '7' /**< Reserved. */ + +/* Mode field bit definitions (hexa-decimal). */ +#define TSUID 0x800 /**< Set UID on execution. */ +#define TSGID 0x400 /**< Set GID on execution. */ +#define TSVTX 0x200 /**< On directories, restricted deletion flag. */ +#define TUREAD 0x100 /**< Read by owner. */ +#define TUWRITE 0x80 /**< Write by owner. */ +#define TUEXEC 0x40 /**< Execute/search by owner. */ +#define TGREAD 0x20 /**< Read by group. */ +#define TGWRITE 0x10 /**< Write by group. */ +#define TGEXEC 0x8 /**< Execute/search by group. */ +#define TOREAD 0x4 /**< Read by other. */ +#define TOWRITE 0x2 /**< Write by other. */ +#define TOEXEC 0x1 /**< Execute/search by other. */ + +/** + * Cypress definitions. + */ + +#define CY_UNTAR_CONTEXT_MAGIC (0x981345A0u) /**< Tag to verify the context. */ +#define CY_MAX_TAR_FILES (8) /**< Max number of files supported in the Tar archive. */ +#define CY_TAR_COALESCE_BUFFER_SIZE (TAR_BLOCK_SIZE * 2) /**< Buffer size used to coalesce sectors if needed. */ +#define CY_FILE_TYPE_LEN (16) /**< Max file type string length. */ +#define CY_VERSION_STRING_MAX (16) /**< Max version string length "1234.56789.012345". */ + +typedef enum { + CY_UNTAR_SUCCESS = 0, /**< Untar successful. */ + CY_UNTAR_ERROR, /**< Generic error in the Untar function. */ + CY_UNTAR_INVALID, /**< Tar archive is invalid. */ + CY_UNTAR_NOT_ENOUGH_DATA, /**< Not enough data in the Tar archive for all files. */ + CY_UNTAR_COMPONENTS_JSON_PARSE_FAIL /**< Parsing the components.json file failed. */ +} cy_untar_result_t; + +typedef enum { + CY_TAR_PARSE_UNINITIALIZED = 0, /**< untar uninitialized. */ + CY_TAR_PARSE_FIND_HEADER, /**< Found tar file header. */ + CY_TAR_PARSE_DATA, /**< This is not a tar archive; process as data. */ +} cy_tar_parse_state_t; + + +/** + * @brief Structure defined by IEEE for start of each file within the archive. + */ +typedef struct ustar_header_s { + /* offset size */ + uint8_t name[TNAMELEN]; /**< 0 0x00 100 File name (NUL terminated) */ + uint8_t mode[8]; /**< 100 0x64 8 See mode bits above. */ + uint8_t uid[8]; /**< 108 0x6c 8 User ID. */ + uint8_t gid[8]; /**< 116 0x74 8 Group ID. */ + uint8_t size[12]; /**< 124 0x7c 12 File size. */ + /* 12-digit octal in ASCII. */ + /* Number of logical records */ + /* written following the header */ + /* shall be (size+511)/512, */ + /* ignoring any fraction in the */ + /* result of the division. */ + uint8_t mtime[12]; /**< 136 0x88 12 Modified time. */ + uint8_t chksum[8]; /**< 148 0x94 8 Checksum. */ + uint8_t typeflag; /**< 156 0x9c 1 Type (see above). */ + uint8_t linkname[TNAMELEN]; /**< 157 0x9d 100 Linked file name. */ + uint8_t magic[TMAGLEN]; /**< 257 0x101 6 TMAGIC (NUL terminated). */ + uint8_t version[TVERSLEN]; /**< 263 0x107 2 TVERSION. */ + uint8_t uname[32]; /**< 265 0x109 32 user name. */ + uint8_t gname[32]; /**< 297 0x129 32 Group name. */ + uint8_t devmajor[8]; /**< 329 0x149 8 Major. */ + uint8_t devminor[8]; /**< 337 0x151 8 Minor. */ + uint8_t prefix[155]; /**< 345 0x159 155 Prefix. */ + /**< 500 0x1f4 12 Padding implied to the end of the 512-byte block. */ +} ustar_header_t; + + +/** + * @brief Structure used for keeping track of files in the tar archive while extracting. + */ +typedef struct cy_ota_file_info_s { + char name[TNAMELEN]; /**< Copied from the components.json file */ + char type[CY_FILE_TYPE_LEN]; /**< From components.json. */ + uint16_t found_in_tar; /**< Encountered the header in the tar file. */ + uint32_t header_offset; /**< Offset of the header in the tar file. */ + uint32_t size; /**< From components.json, verified from the header. */ + uint32_t processed; /**< Bytes processed from the tar file. */ +} cy_ota_file_info_t; + +/** + * @brief Callback to handle the tar data. + * + * @param ctxt untar context. + * @param file_index Index into ctxt->files for the data. + * @param buffer Data to use. + * @param file_offset Offset into the file to store the data. + * @param chunk_size Amount of data in the buffer to use. + * @param cb_arg Argument passed into initialization. + * + * return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +typedef struct cy_untar_context_s * cy_untar_context_ptr; +typedef cy_untar_result_t (*untar_write_callback_t)(cy_untar_context_ptr ctxt, uint16_t file_index, uint8_t *buffer, uint32_t file_offset, uint32_t chunk_size, void *cb_arg); + +/** + * @brief Struct to hold information on the un-tar process. + */ + +typedef struct cy_untar_context_s { + uint32_t magic; /**< CY_UNTAR_CONTEXT_MAGIC. */ + cy_tar_parse_state_t tar_state; /**< Current parsing state. */ + untar_write_callback_t cb_func; /**< Callback function to deal with the data. */ + void *cb_arg; /**< Opaque argument passed to callback. */ + + uint16_t already_parsed_components_json; /**< True if components.json is parsed. */ + uint32_t bytes_processed; /**< Bytes processed from the archive. */ + + /* for JSON parsing */ + char app_version[CY_VERSION_STRING_MAX]; /**< String of major.minor.build. */ + uint16_t num_files_in_json; /**< Number of files in components.json. */ + uint16_t curr_file_in_json; /**< Parsing file info in components.json. */ + + uint16_t current_file; /**< Currently processing this file from the tar archive. */ + uint16_t num_files; /**< number of files encountered. */ + cy_ota_file_info_t files[CY_MAX_TAR_FILES]; /**< File info. */ + + uint32_t coalesce_stream_offset; /**< Offset into the stream where the coalesce buffer starts. */ + uint32_t coalesce_bytes; /**< Number of bytes in the coalesce buffer. */ + uint32_t coalesce_needs; /**< Number of bytes needed in the coalesce buffer. */ + uint8_t coalesce_buffer[CY_TAR_COALESCE_BUFFER_SIZE]; /**< Used to coalesce buffers for longer sequential data. */ +} cy_untar_context_t; + +/** + * @brief Determine whether this is a tar header. + * + * @param[in] buffer Pointer to the data buffer. + * @param[in] size Size of the buffer. + * + * @return CY_UNTAR_NOT_VALID + * CY_UNTAR_VALID + * CY_UNTAR_NOT_ENOUGH_DATA + */ +cy_untar_result_t cy_is_tar_header( uint8_t *buffer, uint32_t size ); + +/** + * @brief Initialize the tar context. + * + * @param[in] ctxt Pointer to the context structure. + * @param[in] cb_func Callback function. + * @param[in] cb_arg opaque argument passed in callback. + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_untar_result_t cy_untar_init( cy_untar_context_t *ctxt, untar_write_callback_t cb_func, void *cb_arg ); + +/** + * @brief De-Initialize the tar context. + * + * @param[in] ctxt Pointer to the context structure. + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_untar_result_t cy_untar_deinit( cy_untar_context_t *ctxt ); + +/** + * @brief Parse the tar data. + * + * NOTE: This is meant to be called for each chunk of data received. + * Callback will be invoked when there is data to write. + * + * @param[in,out] ctxt Pointer to context structure, gets updated + * @param[in] in_stream_offset offset into entire stream + * @param[in] in_buffer Pointer to the next buffer of input + * @param[in] in_size bytes in tar_buffer + * @param[out] consumed Pointer to save bytes used in callbacks (or skipped at end of file) + * + * @return CY_UNTAR_SUCCESS + * CY_UNTAR_ERROR + */ +cy_untar_result_t cy_untar_parse( cy_untar_context_t *ctxt, uint32_t in_stream_offset, uint8_t *in_buffer, uint32_t in_size, uint32_t *consumed); + +#ifdef __cplusplus +} /*extern "C" */ +#endif + + +#endif /* UNTAR_H__ */ diff --git a/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_ARM/cyw20829_ns_flash_cbus_ota_xip.sct b/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_ARM/cyw20829_ns_flash_cbus_ota_xip.sct new file mode 100644 index 0000000..ba80c0d --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_ARM/cyw20829_ns_flash_cbus_ota_xip.sct @@ -0,0 +1,176 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m33 -march=armv8-m.main +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +/***************************************************************************//** +* \file cyw20829_ns_flash_cbus.sct +* \version 1.1.0 +* +* Linker file for the ARMCC compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location starts at 0x0401e000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +#define flash_start_addr_cbus 0x08000000 + MCUBOOT_HEADER_SIZE + FLASH_AREA_IMG_1_PRIMARY_START +#define ram_start_addr_sahb 0x20000000 +#define ram_start_addr_cbus 0x04000000 +#define ram_end_addr_sahb 0x20040000 + +#ifndef APP_BOOTSTRAP_SIZE +#define APP_BOOTSTRAP_SIZE 0x00002400 +#endif +#define BOOTSTRAP_SIZE APP_BOOTSTRAP_SIZE + +#define FLASH_ALIGNMENT_SIZE 0x00000200 + +; The size of the stack section at the end of CM33 SRAM +#define STACK_SIZE 0x00001000 + +/* VMA for bootstrap Text */ +#define bootstrapText_vma ram_start_addr_cbus + ram_end_addr_sahb - ram_start_addr_sahb - BOOTSTRAP_SIZE /* 0x0401DC00 */ +/* Size of bootstrap section */ +#define bootstrapText_size BOOTSTRAP_SIZE + +/* VMA for bootstrap Data */ +#define bootstrapRamVect_vma ram_start_addr_sahb + STACK_SIZE /* 0x20001000 */ + +/* VMA for flash */ +#define appText_vma flash_start_addr_cbus + BOOTSTRAP_SIZE + FLASH_ALIGNMENT_SIZE/* 0x08002600 */ + +; Cortex-M33 application flash area +LR_1 bootstrapText_vma BOOTSTRAP_SIZE +{ + bootstrap bootstrapText_vma bootstrapText_size + { + * (RESET, +FIRST) + * (InRoot$$Sections) + + startup_cat1b_cm33.o (+RO) + system_cyw20829.o (+RO) + + /* drivers */ + cy_device.o (+RO) + cy_btss.o (+RO) + cy_sysclk_v2.o (+RO) + cy_syspm_v2.o (+RO) + cy_sysint_v2.o (+RO) + cy_syslib*.o (+RO) + ppu_v1.o (+RO) + cy_mpc.o (+RO) + cy_syspm_ppu.o (+RO) + *memcpy*.o (+RO) + *memmov*.o (+RO) + *memset*.o (+RO) + rt_mem*.o (+RO) + *(.cy_l1func*) + } + +/* converting c-bus to sahb address */ +#define bootstrapData_vma AlignExpr((ImageLimit(bootstrap) - ram_start_addr_cbus) + ram_start_addr_sahb, 4) + + bootstrapData bootstrapData_vma ALIGN 4 + { + startup_cat1b_cm33.o (+RW, +ZI) + system_cyw20829.o (+RW, +ZI) + + /* drivers */ + cy_device.o (+RW, +ZI) + cy_btss.o (+RW, +ZI) + cy_sysclk_v2.o (+RW, +ZI) + cy_syspm_v2.o (+RW, +ZI) + cy_sysint_v2.o (+RW, +ZI) + cy_syslib*.o (+RW, +ZI) + ppu_v1.o (+RW, +ZI) + cy_mpc.o (+RW, +ZI) + cy_syspm_ppu.o (+RW, +ZI) + *(.cy_l1data*) + } + + bootstrap_vector bootstrapRamVect_vma UNINIT + { + * (.bss.noinit.RESET_RAM, +FIRST) + } +} + +#define appTextRam_vma AlignExpr(ImageLimit( bootstrap_vector), 16) + +LR_2 appText_vma +{ + app appText_vma + { + * (+RO) + } + + appTextRam appTextRam_vma + { + * (.cy_ramfunc) + * (.text.cy_os_common) + * (.text.cy_btstack_common) + * (.text.cy_btstack_gatt) + * (.text.cy_ipc) + * (.text.cy_btstack_porting) + cy_smif.o (+RO) + cy_smif_memslot.o (+RO) + cy_smif_sfdp.o (+RO) + } + +#define appData_vma AlignExpr(ImageLimit(appTextRam), 8) + + appData appData_vma + { + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + appData_noinit +0 UNINIT + { + * (.noinit) + * (.bss.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 ALIGN 8 EMPTY ((ram_end_addr_sahb - BOOTSTRAP_SIZE)-AlignExpr(ImageLimit(appData_noinit), 8)) + { + } + + ; Stack region growing down + ARM_LIB_STACK (ram_start_addr_sahb + STACK_SIZE) ALIGN 32 EMPTY -STACK_SIZE + { + } +} +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_GCC_ARM/cyw20829_ns_flash_sahb_ota_xip.ld b/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_GCC_ARM/cyw20829_ns_flash_sahb_ota_xip.ld new file mode 100644 index 0000000..882bb0f --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_GCC_ARM/cyw20829_ns_flash_sahb_ota_xip.ld @@ -0,0 +1,490 @@ +/***************************************************************************//** +* \file cyw20829_ns_flash_sahb.ld +* \version 1.0.0 +* +* Linker file for the GNU C compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location starts at 0x0401e000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +GROUP(-lgcc -lc -lnosys ) +SEARCH_DIR(.) +GROUP(libgcc.a libc.a libm.a libnosys.a) +ENTRY(Reset_Handler) + +/* Memory reserved for Bootstrap code and data */ +BOOTSTRAP_SIZE = DEFINED(APP_BOOTSTRAP_SIZE) ? APP_BOOTSTRAP_SIZE : 0x00002400 ; + +/* The size of the stack section at the end of CM4 SRAM */ +STACK_SIZE = 0x1000; + +FLASH_START_ADDR_SAHB_ORIG = 0x60000000; +USER_APP_START_OFFSET = MCUBOOT_HEADER_SIZE + FLASH_AREA_IMG_1_PRIMARY_START; + +FLASH_START_ADDR_SAHB = 0x60000000 + USER_APP_START_OFFSET; +FLASH_START_ADDR_CBUS = 0x08000000 + USER_APP_START_OFFSET; +RAM_START_ADDR_SAHB = 0x20000000; +RAM_END_ADDR_SAHB = 0x20040000; /* 256K */ + +RAM_START_ADDR_CBUS = 0x04000000; +RAM_END_ADDR_CBUS = 0x04040000; /* 256K */ + +FLASH_END_ADDR_SAHB = 0x60100000; /* 1MB */ + +BOOTSTRAP_OFFSET_FLASH = 0x00000050; /* toc2=0x10, l1_desc=0x1C, sign_header=0x20 */ + +RAMVECTORS_ALIGNMENT = 512; +FLASH_ALIGNMENT_SIZE = 0x00000200; + +/* vma for bootstrap code region */ +CODE_VMA = RAM_START_ADDR_CBUS + (RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB - BOOTSTRAP_SIZE); /* 0x2003DC00 */ +/* lma for bootstrap code region */ +CODE_LMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_OFFSET_FLASH; /* 0x60000050 */ +/* Maximum bootstrap code + data size */ +CODE_BS_SIZE = BOOTSTRAP_SIZE; /* 9KB */ +/* vma for bootstrap data region */ +DATA_BS_VMA = RAM_END_ADDR_SAHB - BOOTSTRAP_SIZE; /* 0x2003DC00 */ +/* vma for bootstrap and app data region */ +DATA_VMA = RAM_START_ADDR_SAHB; /* 0x20000000 */ +/* vma for appCodeRam region */ +DATA_CBUS_VMA = RAM_START_ADDR_CBUS; /* 0x20000000 */ +/* lma for bootstrap and app data region */ +DATA_LMA = CODE_LMA + CODE_BS_SIZE; /* 0x60002450 */ +/* data size */ +DATA_SIZE = RAM_END_ADDR_SAHB - DATA_VMA - BOOTSTRAP_SIZE; /* 0x3DC00 */ +/* vma for application XIP region */ +XIP_VMA = FLASH_START_ADDR_CBUS + BOOTSTRAP_SIZE + FLASH_ALIGNMENT_SIZE; /* 0x08002600 */ +/* lma for application XIP region */ +XIP_LMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_SIZE + FLASH_ALIGNMENT_SIZE; /* 0x60002600 */ +/* size of XIP region */ +XIP_SIZE = FLASH_END_ADDR_SAHB - XIP_LMA; +/* Total size of SRAM */ +RAM_SIZE = RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB; /* 0x00040000 */ +/* Size of Bootstrap data is kept same as BOOTSTRAP_SIZE */ +DATA_BS_SIZE = BOOTSTRAP_SIZE; + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM33 core. + */ + code (rx) : ORIGIN = CODE_VMA, LENGTH = CODE_BS_SIZE + bsData (rwx) : ORIGIN = DATA_BS_VMA, LENGTH = DATA_BS_SIZE + appCodeRam (rx) : ORIGIN = DATA_CBUS_VMA, LENGTH = DATA_SIZE + data (rwx) : ORIGIN = DATA_VMA, LENGTH = DATA_SIZE + xip (rx) : ORIGIN = XIP_VMA, LENGTH = XIP_SIZE +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + +SECTIONS +{ + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy RAM_START_ADDR_SAHB (NOLOAD): + { + KEEP(*(.stack*)) + } > data + + /* Set stack top beginning of RAM minus the size of stack, and stack limit move down by + * size of stack_dummy section */ + . = ALIGN(32); + __StackTop = RAM_START_ADDR_SAHB + STACK_SIZE; + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + . = ALIGN(RAMVECTORS_ALIGNMENT); + __ramVectors_vma__ = RAM_START_ADDR_SAHB + STACK_SIZE; + + .ramVectors __ramVectors_vma__ (NOLOAD): + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + . = ALIGN(4); + __ram_vectors_end__ = .; + } > data + + __appTextRam_vma__ = (__ram_vectors_end__ - RAM_START_ADDR_SAHB) + RAM_START_ADDR_CBUS; + __appTextRam_lma__ = (__zero_table_end__ - FLASH_START_ADDR_CBUS) + FLASH_START_ADDR_SAHB; + __ezerotable = __zero_table_end__; + + .appTextRam __appTextRam_vma__ : AT (__appTextRam_lma__) + { + . = ALIGN(4); + __app_text_ram_begin__ = .; + KEEP(*(.cy_ramfunc*)) + . = ALIGN(4); + + *cy_smif.o(.text*) + *cy_smif_memslot.o(.text*) + *cy_smif_sfdp.o(.text*) + + KEEP( *(.text.cy_os_common*)) + KEEP (*(.text.cy_btstack_common*)) + KEEP (*(.text.cy_btstack_gatt*)) + KEEP (*(.text.cy_ipc*)) + KEEP (*(.text.cy_btstack_porting*)) + . = ALIGN(4); + __app_text_ram_end__ = .; + + } > appCodeRam + + __data_vma__ = (__app_text_ram_end__ - RAM_START_ADDR_CBUS) + RAM_START_ADDR_SAHB; + __data_lma__ = (__app_text_ram_end__ - __app_text_ram_begin__) + __appTextRam_lma__; + __etext = __data_lma__ - FLASH_START_ADDR_SAHB + FLASH_START_ADDR_CBUS; + + .data __data_vma__ : AT (__data_lma__) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_end = .); + + . = ALIGN(4); + KEEP(*(.jcr*)) + . = ALIGN(4); + + __data_end__ = .; + + } > data + + /* Check if data is exceeding the flash size */ + ASSERT((__data_lma__ + (__data_end__ - __data_start__)) <= FLASH_END_ADDR_SAHB, "data section exceeds Flash size !") + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > data + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > data + + /* Use ramining RAM for Heap */ + __heap_size__ = (RAM_SIZE - ((__bss_end__ - RAM_START_ADDR_SAHB) + (RAM_END_ADDR_CBUS - __bootstrapText_vma__)) - 4); + + .heap (NOLOAD): + { + . = ALIGN(8); + __HeapBase = .; + __end1__ = .; + end = __end1__; + KEEP(*(.heap*)) + . += __heap_size__; + __HeapLimit = .; + } > data + + __bootstrapText_vma__ = ORIGIN(code); + __bootstrapText_lma__ = CODE_LMA; + + /* Cortex-M33 bootstrap code area */ + .bootstrapText __bootstrapText_vma__ : AT (__bootstrapText_lma__) + { + /* Cortex-M33 code vector table */ + . = ALIGN(4); + __bootstrapText_begin = .; + + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + + /* startup code */ + *startup_cat1b_cm33.o(.text*) + *system_cyw20829.o(.text*) + + /* drivers */ + *cy_device.o(.text*) + *cy_btss.o(.text*) + *cy_sysclk_v2.o(.text*) + *cy_syspm_v2.o(.text*) + *cy_sysint_v2.o(.text*) + *cy_syslib*.o(.text*) + *ppu_v1.o(.text*) + *cy_mpc.o(.text*) + *cy_syspm_ppu.o(.text*) + + *memcpy*.o (.text*) /* add memcpy from the NewLib library here*/ + *memset*.o (.text*) /* add memcpy from the NewLib library here*/ + *memmove*.o (.text*) /* add memcpy from the NewLib library here*/ + *s_fabs.o (.text*) + + KEEP(*(.cy_l1func*)) + + . = ALIGN(4); + __bootstrapText_end = .; + } > code + + __bootstrap_zerotable_lma__ = (CODE_LMA + (__bootstrapText_end - __bootstrapText_begin)); + + .bootstrapzero.table : AT (__bootstrap_zerotable_lma__) + { + . = ALIGN(4); + __bootstrapzero_table_start__ = .; + LONG (__bootstrap_bss_start__) + LONG ((__bootstrap_bss_end__ - __bootstrap_bss_start__)/4) + . = ALIGN(4); + __bootstrapzero_table_end__ = .; + } > code + + __bootstrapData_vma__ = ((__bootstrapzero_table_end__ - RAM_START_ADDR_CBUS) + RAM_START_ADDR_SAHB); + __bootstrapData_lma__ = (__bootstrap_zerotable_lma__ + (__bootstrapzero_table_end__ - __bootstrapzero_table_start__)); + + .bootstrapData __bootstrapData_vma__ : AT (__bootstrapData_lma__) + { + __bootstrapData_start__ = .; + . = ALIGN(4); + + /* startup code */ + *startup_cat1b_cm33.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *system_cyw20829.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + /* drivers */ + *cy_device.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_btss.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_sysclk_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_syspm_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_sysint_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_syslib.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *ppu_v1.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_mpc.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + *cy_pd_ppu.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.cy_l1data*)) + + . = ALIGN(4); + __bootstrapData_end__ = .; + } > bsData + + __bootstrap_size_end__ = .; + .bootstrapBss (NOLOAD): + { + . = ALIGN(4); + __bootstrap_bss_start__ = .; + + /* startup code */ + *startup_cat1b_cm33.o(.bss* COMMON) + *system_cyw20829.o(.bss* COMMON) + + /* drivers */ + *cy_device.o(.bss* COMMON) + *cy_btss.o(.bss* COMMON) + *cy_sysclk_v2.o(.bss* COMMON) + *cy_syspm_v2.o(.bss* COMMON) + *cy_sysint_v2.o(.bss* COMMON) + *cy_syslib.o(.bss* COMMON) + *ppu_v1.o(.bss* COMMON) + *cy_mpc.o(.bss* COMMON) + *cy_pd_ppu.o(.bss* COMMON) + KEEP(*(.cy_l1bss*)) + + . = ALIGN(4); + __bootstrap_bss_end__ = .; + } > bsData + + /* Check if bootstrap code + data exceeds RAM limit */ + ASSERT(__bootstrap_bss_end__ < RAM_END_ADDR_SAHB, "bootstrap region exceeds RAM size !") + + __app_text_vma__ = ORIGIN(xip); + __app_text_lma__ = XIP_LMA; + + /* Cortex-M33 application flash area */ + .appText (__app_text_vma__) : AT (__app_text_lma__) + { + /* Cortex-M33 flash vector table */ + . = ALIGN(4); + __text_begin = .; + + *(EXCLUDE_FILE(*cy_smif.o + *cy_smif_memslot.o *cy_smif_sfdp.o) .text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + . = ALIGN(4); + __text_end = .; + + } > xip + + + .copy.table : AT (__app_text_lma__ + (__text_end - __text_begin)) + { + . = ALIGN(4); + __copy_table_start__ = .; + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG ((__data_end__ - __data_start__)/4) /* Size */ + + /* Copy appTextRam section to RAM */ + LONG (__ezerotable) /* From */ + LONG (__ram_vectors_end__) /* To */ + LONG ((__app_text_ram_end__ - __app_text_ram_begin__)/4) /* Size */ + + . = ALIGN(4); + __copy_table_end__ = .; + } > xip + + + + .ARM.extab : AT (__app_text_lma__ + (__text_end - __text_begin) + (__copy_table_end__ - __copy_table_start__)) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > xip + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > xip + __exidx_end = .; + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in CAT1B devices */ + .zero.table : AT (__exidx_end - __app_text_vma__ + __app_text_lma__) + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG ((__bss_end__ - __bss_start__)/4) + + . = ALIGN(4); + __zero_table_end__ = .; + } > xip +} + +/* start of bootstrap code sahb address */ +__bootstrap_start_addr__ = RAM_END_ADDR_SAHB - BOOTSTRAP_SIZE; +/* bootstrap size */ +__bootstrap_size__ = __bootstrap_size_end__ - __bootstrap_start_addr__; diff --git a/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_IAR/cyw20829_ns_flash_cbus_ota_xip.icf b/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_IAR/cyw20829_ns_flash_cbus_ota_xip.icf new file mode 100644 index 0000000..713134f --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/CYW20829/COMPONENT_CM33/TOOLCHAIN_IAR/cyw20829_ns_flash_cbus_ota_xip.icf @@ -0,0 +1,211 @@ +/******************************************************************************* +* \file cyw20829_ns_flash_cbus.icf +* \version 1.1.0 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point starts at 0x0401c600. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + + +/* The size of the stack section at the end of CM33 SRAM */ +define symbol STACK_SIZE = 0x800; +define symbol HEAP_SIZE = 0x0400; + +/* Memory reserved for Bootstrap code and data */ +if (!isdefinedsymbol(APP_BOOTSTRAP_SIZE)) { + define symbol APP_BOOTSTRAP_SIZE = 0x00003A00; +} + +if (!isdefinedsymbol(BOOTSTRAP_SIZE)) { + define symbol BOOTSTRAP_SIZE = APP_BOOTSTRAP_SIZE; +} + +define symbol FLASH_START_ADDR_SAHB_ORIG = 0x60000000; +define symbol USER_APP_START_OFFSET = MCUBOOT_HEADER_SIZE + FLASH_AREA_IMG_1_PRIMARY_START; + +define symbol FLASH_START_ADDR_SAHB = 0x60000000 + USER_APP_START_OFFSET; +define symbol FLASH_START_ADDR_CBUS = 0x08000000 + USER_APP_START_OFFSET; +define symbol RAM_START_ADDR_SAHB = 0x20000000; +define symbol RAM_START_ADDR_CBUS = 0x04000000; +define symbol RAM_END_ADDR_SAHB = 0x20040000; /* 256K */ +define symbol RAM_END_ADDR_CBUS = 0x04040000; /* 256K */ +define symbol FLASH_END_ADDR_SAHB = 0x60100000; /* 1MB */ + +define symbol BOOTSTRAP_OFFSET_FLASH = 0x00000050; /* toc2=0x10, l1_desc=0x1C, sign_header=0x20 */ +define symbol RAMVECTORS_ALIGNMENT = 512; +define symbol FLASH_ALIGNMENT_SIZE = 0x00000200; + +/* vma for bootstrap code region */ +define symbol CODE_VMA = RAM_END_ADDR_SAHB - BOOTSTRAP_SIZE; /* 0x2003c600 */ +/* lma for bootstrap code region */ +define symbol CODE_LMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_OFFSET_FLASH; /* 0x60000050 */ +/* Size of Bootstrap data */ +define symbol DATA_BS_SIZE = 0x00000400; /* 1KB */ +/* Maximum bootstrap code + data size */ +define symbol CODE_BS_SIZE = BOOTSTRAP_SIZE - DATA_BS_SIZE; /* 8KB */ +/* vma for bootstrap data region */ +define symbol DATA_BS_VMA = RAM_END_ADDR_SAHB - BOOTSTRAP_SIZE + CODE_BS_SIZE; /* 0x2001E000 */ +/* vma for app data region */ +define symbol DATA_VMA = RAM_START_ADDR_SAHB; /* 0x20000000 */ +/* app data size */ +define symbol DATA_SIZE = RAM_END_ADDR_SAHB - DATA_VMA - BOOTSTRAP_SIZE; /* 0x3DC00 */ +/* vma for application XIP region */ +define symbol XIP_VMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_SIZE + FLASH_ALIGNMENT_SIZE; /* 0x08002600 */ +/* lma for application XIP region */ +define symbol XIP_LMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_SIZE + FLASH_ALIGNMENT_SIZE; /* 0x60002600 */ +/* size of XIP region */ +define symbol XIP_SIZE = FLASH_END_ADDR_SAHB - XIP_LMA; +/* Total size of SRAM */ +define symbol RAM_SIZE = RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB; /* 0x00040000 */ + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __size_cstack__ = STACK_SIZE; +} else { + define symbol __size_cstack__ = __STACK_SIZE; +} +define symbol __size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __size_heap__ = HEAP_SIZE; +} else { + define symbol __size_heap__ = __HEAP_SIZE; +} + +define memory mem with size = 4G; +/* bootstrap code region */ +define region CODE_region = mem:[from CODE_VMA size CODE_BS_SIZE]; +/* bootstrap data region */ +define region DATA_BS_region = mem:[from DATA_BS_VMA size DATA_BS_SIZE]; +/* app data region */ +define region DATA_region = mem:[from DATA_VMA size DATA_SIZE]; +/* app code (xip) region */ +define region XIP_region = mem:[from XIP_VMA size XIP_SIZE]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __size_heap__ { }; +define block HSTACK {first block CSTACK, block PROC_STACK}; +define block RO {first section .intvec}; +define block RAMVECTOR with alignment = RAMVECTORS_ALIGNMENT { section .intvec_ram}; +define block APPTEXTRAM with alignment = 8 +{ + section .cy_ramfunc, + readwrite code object cy_smif.o, + readwrite code object cy_smif_sfdp.o, + readwrite code object cy_smif_memslot.o, + readwrite code object cy_os_common*.o, + readwrite code object cy_btstack_common*.o, + readwrite code object cy_btstack_gatt*.o, + readwrite code object cy_ipc*.o, + readwrite code object cy_btstack_porting*.o +}; + +define block XIP {readonly}; + +/*-Initializations-*/ +initialize by copy { readwrite }; /* copy .data section from flash to ram and initialize by ILINK */ +initialize by copy { rw, section .cy_ramfunc }; /* copy .data section from flash to ram and initialize by ILINK */ +initialize by copy { readonly object cy_smif.o }; +initialize by copy { readonly object cy_smif_sfdp.o }; +initialize by copy { readonly object cy_smif_memslot.o }; +initialize by copy { readonly object cy_os_common*.o }; +initialize by copy { readonly object cy_btstack_common*.o }; +initialize by copy { readonly object cy_btstack_gatt*.o }; +initialize by copy { readonly object cy_ipc*.o }; +initialize by copy { readonly object cy_btstack_porting*.o }; +do not initialize { section .noinit, section .intvec_ram }; /* exclude .noinit and .intvec_ram sections */ + +/*-Placement-*/ + +/* RAM */ +place at start of CODE_region { block RO }; +place in CODE_region { readonly object *startup_cat1b_cm33.o }; +place in CODE_region { readonly object *system_cyw20829.o }; +place in CODE_region { readonly object *cy_device.o }; +place in CODE_region { readonly object *cy_btss.o }; +place in CODE_region { readonly object *cy_sysclk_v2.o }; +place in CODE_region { readonly object *cy_syspm_v2.o }; +place in CODE_region { readonly object *cy_sysint_v2.o }; +place in CODE_region { readonly object *cy_syslib*.o }; +place in CODE_region { readonly object *ppu_v1.o }; +place in CODE_region { readonly object *cy_mpc.o }; +place in CODE_region { readonly object *cy_syspm_ppu.o }; +place in CODE_region { readonly object *ABImemcpy.o }; +place in CODE_region { readonly object *memcmp.o }; +place in CODE_region { readonly object *ABImemset.o }; +place in CODE_region { readonly object *ABImemset48.o }; +place in CODE_region { readonly object *ABImemclr.o }; +place in CODE_region { readonly object *ABImemclr4.o }; + + +place in DATA_BS_region { readwrite object *startup_cat1b_cm33.o }; +place in DATA_BS_region { readwrite object *system_cyw20829.o }; +place in DATA_BS_region { readwrite object *cy_device.o }; +place in DATA_BS_region { readwrite object *cy_btss.o }; +place in DATA_BS_region { readwrite object *cy_sysclk_v2.o }; +place in DATA_BS_region { readwrite object *cy_syspm_v2.o }; +place in DATA_BS_region { readwrite object *cy_sysint_v2.o }; +place in DATA_BS_region { readwrite object *cy_syslib*.o }; +place in DATA_BS_region { readwrite object *ppu_v1.o }; +place in DATA_BS_region { readwrite object *cy_mpc.o }; +place in DATA_BS_region { readwrite object *cy_syspm_ppu.o }; + +place at start of DATA_region { block HSTACK }; +place in DATA_region { block RAMVECTOR }; +place in DATA_region { block APPTEXTRAM }; +place in DATA_region { readwrite }; +place at end of DATA_region { block HEAP }; + + +place in XIP_region { block XIP }; + + +keep { section .intvec }; + + +define exported symbol __bootstrap_code_vma__ = CODE_VMA; +define exported symbol __bootstrap_code_lma__ = CODE_LMA; +define exported symbol __app_code_vma__ = XIP_VMA; +define exported symbol __app_code_lma__ = XIP_LMA; +define exported symbol __bootstrap_size__ = BOOTSTRAP_SIZE; +define exported symbol __bootstrapzero_table_start__ = DATA_BS_VMA; +define exported symbol __bootstrapzero_table_end__ = DATA_BS_VMA; +define exported symbol __bootstrap_start_addr__ = RAM_END_ADDR_SAHB - BOOTSTRAP_SIZE; +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.sct b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.sct new file mode 100644 index 0000000..6be862b --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.sct @@ -0,0 +1,280 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cy8c6xxa_cm4_dual.sct +;* \version 2.60 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2019 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +#define MCUBOOT_FLASH_SIZE 0x20000 +#define MCUBOOT_RAM_SIZE 0x00800 + +; By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. +; More about CM0+ prebuilt images, see here: +; https://github.com/Infineon/psoc6cm0p +; The size of the Cortex-M0+ application flash image +#define FLASH_CM0P_SIZE 0x00020000 +#define CM0P_RAM_SIZE 0x00003000 + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. +; Using this memory region for other purposes will lead to unexpected behavior. +; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat', +; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'. +; RAM +#define RAM_START (0x08000000 + MCUBOOT_RAM_SIZE + CM0P_RAM_SIZE) +#define RAM_SIZE 0x00042000 +; Flash +#define FLASH_START 0x10000000 +#define FLASH_CM0P_START (FLASH_START + MCUBOOT_FLASH_SIZE + MCUBOOT_HEADER_SIZE) +#define FLASH_CM4_START (FLASH_CM0P_START + FLASH_CM0P_SIZE) +#define FLASH_SIZE (FLASH_AREA_IMG_1_PRIMARY_SIZE) + +; Size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + + +; Cortex-M0+ application flash image area +LR_IROM FLASH_CM0P_START FLASH_CM0P_SIZE +{ + .cy_m0p_image +0 FLASH_CM0P_SIZE + { + * (.cy_m0p_image) + } +} + +; Cortex-M4 application flash area +LR_IROM1 FLASH_CM4_START (FLASH_SIZE - FLASH_CM0P_SIZE) +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 FIXED + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. + .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 + { + * (.cy_app_signature) + } +} + + +; Emulated EEPROM Flash area +LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +{ + .cy_em_eeprom +0 + { + * (.cy_em_eeprom) + } +} + +; Supervisory flash: User data +LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE +{ + .cy_sflash_user_data +0 + { + * (.cy_sflash_user_data) + } +} + +; Supervisory flash: Normal Access Restrictions (NAR) +LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE +{ + .cy_sflash_nar +0 + { + * (.cy_sflash_nar) + } +} + +; Supervisory flash: Public Key +LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE +{ + .cy_sflash_public_key +0 + { + * (.cy_sflash_public_key) + } +} + +; Supervisory flash: Table of Content # 2 Copy +LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +{ + .cy_rtoc_part2 +0 + { + * (.cy_rtoc_part2) + } +} + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +LR_EROM XIP_START XIP_SIZE +{ + cy_xip +0 + { + * (.cy_xip) + } +} + + +; eFuse +LR_EFUSE EFUSE_START EFUSE_SIZE +{ + .cy_efuse +0 + { + * (.cy_efuse) + } +} + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +CYMETA 0x90500000 +{ + .cymeta +0 { * (.cymeta) } +} + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x00100000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.ld b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.ld new file mode 100644 index 0000000..a5b03ac --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.ld @@ -0,0 +1,506 @@ +/******************************************************************************* +* \file cy8c6xx7_cm4_dual_cm0p_bless.ld +* \version 2.91 +* +* Linker file for the GNU C compiler. +* +* This linker script is modified from cy8c6xx7_cm4_dual.ld for CM0P_BLESS image. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + +/* Size of the stack section at the end of SRAM */ +STACK_SIZE = 0x1000; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --defsym,MCUBOOT_HEADER_SIZE=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + + + +/* + Flash Memory Layout for using with OTA support + MCUBootApp is the boot application that does the actual SWAP of Primary and Secondary Slots. + + NOTE: MCUBootApp treats the Slots as Monolithic Chunks, not caring for the majority of the + content with the only exceptions being the 0x400 header and a 0x400 trailer contained + within the slot. The header to validate the slot and the trailer for update information. + The User Application uses the ota-update library to download and store new app to Secondary Slot. + + We use a JSON file to define the flash layout. The layout here is defined in: + /configs/COMPONENT_MCUBOOT/flashmap/psoc62_1m_cm0_int_swap_single.json + It is copied when building MCUBootApp, and must be reflected here manually. + + Internal Flash Layout +0x10000000 ---------------------------------------- + | MCUBootApp | +0x10020000 ---------------------------------------- ------------------------------------ + | Required MCUBootHeader | (added in signing step of User App) \ +0x10020400 | ------------------ | ---------------- \ + | Application cm0p code | BLE code \ +0x10040000 ------------------ | ---------------- --> Primary slot + | | / + | Application cm4 code | User Application / + | | / +0x10080000 ---------------------------------------- ------------------------------------ + | Required MCUBootHeader | (added in signing step of User App) \ +0x10080400 | ------------------ | ---------------- \ + | Application cm0p code | BLE code \ +0x10040000 ------------------ | ---------------- --> Secondary slot + | | / + | Application cm4 code | User Application / + | | / +0x100e0000 ---------------------------------------- ------------------------------------ + | Scratch Area | Used by MCUBootApp while SWAPping Primary and Secondary Slots + | | Larger Scratch Area will speed up the SWAP and increase the flash life +0x100e4000 -------------------------------------------- + | Status Area (For MCUBoot) | Used by MCUBootApp to keep track of the SWAP process and provide information + | | needed to resume the SWAP if there is a reset during the SWAP process. +0x100e8000 ---------------------------------------- + | Unused 0x00018000 (96k) | +0x10100000 ---------------------------------------- + + SRAM usage for OTA applciation support + CY8CKIT-062-BLE, CY8CPROTO-063-BLE and CYBLE-416045-EVAL have 278k RAM (0x45800) available for use. + High 0x800 bytes are used by the System (from 0x46000 bytes) + MCUBootApp requires 0x800 bytes at start of RAM for it's "public" RAM usage. + +0x08000000 ---------------------------------------- + | MCUBootApp | +0x08000800 ---------------------------------------- + | cm0p code RAM | + | 0x00003000 bytes (12k) | +0x08003800 ---------------------------------------- + | | + | cm4 User Application RAM | + | 0x00042000 bytes (264k) | + | | +0x08045800 ---------------------------------------- + | System RAM 0x800 | +0x08046000 ---------------------------------------- + +*/ + +/* FLASH for MCUBootApp */ +MCUBOOT_APP_SIZE = 0x00020000; +MCUBOOT_HEADER_SIZE = 0x00000400; +/* RAM for MCUBootApp */ +MCUBOOT_RAM_SIZE = 0x00000800; + +/* FLASH for cm0+ */ +CM0P_FLASH_SIZE = 0x00020000; +/* RAM for cm0+ */ +CM0P_RAM_SIZE = 0x00003000; + +/* System reserved RAM at to of RAM area */ +SYSTEM_RESERVED_RAM = 0x00000800; + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing the 'ram' and 'flash' regions. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'. + */ + + ram (rwx) : ORIGIN = 0x08000000 + MCUBOOT_RAM_SIZE + CM0P_RAM_SIZE, LENGTH = 0x00046000 - MCUBOOT_RAM_SIZE - CM0P_RAM_SIZE - SYSTEM_RESERVED_RAM + flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x00100000 + + /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */ + sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */ + sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */ + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */ + efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */ +} + +/* Size and start address of the Cortex-M0+ application image */ +FLASH_CM0P_START = ORIGIN(flash) + MCUBOOT_APP_SIZE + MCUBOOT_HEADER_SIZE; +FLASH_CM0P_SIZE = 0x20000; +/* Size and start address of the Cortex-M4 application image */ +FLASH_CM4_START = FLASH_CM0P_START + FLASH_CM0P_SIZE; +FLASH_CM4_SIZE = LENGTH(flash) - (FLASH_CM0P_START + FLASH_CM0P_SIZE); + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + + +SECTIONS +{ + /* Cortex-M0+ application image */ + .cy_m0p_image FLASH_CM0P_START : + { + . = ALIGN(4); + __cy_m0p_code_start = . ; + + *psoc6_cm0p_bless_ota + + KEEP(*(.cy_m0p_image)) + __cy_m0p_code_end = . ; + } > flash + + /* Check if .cy_m0p_image size exceeds FLASH_CM0P_SIZE */ + ASSERT(__cy_m0p_code_end <= ORIGIN(flash) + FLASH_CM0P_START + FLASH_CM0P_SIZE, "CM0+ flash image overflows with CM4, increase FLASH_CM0P_SIZE") + + /* Cortex-M4 application flash area */ + .text FLASH_CM4_START : + { + . = ALIGN(4); + __cy_app_load_addr = . ; + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_psoc6_02_cm4.S */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + /* Copy interrupt vectors from flash to RAM */ + LONG (__Vectors) /* From */ + LONG (__ram_vectors_start__) /* To */ + LONG (__Vectors_End - __Vectors) /* Size */ + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG (__data_end__ - __data_start__) /* Size */ + + __copy_table_end__ = .; + } > flash + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_02_cm4.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : AT (__etext) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(4); + + __data_end__ = .; + + } > ram + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Used for the digital signature of the secure application and the Bootloader SDK application. + * The size of the section depends on the required data size. */ + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom (NOLOAD): + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + + /* Supervisory Flash: Table of Content # 2 Copy */ + .cy_rtoc_part2 : + { + KEEP(*(.cy_rtoc_part2)) + } > sflash_rtoc_2 + + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + .cy_xip : + { + KEEP(*(.cy_xip)) + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse + + + /* These sections are used for additional metadata (silicon revision, + * Silicon/JTAG ID, etc.) storage. + */ + .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x00200000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x200; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual_ota_cm0p_int.icf b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual_ota_cm0p_int.icf new file mode 100644 index 0000000..918f995 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_1M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual_ota_cm0p_int.icf @@ -0,0 +1,264 @@ +/******************************************************************************* +* \file cy8c6xx7_cm4_dual.icf +* \version 2.91 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ +define symbol MCUBOOT_FLASH_SIZE = 0x20000; +define symbol MCUBOOT_RAM_SIZE = 0x00800; + +/* By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. + * More about CM0+ prebuilt images, see here: + * https://github.com/Infineon/psoc6cm0p + */ +/* The size of the Cortex-M0+ application image */ +define symbol FLASH_CM0P_SIZE = 0x00020000; +define symbol CM0P_RAM_SIZE = 0x00003000; + +define symbol FLASH_START = 0x10000000; +define symbol FLASH_CM0P_START = (FLASH_START + MCUBOOT_FLASH_SIZE + MCUBOOT_HEADER_SIZE); +define symbol FLASH_CM4_START = (FLASH_CM0P_START + FLASH_CM0P_SIZE); +define symbol FLASH_END = FLASH_AREA_IMG_1_PRIMARY_SIZE; + + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000 + MCUBOOT_RAM_SIZE + CM0P_RAM_SIZE; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x08042000; +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = FLASH_CM0P_START; /* was 0x10000000 */ +define symbol __ICFEDIT_region_IROM1_end__ = 0x10100000; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* Supervisory FLASH - User Data */ +define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800; +define symbol __ICFEDIT_region_IROM3_end__ = 0x160007FF; + +/* Supervisory FLASH - Normal Access Restrictions (NAR) */ +define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00; +define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF; + +/* Supervisory FLASH - Public Key */ +define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00; +define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF; + +/* Supervisory FLASH - Table of Content # 2 */ +define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00; +define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF; + +/* Supervisory FLASH - Table of Content # 2 Copy */ +define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00; +define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF; + +/* eFuse */ +define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000; +define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF; + +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__]; +define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__]; +define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__]; +define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__]; +define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__]; +define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; +define block CM0P_RO with size = FLASH_CM0P_SIZE { readonly section .cy_m0p_image }; +define block RO {first section .intvec, readonly}; + +define block cy_xip { section .cy_xip }; + +/* define region FLASH_REGION = mem:[from FLASH_CM0P_START to FLASH_END]; */ + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/*-Placement-*/ + +/* Flash - Cortex-M0+ application image */ +place at start of IROM1_region { block CM0P_RO }; + +/* Flash - Cortex-M4 application */ +place in IROM1_region { block RO }; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature }; + +/* Emulated EEPROM Flash area */ +".cy_em_eeprom" : place at start of IROM2_region { section .cy_em_eeprom }; + +/* Supervisory Flash - User Data */ +".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data }; + +/* Supervisory Flash - NAR */ +".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar }; + +/* Supervisory Flash - Public Key */ +".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key }; + +/* Supervisory Flash - TOC2 */ +".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 }; + +/* Supervisory Flash - RTOC2 */ +".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 }; + +/* eFuse */ +".cy_efuse" : place at start of IROM8_region { section .cy_efuse }; + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +"cy_xip" : place at start of EROM1_region { block cy_xip }; + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place at end of IRAM1_region { block HSTACK }; + +/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */ +".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta }; + + +keep { section .cy_m0p_image, + section .cy_app_signature, + section .cy_em_eeprom, + section .cy_sflash_user_data, + section .cy_sflash_nar, + section .cy_sflash_public_key, + section .cy_toc_part2, + section .cy_rtoc_part2, + section .cy_efuse, + section .cy_xip, + section .cymeta, + }; + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +define exported symbol __cy_memory_0_start = 0x10000000; +define exported symbol __cy_memory_0_length = 0x00100000; +define exported symbol __cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +define exported symbol __cy_memory_1_start = 0x14000000; +define exported symbol __cy_memory_1_length = 0x8000; +define exported symbol __cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +define exported symbol __cy_memory_2_start = 0x16000000; +define exported symbol __cy_memory_2_length = 0x8000; +define exported symbol __cy_memory_2_row_size = 0x200; + +/* XIP */ +define exported symbol __cy_memory_3_start = 0x18000000; +define exported symbol __cy_memory_3_length = 0x08000000; +define exported symbol __cy_memory_3_row_size = 0x200; + +/* eFuse */ +define exported symbol __cy_memory_4_start = 0x90700000; +define exported symbol __cy_memory_4_length = 0x100000; +define exported symbol __cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xxa_cm4_dual_ota_int.sct b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xxa_cm4_dual_ota_int.sct new file mode 100644 index 0000000..ce9da56 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xxa_cm4_dual_ota_int.sct @@ -0,0 +1,241 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cy8c6xxa_cm4_dual.sct +;* \version 2.60 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2019 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. +; Using this memory region for other purposes will lead to unexpected behavior. +; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat', +; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'. +; RAM +#define RAM_START 0x08020800 +#define RAM_SIZE 0x000DF000 +; Flash +#define FLASH_START (0x10000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE) +#define FLASH_SIZE (FLASH_AREA_IMG_1_PRIMARY_SIZE) ; Our code must fit into a single slot - header + +; Size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + +; Cortex-M4 application flash area +LOAD_REGION_1 FLASH_START FLASH_SIZE +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + ; How can we get the data initialization values placed at the end of the other data + ; and have the scatter code copy it to the RAM locations? + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Emulated EEPROM Flash area + ; The alignment and size of this region must match the + ; requirements for the emeeprom component + ER_EM_EEPROM EM_EEPROM_START EMPTY NOCOMPRESS EM_EEPROM_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. +; .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 +; { +; * (.cy_app_signature) +; } + +} + + +; Emulated EEPROM Flash area - Do not load into HEX file output +;LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +;{ +; .cy_em_eeprom +0 +; { +; * (.cy_em_eeprom) +; } +;} + +; Supervisory flash: Table of Content # 2 Copy +;LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +;{ +; .cy_rtoc_part2 +0 +; { +; * (.cy_rtoc_part2) +; } +;} + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +;LR_EROM XIP_START XIP_SIZE +;{ +; .cy_xip +0 +; { +; * (.cy_xip) +; } +;} + + +; eFuse +;LR_EFUSE EFUSE_START EFUSE_SIZE +;{ +; .cy_efuse +0 +; { +; * (.cy_efuse) +; } +;} + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +;CYMETA 0x90500000 +;{ +; .cymeta +0 { * (.cymeta) } +;} + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x00200000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xxa_cm4_dual_ota_int.ld b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xxa_cm4_dual_ota_int.ld new file mode 100644 index 0000000..0a1545f --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xxa_cm4_dual_ota_int.ld @@ -0,0 +1,401 @@ +/***************************************************************************//** +* \file cy8c6xxa_cm4_dual.ld +* \version 2.60 +* +* Linker file for the GNU C compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + +/* Size of the stack section at the end of CM4 SRAM */ +STACK_SIZE = 0x1000; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --defsym,MCUBOOT_HEADER_SIZE=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing the 'ram' and 'flash' regions. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'. + */ + ram (rwx) : ORIGIN = 0x08020800, LENGTH = 0xDF000 + flash (rx) : ORIGIN = 0x10000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE, LENGTH = FLASH_AREA_IMG_1_PRIMARY_SIZE - MCUBOOT_HEADER_SIZE + + /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */ + sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */ + sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */ + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */ + efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */ +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + + +SECTIONS +{ + /* Cortex-M4 application flash area */ + .text ORIGIN(flash) : + { + . = ALIGN(8); + __cy_app_load_addr = . ; + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(8); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(8); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_psoc6_02_cm4.S */ + .copy.table : + { + . = ALIGN(8); + __copy_table_start__ = .; + + /* Copy interrupt vectors from flash to RAM */ + LONG (__Vectors) /* From */ + LONG (__ram_vectors_start__) /* To */ + LONG (__Vectors_End - __Vectors) /* Size */ + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG (__data_end__ - __data_start__) /* Size */ + + __copy_table_end__ = .; + } > flash + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_02_cm4.S */ + .zero.table : + { + . = ALIGN(8); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : AT (__etext) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(8); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(8); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(8); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(8); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(8); + + __data_end__ = .; + + } > ram + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(8); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Used for the digital signature of the secure application and the Bootloader SDK application. + * The size of the section depends on the required data size. */ + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom (NOLOAD): + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + + /* Supervisory Flash: Table of Content # 2 Copy */ + .cy_rtoc_part2 : + { + KEEP(*(.cy_rtoc_part2)) + } > sflash_rtoc_2 + + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + .cy_xip : + { + KEEP(*(.cy_xip)) + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse + + + /* These sections are used for additional metadata (silicon revision, + * Silicon/JTAG ID, etc.) storage. + */ + .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x00200000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x200; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xxa_cm4_dual_ota_int.icf b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xxa_cm4_dual_ota_int.icf new file mode 100644 index 0000000..698d62f --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_2M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xxa_cm4_dual_ota_int.icf @@ -0,0 +1,249 @@ +/***************************************************************************//** +* \file cy8c6xxa_cm4_dual.icf +* \version 2.60 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08020800; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x080DF000; +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x10200000; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* Supervisory FLASH - User Data */ +define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800; +define symbol __ICFEDIT_region_IROM3_end__ = 0x160007FF; + +/* Supervisory FLASH - Normal Access Restrictions (NAR) */ +define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00; +define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF; + +/* Supervisory FLASH - Public Key */ +define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00; +define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF; + +/* Supervisory FLASH - Table of Content # 2 */ +define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00; +define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF; + +/* Supervisory FLASH - Table of Content # 2 Copy */ +define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00; +define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF; + +/* eFuse */ +define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000; +define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF; + +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__]; +define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__]; +define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__]; +define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__]; +define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__]; +define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +define symbol FLASH_START = 0x10000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE; +define symbol FLASH_END = FLASH_START + FLASH_AREA_IMG_1_PRIMARY_SIZE - MCUBOOT_HEADER_SIZE; + +define region FLASH_REGION = mem:[from FLASH_START to FLASH_END]; + +/*-Placement-*/ + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/* Flash - Cortex-M4 application */ +place at start of FLASH_REGION {section .intvec, readonly}; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +/* ".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature }; [stde] */ + +/* Emulated EEPROM Flash area - Do not load into HEX file output */ +".cy_em_eeprom" : place noload at start of IROM2_region { section .cy_em_eeprom }; + +/* Supervisory Flash - User Data */ +/* ".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data }; [stde] */ + +/* Supervisory Flash - NAR */ +/* ".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar }; [stde] */ + +/* Supervisory Flash - Public Key */ +/* ".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key }; [stde] */ + +/* Supervisory Flash - TOC2 */ +/* ".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 }; [stde] */ + +/* Supervisory Flash - RTOC2 */ +/* ".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 }; [stde] */ + +/* eFuse */ +/* ".cy_efuse" : place at start of IROM8_region { section .cy_efuse }; [stde] */ + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +/* ".cy_xip" : place at start of EROM1_region { section .cy_xip }; [stde] */ + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place at end of IRAM1_region { block HSTACK }; + +/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */ +/* ".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta }; [stde] */ + +keep { + section .intvec, +/* + section .cy_app_signature, + section .cy_em_eeprom, - Do not load into HEX file output + section .cy_sflash_user_data, + section .cy_sflash_nar, + section .cy_sflash_public_key, + section .cy_toc_part2, + section .cy_rtoc_part2, + section .cy_efuse, + section .cy_xip, + section .cymeta, +*/ + }except{ + section .cy_sflash_user_data, + section .cy_toc_part2 + }; + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +define exported symbol __cy_memory_0_start = 0x10000000; +define exported symbol __cy_memory_0_length = 0x00200000; +define exported symbol __cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +define exported symbol __cy_memory_1_start = 0x14000000; +define exported symbol __cy_memory_1_length = 0x8000; +define exported symbol __cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +define exported symbol __cy_memory_2_start = 0x16000000; +define exported symbol __cy_memory_2_length = 0x8000; +define exported symbol __cy_memory_2_row_size = 0x200; + +/* XIP */ +define exported symbol __cy_memory_3_start = 0x18000000; +define exported symbol __cy_memory_3_length = 0x08000000; +define exported symbol __cy_memory_3_row_size = 0x200; + +/* eFuse */ +define exported symbol __cy_memory_4_start = 0x90700000; +define exported symbol __cy_memory_4_length = 0x100000; +define exported symbol __cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx5_cm4_dual_ota_int.sct b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx5_cm4_dual_ota_int.sct new file mode 100644 index 0000000..a336df7 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx5_cm4_dual_ota_int.sct @@ -0,0 +1,281 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cy8c6xx5_cm4_dual.sct +;* \version 2.91 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2021 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. +; Using this memory region for other purposes will lead to unexpected behavior. +; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat', +; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'. +; RAM +#define RAM_START 0x08002000 +#define RAM_SIZE 0x0003D800 +; Flash +#define FLASH_START (0x10000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE) +#define FLASH_SIZE (FLASH_AREA_IMG_1_PRIMARY_SIZE) ; Our code must fit into a single slot - header + +; The size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. +; More about CM0+ prebuilt images, see here: +; https://github.com/Infineon/psoc6cm0p +; The size of the Cortex-M0+ application flash image +#define FLASH_CM0P_SIZE 0x2000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + + +; Cortex-M4 application flash area +LR_IROM1 FLASH_START FLASH_SIZE +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 FIXED + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Emulated EEPROM Flash area + ; The alignment and size of this region must match the + ; requirements for the emeeprom component + ER_EM_EEPROM EM_EEPROM_START EMPTY NOCOMPRESS EM_EEPROM_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. +; .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 +; { +; * (.cy_app_signature) +; } +} + + +; Emulated EEPROM Flash area +;LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +;{ +; .cy_em_eeprom +0 +; { +; * (.cy_em_eeprom) +; } +;} + +; Supervisory flash: User data +;LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE +;{ +; .cy_sflash_user_data +0 +; { +; * (.cy_sflash_user_data) +; } +;} + +; Supervisory flash: Normal Access Restrictions (NAR) +;LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE +;{ +; .cy_sflash_nar +0 +; { +; * (.cy_sflash_nar) +; } +;} + +; Supervisory flash: Public Key +;LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE +;{ +; .cy_sflash_public_key +0 +; { +; * (.cy_sflash_public_key) +; } +;} + +; Supervisory flash: Table of Content # 2 +;LR_SFLASH_TOC_2 SFLASH_TOC_2_START SFLASH_TOC_2_SIZE +;{ +; .cy_toc_part2 +0 +; { +; * (.cy_toc_part2) +; } +;} + +; Supervisory flash: Table of Content # 2 Copy +;LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +;{ +; .cy_rtoc_part2 +0 +; { +; * (.cy_rtoc_part2) +; } +;} + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +;LR_EROM XIP_START XIP_SIZE +;{ +; cy_xip +0 +; { +; * (.cy_xip) +; } +;} + + +; eFuse +;LR_EFUSE EFUSE_START EFUSE_SIZE +;{ +; .cy_efuse +0 +; { +; * (.cy_efuse) +; } +;} + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +;CYMETA 0x90500000 +;{ +; .cymeta +0 { * (.cymeta) } +;} + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x00080000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx5_cm4_dual_ota_xip.sct b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx5_cm4_dual_ota_xip.sct new file mode 100644 index 0000000..ce79b96 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx5_cm4_dual_ota_xip.sct @@ -0,0 +1,286 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cy8c6xx5_cm4_dual_ota_xip.sct +;* \version 2.91 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2021 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. +; Using this memory region for other purposes will lead to unexpected behavior. +; RAM +#define RAM_START 0x08002000 +#define RAM_SIZE 0x0003D800 +; Flash +#define FLASH_START (0x18000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE) +#define FLASH_SIZE FLASH_AREA_IMG_1_PRIMARY_SIZE + +; The size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + + +; Cortex-M4 application flash area +LOAD_REGION_1 FLASH_START FLASH_SIZE +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + + cy_ota_flash.o (+RO, +RW, +ZI) + flash_qspi.o (+RO, +RW, +ZI) + cy_device.o (+RO, +RW, +ZI) + lib_a-memset.o (+RO, +RW, +ZI) + *memset.o (+RO, +RW, +ZI) + aeabi_memset4.o (+RO, +RW, +ZI) + cy_smif.o (+RO, +RW, +ZI) + cy_smif_memslot.o (+RO, +RW, +ZI) + cy_smif_sfdp.o (+RO, +RW, +ZI) + cy_syslib.o (+RO, +RW, +ZI) + cy_syslib_ext.o (+RO, +RW, +ZI) + cycfg_qspi_memslot.o (+RO, +RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Emulated EEPROM Flash area + ; The alignment and size of this region must match the + ; requirements for the emeeprom component + ER_EM_EEPROM EM_EEPROM_START EMPTY NOCOMPRESS EM_EEPROM_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. +; .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 +; { +; * (.cy_app_signature) +; } +} + + +; Emulated EEPROM Flash area +;LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +;{ +; .cy_em_eeprom +0 +; { +; * (.cy_em_eeprom) +; } +;} + +; Supervisory flash: User data +;LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE +;{ +; .cy_sflash_user_data +0 +; { +; * (.cy_sflash_user_data) +; } +;} + +; Supervisory flash: Normal Access Restrictions (NAR) +;LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE +;{ +; .cy_sflash_nar +0 +; { +; * (.cy_sflash_nar) +; } +;} + +; Supervisory flash: Public Key +;LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE +;{ +; .cy_sflash_public_key +0 +; { +; * (.cy_sflash_public_key) +; } +;} + +; Supervisory flash: Table of Content # 2 +;LR_SFLASH_TOC_2 SFLASH_TOC_2_START SFLASH_TOC_2_SIZE +;{ +; .cy_toc_part2 +0 +; { +; * (.cy_toc_part2) +; } +;} + +; Supervisory flash: Table of Content # 2 Copy +;LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +;{ +; .cy_rtoc_part2 +0 +; { +; * (.cy_rtoc_part2) +; } +;} + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +;LR_EROM XIP_START XIP_SIZE +;{ +; cy_xip +0 +; { +; * (.cy_xip) +; } +;} + + +; eFuse +;LR_EFUSE EFUSE_START EFUSE_SIZE +;{ +; .cy_efuse +0 +; { +; * (.cy_efuse) +; } +;} + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +;CYMETA 0x90500000 +;{ +; .cymeta +0 { * (.cymeta) } +;} + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x00200000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx5_cm4_dual_ota_int.ld b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx5_cm4_dual_ota_int.ld new file mode 100644 index 0000000..3222e06 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx5_cm4_dual_ota_int.ld @@ -0,0 +1,401 @@ +/***************************************************************************//** +* \file cy8c6xxa_cm4_dual.ld +* \version 2.60 +* +* Linker file for the GNU C compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + +/* Size of the stack section at the end of CM4 SRAM */ +STACK_SIZE = 0x1000; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --defsym,MCUBOOT_HEADER_SIZE=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing the 'ram' and 'flash' regions. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'. + */ + ram (rwx) : ORIGIN = 0x08002000, LENGTH = 0x3D800 + flash (rx) : ORIGIN = 0x10000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE, LENGTH = FLASH_AREA_IMG_1_PRIMARY_SIZE - MCUBOOT_HEADER_SIZE + + /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */ + sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */ + sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */ + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */ + efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */ +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + + +SECTIONS +{ + /* Cortex-M4 application flash area */ + .text ORIGIN(flash) : + { + . = ALIGN(8); + __cy_app_load_addr = . ; + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(8); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(8); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_psoc6_02_cm4.S */ + .copy.table : + { + . = ALIGN(8); + __copy_table_start__ = .; + + /* Copy interrupt vectors from flash to RAM */ + LONG (__Vectors) /* From */ + LONG (__ram_vectors_start__) /* To */ + LONG (__Vectors_End - __Vectors) /* Size */ + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG (__data_end__ - __data_start__) /* Size */ + + __copy_table_end__ = .; + } > flash + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_02_cm4.S */ + .zero.table : + { + . = ALIGN(8); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : AT (__etext) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(8); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(8); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(8); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(8); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(8); + + __data_end__ = .; + + } > ram + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(8); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Used for the digital signature of the secure application and the Bootloader SDK application. + * The size of the section depends on the required data size. */ + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom (NOLOAD): + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + + /* Supervisory Flash: Table of Content # 2 Copy */ + .cy_rtoc_part2 : + { + KEEP(*(.cy_rtoc_part2)) + } > sflash_rtoc_2 + + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + .cy_xip : + { + KEEP(*(.cy_xip)) + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse + + + /* These sections are used for additional metadata (silicon revision, + * Silicon/JTAG ID, etc.) storage. + */ + .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x00200000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x200; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx5_cm4_dual_ota_xip.ld b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx5_cm4_dual_ota_xip.ld new file mode 100644 index 0000000..dab7ee8 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx5_cm4_dual_ota_xip.ld @@ -0,0 +1,268 @@ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + + +STACK_SIZE = 0x1000; + + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --defsym,MCUBOOT_HEADER_SIZE=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +EXTERN(Reset_Handler) + +MEMORY +{ + ram (rwx) : ORIGIN = 0x08002000, LENGTH = 0x3D800 + flash (rx) : ORIGIN = 0x18000000 + FLASH_AREA_IMG_1_PRIMARY_START, LENGTH = 0x8000000 + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 +} + + +GROUP(libgcc.a libc.a libm.a libnosys.a) +SECTIONS +{ + .text ORIGIN(flash) + MCUBOOT_HEADER_SIZE : + { + . = ALIGN(4); + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + + /* Exclude external flash access code from running in external flash - added as RAM functions in appTextRam */ + EXCLUDE_FILE( + /* Add Application files entries here.*/ + *cy_ota_flash.o + *flash_qspi.o + + /* Files, OTA library expects to be in RAM */ + *cy_syslib_ext.o + *lib_a-memset.o + *cy_smif.o + *cy_smif_memslot.o + *cy_smif_psoc6.o + *cy_smif_sfdp.o + *cyhal_qspi.o + *cy_syslib.o + *cycfg_qspi_memslot.o + *bootutil_misc.o + ) *(.text) *(.vfp11) + + KEEP(*(.init)) + KEEP(*(.fini)) + + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + KEEP(*(.eh_frame*)) + } > flash + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + + LONG (__Vectors) + LONG (__ram_vectors_start__) + LONG (__Vectors_End - __Vectors) + + + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + + __copy_table_end__ = .; + } > flash + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + .data __ram_vectors_end__ : AT (__etext) + { + . = ALIGN(4); + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + /* Add Application files entries here.*/ + *cy_ota_flash.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *flash_qspi.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + + /* Files, OTA library expects to be in RAM */ + *cy_syslib_ext.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *lib_a-memset.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *cy_smif.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *cy_smif_memslot.o(.text* .rodata .rodata* .rodata.CSWTCH.* .constdata .constdata* .conststring .conststring*) + *cy_smif_psoc6.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *cy_smif_sfdp.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *cyhal_qspi.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *cy_syslib.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *cycfg_qspi_memslot.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + *bootutil_misc.o(.text* .rodata .rodata* .constdata .constdata* .conststring .conststring*) + + . = ALIGN(4); + + __data_end__ = .; + + } > ram + + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > ram + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + .cy_em_eeprom (NOLOAD): + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + +/* + .cy_xip : + { + __cy_xip_start = .; + KEEP(*(.cy_xip)) + __cy_xip_end = .; + } > xip +*/ + +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x00200000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x00040000; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx5_cm4_dual_ota_int.icf b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx5_cm4_dual_ota_int.icf new file mode 100644 index 0000000..6c36908 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx5_cm4_dual_ota_int.icf @@ -0,0 +1,251 @@ +/******************************************************************************* +* \file cy8c6xx5_cm4_dual.icf +* \version 2.91 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08002000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x0803F7FF; + +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x1007FFFF; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* Supervisory FLASH - User Data */ +define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800; +define symbol __ICFEDIT_region_IROM3_end__ = 0x16000FFF; + +/* Supervisory FLASH - Normal Access Restrictions (NAR) */ +define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00; +define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF; + +/* Supervisory FLASH - Public Key */ +define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00; +define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF; + +/* Supervisory FLASH - Table of Content # 2 */ +define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00; +define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF; + +/* Supervisory FLASH - Table of Content # 2 Copy */ +define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00; +define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF; + +/* eFuse */ +define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000; +define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF; + +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__]; +define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__]; +define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__]; +define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__]; +define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__]; +define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; +define block RO {first section .intvec, readonly}; + +/*define block cy_xip { section .cy_xip };*/ + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +define symbol FLASH_START = 0x10000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE; +define symbol FLASH_END = FLASH_START + FLASH_AREA_IMG_1_PRIMARY_SIZE - MCUBOOT_HEADER_SIZE; + +define region FLASH_REGION = mem:[from FLASH_START to FLASH_END]; + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/*-Placement-*/ + +/* Flash - Cortex-M4 application */ +place in FLASH_REGION { block RO }; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +/* ".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature };*/ + +/* Emulated EEPROM Flash area - Do not load into HEX file output */ +".cy_em_eeprom" : place noload at start of IROM2_region { section .cy_em_eeprom }; + +/* Supervisory Flash - User Data */ +/* ".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data };*/ + +/* Supervisory Flash - NAR */ +/*".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar };*/ + +/* Supervisory Flash - Public Key */ +/*".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key };*/ + +/* Supervisory Flash - TOC2 */ +/*".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 };*/ + +/* Supervisory Flash - RTOC2 */ +/*".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 };*/ + +/* eFuse */ +/*".cy_efuse" : place at start of IROM8_region { section .cy_efuse };*/ + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +/*"cy_xip" : place at start of EROM1_region { block cy_xip };*/ + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place at end of IRAM1_region { block HSTACK }; + +/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */ +/*".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta };*/ + + +keep { + section .intvec, +/* + section .cy_app_signature, + section .cy_em_eeprom, - Do not load into HEX file output + section .cy_sflash_user_data, + section .cy_sflash_nar, + section .cy_sflash_public_key, + section .cy_toc_part2, + section .cy_rtoc_part2, + section .cy_efuse, + section .cy_xip, + section .cymeta, +*/ + }; + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +define exported symbol __cy_memory_0_start = 0x10000000; +define exported symbol __cy_memory_0_length = 0x00080000; +define exported symbol __cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +define exported symbol __cy_memory_1_start = 0x14000000; +define exported symbol __cy_memory_1_length = 0x8000; +define exported symbol __cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +define exported symbol __cy_memory_2_start = 0x16000000; +define exported symbol __cy_memory_2_length = 0x8000; +define exported symbol __cy_memory_2_row_size = 0x200; + +/* XIP */ +define exported symbol __cy_memory_3_start = 0x18000000; +define exported symbol __cy_memory_3_length = 0x08000000; +define exported symbol __cy_memory_3_row_size = 0x200; + +/* eFuse */ +define exported symbol __cy_memory_4_start = 0x90700000; +define exported symbol __cy_memory_4_length = 0x100000; +define exported symbol __cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx5_cm4_dual_ota_xip.icf b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx5_cm4_dual_ota_xip.icf new file mode 100644 index 0000000..d842131 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_062_512K/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx5_cm4_dual_ota_xip.icf @@ -0,0 +1,298 @@ +/******************************************************************************* +* \file cy8c6xx5_cm4_dual.icf +* \version 2.91 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08002000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x0803F7FF; + +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x1007FFFF; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* Supervisory FLASH - User Data */ +define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800; +define symbol __ICFEDIT_region_IROM3_end__ = 0x16000FFF; + +/* Supervisory FLASH - Normal Access Restrictions (NAR) */ +define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00; +define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF; + +/* Supervisory FLASH - Public Key */ +define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00; +define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF; + +/* Supervisory FLASH - Table of Content # 2 */ +define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00; +define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF; + +/* Supervisory FLASH - Table of Content # 2 Copy */ +define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00; +define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF; + +/* eFuse */ +define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000; +define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF; + +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__]; +define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__]; +define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__]; +define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__]; +define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__]; +define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; +define block RO {first section .intvec, readonly}; + +/*define block cy_xip { section .cy_xip };*/ + +define block LIB +{ + readwrite code object cy_ota_flash.o, + readwrite code object flash_qspi.o, + readwrite code object memset.o, + readwrite code object ABImemset.o, + readwrite code object ABImemset48.o, + readwrite code object cy_syslib*.o, + readwrite code object cy_smif.o, + readwrite code object cy_smif_sfdp.o, + readwrite code object cy_smif_memslot.o, + readwrite code object cycfg_qspi_memslot.o, +}; + +define block LIB_INIT +{ + readonly code section *_init object cy_ota_flash.o, + readonly code section *_init object flash_qspi.o, + readonly code section *_init object memset.o, + readonly code section *_init object ABImemset.o, + readonly code section *_init object ABImemset48.o, + readonly code section *_init object cy_syslib*.o, + readonly code section *_init object cy_smif.o, + readonly code section *_init object cy_smif_sfdp.o, + readonly code section *_init object cy_smif_memslot.o, + readonly code section *_init object cycfg_qspi_memslot.o, +}; + + +/*-Initializations-*/ +initialize by copy { readwrite, section code_in_RAM }; +initialize by copy { readonly object cy_ota_flash.o }; +initialize by copy { readonly object flash_qspi.o }; +/*initialize by copy { readonly object cy_syslib.o };*/ +initialize by copy { readonly object memset.o }; +initialize by copy { readonly object ABImemset.o }; +initialize by copy { readonly object ABImemset48.o }; +initialize by copy { readonly object cy_syslib*.o }; +initialize by copy { readonly object cy_smif.o }; +initialize by copy { readonly object cy_smif_sfdp.o }; +initialize by copy { readonly object cy_smif_memslot.o }; +initialize by copy { readonly object cycfg_qspi_memslot.o }; + +do not initialize { section .noinit, section .intvec_ram }; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +define symbol FLASH_START = 0x18000000 + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE; +define symbol FLASH_END = FLASH_START + FLASH_AREA_IMG_1_PRIMARY_SIZE; + +define region FLASH_REGION = mem:[from FLASH_START to FLASH_END]; + +/*-Initializations-*/ +/* initialize by copy { readwrite }; */ +/* do not initialize { section .noinit, section .intvec_ram }; */ + +/*-Placement-*/ + +/* Flash - Cortex-M4 application */ +place in FLASH_REGION { block RO }; +place in FLASH_REGION { block LIB_INIT }; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +/* ".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature };*/ + +/* Emulated EEPROM Flash area - Do not load into HEX file output */ +".cy_em_eeprom" : place noload at start of IROM2_region { section .cy_em_eeprom }; + +/* Supervisory Flash - User Data */ +/* ".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data };*/ + +/* Supervisory Flash - NAR */ +/*".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar };*/ + +/* Supervisory Flash - Public Key */ +/*".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key };*/ + +/* Supervisory Flash - TOC2 */ +/*".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 };*/ + +/* Supervisory Flash - RTOC2 */ +/*".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 };*/ + +/* eFuse */ +/*".cy_efuse" : place at start of IROM8_region { section .cy_efuse };*/ + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +/*"cy_xip" : place at start of EROM1_region { block cy_xip };*/ + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place in IRAM1_region { block LIB }; +place at end of IRAM1_region { block HSTACK }; + +/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */ +/*".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta };*/ + + +keep { + section .intvec, +/* + section .cy_app_signature, + section .cy_em_eeprom, - Do not load into HEX file output + section .cy_sflash_user_data, + section .cy_sflash_nar, + section .cy_sflash_public_key, + section .cy_toc_part2, + section .cy_rtoc_part2, + section .cy_efuse, + section .cy_xip, + section .cymeta, +*/ + }; + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +define exported symbol __cy_memory_0_start = 0x10000000; +define exported symbol __cy_memory_0_length = 0x00080000; +define exported symbol __cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +define exported symbol __cy_memory_1_start = 0x14000000; +define exported symbol __cy_memory_1_length = 0x8000; +define exported symbol __cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +define exported symbol __cy_memory_2_start = 0x16000000; +define exported symbol __cy_memory_2_length = 0x8000; +define exported symbol __cy_memory_2_row_size = 0x200; + +/* XIP */ +define exported symbol __cy_memory_3_start = 0x18000000; +define exported symbol __cy_memory_3_length = 0x08000000; +define exported symbol __cy_memory_3_row_size = 0x200; + +/* eFuse */ +define exported symbol __cy_memory_4_start = 0x90700000; +define exported symbol __cy_memory_4_length = 0x100000; +define exported symbol __cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.sct b/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.sct new file mode 100644 index 0000000..6be862b --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.sct @@ -0,0 +1,280 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cy8c6xxa_cm4_dual.sct +;* \version 2.60 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2019 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +#define MCUBOOT_FLASH_SIZE 0x20000 +#define MCUBOOT_RAM_SIZE 0x00800 + +; By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. +; More about CM0+ prebuilt images, see here: +; https://github.com/Infineon/psoc6cm0p +; The size of the Cortex-M0+ application flash image +#define FLASH_CM0P_SIZE 0x00020000 +#define CM0P_RAM_SIZE 0x00003000 + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. +; Using this memory region for other purposes will lead to unexpected behavior. +; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat', +; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'. +; RAM +#define RAM_START (0x08000000 + MCUBOOT_RAM_SIZE + CM0P_RAM_SIZE) +#define RAM_SIZE 0x00042000 +; Flash +#define FLASH_START 0x10000000 +#define FLASH_CM0P_START (FLASH_START + MCUBOOT_FLASH_SIZE + MCUBOOT_HEADER_SIZE) +#define FLASH_CM4_START (FLASH_CM0P_START + FLASH_CM0P_SIZE) +#define FLASH_SIZE (FLASH_AREA_IMG_1_PRIMARY_SIZE) + +; Size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + + +; Cortex-M0+ application flash image area +LR_IROM FLASH_CM0P_START FLASH_CM0P_SIZE +{ + .cy_m0p_image +0 FLASH_CM0P_SIZE + { + * (.cy_m0p_image) + } +} + +; Cortex-M4 application flash area +LR_IROM1 FLASH_CM4_START (FLASH_SIZE - FLASH_CM0P_SIZE) +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 FIXED + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. + .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 + { + * (.cy_app_signature) + } +} + + +; Emulated EEPROM Flash area +LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +{ + .cy_em_eeprom +0 + { + * (.cy_em_eeprom) + } +} + +; Supervisory flash: User data +LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE +{ + .cy_sflash_user_data +0 + { + * (.cy_sflash_user_data) + } +} + +; Supervisory flash: Normal Access Restrictions (NAR) +LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE +{ + .cy_sflash_nar +0 + { + * (.cy_sflash_nar) + } +} + +; Supervisory flash: Public Key +LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE +{ + .cy_sflash_public_key +0 + { + * (.cy_sflash_public_key) + } +} + +; Supervisory flash: Table of Content # 2 Copy +LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +{ + .cy_rtoc_part2 +0 + { + * (.cy_rtoc_part2) + } +} + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +LR_EROM XIP_START XIP_SIZE +{ + cy_xip +0 + { + * (.cy_xip) + } +} + + +; eFuse +LR_EFUSE EFUSE_START EFUSE_SIZE +{ + .cy_efuse +0 + { + * (.cy_efuse) + } +} + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +CYMETA 0x90500000 +{ + .cymeta +0 { * (.cymeta) } +} + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x00100000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.ld b/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.ld new file mode 100644 index 0000000..a5b03ac --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual_ota_cm0p_int.ld @@ -0,0 +1,506 @@ +/******************************************************************************* +* \file cy8c6xx7_cm4_dual_cm0p_bless.ld +* \version 2.91 +* +* Linker file for the GNU C compiler. +* +* This linker script is modified from cy8c6xx7_cm4_dual.ld for CM0P_BLESS image. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + +/* Size of the stack section at the end of SRAM */ +STACK_SIZE = 0x1000; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --defsym,MCUBOOT_HEADER_SIZE=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + + + +/* + Flash Memory Layout for using with OTA support + MCUBootApp is the boot application that does the actual SWAP of Primary and Secondary Slots. + + NOTE: MCUBootApp treats the Slots as Monolithic Chunks, not caring for the majority of the + content with the only exceptions being the 0x400 header and a 0x400 trailer contained + within the slot. The header to validate the slot and the trailer for update information. + The User Application uses the ota-update library to download and store new app to Secondary Slot. + + We use a JSON file to define the flash layout. The layout here is defined in: + /configs/COMPONENT_MCUBOOT/flashmap/psoc62_1m_cm0_int_swap_single.json + It is copied when building MCUBootApp, and must be reflected here manually. + + Internal Flash Layout +0x10000000 ---------------------------------------- + | MCUBootApp | +0x10020000 ---------------------------------------- ------------------------------------ + | Required MCUBootHeader | (added in signing step of User App) \ +0x10020400 | ------------------ | ---------------- \ + | Application cm0p code | BLE code \ +0x10040000 ------------------ | ---------------- --> Primary slot + | | / + | Application cm4 code | User Application / + | | / +0x10080000 ---------------------------------------- ------------------------------------ + | Required MCUBootHeader | (added in signing step of User App) \ +0x10080400 | ------------------ | ---------------- \ + | Application cm0p code | BLE code \ +0x10040000 ------------------ | ---------------- --> Secondary slot + | | / + | Application cm4 code | User Application / + | | / +0x100e0000 ---------------------------------------- ------------------------------------ + | Scratch Area | Used by MCUBootApp while SWAPping Primary and Secondary Slots + | | Larger Scratch Area will speed up the SWAP and increase the flash life +0x100e4000 -------------------------------------------- + | Status Area (For MCUBoot) | Used by MCUBootApp to keep track of the SWAP process and provide information + | | needed to resume the SWAP if there is a reset during the SWAP process. +0x100e8000 ---------------------------------------- + | Unused 0x00018000 (96k) | +0x10100000 ---------------------------------------- + + SRAM usage for OTA applciation support + CY8CKIT-062-BLE, CY8CPROTO-063-BLE and CYBLE-416045-EVAL have 278k RAM (0x45800) available for use. + High 0x800 bytes are used by the System (from 0x46000 bytes) + MCUBootApp requires 0x800 bytes at start of RAM for it's "public" RAM usage. + +0x08000000 ---------------------------------------- + | MCUBootApp | +0x08000800 ---------------------------------------- + | cm0p code RAM | + | 0x00003000 bytes (12k) | +0x08003800 ---------------------------------------- + | | + | cm4 User Application RAM | + | 0x00042000 bytes (264k) | + | | +0x08045800 ---------------------------------------- + | System RAM 0x800 | +0x08046000 ---------------------------------------- + +*/ + +/* FLASH for MCUBootApp */ +MCUBOOT_APP_SIZE = 0x00020000; +MCUBOOT_HEADER_SIZE = 0x00000400; +/* RAM for MCUBootApp */ +MCUBOOT_RAM_SIZE = 0x00000800; + +/* FLASH for cm0+ */ +CM0P_FLASH_SIZE = 0x00020000; +/* RAM for cm0+ */ +CM0P_RAM_SIZE = 0x00003000; + +/* System reserved RAM at to of RAM area */ +SYSTEM_RESERVED_RAM = 0x00000800; + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing the 'ram' and 'flash' regions. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'. + */ + + ram (rwx) : ORIGIN = 0x08000000 + MCUBOOT_RAM_SIZE + CM0P_RAM_SIZE, LENGTH = 0x00046000 - MCUBOOT_RAM_SIZE - CM0P_RAM_SIZE - SYSTEM_RESERVED_RAM + flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x00100000 + + /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */ + sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */ + sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */ + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */ + efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */ +} + +/* Size and start address of the Cortex-M0+ application image */ +FLASH_CM0P_START = ORIGIN(flash) + MCUBOOT_APP_SIZE + MCUBOOT_HEADER_SIZE; +FLASH_CM0P_SIZE = 0x20000; +/* Size and start address of the Cortex-M4 application image */ +FLASH_CM4_START = FLASH_CM0P_START + FLASH_CM0P_SIZE; +FLASH_CM4_SIZE = LENGTH(flash) - (FLASH_CM0P_START + FLASH_CM0P_SIZE); + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + + +SECTIONS +{ + /* Cortex-M0+ application image */ + .cy_m0p_image FLASH_CM0P_START : + { + . = ALIGN(4); + __cy_m0p_code_start = . ; + + *psoc6_cm0p_bless_ota + + KEEP(*(.cy_m0p_image)) + __cy_m0p_code_end = . ; + } > flash + + /* Check if .cy_m0p_image size exceeds FLASH_CM0P_SIZE */ + ASSERT(__cy_m0p_code_end <= ORIGIN(flash) + FLASH_CM0P_START + FLASH_CM0P_SIZE, "CM0+ flash image overflows with CM4, increase FLASH_CM0P_SIZE") + + /* Cortex-M4 application flash area */ + .text FLASH_CM4_START : + { + . = ALIGN(4); + __cy_app_load_addr = . ; + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_psoc6_02_cm4.S */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + /* Copy interrupt vectors from flash to RAM */ + LONG (__Vectors) /* From */ + LONG (__ram_vectors_start__) /* To */ + LONG (__Vectors_End - __Vectors) /* Size */ + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG (__data_end__ - __data_start__) /* Size */ + + __copy_table_end__ = .; + } > flash + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_02_cm4.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : AT (__etext) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(4); + + __data_end__ = .; + + } > ram + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Used for the digital signature of the secure application and the Bootloader SDK application. + * The size of the section depends on the required data size. */ + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom (NOLOAD): + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + + /* Supervisory Flash: Table of Content # 2 Copy */ + .cy_rtoc_part2 : + { + KEEP(*(.cy_rtoc_part2)) + } > sflash_rtoc_2 + + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + .cy_xip : + { + KEEP(*(.cy_xip)) + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse + + + /* These sections are used for additional metadata (silicon revision, + * Silicon/JTAG ID, etc.) storage. + */ + .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x00200000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x200; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual_ota_cm0p_int.icf b/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual_ota_cm0p_int.icf new file mode 100644 index 0000000..918f995 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_063_1M/COMPONENT_CM4/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual_ota_cm0p_int.icf @@ -0,0 +1,264 @@ +/******************************************************************************* +* \file cy8c6xx7_cm4_dual.icf +* \version 2.91 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ +define symbol MCUBOOT_FLASH_SIZE = 0x20000; +define symbol MCUBOOT_RAM_SIZE = 0x00800; + +/* By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. + * More about CM0+ prebuilt images, see here: + * https://github.com/Infineon/psoc6cm0p + */ +/* The size of the Cortex-M0+ application image */ +define symbol FLASH_CM0P_SIZE = 0x00020000; +define symbol CM0P_RAM_SIZE = 0x00003000; + +define symbol FLASH_START = 0x10000000; +define symbol FLASH_CM0P_START = (FLASH_START + MCUBOOT_FLASH_SIZE + MCUBOOT_HEADER_SIZE); +define symbol FLASH_CM4_START = (FLASH_CM0P_START + FLASH_CM0P_SIZE); +define symbol FLASH_END = FLASH_AREA_IMG_1_PRIMARY_SIZE; + + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000 + MCUBOOT_RAM_SIZE + CM0P_RAM_SIZE; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x08042000; +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = FLASH_CM0P_START; /* was 0x10000000 */ +define symbol __ICFEDIT_region_IROM1_end__ = 0x10100000; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* Supervisory FLASH - User Data */ +define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800; +define symbol __ICFEDIT_region_IROM3_end__ = 0x160007FF; + +/* Supervisory FLASH - Normal Access Restrictions (NAR) */ +define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00; +define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF; + +/* Supervisory FLASH - Public Key */ +define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00; +define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF; + +/* Supervisory FLASH - Table of Content # 2 */ +define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00; +define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF; + +/* Supervisory FLASH - Table of Content # 2 Copy */ +define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00; +define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF; + +/* eFuse */ +define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000; +define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF; + +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__]; +define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__]; +define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__]; +define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__]; +define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__]; +define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; +define block CM0P_RO with size = FLASH_CM0P_SIZE { readonly section .cy_m0p_image }; +define block RO {first section .intvec, readonly}; + +define block cy_xip { section .cy_xip }; + +/* define region FLASH_REGION = mem:[from FLASH_CM0P_START to FLASH_END]; */ + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/*-Placement-*/ + +/* Flash - Cortex-M0+ application image */ +place at start of IROM1_region { block CM0P_RO }; + +/* Flash - Cortex-M4 application */ +place in IROM1_region { block RO }; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature }; + +/* Emulated EEPROM Flash area */ +".cy_em_eeprom" : place at start of IROM2_region { section .cy_em_eeprom }; + +/* Supervisory Flash - User Data */ +".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data }; + +/* Supervisory Flash - NAR */ +".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar }; + +/* Supervisory Flash - Public Key */ +".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key }; + +/* Supervisory Flash - TOC2 */ +".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 }; + +/* Supervisory Flash - RTOC2 */ +".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 }; + +/* eFuse */ +".cy_efuse" : place at start of IROM8_region { section .cy_efuse }; + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +"cy_xip" : place at start of EROM1_region { block cy_xip }; + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place at end of IRAM1_region { block HSTACK }; + +/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */ +".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta }; + + +keep { section .cy_m0p_image, + section .cy_app_signature, + section .cy_em_eeprom, + section .cy_sflash_user_data, + section .cy_sflash_nar, + section .cy_sflash_public_key, + section .cy_toc_part2, + section .cy_rtoc_part2, + section .cy_efuse, + section .cy_xip, + section .cymeta, + }; + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +define exported symbol __cy_memory_0_start = 0x10000000; +define exported symbol __cy_memory_0_length = 0x00100000; +define exported symbol __cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +define exported symbol __cy_memory_1_start = 0x14000000; +define exported symbol __cy_memory_1_length = 0x8000; +define exported symbol __cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +define exported symbol __cy_memory_2_start = 0x16000000; +define exported symbol __cy_memory_2_length = 0x8000; +define exported symbol __cy_memory_2_row_size = 0x200; + +/* XIP */ +define exported symbol __cy_memory_3_start = 0x18000000; +define exported symbol __cy_memory_3_length = 0x08000000; +define exported symbol __cy_memory_3_row_size = 0x200; + +/* eFuse */ +define exported symbol __cy_memory_4_start = 0x90700000; +define exported symbol __cy_memory_4_length = 0x100000; +define exported symbol __cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_ARM/cyb06xxa_cm4_dual_ota_int.sct b/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_ARM/cyb06xxa_cm4_dual_ota_int.sct new file mode 100644 index 0000000..1e2e0ab --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_ARM/cyb06xxa_cm4_dual_ota_int.sct @@ -0,0 +1,284 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cyb06xxa_cm4_dual.sct +;* \version 2.91 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2021 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; Arguments passed to ld.exe +; +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_START=XXXX - not used for this build +; --pd=-DFLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +; --pd=-DMCUBOOT_HEADER_SIZE=XXXX + +; The size of the Cortex-M0+ application image (including MCU boot header area) +#define FLASH_CM0P_SIZE 0x00010000 + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat', +; where 'xx' is the device group; for example, 'cyb06xx7_cm0plus.scat'. +; RAM +#define RAM_START 0x08001800 +#define RAM_SIZE 0x000DE800 +; Flash +#define FLASH_START 0x10000000 +#define FLASH_SIZE FLASH_AREA_IMG_1_PRIMARY_SIZE + MCUBOOT_HEADER_SIZE + FLASH_CM0P_SIZE + +; The size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + +; Cortex-M0+ application flash image area +LR_IROM (FLASH_START + MCUBOOT_HEADER_SIZE) (FLASH_CM0P_SIZE - MCUBOOT_HEADER_SIZE) +{ + .cy_m0p_image +0 + { + * (.cy_m0p_image) + } +} + +; Cortex-M4 application flash area +LR_IROM1 (FLASH_START + FLASH_CM0P_SIZE) (FLASH_SIZE - FLASH_CM0P_SIZE) +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 FIXED + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Emulated EEPROM Flash area + ; The alignment and size of this region must match the + ; requirements for the emeeprom component + ER_EM_EEPROM EM_EEPROM_START EMPTY NOCOMPRESS EM_EEPROM_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. + ; .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 + ; { + ; * (.cy_app_signature) + ; } +} + + +; Emulated EEPROM Flash area - Do not load into HEX file output +;LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +;{ +; .cy_em_eeprom +0 +; { +; * (.cy_em_eeprom) +; } +;} + +; Supervisory flash: User data +; LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE +; { +; .cy_sflash_user_data +0 +; { +; * (.cy_sflash_user_data) +; } +; } + +; Supervisory flash: Normal Access Restrictions (NAR) +; LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE +; { +; .cy_sflash_nar +0 +; { +; * (.cy_sflash_nar) +; } +; } + +; Supervisory flash: Public Key +; LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE +; { +; .cy_sflash_public_key +0 +; { +; * (.cy_sflash_public_key) +; } +; } + +; Supervisory flash: Table of Content # 2 +; LR_SFLASH_TOC_2 SFLASH_TOC_2_START SFLASH_TOC_2_SIZE +; { +; .cy_toc_part2 +0 +; { +; * (.cy_toc_part2) +; } +; } + +; Supervisory flash: Table of Content # 2 Copy +; LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +; { +; .cy_rtoc_part2 +0 +; { +; * (.cy_rtoc_part2) +; } +; } + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +; LR_EROM XIP_START XIP_SIZE +; { +; .cy_xip +0 +; { +; * (.cy_xip) +; } +; } + + +; eFuse +; LR_EFUSE EFUSE_START EFUSE_SIZE +; { +; .cy_efuse +0 +; { +; * (.cy_efuse) +; } +; } + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +; CYMETA 0x90500000 +; { +; .cymeta +0 { * (.cymeta) } +; } + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x001D0000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cyb06xxa_cm4_dual_ota_int.ld b/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cyb06xxa_cm4_dual_ota_int.ld new file mode 100644 index 0000000..9b03677 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cyb06xxa_cm4_dual_ota_int.ld @@ -0,0 +1,443 @@ +/***************************************************************************//** +* \file cyb06xxa_cm4_dual.ld +* \version 2.90.1 +* +* Linker file for the GNU C compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2020 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + +/* The size of the stack section at the end of CM4 SRAM */ +STACK_SIZE = 0x1000; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --defsym,MCUBOOT_HEADER_SIZE=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --defsym,FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + + +/* The size of the Cortex-M0+ application image (including MCU boot header area) */ +FLASH_CM0P_SIZE = 0x10000; + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing the 'ram' and 'flash' regions. + * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld', + * where 'xx' is the device group; for example, 'cyb06xx7_cm0plus.ld'. + */ + ram (rwx) : ORIGIN = 0x08001800, LENGTH = 0xDE800 + flash (rx) : ORIGIN = 0x10000000, LENGTH = FLASH_AREA_IMG_1_PRIMARY_SIZE + MCUBOOT_HEADER_SIZE + FLASH_CM0P_SIZE + + /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */ + sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */ + sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */ + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */ + efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */ +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + + +SECTIONS +{ + /* Cortex-M0+ application flash image area */ + .cy_m0p_image ORIGIN(flash) + MCUBOOT_HEADER_SIZE : + { + . = ALIGN(4); + __cy_m0p_code_start = . ; + KEEP(*(.cy_m0p_image)) + __cy_m0p_code_end = . ; + } > flash + + /* Check if .cy_m0p_image size exceeds FLASH_CM0P_SIZE */ + ASSERT(__cy_m0p_code_end <= ORIGIN(flash) + FLASH_CM0P_SIZE, "CM0+ flash image overflows with CM4, increase FLASH_CM0P_SIZE") + + /* Cortex-M4 application flash area */ + .text ORIGIN(flash) + FLASH_CM0P_SIZE : + { + . = ALIGN(4); + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_psoc6_02_cm4.S */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + /* Copy interrupt vectors from flash to RAM */ + LONG (__Vectors) /* From */ + LONG (__ram_vectors_start__) /* To */ + LONG (__Vectors_End - __Vectors) /* Size */ + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG (__data_end__ - __data_start__) /* Size */ + + __copy_table_end__ = .; + } > flash + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_02_cm4.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : AT (__etext) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(4); + + __data_end__ = .; + + } > ram + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Used for the digital signature of the secure application and the Bootloader SDK application. + * The size of the section depends on the required data size. */ + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom (NOLOAD): + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + /* Supervisory Flash: User data */ + .cy_sflash_user_data : + { + KEEP(*(.cy_sflash_user_data)) + } > sflash_user_data + + + /* Supervisory Flash: Normal Access Restrictions (NAR) */ + .cy_sflash_nar : + { + KEEP(*(.cy_sflash_nar)) + } > sflash_nar + + + /* Supervisory Flash: Public Key */ + .cy_sflash_public_key : + { + KEEP(*(.cy_sflash_public_key)) + } > sflash_public_key + + + /* Supervisory Flash: Table of Content # 2 */ + .cy_toc_part2 : + { + KEEP(*(.cy_toc_part2)) + } > sflash_toc_2 + + + /* Supervisory Flash: Table of Content # 2 Copy */ + .cy_rtoc_part2 : + { + KEEP(*(.cy_rtoc_part2)) + } > sflash_rtoc_2 + + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + cy_xip : + { + __cy_xip_start = .; + KEEP(*(.cy_xip)) + __cy_xip_end = .; + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse + + + /* These sections are used for additional metadata (silicon revision, + * Silicon/JTAG ID, etc.) storage. + */ + .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x001D0000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x200; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_IAR/cyb06xxa_cm4_dual_ota_int.icf b/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_IAR/cyb06xxa_cm4_dual_ota_int.icf new file mode 100644 index 0000000..94a8492 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/PSOC_064_2M/COMPONENT_CM4/TOOLCHAIN_IAR/cyb06xxa_cm4_dual_ota_int.icf @@ -0,0 +1,164 @@ +/******************************************************************************* +* \file cyb06xxa_cm4_dual.icf +* \version 2.91 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cyb06xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08001800; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x080DE800; + +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x100DFFFF; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +/* The size of the Cortex-M0+ application image (including MCU boot header area) */ +define symbol FLASH_CM0P_SIZE = 0x10000; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; +define block CM0P_RO with size = (FLASH_CM0P_SIZE - MCUBOOT_HEADER_SIZE) { readonly section .cy_m0p_image }; +define block RO {first section .intvec, readonly}; + +define block cy_xip { section .cy_xip }; + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/*-Placement-*/ + +/* Flash - Cortex-M0+ application image */ +place at address (__ICFEDIT_region_IROM1_start__ + MCUBOOT_HEADER_SIZE) { block CM0P_RO }; + +/* Flash - Cortex-M4 application */ +place at address (__ICFEDIT_region_IROM1_start__ + FLASH_CM0P_SIZE) { block RO }; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature }; + +/* Emulated EEPROM Flash area - Do not load into HEX file output */ +".cy_em_eeprom" : place noload at start of IROM2_region { section .cy_em_eeprom }; + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +"cy_xip" : place at start of EROM1_region { block cy_xip }; + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place at end of IRAM1_region { block HSTACK }; + +keep { section .cy_m0p_image, + section .cy_app_signature, +/* section .cy_em_eeprom, - Do not load into HEX file output */ + section .cy_xip, + }; + + + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_ARM/xmc7200d_x8384_cm7_ota_int.sct b/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_ARM/xmc7200d_x8384_cm7_ota_int.sct new file mode 100644 index 0000000..8e034eb --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_ARM/xmc7200d_x8384_cm7_ota_int.sct @@ -0,0 +1,165 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m7 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file xmc7200d_x8384_cm7.sct +;* \version 1.0 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2021 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; The following defines control RAM and flash memory allocation for the CM0+ core. +; You can change the memory allocation by editing the RAM and Flash defines. +; Your changes must be aligned with the corresponding defines for the CM7 core in 'xxx_cm7.sct', +; where 'xx' is the device group; for example, 'xmc7200d_x8384_cm7.sct'. + + +; RAM +#define SRAM_TOTAL_SIZE 0x00100000 /* 1024K : SRAM0 + SRAM1 */ + +; FLASH +#define CODE_FLASH_TOTAL_SIZE 0x00830000 /* 8384K : TOTAL FLASH SIZE */ + +#define SRAM_START_RESERVE 0 +#define SRAM_PRIVATE_FOR_SROM 0x800 /* 2K Private SRAM for SROM (e.g. API processing). Reserved at the beginning */ +#define STACK_SIZE 0x1000 +#define RAMVECTORS_ALIGNMENT 128 + +; RAM +#define SRAM_BASE_ADDRESS 0x28000000 /* SRAM START */ +#define CM0PLUS_SRAM_RESERVE 0x00020000 /* 128K : cm0 sram size */ +#define CM7_0_SRAM_RESERVE 0x000D0000 /* 832K: cm7_0 sram size */ + +; FLASH +#define CODE_FLASH_BASE_ADDRESS 0x10000000 /* FLASH START */ +#define CM0PLUS_CODE_FLASH_RESERVE 0x00080000 /* 512K : cm0 flash size */ +#define CM7_0_CODE_FLASH_RESERVE 0x00770000 /* 7616K: cm7_0 flash size */ + +; SRAM reservations +#define BASE_SRAM_CM0P SRAM_BASE_ADDRESS + SRAM_START_RESERVE + SRAM_PRIVATE_FOR_SROM +#define SIZE_SRAM_CM0P CM0PLUS_SRAM_RESERVE - SRAM_START_RESERVE - SRAM_PRIVATE_FOR_SROM +#define BASE_SRAM_CM7_0 SRAM_BASE_ADDRESS + CM0PLUS_SRAM_RESERVE +#define SIZE_SRAM_CM7_0 CM7_0_SRAM_RESERVE +/* In case of single CM7 device CM7_1 values should not be used */ +#define SIZE_SRAM_CM7_1 SRAM_TOTAL_SIZE - CM0PLUS_SRAM_RESERVE - CM7_0_SRAM_RESERVE /* 8K : cm7_1 sram size */ +#define BASE_SRAM_CM7_1 SRAM_BASE_ADDRESS + CM0PLUS_SRAM_RESERVE + CM7_0_SRAM_RESERVE + +; Code flash reservations +#define BASE_CODE_FLASH_CM0P CODE_FLASH_BASE_ADDRESS +#define SIZE_CODE_FLASH_CM0P CM0PLUS_CODE_FLASH_RESERVE +#define BASE_CODE_FLASH_CM7_0 CODE_FLASH_BASE_ADDRESS + CM0PLUS_CODE_FLASH_RESERVE +#define SIZE_CODE_FLASH_CM7_0 CM7_0_CODE_FLASH_RESERVE +#define BASE_CODE_FLASH_CM7_1 CODE_FLASH_BASE_ADDRESS + CM0PLUS_CODE_FLASH_RESERVE + CM7_0_CODE_FLASH_RESERVE +#define SIZE_CODE_FLASH_CM7_1 CODE_FLASH_TOTAL_SIZE - CM0PLUS_CODE_FLASH_RESERVE - CM7_0_CODE_FLASH_RESERVE /* 2752K : cm7_1 flash size */ + +; For the non-dual cm7 device, _CORE_CM7_0_ should be defined and _CORE_CM7_1_ should not be defined +#ifdef _CORE_CM7_1_ +#define BASE_SRAM BASE_SRAM_CM7_1 +#define SIZE_SRAM SIZE_SRAM_CM7_1 +#define BASE_CODE_FLASH BASE_CODE_FLASH_CM7_1 +#define SIZE_CODE_FLASH SIZE_CODE_FLASH_CM7_1 +#elif _CORE_CM7_0_ +#define BASE_SRAM BASE_SRAM_CM7_0 +#define SIZE_SRAM SIZE_SRAM_CM7_0 +#define BASE_CODE_FLASH CODE_FLASH_BASE_ADDRESS + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE +#define SIZE_CODE_FLASH FLASH_AREA_IMG_1_PRIMARY_SIZE +#else +; Assert if either _CORE_CM7_1_ or _CORE_CM7_0_ is not defined +ScatterAssert(0); +#endif + +#ifdef _CORE_CM7_0_ +;Cortex-M0+ application flash image area +;LR_IROM BASE_CODE_FLASH_CM0P SIZE_CODE_FLASH_CM0P +;{ +; .cy_m0p_image +0 +; { +; * (.cy_m0p_image) +; } +;} +#endif + +; Cortex-M7 application flash area +LR_IROM1 BASE_CODE_FLASH SIZE_CODE_FLASH +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 FIXED + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS BASE_SRAM UNINIT + { + * (.bss.noinit.RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (+RW, +ZI) + } + + RW_RAM_SHARED_DATA +0 ALIGN 32 + { + * (.cy_sharedmem) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + * (.bss.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY BASE_SRAM+SIZE_SRAM-STACK_SIZE-AlignExpr(ImageLimit(RW_IRAM1), 8) + { + } + + ; Stack region growing down + ARM_LIB_STACK (BASE_SRAM+SIZE_SRAM) EMPTY -STACK_SIZE + { + } +} diff --git a/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_GCC_ARM/xmc7200d_x8384_cm7_ota_int.ld b/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_GCC_ARM/xmc7200d_x8384_cm7_ota_int.ld new file mode 100644 index 0000000..ce6e2be --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_GCC_ARM/xmc7200d_x8384_cm7_ota_int.ld @@ -0,0 +1,451 @@ +/***************************************************************************//** +* \file xmc7200d_x8384_cm7.ld +* \version 1.0.0 +* +* Linker file for the GNU C compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +GROUP(-lgcc -lc -lnosys ) +SEARCH_DIR(.) +GROUP(libgcc.a libc.a libm.a libnosys.a) +ENTRY(Reset_Handler) + +/* The size of the MCU boot header area at the start of FLASH */ +BOOT_HEADER_SIZE = 0x400; + +/* The size of the stack section at the end of CM7 SRAM */ +STACK_SIZE = 0x1000; +RAMVECTORS_ALIGNMENT = 128; + +sram_start_reserve = 0; + +sram_total_size = 0x00100000; /* SRAM0 + SRAM1 */ +sram_private_for_srom = 0x00000800; /* Private SRAM for SROM (e.g. API processing) */ +sram_used_by_boot = 0x0; /* Used during boot by Cypress firmware (content will be overwritten on reset, so it should not be used for loadable sections in case of RAM build configurations) */ + +cm0plus_sram_reserve = 0x00020000; /* 128K : cm0 sram size */ +cm7_0_sram_reserve = 0x000D0000; /* 832K: cm7_0 sram size */ + +code_flash_total_size = 0x00830000; /* 8384K: total flash size */ +cm0plus_code_flash_reserve = 0x00080000; /* 512K : cm0 flash size */ +cm7_0_code_flash_reserve = 0x00770000; /* 7616K: cm7_0 flash size */ + +code_flash_base_address = 0x10000000; +sram_base_address = 0x28000000; + +/* SRAM reservations */ +_base_SRAM_CM7_0 = sram_base_address + cm0plus_sram_reserve; +_size_SRAM_CM7_0 = cm7_0_sram_reserve; +/* In case of single CM7 device CM7_1 values should not be used */ +_base_SRAM_CM7_1 = sram_base_address + cm0plus_sram_reserve + cm7_0_sram_reserve; +_size_SRAM_CM7_1 = sram_total_size - cm0plus_sram_reserve - cm7_0_sram_reserve; /* 64K : cm7_1 sram size */ + +/* Code flash reservations */ +_base_CODE_FLASH_CM0P = code_flash_base_address; +_size_CODE_FLASH_CM0P = cm0plus_code_flash_reserve; +_base_CODE_FLASH_CM7_0 = code_flash_base_address + cm0plus_code_flash_reserve; +_size_CODE_FLASH_CM7_0 = cm7_0_code_flash_reserve; +_base_CODE_FLASH_CM7_1 = code_flash_base_address + cm0plus_code_flash_reserve + cm7_0_code_flash_reserve; +_size_CODE_FLASH_CM7_1 = code_flash_total_size - cm0plus_code_flash_reserve - cm7_0_code_flash_reserve; + +/* Fixed Addresses */ +_base_WORK_FLASH = 0x14000000; +_size_WORK_FLASH = 0x00040000; /* 256K Work flash */ +_base_CM7_0_ITCM = 0x00000000; +_size_CM7_0_ITCM = 0x00004000; +_base_CM7_0_DTCM = 0x20000000; +_size_CM7_0_DTCM = 0x00004000; +_base_CM7_1_ITCM = 0x00000000; +_size_CM7_1_ITCM = 0x00004000; +_base_CM7_1_DTCM = 0x20000000; +_size_CM7_1_DTCM = 0x00004000; + +/* For the non-dual cm7 device, _CORE_CM7_0_ should be defined and _CORE_CM7_1_ should not be defined */ +_base_SRAM = DEFINED(_CORE_CM7_1_) ? _base_SRAM_CM7_1 : DEFINED(_CORE_CM7_0_) ? _base_SRAM_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_size_SRAM = DEFINED(_CORE_CM7_1_) ? _size_SRAM_CM7_1 : DEFINED(_CORE_CM7_0_) ? _size_SRAM_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_base_CODE_FLASH = DEFINED(_CORE_CM7_1_) ? _base_CODE_FLASH_CM7_1 : DEFINED(_CORE_CM7_0_) ? _base_CODE_FLASH_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_size_CODE_FLASH = DEFINED(_CORE_CM7_1_) ? _size_CODE_FLASH_CM7_1 : DEFINED(_CORE_CM7_0_) ? _size_CODE_FLASH_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_base_SFLASH_USER_DATA = 0x17000800; +_size_SFLASH_USER_DATA = 0x00000800; +_base_SFLASH_NAR = 0x17001A00; +_size_SFLASH_NAR = 0x00000200; +_base_SFLASH_PUB_KEY = 0x17006400; +_size_SFLASH_PUB_KEY = 0x00000C00; +_base_SFLASH_APP_PROT = 0x17007600; +_size_SFLASH_APP_PROT = 0x00000200; +_base_SFLASH_TOC2 = 0x17007C00; +_size_SFLASH_TOC2 = 0x00000200; +_base_XIP = 0x60000000; +_size_XIP = 0x08000000; +_base_EFUSE = 0x90700000; +_size_EFUSE = 0x00100000; +_base_ITCM = DEFINED(_CORE_CM7_1_) ? _base_CM7_1_ITCM : DEFINED(_CORE_CM7_0_) ? _base_CM7_0_ITCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_size_ITCM = DEFINED(_CORE_CM7_1_) ? _size_CM7_1_ITCM : DEFINED(_CORE_CM7_0_) ? _size_CM7_0_ITCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_base_DTCM = DEFINED(_CORE_CM7_1_) ? _base_CM7_1_DTCM : DEFINED(_CORE_CM7_0_) ? _base_CM7_0_DTCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); +_size_DTCM = DEFINED(_CORE_CM7_1_) ? _size_CM7_1_DTCM : DEFINED(_CORE_CM7_0_) ? _size_CM7_0_DTCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); + + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM7_0/CM7_1 core. */ + ram (rxw) : ORIGIN = _base_SRAM, LENGTH = _size_SRAM /* SRAM */ + flash_cm0p (rx) : ORIGIN = _base_CODE_FLASH_CM0P, LENGTH = _size_CODE_FLASH_CM0P /* CODE flash CM0+ */ + flash (rx) : ORIGIN = code_flash_base_address + FLASH_AREA_IMG_1_PRIMARY_START, LENGTH = FLASH_AREA_IMG_1_PRIMARY_SIZE /* CODE flash CM7_0/1 */ + + /* This is a 256K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + */ + em_eeprom (rw) : ORIGIN = _base_WORK_FLASH, LENGTH = _size_WORK_FLASH /* WORK flash */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = _base_SFLASH_USER_DATA, LENGTH = _size_SFLASH_USER_DATA /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = _base_SFLASH_NAR, LENGTH = _size_SFLASH_NAR /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = _base_SFLASH_PUB_KEY, LENGTH = _size_SFLASH_PUB_KEY /* Supervisory flash: Public Key */ + sflash_app_prot (rx) : ORIGIN = _base_SFLASH_APP_PROT, LENGTH = _size_SFLASH_APP_PROT + sflash_toc_2 (rx) : ORIGIN = _base_SFLASH_TOC2, LENGTH = _size_SFLASH_TOC2 /* Supervisory flash: Table of Content # 2 */ + xip (rx) : ORIGIN = _base_XIP, LENGTH = _size_XIP /* XIP: 128 MB */ + efuse (rx) : ORIGIN = _base_EFUSE, LENGTH = _size_EFUSE /* 1MB */ + itcm (rx) : ORIGIN = _base_ITCM, LENGTH = _size_ITCM /* ITCM */ + dtcm (rx) : ORIGIN = _base_DTCM, LENGTH = _base_DTCM /* DTCM */ +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +SECTIONS +{ + /* Cortex-M0+ application flash image area. Comment this section if you don't want to include CM0+ image */ + /* .cy_cm0p_image ORIGIN(flash_cm0p): + { + . = ALIGN(4); + __cy_m0p_code_start = . ; + KEEP(*(.cy_m0p_image)) + __cy_m0p_code_end = . ; + } > flash_cm0p */ + + /* Check if .cy_m0p_image size exceeds cm0plus_code_flash_reserve */ + /* ASSERT(__cy_m0p_code_end < ORIGIN(flash), "CM0+ flash image overflows with CM7, increase CM7 base address ") */ + + /* Cortex-M7 application flash area */ + .text ORIGIN(flash) + BOOT_HEADER_SIZE : + { + /* Cortex-M7 flash vector table */ + . = ALIGN(4); + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG ((__data_end__ - __data_start__)/4) /* Size */ + + /* Copy code to ITCM */ + LONG (__zero_table_end__) /* From */ + LONG (__itcm_start__) /* To */ + LONG ((__itcm_end__ - __itcm_start__)/4) /* Size */ + + /* Copy data to DTCM */ + LONG (__itcm_flash_end__) /* From */ + LONG (__dtcm_start__) /* To */ + LONG ((__dtcm_end__ - __dtcm_start__)/4) /* Size */ + + __copy_table_end__ = .; + } > flash + + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG ((__bss_end__ - __bss_start__)/4) + __zero_table_end__ = .; + } > flash + + + /* itcm */ + .cy_itcm ORIGIN(itcm): + { + __itcm_start__ = .; + KEEP(*(.cy_itcm)) + __itcm_end__ = .; + } > itcm AT>flash + + __itcm_flash_end__ = __zero_table_end__ + (__itcm_end__ - __itcm_start__); + + /* dtcm */ + .cy_dtcm ORIGIN(dtcm): + { + __dtcm_start__ = .; + KEEP(*(.cy_dtcm)) + __dtcm_end__ = .; + } > dtcm AT>flash + + __etext = __itcm_flash_end__ + (__dtcm_end__ - __dtcm_start__) ; + + + .ramVectors (NOLOAD) : + { + . = ALIGN(RAMVECTORS_ALIGNMENT); + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : + { + . = ALIGN(4); + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(32); + + KEEP(*(cy_sharedmem*)) + . = ALIGN(4); + + __data_end__ = .; + + } > ram AT>flash + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom : + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + + /* Supervisory Flash: User data */ + .cy_sflash_user_data : + { + KEEP(*(.cy_sflash_user_data)) + } > sflash_user_data + + + /* Supervisory Flash: Normal Access Restrictions (NAR) */ + .cy_sflash_nar : + { + KEEP(*(.cy_sflash_nar)) + } > sflash_nar + + + /* Supervisory Flash: Public Key */ + .cy_sflash_public_key : + { + KEEP(*(.cy_sflash_public_key)) + } > sflash_public_key + + + /* Supervisory Flash: Table of Content # 2 */ + .cy_toc_part2 : + { + KEEP(*(.cy_toc_part2)) + } > sflash_toc_2 + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + cy_xip : + { + __cy_xip_start = .; + KEEP(*(.cy_xip)) + __cy_xip_end = .; + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse +} + + +/*============================================================ + * Symbols for use by application + *============================================================ + */ + +__ecc_init_sram_start_address = ORIGIN(ram); +__ecc_init_sram_end_address = ORIGIN(ram) + LENGTH(ram); + +/* EOF */ diff --git a/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_IAR/xmc7200d_x8384_cm7_ota_int.icf b/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_IAR/xmc7200d_x8384_cm7_ota_int.icf new file mode 100644 index 0000000..50ae176 --- /dev/null +++ b/template_linkers/COMPONENT_MCUBOOT/XMC7200/COMPONENT_CM7/TOOLCHAIN_IAR/xmc7200d_x8384_cm7_ota_int.icf @@ -0,0 +1,140 @@ +/***************************************************************************//** +* \file xmc7200d_x8384_cm7_ota_int.icf +* \version 1.0.0 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2023 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM7_0 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xmc7200d_x8384_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x28020000; /* 0x20000 is reserved for cm0+ */ +define symbol __ICFEDIT_region_IRAM1_end__ = 0x28100000; +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; /* 0x80000 is reserved for cm0+ */ +define symbol __ICFEDIT_region_IROM1_end__ = 0x107F0000; + +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; + +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x40000; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +define symbol RAMVECTORS_ALIGNMENT = 128; + +define memory mem with size = 4G; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with expanding size, alignment = 8, size = __ICFEDIT_size_heap__ { }; +define block RAMVECTOR with alignment = RAMVECTORS_ALIGNMENT { readwrite section .intvec_ram}; + +/* + Arguments for OTA using MCUBoot -- will get from passed in Makefile: + --config_def MCUBOOT_HEADER_SIZE=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_START=XXXX + --config_def FLASH_AREA_IMG_1_PRIMARY_SIZE=XXXX +*/ + +define symbol FLASH_START = __ICFEDIT_region_IROM1_start__ + FLASH_AREA_IMG_1_PRIMARY_START + MCUBOOT_HEADER_SIZE; +define symbol FLASH_END = FLASH_START + FLASH_AREA_IMG_1_PRIMARY_SIZE - MCUBOOT_HEADER_SIZE; + +define region CODE_region = mem:[from FLASH_START to FLASH_END]; + +/*-Placement-*/ + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/* Flash - Cortex-M7_0 application */ +"intvec": +place at address mem:FLASH_START { readonly section .intvec }; + +"code": +place in CODE_region { readonly }; + +"intvec_ram": +place at start of IRAM1_region { block RAMVECTOR }; +"data": +place in IRAM1_region { readwrite }; +"heap": +place in IRAM1_region { block HEAP }; +"stack": +place at end of IRAM1_region { block CSTACK }; + +keep { + section .intvec, + section .intvec_ram + }; + +define exported symbol __ecc_init_sram_start_address = start(IRAM1_region); +define exported symbol __ecc_init_sram_end_address = end(IRAM1_region); + +/* EOF */ diff --git a/version.xml b/version.xml new file mode 100644 index 0000000..ddd8191 --- /dev/null +++ b/version.xml @@ -0,0 +1 @@ +1.0.0.104