If you’ve ever tried to validate embedded behavior in a virtual environment, you know the pain: you can observe what the system does, but the moment you need to interact with it—drive a pin high, simulate a button press, flick an LED on and off—you’re suddenly deep in custom tooling, rewrites, and one-off scripts.
That’s exactly where I started in a recent customer engagement bringing up their system in Corellium Atlas.
CoreModel is the set of interfaces which we use to virtualize peripherals. We already provide a coremodel-gpio example that could monitor GPIO pins. Great for visibility. Not enough for real testing. I needed true bidirectional GPIO control—the kind that lets you build realistic scenarios, poke the SoC like real hardware would, and keep iterating without restarting your app.
I used Kiro’s spec-driven development flow to go from a rough idea to production-quality C code fast.
Here’s what that journey looked like—and why it changed the way I build low-level tooling.
CoreModel is a C API library for remote peripheral interaction in Corellium virtual machines. It’s powerful, lean, and designed for serious systems work. But the GPIO example was limited to read-only behavior.
For my use case, that wasn’t just inconvenient—it was a blocker.
I needed to:
That meant writing a new example that fit CoreModel’s patterns, used its select-based event loop correctly, and handling errors accordingly.
Traditional path:
I needed to accelerate the development of the working solution to quickly hit a timeline for when it would be implemented. I couldn’t sift through every single line of code just figure out how to connect the pieces of the API together.
Instead, I used Kiro’s spec feature.
Specs allowed me to move quickly through the problem in order:
That structured approach enabled me to be able to focus on delivery of a working solution faster than reading documentation and reviewing my code line by line.
I had Kiro write a requirements spec that included:
Kiro made these into clean, testable requirements. The biggest win wasn’t documentation—it was momentum. With these specific requirements, implementation became an easier direct task.
With requirements done, Kiro guided a design doc that mapped cleanly to CoreModel’s structure:
The doc included ASCII diagrams and function signatures, so when coding began, Kiro could easily follow the blueprint it created.
Then Kiro generated an implementation plan:
8 major tasks → 18 subtasks
Each tied back to requirements.
With the tasks created, it was easy to follow the logic that Kiro used to build the code for the solution. It was clear what Kiro was working on and building on top of.
Once the tasks existed, the coding phase was the easiest part of the process.
The CLI had to support hybrid input/output configs like:
./coremodel-gpio-rw 10.10.0.3:1900 gpio1 0 1=3300 2 3=1800
Meaning:
Kiro helped me implement robust parsing with strict validation and clear user errors without having to worry about cumbersome argument handling.
CoreModel uses select() for its event loop. I needed to extend it without breaking established flow.
The custom loop:
This was a subtle integration point—and the spec made it predictable.
The CLI supports:
Every command validates pin range, voltage bounds, and current state. Feedback is instant. The tool feels like a lab instrument, not a dev hack.
Misconfigured pins, attachment failures, API errors, malloc failures—everything emits a meaningful error and cleans up correctly.
The initial spec and acceptance criteria emphasized quality to ensure it was a production ready tool that could be used out of the box.
The final implementation is ~550 lines of clean, documented C that:
Kiro was able to produce a usable peripheral-control harness with some debugging afterwards.
LED control
./coremodel-gpio-rw 10.10.0.3:1900 gpio1 5=3300
> set 5 0
> set 5 3300
Button monitoring
./coremodel-gpio-rw 10.10.0.3:1900 gpio1 10
# GPIO[gpio1:10] = 3300 mV when pressed
Bidirectional interaction
./coremodel-gpio-rw 10.10.0.3:1900 gpio1 0=3300 1
> set 0 0
> set 0 3300
# watch pin 1 respond
This is the kind of control you need for real firmware workflows—not just “logging.”
I always knew:
Kiro progressed through the tasks because it had laid the groundwork with well thought out requirements and implementation plan.
Because Kiro had context from:
Its suggestions were native to the project, not generic boilerplate like an LLM that you copy and paste into or have an integrated co-pilot with.
18 subtasks meant Kiro always had a “next step” small enough to finish, but valuable enough to feel real progress.
Doc requirements, edge cases, and graceful shutdown weren’t afterthoughts—they were tasks.
Spec-driven development flips the order of work and steering docs keep Kiro in line with your style:
Old way: (multiple days to weeks)
code → discover gaps → redesign → refactor → ship eventually
Kiro way: (3hrs)
requirements → design → tasks → code → ship confidently
The spec becomes living documentation and a map for future maintainers. It explains the “what,” the “how,” and the “why” in one place.
The new example lives here:
cd coremodel/examples/gpio-rw
make
./coremodel-gpio-rw <vm-address> <gpio-bank> <pin-specs>
If you’re working with Corellium Atlas virtual hardware and want real GPIO control, it’s ready. And if you’re building complex features—especially in low-level code—try Kiro IDE. It’s not “extra process.” It’s a faster path to correct, shippable, production ready software. Take a task that would have taken a team months, and finish it in hours with Kiro. From requirement to code to documentation.
When it comes to mobile security testing, Corellium is the clear choice to stay ahead of the curve. See all the Corellium platform features.
Ready to transform your mobile penetration testing workflow? Explore Corellium today and experience the future of iOS security testing. Meet with our team to learn more.