diff --git a/tools/memory_estimator/README.md b/tools/memory_estimator/README.md new file mode 100644 index 0000000000..aa3090cc71 --- /dev/null +++ b/tools/memory_estimator/README.md @@ -0,0 +1,27 @@ +# MemoryEstimator + +This utility helps in determining the memory estimates for FreeRTOS libraries. + +# Usage + +``` +python memory_estimator.py -p -o -l +``` + +Where: + +* `` is the path to the directory containing FreeRTOS LTS source code. +* `` is the compiler optimization level (O0, Os etc). +* `` is the library to calculate the memory estimates for. + + +# Options +| Short Name | Long Name | Default |Description | +| ---------- | --------- | ------- | ---------- | +| -p | --lts-path | | Path to the directory containing FreeRTOS LTS code. | +| -o | --optimization | O0 | Compiler optimization level (O0, Os etc). | +| -l | --lib | `mqtt` | The library to calculate the memory estimates for. Currently supported libraries are: `mqtt`, `light-mqtt`, `https`, `shadow`, `jobs`, `ota`, `kernel`| +| -c | --compiler | arm-none-eabi-gcc | Compiler to use. | +| -s | --sizetool | arm-none-eabi-size | Size tool to use. | +| -d | --dontclean | | The generated artifacts, which include the generated Makefile and built object files, are deleted by default. Pass `-d` to ensure that the generated artifacts are not deleted. | + diff --git a/tools/memory_estimator/config_files/FreeRTOSConfig.h b/tools/memory_estimator/config_files/FreeRTOSConfig.h new file mode 100644 index 0000000000..642796cf76 --- /dev/null +++ b/tools/memory_estimator/config_files/FreeRTOSConfig.h @@ -0,0 +1,200 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* +* See http://www.freertos.org/a00110.html. +*----------------------------------------------------------*/ + +/* Ensure stdint is only used by the compiler, and not the assembler. */ +#if defined( __ICCARM__ ) || defined( __CC_ARM ) || defined( __GNUC__ ) + #include + extern uint32_t SystemCoreClock; +#endif + +#define configSUPPORT_STATIC_ALLOCATION 1 + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configUSE_TICKLESS_IDLE 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 1 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 7 ) +#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 90 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 60 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configGENERATE_RUN_TIME_STATS 0 +#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 6 ) + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 4 /* 15 priority levels. */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" + * function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf + +/* The highest interrupt priority that can be used by any interrupt service + * routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + * INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + * PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +* to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY \ + ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY \ + ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) ) + +/* Normal assert() semantics without relying on the provision of an assert.h + * header file. */ +#define configASSERT( x ) \ + if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ; ; ) {; } \ + } + +/* Logging task definitions. */ +extern void vMainUARTPrintString( char * pcString ); +void vLoggingPrintf( const char * pcFormat, + ... ); + +/* Map the FreeRTOS printf() to the logging task printf. */ +#define configPRINTF( x ) vLoggingPrintf x + +/* Map the logging task's printf to the board specific output function. */ +#define configPRINT_STRING( x ) vMainUARTPrintString( x ); + +/* Sets the length of the buffers into which logging messages are written - so + * also defines the maximum length of each log message. */ +#define configLOGGING_MAX_MESSAGE_LENGTH 160 + +/* Set to 1 to prepend each log message with a message number, the task name, + * and a time stamp. */ +#define configLOGGING_INCLUDE_TIME_AND_TASK_NAME 1 + +/* Pseudo random number generator, just used by demos so does not have to be + * secure. Do not use the standard C library rand() function as it can cause + * unexpected behaviour, such as calls to malloc(). */ +extern int iMainRand32( void ); +#define configRAND32() iMainRand32() + +/* Demo specific macros that allow the application writer to insert code to be + * executed immediately before the MCU's STOP low power mode is entered and exited + * respectively. These macros are in addition to the standard + * configPRE_SLEEP_PROCESSING() and configPOST_SLEEP_PROCESSING() macros, which are + * called pre and post the low power SLEEP mode being entered and exited. These + * macros can be used to turn turn off and on IO, clocks, the Flash etc. to obtain + * the lowest power possible while the tick is off. */ +#if defined( __ICCARM__ ) || defined( __CC_ARM ) || defined( __GNUC__ ) + void vMainPreStopProcessing( void ); + void vMainPostStopProcessing( void ); +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ + +#define configPRE_STOP_PROCESSING vMainPreStopProcessing +#define configPOST_STOP_PROCESSING vMainPostStopProcessing + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS + * standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define vHardFault_Handler HardFault_Handler + +/* IMPORTANT: This define MUST be commented when used with STM32Cube firmware, + * to prevent overwriting SysTick_Handler defined within STM32Cube HAL. */ +/* #define xPortSysTickHandler SysTick_Handler */ + +/********************************************* + * FreeRTOS specific demos + ********************************************/ + +/* The address of an echo server that will be used by the two demo echo client + * tasks. + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ +#define configECHO_SERVER_ADDR0 192 +#define configECHO_SERVER_ADDR1 168 +#define configECHO_SERVER_ADDR2 2 +#define configECHO_SERVER_ADDR3 6 +#define configTCP_ECHO_CLIENT_PORT 7 + +/* The platform FreeRTOS is running on. */ +#define configPLATFORM_NAME "STM32L475" + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/memory_estimator/config_files/aws_application_version.h b/tools/memory_estimator/config_files/aws_application_version.h new file mode 100644 index 0000000000..37ea771bf4 --- /dev/null +++ b/tools/memory_estimator/config_files/aws_application_version.h @@ -0,0 +1,38 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef _AWS_APPLICATION_VERSION_H_ +#define _AWS_APPLICATION_VERSION_H_ + +#include "iot_appversion32.h" +extern const AppVersion32_t xAppFirmwareVersion; + +#define APP_VERSION_MAJOR 0 +#define APP_VERSION_MINOR 9 +#define APP_VERSION_BUILD 2 + +#endif diff --git a/tools/memory_estimator/config_files/aws_ota_agent_config.h b/tools/memory_estimator/config_files/aws_ota_agent_config.h new file mode 100644 index 0000000000..8b1595a253 --- /dev/null +++ b/tools/memory_estimator/config_files/aws_ota_agent_config.h @@ -0,0 +1,143 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/** + * @file aws_ota_agent_config.h + * @brief OTA user configurable settings. + */ + +#ifndef _AWS_OTA_AGENT_CONFIG_H_ +#define _AWS_OTA_AGENT_CONFIG_H_ + +/** + * @brief The number of words allocated to the stack for the OTA agent. + */ +#define otaconfigSTACK_SIZE 3584U + +/** + * @brief Log base 2 of the size of the file data block message (excluding the header). + * + * 10 bits yields a data block size of 1KB. + */ +#define otaconfigLOG2_FILE_BLOCK_SIZE 10UL + +/** + * @brief Milliseconds to wait for the self test phase to succeed before we force reset. + */ +#define otaconfigSELF_TEST_RESPONSE_WAIT_MS 16000U + +/** + * @brief Milliseconds to wait before requesting data blocks from the OTA service if nothing is happening. + * + * The wait timer is reset whenever a data block is received from the OTA service so we will only send + * the request message after being idle for this amount of time. + */ +#define otaconfigFILE_REQUEST_WAIT_MS 10000U + +/** + * @brief The OTA agent task priority. Normally it runs at a low priority. + */ +#define otaconfigAGENT_PRIORITY tskIDLE_PRIORITY + +/** + * @brief The maximum allowed length of the thing name used by the OTA agent. + * + * AWS IoT requires Thing names to be unique for each device that connects to the broker. + * Likewise, the OTA agent requires the developer to construct and pass in the Thing name when + * initializing the OTA agent. The agent uses this size to allocate static storage for the + * Thing name used in all OTA base topics. Namely $aws/things/ + */ +#define otaconfigMAX_THINGNAME_LEN 64U + +/** + * @brief The maximum number of data blocks requested from OTA streaming service. + * + * This configuration parameter is sent with data requests and represents the maximum number of + * data blocks the service will send in response. The maximum limit for this must be calculated + * from the maximum data response limit (128 KB from service) divided by the block size. + * For example if block size is set as 1 KB then the maximum number of data blocks that we can + * request is 128/1 = 128 blocks. Configure this parameter to this maximum limit or lower based on + * how many data blocks response is expected for each data requests. + * Please note that this must be set larger than zero. + * + */ +#define otaconfigMAX_NUM_BLOCKS_REQUEST 8U + +/** + * @brief The maximum number of requests allowed to send without a response before we abort. + * + * This configuration parameter sets the maximum number of times the requests are made over + * the selected communication channel before aborting and returning error. + * + */ +#define otaconfigMAX_NUM_REQUEST_MOMENTUM 32U + +/** + * @brief The number of data buffers reserved by the OTA agent. + * + * This configurations parameter sets the maximum number of static data buffers used by + * the OTA agent for job and file data blocks received. + */ +#define otaconfigMAX_NUM_OTA_DATA_BUFFERS 2U + +/** + * @brief The protocol selected for OTA control operations. + + * This configurations parameter sets the default protocol for all the OTA control + * operations like requesting OTA job, updating the job status etc. + * + * Note - Only MQTT is supported at this time for control operations. + */ +#define configENABLED_CONTROL_PROTOCOL ( OTA_CONTROL_OVER_MQTT ) + +/** + * @brief The protocol selected for OTA data operations. + + * This configurations parameter sets the protocols selected for the data operations + * like requesting file blocks from the service. + * + * Note - Both MQTT and HTTP is supported for data transfer. This configuration parameter + * can be set to following - + * Enable data over MQTT - ( OTA_DATA_OVER_MQTT ) + * Enable data over HTTP - ( OTA_DATA_OVER_HTTP) + * Enable data over both MQTT & HTTP ( OTA_DATA_OVER_MQTT | OTA_DATA_OVER_HTTP ) + */ +#define configENABLED_DATA_PROTOCOLS ( OTA_DATA_OVER_MQTT | OTA_DATA_OVER_HTTP ) + + /** + * @brief The preferred protocol selected for OTA data operations. + * + * Primary data protocol will be the protocol used for downloading file if more than + * one protocol is selected while creating OTA job. Default primary data protocol is MQTT + * and following update here to switch to HTTP as primary. + * + * Note - use OTA_DATA_OVER_HTTP for HTTP as primary data protocol. + */ + +#define configOTA_PRIMARY_DATA_PROTOCOL ( OTA_DATA_OVER_MQTT ) + +#endif /* _AWS_OTA_AGENT_CONFIG_H_ */ diff --git a/tools/memory_estimator/config_files/iot_appversion32.h b/tools/memory_estimator/config_files/iot_appversion32.h new file mode 100644 index 0000000000..2952f28474 --- /dev/null +++ b/tools/memory_estimator/config_files/iot_appversion32.h @@ -0,0 +1,60 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef _IOT_APPVERSION32_H_ +#define _IOT_APPVERSION32_H_ + +#include + +/* Application version structure. */ +typedef struct +{ + union + { + #if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) + struct version + { + uint16_t usBuild; + uint8_t ucMinor; + uint8_t ucMajor; + } x; + #elif ( defined( __BYTE_ORDER__ ) && defined( __ORDER_BIG_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) || ( __big_endian__ == 1 ) || ( __BYTE_ORDER == __BIG_ENDIAN ) + struct version + { + uint8_t ucMajor; + uint8_t ucMinor; + uint16_t usBuild; + } x; + #else /* if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) */ + #error "Unable to determine byte order!" + #endif /* if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) */ + uint32_t ulVersion32; + int32_t lVersion32; + } u; +} AppVersion32_t; + +#endif /* ifndef _IOT_APPVERSION32_H_ */ diff --git a/tools/memory_estimator/config_files/iot_config.h b/tools/memory_estimator/config_files/iot_config.h new file mode 100644 index 0000000000..2c87df6923 --- /dev/null +++ b/tools/memory_estimator/config_files/iot_config.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* This file contains configuration settings for the demos. */ + +#ifndef IOT_CONFIG_H_ +#define IOT_CONFIG_H_ + +/* Configure the IoT Libraries for FreeRTOS by including the FreeRTOS header and + * the FreeRTOS platform types. */ +#include "FreeRTOS.h" +#include "platform/iot_platform_types_freertos.h" + +/** + * @brief Set a global default for log levels. + * + * This setting is overridden by log level settings of specific libraries. + * Undefined library-specific log levels will default to this value. + * + * Possible values: One of the Log levels. + * Default value (if undefined): IOT_LOG_NONE. + */ +#define IOT_LOG_LEVEL_GLOBAL IOT_LOG_NONE + +/** + * @brief Set the log level of the platform libraries except the network + * component. + * + * Log messages from the platform libraries at or below this setting + * will be printed. As the network component is more verbose, its logging + * is controlled by its own setting, IOT_LOG_LEVEL_NETWORK. + * + * Possible values: One of the Log levels. + * Default value (if undefined): IOT_LOG_LEVEL_GLOBAL; if that is undefined, + * then IOT_LOG_NONE. + */ +#define IOT_LOG_LEVEL_PLATFORM IOT_LOG_NONE + +/** + * @brief Set the log level of the platform network library. + * + * Log messages from the platform network library at or below this setting + * will be printed. + * + * Possible values: One of the Log levels. + * Default value (if undefined): IOT_LOG_LEVEL_GLOBAL; if that is undefined, + * then IOT_LOG_NONE. + */ +#define IOT_LOG_LEVEL_NETWORK IOT_LOG_NONE + +/** + * @brief Set the log level of the MQTT library. + * + * Log messages from the MQTT library at or below this setting will be printed. + * + * Possible values: One of the Log levels. + * Default value (if undefined): IOT_LOG_LEVEL_GLOBAL; if that is undefined, + * then IOT_LOG_NONE. + */ +#define IOT_LOG_LEVEL_MQTT IOT_LOG_NONE + +/** + * @brief The number of worker tasks in the task pool. + * + * The full IoT Task Pool Library has many use cases, including Linux + * development. Typical FreeRTOS use cases do not require the full + * functionality so an optimized implementation is provided specifically for use + * with FreeRTOS. The optimized version has a fixed number of tasks in the + * task pool, each of which uses statically allocated memory to ensure creation + * of the task pool is guaranteed (it does not run out of heap space). + */ +#define TASKPOOL_NUMBER_OF_WORKERS 1 + +/** + * @brief The priority at which that the worker tasks in the task pool get + * created. All the worker tasks (whose count is specificed by the + * #TASKPOOL_NUMBER_OF_WORKERS configuration) is created with the same priority. + */ +#define TASKPOOL_WORKER_PRIORITY 1 + +/** + * @brief The stack size (in bytes) for each worker task in the task pool. + * + * The minimal version of the of task pool library only supports one task pool + * and the configuration of each worker task fixed at the compile time. + */ +#define TASKPOOL_WORKER_STACK_SIZE_BYTES 2048 + +/** + * @brief Enable/Disable asserts for the linear containers library. + * + * Set this to 1 to perform sanity checks when using the linear containers library. + * Asserts are useful for debugging, but should be disabled in production code. + * If this is set to 1, IotContainers_Assert can be defined to set the assertion + * function; otherwise, the standard library's assert function will be used. + * + * Possible values: 0 (asserts disabled) or 1 (asserts enabled) + * Recommended values: 1 when debugging; 0 in production code. + * Default value (if undefined): 0 + */ +#define IOT_CONTAINERS_ENABLE_ASSERTS 0 + +/** + * @brief Enable/Disable asserts for the MQTT library. + * + * Set this to 1 to perform sanity checks when using the MQTT library. + * Asserts are useful for debugging, but should be disabled in production code. + * If this is set to 1, IotMqtt_Assert can be defined to set the assertion + * function; otherwise, the standard library's assert function will be used. + * + * Possible values: 0 (asserts disabled) or 1 (asserts enabled) + * Recommended values: 1 when debugging; 0 in production code. + * Default value (if undefined): 0 + */ +#define IOT_MQTT_ENABLE_ASSERTS 0 + +/** + * @brief Enable/Disable anonymous metrics collection when using AWS IoT. + * + * This demo does not use TLS and so does not work with AWS IoT. Therefore, + * the metric collection must be disabled. + */ +#define AWS_IOT_MQTT_ENABLE_METRICS 0 + +/* Common settings for FreeRTOS; settings below this line generally do not need + * to be changed. */ + +/* Logging puts function on FreeRTOS. */ +#define IotLogging_Puts( str ) configPRINTF( ( "%s\r\n", str ) ) + +/* Assert functions on FreeRTOS. */ +#define Iot_DefaultAssert + +/* Memory allocation functions on FreeRTOS. */ +#define Iot_DefaultMalloc pvPortMalloc +#define Iot_DefaultFree vPortFree + +/* Enable static allocation. */ +#define IOT_STATIC_MEMORY_ONLY 1 + +#endif /* ifndef IOT_CONFIG_H_ */ diff --git a/tools/memory_estimator/config_files/iot_pkcs11_config.h b/tools/memory_estimator/config_files/iot_pkcs11_config.h new file mode 100644 index 0000000000..5a7a6d6afd --- /dev/null +++ b/tools/memory_estimator/config_files/iot_pkcs11_config.h @@ -0,0 +1,136 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/** + * @file aws_pkcs11_config.h + * @brief PCKS#11 config options. + */ + + +#ifndef _AWS_PKCS11_CONFIG_H_ +#define _AWS_PKCS11_CONFIG_H_ + +#include + +/* A non-standard version of C_INITIALIZE should be used by this port. */ +/* #define pkcs11configC_INITIALIZE_ALT */ + +/** + * @brief PKCS #11 default user PIN. + * + * The PKCS #11 standard specifies the presence of a user PIN. That feature is + * sensible for applications that have an interactive user interface and memory + * protections. However, since typical microcontroller applications lack one or + * both of those, the user PIN is assumed to be used herein for interoperability + * purposes only, and not as a security feature. + */ +#define configPKCS11_DEFAULT_USER_PIN "0000" + +/** + * @brief Maximum length (in characters) for a PKCS #11 CKA_LABEL + * attribute. + */ +#define pkcs11configMAX_LABEL_LENGTH 32 + +/** + * @brief Maximum number of token objects that can be stored + * by the PKCS #11 module. + */ +#define pkcs11configMAX_NUM_OBJECTS 6 + +/** + * @brief Set to 1 if a PAL destroy object is implemented. + * + * If set to 0, no PAL destroy object is implemented, and this functionality + * is implemented in the common PKCS #11 layer. + */ +#define pkcs11configPAL_DESTROY_SUPPORTED 0 + +/** + * @brief Set to 1 if OTA image verification via PKCS #11 module is supported. + * + * If set to 0, OTA code signing certificate is built in via + * aws_ota_codesigner_certificate.h. + */ +#define pkcs11configOTA_SUPPORTED 0 + +/** + * @brief Set to 1 if PAL supports storage for JITP certificate, + * code verify certificate, and trusted server root certificate. + * + * If set to 0, PAL does not support storage mechanism for these, and + * they are accessed via headers compiled into the code. + */ +#define pkcs11configJITP_CODEVERIFY_ROOT_CERT_SUPPORTED 0 + +/** + * @brief The PKCS #11 label for device private key. + * + * Private key for connection to AWS IoT endpoint. The corresponding + * public key should be registered with the AWS IoT endpoint. + */ +#define pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS "Device Priv TLS Key" + +/** + * @brief The PKCS #11 label for device public key. + * + * The public key corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS. + */ +#define pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS "Device Pub TLS Key" + +/** + * @brief The PKCS #11 label for the device certificate. + * + * Device certificate corresponding to + * pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS. + */ +#define pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS "Device Cert" + +/** + * @brief The PKCS #11 label for the object to be used for code verification. + * + * Used by over-the-air update code to verify an incoming signed image. + */ +#define pkcs11configLABEL_CODE_VERIFICATION_KEY "Code Verify Key" + +/** + * @brief The PKCS #11 label for Just-In-Time-Provisioning. + * + * The certificate corresponding to the issuer of the device certificate + * (pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS) when using the JITR or + * JITP flow. + */ +#define pkcs11configLABEL_JITP_CERTIFICATE "JITP Cert" + +/** + * @brief The PKCS #11 label for the AWS Trusted Root Certificate. + * + * @see aws_default_root_certificates.h + */ +#define pkcs11configLABEL_ROOT_CERTIFICATE "Root Cert" + +#endif /* _AWS_PKCS11_CONFIG_H_ include guard. */ diff --git a/tools/memory_estimator/makefile_generator.py b/tools/memory_estimator/makefile_generator.py new file mode 100644 index 0000000000..2e09e5318f --- /dev/null +++ b/tools/memory_estimator/makefile_generator.py @@ -0,0 +1,27 @@ + + +def generate_makefile_from_template(source_files, include_dirs, optimization, template_file, output_file): + ''' + source_files - A list containing all source files. + include_dirs - A list containing all include directories. + optimization - Compiler optimization (O0, Os etc.). + template_file - Makefile template to use. + output_file - Generated Makefile path. + ''' + formatted_source_files = 'SRCS=' + ' \\\n'.join(source_files) + formatted_source_files += '\n' + + formatted_include_dirs='' + for include_dir in include_dirs: + formatted_include_dirs += 'INCLUDE_DIRS+=-I ' + include_dir + '\n' + formatted_include_dirs += '\n' + + with open(template_file, 'r') as f: + makefile_content = f.read() + + makefile_content = makefile_content.replace('SOURCE_FILES', formatted_source_files) + makefile_content = makefile_content.replace('INCLUDE_DIRECTORIES', formatted_include_dirs) + makefile_content = makefile_content.replace('OPTIMIZATION', optimization) + + with open(output_file, 'w') as f: + f.write(makefile_content) diff --git a/tools/memory_estimator/memory_estimator.py b/tools/memory_estimator/memory_estimator.py new file mode 100644 index 0000000000..db42a00fd6 --- /dev/null +++ b/tools/memory_estimator/memory_estimator.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 + +import io +import os +import re +import argparse +import subprocess +from makefile_generator import generate_makefile_from_template + + +__THIS_FILE_PATH__ = os.path.dirname(os.path.abspath(__file__)) +__MAKE_FILE_TEMPLATE__ = os.path.join(__THIS_FILE_PATH__, 'template', 'Makefile.template') +__GENERATED_MAKE_FILE__ = os.path.join(__THIS_FILE_PATH__, 'Makefile') + +__FREERTOS_SRC_DIR__ = os.path.join('FreeRTOS', 'Source') +__FREERTOS_PLUS_SRC_DIR__ = os.path.join('FreeRTOS-Plus', 'Source') +__IOT_LIBS_DIR__ = os.path.join(__FREERTOS_PLUS_SRC_DIR__, 'FreeRTOS-IoT-Libraries') + + +__LIB_NAME_TO_SRC_DIRS_MAPPING__ = { + 'light-mqtt' : [ + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'standard', 'mqtt', 'src', 'iot_mqtt_lightweight_api.c'), + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'standard', 'mqtt', 'src', 'iot_mqtt_helper.c') + ], + 'mqtt' : [ + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'standard', 'mqtt', 'src') + ], + 'https' : [ + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'standard', 'https', 'src'), + os.path.join(__FREERTOS_PLUS_SRC_DIR__, 'http-parser') + ], + 'shadow' : [ + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'aws', 'shadow', 'src'), + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'aws', 'common', 'src') + ], + 'jobs' : [ + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'aws', 'jobs', 'src'), + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'aws', 'common', 'src') + ], + 'ota' : [ + os.path.join(__IOT_LIBS_DIR__, 'c_sdk', 'aws', 'ota', 'src') + ], + 'kernel' : [ + os.path.join(__FREERTOS_SRC_DIR__, 'event_groups.c'), + os.path.join(__FREERTOS_SRC_DIR__, 'list.c'), + os.path.join(__FREERTOS_SRC_DIR__, 'queue.c'), + os.path.join(__FREERTOS_SRC_DIR__, 'stream_buffer.c'), + os.path.join(__FREERTOS_SRC_DIR__, 'tasks.c'), + os.path.join(__FREERTOS_SRC_DIR__, 'timers.c'), + os.path.join(__FREERTOS_SRC_DIR__, 'portable', 'GCC', 'ARM_CM4F', 'port.c') + ] +} + + +def generate_makefile(freertos_lts, optimization, lib_name): + freertos_src_dir = os.path.join(freertos_lts, __FREERTOS_SRC_DIR__) + freertos_plus_src_dir = os.path.join(freertos_lts, __FREERTOS_PLUS_SRC_DIR__) + + # Generate include dirs list. + include_dirs = [] + for root, dirs, files in os.walk(freertos_plus_src_dir): + for dir in dirs: + include_dirs.append(os.path.join(root, dir)) + + # Add FreeRTOS include dirs for Cortex-M4 to include dirs list. + include_dirs.append(os.path.join(freertos_src_dir, 'include')) + include_dirs.append(os.path.join(freertos_src_dir, 'portable', 'GCC', 'ARM_CM4F')) + + # Add config files dir to include dirs list. + include_dirs.append(os.path.join(__THIS_FILE_PATH__, 'config_files')) + + # Generate source files list. + if lib_name in __LIB_NAME_TO_SRC_DIRS_MAPPING__: + source_files=[] + for lib_src_location in __LIB_NAME_TO_SRC_DIRS_MAPPING__[lib_name]: + lib_src_full_path = os.path.join(freertos_lts, lib_src_location) + + # Traverse if the location is a directory, otherwise just append it. + if os.path.isdir(lib_src_full_path): + for root, dirs, files in os.walk(lib_src_full_path): + for file in files: + if file.endswith('.c'): + source_files.append(os.path.join(root, file)) + else: + source_files.append(lib_src_full_path) + else: + raise ValueError('Library name: {} is invalid'.format(lib_name)) + + # Generate makefile. + generate_makefile_from_template(source_files, + include_dirs, + optimization, + __MAKE_FILE_TEMPLATE__, + __GENERATED_MAKE_FILE__) + + +def make(compiler): + compiler_command='CC={}'.format(compiler) + + print('---- Starting Build. Compiler: {} ---- \n'.format(compiler)) + + proc = subprocess.Popen(['make', '-f', __GENERATED_MAKE_FILE__, compiler_command], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + warnings = [] + for line in iter(proc.stdout.readline, b''): + line = line.decode('utf-8').strip() + print(line) + if re.match('.*: warning: .*', line): + warnings.append(line.strip()) + + print('---- Build Finished ---- \n') + return warnings + + +def calculate_size(sizetool): + sizetool_command='SIZETOOL={}'.format(sizetool) + + proc = subprocess.Popen(['make', '-f', __GENERATED_MAKE_FILE__, 'size', sizetool_command], + stdout=subprocess.PIPE) + + calculated_sizes = [] + for line in iter(proc.stdout.readline, b''): + line = line.decode('utf-8').strip() + calculated_sizes.append(line) + + return calculated_sizes + + +def clean(): + proc = subprocess.Popen(['make', '-f', __GENERATED_MAKE_FILE__, 'clean'], + stdout=subprocess.PIPE) + + for line in iter(proc.stdout.readline, b''): + line = line.decode('utf-8').strip() + print(line) + + +def remove_generated_makefile(): + os.remove(__GENERATED_MAKE_FILE__) + + +def pretty_print_warnings(warnings): + if len(warnings) > 0: + print('\n\n---- Warnings ---- ') + print('------------------') + for warning in warnings: + print(warning) + print('------------------') + + +def pretty_print_sizes(sizes): + print('\n\n---- Sizes ---- ') + print('---------------') + for size in sizes[1:]: + print(size) + print('---------------') + + +def parse_arguments(): + parser = argparse.ArgumentParser(description='Memory Estimator.') + + parser.add_argument('-p', '--lts-path', required=True, help='Path to FreeRTOS LTS directory.') + parser.add_argument('-o', '--optimization', default='O0', help='Compiler optimization (O0, Os etc.).') + parser.add_argument('-l', '--lib', default='mqtt', help='Library name to generate the memory estimate for.') + parser.add_argument('-c', '--compiler', default='arm-none-eabi-gcc', help='Compiler to use.') + parser.add_argument('-s', '--sizetool', default='arm-none-eabi-size', help='Size tool to use.') + parser.add_argument('-d', '--dontclean', action='store_true', help='Do not clean the generated artifacts.') + + return vars(parser.parse_args()) + + + +def main(): + args = parse_arguments() + + # Generate Makefile. + generate_makefile(args['lts_path'], args['optimization'], args['lib']) + + # Run make build. + warnings = make(args['compiler']) + + # Run make size. + calculated_sizes = calculate_size(args['sizetool']) + + # Remove the generated artifacts. + if not args['dontclean']: + clean() + remove_generated_makefile() + + # Print the generated warnings. + pretty_print_warnings(warnings) + + # Print the calculated sizes. + pretty_print_sizes(calculated_sizes) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/tools/memory_estimator/template/Makefile.template b/tools/memory_estimator/template/Makefile.template new file mode 100644 index 0000000000..568ff41c77 --- /dev/null +++ b/tools/memory_estimator/template/Makefile.template @@ -0,0 +1,25 @@ +# Source Files +SOURCE_FILES + +# Include Directories +INCLUDE_DIRECTORIES + +OBJS=$(SRCS:.c=.o) + +CFLAGS+=-std=gnu99 -Wall -Wextra -ggdb -OPTIMIZATION +CFLAGS+=-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +.DEFAULT_GOAL:=build + +build: $(OBJS) + +size: + $(SIZETOOL) $(OBJS) + +clean: + rm -rf $(OBJS) + +.PHONY: build size clean + +.c.o: + $(CC) $(CFLAGS) $(INCLUDE_DIRS) -c $< -o $@