Benchmarks
Microcontrollers have tight hardware constraints which affect how much resources the firmware can demand. It is important to make sure that the available resources are not depleted to allow for robust operation and that there is sufficient flash head room to allow for future software upgrades.
In general, microcontrollers have three relevant hardware constraints:
- Limited processing speed
- Limited memory size
- Limited flash size
For OCPP, the relevant bottlenecks are especially the memory and flash size. The processing speed is no concern, since OCPP is not computationally complex and does not include any extensive planning algorithms on the charger size. A previous benchmark on the ESP-IDF showed that the processing times are in the lower milliseconds range and are probably outweighed by IO times and network round trip times.
However, the memory and flash requirements are important figures, because the device model of OCPP has a significant size. The microcontroller needs to keep the model data in the heap memory for the largest part and the firmware which covers the corresponding processing routines needs to have sufficient space on flash.
This chapter presents benchmarks of the memory and flash requirements. They should help to determine the required microcontroller capabilities, or to give general insights for taking further action on optimizing the firmware.
Firmware size
When compiling a firmware with MicroOCPP, the resulting binary will contain functionality which is not related to OCPP, like hardware drivers, modules which are shared, like MbedTLS and the actual MicroOCPP object files. The size of the latter is the final flash requirement of MicroOCPP.
For the flash benchmark, the profiler compiles a dummy OCPP firmware, analyzes the size of the compilation units using bloaty and evaluates the bloaty report using a Python script. To give realistic results, the firwmare is compiled with -Os
, no RTTI or exceptions and newlib as the standard C library. The following tables show the results.
OCPP 1.6
The following table shows the cumulated size of the objects files per module. The Module category consists of the OCPP 2.0.1 functional blocks, OCPP 1.6 feature profiles and general functionality which is shared accross the library. If a feature of the implementation falls under both an OCPP 2.0.1 functional block and OCPP 1.6 feature profile definition, it is preferrably assigned to the OCPP 2.0.1 category. This allows for better comparability between both OCPP versions.
Table 1: Firmware size per Module
Module | Binary size (Bytes) |
---|---|
B - Provisioning | 6704 |
C - Authorization | 640 |
Configuration | 12384 |
Core | 16012 |
D - Local Authorization List Management | 7576 |
E - Transactions | 10360 |
Firmware Management | 11345 |
G - Availability | 2588 |
General | 14612 |
General - API | 16284 |
General - Hardware Abstraction Layer | 1468 |
General - RPC framework | 11796 |
H - Reservation | 3976 |
J - MeterValues | 13776 |
K - SmartCharging | 14952 |
M - Certificate Management | 4452 |
TriggerMessage | 836 |
Total | 149761 |
OCPP 2.0.1
Table 2: Firmware size per Module
Module | Binary size (Bytes) |
---|---|
B - Provisioning | 8752 |
B - Provisioning - Variables | 15344 |
C - Authorization | 1356 |
Configuration | 11556 |
E - Transactions | 13540 |
F - RemoteControl | 844 |
G - Availability | 3904 |
General | 15132 |
General - API | 19364 |
General - Hardware Abstraction Layer | 1468 |
General - RPC framework | 11980 |
J - MeterValues | 3508 |
M - Certificate Management | 4492 |
Total | 111240 |
Memory usage
MicroOCPP uses the heap memory to process incoming messages, maintain the device model and create outgoing OCPP messages. The total heap usage should remain low enough to not risk a heap depletion which would not only affect the OCPP module, but the whole controller, because heap memory is typically shared on microcontrollers. To assess the heap usage of MicroOCPP, a test suite runs a variety of simulated charger use cases and measures the maximum occupied memory. Then, the maximum observed value is considered as the memory requirement of MicroOCPP.
Another important figure is the base level which is much closer to the average heap usage. The total heap usage consists of a base level and a dynamic part. Some memory objects are only initialized once during startup or as the device model is populated (e.g. Charging Schedules) and therefore belong to the base which changes only slowly over time. In contrast, objects for the JSON parsing and serialization and the internal execution of the operations are highly dynamic as they are instantiated for one operation and freed again after completion of the action. If the firmware contains multiple components besides MicroOCPP with this usage pattern, then the average total memory occupation of the device RAM is even closer to the base levels of the individual components.
The following table shows the dynamic heap usage for a variety of test cases, followed by the base level and resulting maximum memory occupation of MicroOCPP. At the time being, the measurements are limited to only OCPP 2.0.1 and a narrow set of test cases. They will be gradually extended over time.
Table 3: Memory usage per use case and total
Testcase | Pass | Heap usage (Bytes) |
---|---|---|
B:Provisioning | ||
Get Variables - single value | - | 2380 |
Set Variables - multiple values | - | 2523 |
Get Base Report - FullInventory | x | 22287 |
Set Variables - Unknown component | x | 1899 |
Set Variables - Read-only | - | 2349 |
C:Authorization | ||
Local start transaction - Authorization Blocked | x | 2997 |
E:Transactions | ||
Start transaction options - PowerPathClosed | x | 3173 |
Local start transaction - Authorization first - Success | - | 3173 |
Stop transaction options - PowerPathClosed - Local stop | - | 3173 |
Stop transaction options - StopAuthorized - Local | - | 3173 |
Stop transaction options - StopAuthorized - Remote | - | 3173 |
Check Transaction status - TransactionId unknown | - | 1445 |
Check Transaction status - Transaction with id ended - with message in queue | - | 1445 |
Check Transaction status - Without transactionId - without message in queue | - | 1445 |
F:Remote Control | ||
Remote start transaction - Cable plugin first | - | 2997 |
Remote start transaction - Remote start first - Cable plugin timeout | x | 3277 |
Remote unlock Connector - Without ongoing transaction - No cable connected | - | 1445 |
Remote unlock Connector - Without ongoing transaction - UnknownConnector | - | 1445 |
Trigger message - TransactionEvent - Specific EVSE | - | 3173 |
Trigger message - StatusNotification - Specific EVSE - Available | - | 1445 |
Trigger message - NotImplemented | - | 1445 |
G:Availability | ||
Change Availability EVSE - Operative to inoperative | x | 1445 |
Change Availability Charging Station - Inoperative to operative | x | 1445 |
Change Availability EVSE - Operative to operative | x | 1445 |
Change Availability Charging Station - Operative to operative | x | 1445 |
Change Availability Connector - Operative to operative | x | 1445 |
J:Meter Values | ||
[Watchlist] Sampled Meter Values - EventType Started - EVSE known | - | 3239 |
[Watchlist] Sampled Meter Values - EventType Ended | - | 1445 |
Simulator stats | ||
Base memory occupation | 16824 | |
Test case maximum | 22287 | |
Total memory maximum | 39111 |
Full data sets
This section contains the raw data which is the basis for the evaluations above.
Table 4: All compilation units for OCPP 1.6 firmware
Compile Unit | Binary size (Bytes) | v16 | v201 | Module |
---|---|---|---|---|
MicroOcpp.cpp | 14368 | x | x | General - API |
Core/Configuration.cpp | 3104 | x | x | Configuration |
Core/ConfigurationContainer.cpp | 864 | x | x | Configuration |
Core/ConfigurationContainerFlash.cpp | 4192 | x | x | Configuration |
Core/ConfigurationKeyValue.cpp | 708 | x | x | Configuration |
Core/Connection.cpp | 272 | x | x | General - Hardware Abstraction Layer |
Core/Context.cpp | 380 | x | x | General |
Core/FilesystemAdapter.cpp | 1196 | x | x | General - Hardware Abstraction Layer |
Core/FilesystemUtils.cpp | 4592 | x | x | General |
Core/FtpMbedTLS.cpp | 5140 | x | x | General |
Core/Memory.cpp | 156 | x | x | General |
Core/Operation.cpp | 104 | x | x | General - RPC framework |
Core/OperationRegistry.cpp | 1616 | x | x | General - RPC framework |
Core/Request.cpp | 3400 | x | x | General - RPC framework |
Core/RequestQueue.cpp | 6676 | x | x | General - RPC framework |
Core/Time.cpp | 2472 | x | x | General |
Model/Authorization/AuthorizationData.cpp | 1320 | x | D - Local Authorization List Management | |
Model/Authorization/AuthorizationList.cpp | 3732 | x | D - Local Authorization List Management | |
Model/Authorization/AuthorizationService.cpp | 1704 | x | D - Local Authorization List Management | |
Model/Boot/BootService.cpp | 3804 | x | x | B - Provisioning |
Model/Certificates/Certificate.cpp | 668 | x | x | M - Certificate Management |
Model/Certificates/CertificateMbedTLS.cpp | 2100 | x | x | M - Certificate Management |
Model/Certificates/CertificateService.cpp | 468 | x | x | M - Certificate Management |
Model/Certificates/Certificate_c.cpp | 0 | x | x | M - Certificate Management |
Model/ConnectorBase/Connector.cpp | 12240 | x | Core | |
Model/ConnectorBase/ConnectorsCommon.cpp | 2136 | x | Core | |
Model/ConnectorBase/Notification.cpp | 72 | x | Core | |
Model/Diagnostics/DiagnosticsService.cpp | 5825 | x | Firmware Management | |
Model/FirmwareManagement/FirmwareService.cpp | 4060 | x | Firmware Management | |
Model/Heartbeat/HeartbeatService.cpp | 420 | x | x | G - Availability |
Model/Metering/MeterStore.cpp | 2900 | x | J - MeterValues | |
Model/Metering/MeterValue.cpp | 3276 | x | J - MeterValues | |
Model/Metering/MeteringConnector.cpp | 4312 | x | J - MeterValues | |
Model/Metering/MeteringService.cpp | 1848 | x | J - MeterValues | |
Model/Metering/ReadingContext.cpp | 180 | x | J - MeterValues | |
Model/Metering/SampledValue.cpp | 780 | x | J - MeterValues | |
Model/Model.cpp | 1872 | x | x | General |
Model/Reservation/Reservation.cpp | 1072 | x | H - Reservation | |
Model/Reservation/ReservationService.cpp | 1384 | x | H - Reservation | |
Model/Reset/ResetService.cpp | 984 | x | x | B - Provisioning |
Model/SmartCharging/SmartChargingModel.cpp | 3804 | x | K - SmartCharging | |
Model/SmartCharging/SmartChargingService.cpp | 6932 | x | K - SmartCharging | |
Model/Transactions/Transaction.cpp | 156 | x | x | E - Transactions |
Model/Transactions/TransactionDeserialize.cpp | 3048 | x | E - Transactions | |
Model/Transactions/TransactionStore.cpp | 2372 | x | E - Transactions | |
Operations/Authorize.cpp | 640 | x | x | C - Authorization |
Operations/BootNotification.cpp | 1288 | x | x | B - Provisioning |
Operations/CancelReservation.cpp | 364 | x | H - Reservation | |
Operations/ChangeAvailability.cpp | 496 | x | G - Availability | |
Operations/ChangeConfiguration.cpp | 836 | x | Configuration | |
Operations/ClearCache.cpp | 432 | x | Core | |
Operations/ClearChargingProfile.cpp | 824 | x | K - SmartCharging | |
Operations/CustomOperation.cpp | 0 | x | x | General - RPC framework |
Operations/DataTransfer.cpp | 516 | x | Core | |
Operations/DeleteCertificate.cpp | 700 | x | x | M - Certificate Management |
Operations/DiagnosticsStatusNotification.cpp | 220 | x | Firmware Management | |
Operations/FirmwareStatusNotification.cpp | 244 | x | Firmware Management | |
Operations/GetCompositeSchedule.cpp | 1076 | x | K - SmartCharging | |
Operations/GetConfiguration.cpp | 2680 | x | x | Configuration |
Operations/GetDiagnostics.cpp | 640 | x | Firmware Management | |
Operations/GetInstalledCertificateIds.cpp | 1588 | x | K - SmartCharging | |
Operations/GetLocalListVersion.cpp | 268 | x | D - Local Authorization List Management | |
Operations/Heartbeat.cpp | 780 | x | x | G - Availability |
Operations/InstallCertificate.cpp | 516 | x | x | M - Certificate Management |
Operations/MeterValues.cpp | 660 | x | J - MeterValues | |
Operations/RemoteStartTransaction.cpp | 1180 | x | E - Transactions | |
Operations/RemoteStopTransaction.cpp | 404 | x | E - Transactions | |
Operations/ReserveNow.cpp | 1156 | x | H - Reservation | |
Operations/Reset.cpp | 628 | x | x | B - Provisioning |
Operations/SendLocalList.cpp | 552 | x | D - Local Authorization List Management | |
Operations/SetChargingProfile.cpp | 728 | x | K - SmartCharging | |
Operations/StartTransaction.cpp | 1352 | x | E - Transactions | |
Operations/StatusNotification.cpp | 892 | x | x | G - Availability |
Operations/StopTransaction.cpp | 1848 | x | E - Transactions | |
Operations/TriggerMessage.cpp | 836 | x | TriggerMessage | |
Operations/UnlockConnector.cpp | 616 | x | Core | |
Operations/UpdateFirmware.cpp | 356 | x | Firmware Management | |
MicroOcpp_c.cpp | 1916 | x | x | General - API |
Table 5: All compilation units for OCPP 2.0.1 firmware
Compile Unit | Binary size (Bytes) | v16 | v201 | Module |
---|---|---|---|---|
MicroOcpp.cpp | 17568 | x | x | General - API |
Core/Configuration.cpp | 3104 | x | x | Configuration |
Core/ConfigurationContainer.cpp | 864 | x | x | Configuration |
Core/ConfigurationContainerFlash.cpp | 4192 | x | x | Configuration |
Core/ConfigurationKeyValue.cpp | 708 | x | x | Configuration |
Core/Connection.cpp | 272 | x | x | General - Hardware Abstraction Layer |
Core/Context.cpp | 396 | x | x | General |
Core/FilesystemAdapter.cpp | 1196 | x | x | General - Hardware Abstraction Layer |
Core/FilesystemUtils.cpp | 4592 | x | x | General |
Core/FtpMbedTLS.cpp | 5172 | x | x | General |
Core/Memory.cpp | 156 | x | x | General |
Core/Operation.cpp | 104 | x | x | General - RPC framework |
Core/OperationRegistry.cpp | 1632 | x | x | General - RPC framework |
Core/Request.cpp | 3484 | x | x | General - RPC framework |
Core/RequestQueue.cpp | 6760 | x | x | General - RPC framework |
Core/Time.cpp | 2504 | x | x | General |
Model/Authorization/AuthorizationData.cpp | 1356 | x | D - Local Authorization List Management | |
Model/Authorization/AuthorizationList.cpp | 3760 | x | D - Local Authorization List Management | |
Model/Authorization/AuthorizationService.cpp | 1712 | x | D - Local Authorization List Management | |
Model/Authorization/IdToken.cpp | 344 | x | C - Authorization | |
Model/Availability/AvailabilityService.cpp | 1380 | x | x | G - Availability |
Model/Boot/BootService.cpp | 3872 | x | x | B - Provisioning |
Model/Certificates/Certificate.cpp | 668 | x | x | M - Certificate Management |
Model/Certificates/CertificateMbedTLS.cpp | 2104 | x | x | M - Certificate Management |
Model/Certificates/CertificateService.cpp | 468 | x | x | M - Certificate Management |
Model/Certificates/Certificate_c.cpp | 0 | x | x | M - Certificate Management |
Model/ConnectorBase/Connector.cpp | 12448 | x | Core | |
Model/ConnectorBase/ConnectorsCommon.cpp | 2448 | x | Core | |
Model/ConnectorBase/Notification.cpp | 72 | x | Core | |
Model/Diagnostics/DiagnosticsService.cpp | 5861 | x | Firmware Management | |
Model/FirmwareManagement/FirmwareService.cpp | 4076 | x | Firmware Management | |
Model/Heartbeat/HeartbeatService.cpp | 420 | x | x | G - Availability |
Model/Metering/MeterStore.cpp | 2924 | x | J - MeterValues | |
Model/Metering/MeterValue.cpp | 3300 | x | J - MeterValues | |
Model/Metering/MeterValuesV201.cpp | 3328 | x | J - MeterValues | |
Model/Metering/MeteringConnector.cpp | 4312 | x | J - MeterValues | |
Model/Metering/MeteringService.cpp | 1848 | x | J - MeterValues | |
Model/Metering/ReadingContext.cpp | 180 | x | J - MeterValues | |
Model/Metering/SampledValue.cpp | 780 | x | J - MeterValues | |
Model/Model.cpp | 2312 | x | x | General |
Model/RemoteControl/RemoteControlService.cpp | 844 | x | F - RemoteControl | |
Model/Reservation/Reservation.cpp | 1072 | x | H - Reservation | |
Model/Reservation/ReservationService.cpp | 1384 | x | H - Reservation | |
Model/Reset/ResetService.cpp | 2612 | x | x | B - Provisioning |
Model/SmartCharging/SmartChargingModel.cpp | 3804 | x | K - SmartCharging | |
Model/SmartCharging/SmartChargingService.cpp | 6932 | x | K - SmartCharging | |
Model/Transactions/Transaction.cpp | 1628 | x | x | E - Transactions |
Model/Transactions/TransactionDeserialize.cpp | 2964 | x | E - Transactions | |
Model/Transactions/TransactionService.cpp | 9040 | x | E - Transactions | |
Model/Transactions/TransactionStore.cpp | 10960 | x | E - Transactions | |
Model/Variables/Variable.cpp | 1800 | x | B - Provisioning - Variables | |
Model/Variables/VariableContainer.cpp | 2196 | x | B - Provisioning - Variables | |
Model/Variables/VariableService.cpp | 4420 | x | B - Provisioning - Variables | |
Operations/Authorize.cpp | 1012 | x | x | C - Authorization |
Operations/BootNotification.cpp | 1408 | x | x | B - Provisioning |
Operations/CancelReservation.cpp | 368 | x | H - Reservation | |
Operations/ChangeAvailability.cpp | 888 | x | G - Availability | |
Operations/ChangeConfiguration.cpp | 860 | x | Configuration | |
Operations/ClearCache.cpp | 440 | x | Core | |
Operations/ClearChargingProfile.cpp | 752 | x | K - SmartCharging | |
Operations/CustomOperation.cpp | 0 | x | x | General - RPC framework |
Operations/DataTransfer.cpp | 520 | x | Core | |
Operations/DeleteCertificate.cpp | 716 | x | x | M - Certificate Management |
Operations/DiagnosticsStatusNotification.cpp | 220 | x | Firmware Management | |
Operations/FirmwareStatusNotification.cpp | 244 | x | Firmware Management | |
Operations/GetBaseReport.cpp | 544 | x | B - Provisioning - Variables | |
Operations/GetCompositeSchedule.cpp | 1040 | x | K - SmartCharging | |
Operations/GetConfiguration.cpp | 2688 | x | x | Configuration |
Operations/GetDiagnostics.cpp | 652 | x | Firmware Management | |
Operations/GetInstalledCertificateIds.cpp | 1596 | x | K - SmartCharging | |
Operations/GetLocalListVersion.cpp | 268 | x | D - Local Authorization List Management | |
Operations/GetVariables.cpp | 2356 | x | B - Provisioning - Variables | |
Operations/Heartbeat.cpp | 780 | x | x | G - Availability |
Operations/InstallCertificate.cpp | 536 | x | x | M - Certificate Management |
Operations/MeterValues.cpp | 660 | x | J - MeterValues | |
Operations/NotifyReport.cpp | 2112 | x | B - Provisioning - Variables | |
Operations/RemoteStartTransaction.cpp | 1192 | x | E - Transactions | |
Operations/RemoteStopTransaction.cpp | 408 | x | E - Transactions | |
Operations/RequestStartTransaction.cpp | 536 | x | E - Transactions | |
Operations/RequestStopTransaction.cpp | 396 | x | E - Transactions | |
Operations/ReserveNow.cpp | 1160 | x | H - Reservation | |
Operations/Reset.cpp | 860 | x | x | B - Provisioning |
Operations/SendLocalList.cpp | 560 | x | D - Local Authorization List Management | |
Operations/SetChargingProfile.cpp | 732 | x | K - SmartCharging | |
Operations/SetVariables.cpp | 1916 | x | B - Provisioning - Variables | |
Operations/StartTransaction.cpp | 1292 | x | E - Transactions | |
Operations/StatusNotification.cpp | 1324 | x | x | G - Availability |
Operations/StopTransaction.cpp | 1848 | x | E - Transactions | |
Operations/TransactionEvent.cpp | 1940 | x | E - Transactions | |
Operations/TriggerMessage.cpp | 844 | x | TriggerMessage | |
Operations/UnlockConnector.cpp | 172 | x | Core | |
Operations/UpdateFirmware.cpp | 364 | x | Firmware Management | |
MicroOcpp_c.cpp | 1796 | x | x | General - API |