Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Over-the-air firmware update implementation expertise for embedded systems. Expert skill for delta updates, image signing, update protocols, partition management, and rollback mechanisms.
.claude/skills/a5c-ai-ota-firmware-update/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 66% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 92% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 260% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 161% | 0% |
Expert skill for over-the-air firmware update implementation in embedded systems. Provides expertise in update image generation, signing, transport protocols, partition management, and rollback mechanisms.
The OTA Firmware Update skill enables comprehensive firmware update capabilities:
Generate firmware update images with metadata:
javascript// Example: Update image generation configuration const imageConfig = { type: 'full', // or 'delta' input: 'build/firmware.bin', output: 'release/firmware-v1.2.0.update', version: { major: 1, minor: 2, patch: 0, build: 456 }, compression: 'lz4', // none, lz4, zlib, lzma encryption: { algorithm: 'aes-128-ctr', keyFile: 'keys/update-key.bin' } };
Sign firmware images for secure boot chain:
bash# Sign image with MCUboot imgtool imgtool sign \ --key keys/signing-key.pem \ --align 4 \ --version 1.2.0 \ --header-size 0x200 \ --slot-size 0x60000 \ --pad-header \ build/firmware.bin \ release/firmware-v1.2.0-signed.bin # Verify signature imgtool verify \ --key keys/signing-key.pub.pem \ release/firmware-v1.2.0-signed.bin
Generate differential updates to minimize transfer size:
javascript// Delta update configuration const deltaConfig = { baseVersion: 'v1.1.0', baseImage: 'releases/firmware-v1.1.0.bin', targetImage: 'build/firmware.bin', algorithm: 'bsdiff', // bsdiff, xdelta, vcdiff output: 'patches/v1.1.0-to-v1.2.0.patch', metadata: { sourceVersion: '1.1.0', targetVersion: '1.2.0', sourceHash: 'sha256:...', targetHash: 'sha256:...' } }; // Size comparison // Full image: 245,760 bytes // Delta patch: 12,340 bytes (95% reduction)
Generate update manifest with metadata:
json{ "version": "1.2.0", "build": 456, "timestamp": "2026-01-24T10:30:00Z", "images": [ { "slot": "primary", "type": "application", "file": "firmware-v1.2.0-signed.bin", "size": 245760, "hash": { "algorithm": "sha256", "value": "3b9d8a2f..." }, "signature": { "algorithm": "ecdsa-p256", "value": "base64..." } } ], "compatibility": { "minBootloaderVersion": "1.0.0", "hardwareRevision": ["rev-a", "rev-b"], "requiredBaseVersion": "1.1.0" }, "delta": { "available": true, "baseVersions": ["1.1.0", "1.0.0"], "files": { "1.1.0": "patches/v1.1.0-to-v1.2.0.patch" } }, "releaseNotes": "Bug fixes and performance improvements" }
Configure A/B partition scheme for safe updates:
c/** * @brief Flash partition layout for A/B updates * * Partition | Start | Size | Purpose * -------------|------------|--------|------------------ * Bootloader | 0x08000000 | 32KB | MCUboot bootloader * Slot A | 0x08008000 | 240KB | Primary application * Slot B | 0x08044000 | 240KB | Secondary/staging * Scratch | 0x08080000 | 64KB | Swap scratch area * Config | 0x08090000 | 16KB | Persistent config */ typedef struct { uint32_t magic; // Partition magic number uint8_t image_ok; // Image confirmed working uint8_t copy_done; // Swap operation complete uint16_t swap_type; // None, Test, Revert, Permanent uint32_t version; // Firmware version uint32_t crc32; // Image CRC } partition_header_t;
Configure MCUboot for secure firmware updates:
ini# MCUboot configuration (prj.conf for Zephyr) CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="keys/signing-key.pem" CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE="keys/encryption-key.pem" CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--pad --confirm" # Image configuration CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="1.2.0" CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=n CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE=y # Update settings CONFIG_MCUBOOT_SWAP_USING_SCRATCH=y CONFIG_IMG_MANAGER=y CONFIG_STREAM_FLASH=y
Implement automatic rollback on update failure:
c/** * @brief Firmware update state machine */ typedef enum { UPDATE_STATE_IDLE, // No update in progress UPDATE_STATE_DOWNLOADING, // Receiving update image UPDATE_STATE_VERIFYING, // Verifying signature/hash UPDATE_STATE_APPLYING, // Writing to flash UPDATE_STATE_PENDING_REBOOT, // Ready to boot new image UPDATE_STATE_TESTING, // Running new image (not confirmed) UPDATE_STATE_CONFIRMED, // Update successful UPDATE_STATE_REVERTING, // Rolling back to previous UPDATE_STATE_FAILED // Update failed } update_state_t; /** * @brief Confirm update after successful boot * * Must be called after new firmware boots successfully. * Failure to confirm within timeout triggers automatic rollback. * * @param timeout_ms Confirmation timeout in milliseconds * @return OTA_OK on success, error code otherwise */ ota_status_t ota_confirm_update(uint32_t timeout_ms); /** * @brief Trigger manual rollback to previous version * * @return OTA_OK if rollback initiated, error otherwise */ ota_status_t ota_rollback(void);
Integrate with IoT cloud platforms:
javascript// AWS IoT Jobs integration const jobDocument = { operation: 'firmware-update', version: '1.2.0', files: { firmware: { url: 'https://firmware.s3.amazonaws.com/v1.2.0/firmware.bin', fileType: 'binary', size: 245760, sha256: '3b9d8a2f...' } }, autoReboot: true, confirmationRequired: true }; // Azure IoT Hub device twin update const desiredProperties = { firmware: { version: '1.2.0', downloadUrl: 'https://blob.azure.com/firmware/v1.2.0.bin', checksum: 'sha256:3b9d8a2f...', updateTime: '2026-01-24T12:00:00Z' } };
This skill integrates with the following processes:
| Process | Integration Point | |---------|-------------------| | ota-firmware-update.js | Primary OTA implementation | | secure-boot-implementation.js | Secure update chain | | bootloader-implementation.js | Bootloader integration |
bash# Generate signing keys imgtool keygen -k keys/signing-key.pem -t ecdsa-p256 # Extract public key for device imgtool getpub -k keys/signing-key.pem > keys/signing-key.pub.pem # Generate encryption key (optional) openssl rand -hex 16 > keys/encryption-key.bin
bash# Build firmware west build -b nrf52840dk_nrf52840 app # Sign with MCUboot west sign -t imgtool \ -- --key keys/signing-key.pem \ --version 1.2.0 # Generate manifest ota-tools manifest generate \ --image build/zephyr/zephyr.signed.bin \ --output release/manifest.json
bash# Upload to S3 (AWS) aws s3 cp release/ s3://firmware-bucket/v1.2.0/ --recursive # Create IoT Job aws iot create-job \ --job-id firmware-update-v1.2.0 \ --targets arn:aws:iot:region:account:thinggroup/devices \ --document file://job-document.json
javascript// Device-side progress reporting const updateStatus = { state: 'downloading', progress: 45, version: '1.2.0', details: { bytesReceived: 110592, totalBytes: 245760, downloadSpeed: 12500 // bytes/sec } }; // Report to cloud mqtt.publish('$aws/things/device-id/jobs/job-id/update', JSON.stringify(updateStatus));
json{ "updateImage": { "file": "firmware-v1.2.0-signed.bin", "size": 245760, "hash": "sha256:3b9d8a2f...", "version": "1.2.0", "signed": true, "encrypted": false }, "deltaPatches": [ { "fromVersion": "1.1.0", "file": "patches/v1.1.0-to-v1.2.0.patch", "size": 12340, "savings": "95%" } ], "manifest": { "file": "manifest.json", "timestamp": "2026-01-24T10:30:00Z" }, "deployment": { "platform": "aws-iot", "jobId": "firmware-update-v1.2.0", "targetDevices": 1500 }, "artifacts": [ "firmware-v1.2.0-signed.bin", "manifest.json", "patches/v1.1.0-to-v1.2.0.patch" ] }
Compatible MCP servers:
| Server | Purpose | |--------|---------| | tinymcp | Device control via Golioth | | esp-rainmaker-mcp | ESP32 RainMaker integration | | aws-iot-mcp | AWS IoT Jobs management |
ota-firmware-update.js - OTA implementation processsecure-boot-implementation.js - Secure boot setupbootloader-implementation.js - Bootloader development| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 23,359 | 17,801 | -24% | 1 | 1 | 0% | 3,960 | 6,566 | +66% | 0 | 0 | — |
case-02 | fail→pass | 20,624 | 15,123 | -27% | 1 | 1 | 0% | 3,065 | 5,872 | +92% | 0 | 0 | — |
case-03 | fail→pass | 24,370 | 17,255 | -29% | 1 | 1 | 0% | 4,321 | 6,396 | +48% | 0 | 0 | — |
case-04 | fail→fail | 12,846 | 16,767 | +31% | 1 | 1 | 0% | 1,853 | 5,956 | +221% | 0 | 0 | — |
case-05 | fail→fail | 9,969 | 9,382 | -6% | 1 | 1 | 0% | 1,525 | 4,820 | +216% | 0 | 0 | — |
case-06 | pass→pass | 8,055 | 6,000 | -26% | 1 | 1 | 0% | 1,618 | 4,435 | +174% | 0 | 0 | — |
case-07 | fail→fail | 19,804 | 23,430 | +18% | 1 | 1 | 0% | 3,050 | 7,194 | +136% | 0 | 0 | — |
case-08 | fail→fail | 9,654 | 18,101 | +87% | 1 | 1 | 0% | 1,916 | 6,228 | +225% | 0 | 0 | — |
case-09 | fail→fail | 29,412 | 33,377 | +13% | 1 | 1 | 0% | 4,889 | 10,398 | +113% | 0 | 0 | — |
case-10 | fail→fail | 13,549 | 21,633 | +60% | 1 | 1 | 0% | 2,552 | 6,845 | +168% | 0 | 0 | — |
case-11 | fail→fail | 10,263 | 11,752 | +15% | 1 | 1 | 0% | 1,666 | 5,257 | +216% | 0 | 0 | — |
case-12 | fail→pass | 6,806 | 9,393 | +38% | 1 | 1 | 0% | 1,342 | 4,828 | +260% | 0 | 0 | — |
case-13 | fail→pass | 11,977 | 12,065 | +1% | 1 | 1 | 0% | 1,959 | 5,119 | +161% | 0 | 0 | — |
case-14 | fail→fail | 15,416 | 11,778 | -24% | 1 | 1 | 0% | 2,280 | 5,539 | +143% | 0 | 0 | — |
case-15 | fail→fail | 11,635 | 9,257 | -20% | 1 | 1 | 0% | 1,722 | 4,800 | +179% | 0 | 0 | — |
case-16 | fail→fail | 10,057 | 5,379 | -47% | 1 | 1 | 0% | 1,787 | 4,158 | +133% | 0 | 0 | — |
case-17 | fail→pass | 17,058 | 10,385 | -39% | 1 | 1 | 0% | 2,868 | 5,092 | +78% | 0 | 0 | — |
case-18 | fail→fail | 10,661 | 14,455 | +36% | 1 | 1 | 0% | 1,968 | 5,468 | +178% | 0 | 0 | — |
case-19 | pass→pass | 14,552 | 12,249 | -16% | 1 | 1 | 0% | 2,193 | 5,191 | +137% | 0 | 0 | — |
case-20 | pass→pass | 42,410 | 35,705 | -16% | 1 | 1 | 0% | 7,108 | 11,593 | +63% | 0 | 0 | — |
case-21 | pass→pass | 27,245 | 24,334 | -11% | 1 | 1 | 0% | 4,014 | 8,124 | +102% | 0 | 0 | — |
case-22 | pass→pass | 21,937 | 27,879 | +27% | 1 | 1 | 0% | 4,481 | 7,790 | +74% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.