| Episodes | 65 |
| Mentions | 87 |
| Cited here | 46 |
| First — last | #8 — #722 |
| Top guests | Michael, Matt Richardson, Omer Kilic |
| Related | digi key · bluetooth · internet of things · arduino · linux |
An application programming interface (API) is the defined boundary through which one piece of software or hardware exposes its functions to another: a component distributor’s part database queried by design software,[8][411] a driver that presents several physical devices as one set of calls,[101] or a web endpoint that triggers a manufacturing order without a human placing the request.[315] In electronic systems, APIs appear at every level of the stack, from register access inside an FPGA fabric to cloud services behind connected products, and their structure, documentation and stability determine how easily systems can be integrated, ported and maintained.[375][235][221]
Layering and hardware abstraction
A recurring pattern is a single API that hides device-specific detail behind a common interface. Ettus Research publishes one driver, the USRP Hardware Driver (UHD), and exposes one API to all users; the LabVIEW drivers written with National Instruments, the MathWorks MATLAB and Simulink drivers, and GNU Radio all build on that same API rather than talking to the hardware directly.[101] Because the API is common across the product family, application code does not change when the user moves between devices; the vendor absorbs device-specific handling inside the driver.[101]
The same layering appears at smaller scales. The I2Cdev library is structured as a base class that performs raw I2C transfers of a bit, a byte or a string of bytes in a single call, with per-device classes layered on top; the device class for a part such as the MPU-6050 does the register-level work so the application receives orientation data directly in a chosen format.[155] A BeagleBone motion-control stack presented a stepper element with a move-to-position or move-by-increment call and isolated the PRU-specific code behind a hardware abstraction layer, so the same interface could be carried to other boards.[378]
Zephyr formalises the pattern as a class API. A device driver is written by populating a predefined struct for its device class with the required function pointers, such as initialisation, write and clear for a real-time clock; the application then obtains the device by name through the device tree and calls it as a generic device.[509] Where the framework has no class API matching a part exactly, the practical route is to implement the part against the nearest existing class API, as a real-time clock chip was implemented against Zephyr’s timer API.[509] Because drivers conform to the class API, substituting a different part of the same class means writing a new driver against the same struct and changing a project configuration entry, with application code untouched.[509]
CircuitPython achieves chip-to-chip uniformity by factoring the C code that implements its Python-visible API out of the individual hardware ports into one shared implementation, which then calls down into port-specific C; the objects exposed to Python are C structs.[383] MicroPython, by contrast, offers no guarantee that a script written against one port runs on another, so code written for an ESP8266 will not necessarily work on an STM32; portability has to be engineered into the API layer rather than assumed from a shared language.[383] In LiteX-based FPGA designs, a host bridge lets Python scripts on a PC read and write the Wishbone registers of peripherals instantiated inside the FPGA, and with MicroPython running on a soft core the same scripts run on-chip unchanged, because the register API is identical and only the transport differs.[375]
An API can also conceal the implementation technology entirely. An FFT implemented in an embedded FPGA fabric was delivered to the customer as a bitstream plus a C API, so their software engineers called it as an ordinary function without knowing it ran in hardware; the benefit surfaced only as freed CPU cycles and memory, since the multiply-accumulate load moved off the processor.[525] Nordic’s Bluetooth stack ships as a precompiled binary, the soft device, occupying a reserved region at the bottom of flash and a reserved portion of RAM and reached only through a fixed API; the bootloader sits at the top of memory, and both regions must be placed in protected memory so application code cannot corrupt them.[516] A certified wireless module ships with a vendor-supplied API, often no more than AT commands, which transfers responsibility for the radio’s correctness and field testing to the module supplier; a wired link such as RS-485 has no equivalent pre-certified building block, so the integrator retains that testing work, which can make wireless the easier path to a reliable integration.[443]
Documentation
Interface documentation is part of the interface: a well-documented API, whether on a web service or on a hardware component, is a selection criterion in its own right because it determines how quickly an integrator can get working without reinventing existing functionality.[235] An API reference that lists public functions without describing their behaviour leaves the porting engineer to discover the constraints by experiment: on the early ESP32 the documentation did not say which calls were safe from an interrupt or under the RTOS, which made porting into a multi-core, RTOS-based part substantially harder than the Arduino-level documentation suggested.[438] Board bring-up documentation is usefully treated as an API for the hardware, stating for each pin what software may do with it and in which direction; inferring direction from net names is unreliable, since a net named with “out” may be an output of the peripheral and therefore an input to the processor.[373]
Versioning and breaking change
The Arduino 1.0 release changed the core API, and a substantial body of existing third-party sketches and libraries would no longer compile against it.[80] Where an ecosystem’s principal asset is its accumulated body of example code, a breaking API change devalues that asset even when the per-file fix is trivial: a beginner following an old example gets a compile failure reported as cryptic C++ errors rather than a statement that the code targets an older API.[80]
Downstream products inherit the upstream supplier’s freedom to change. A product built on a third party’s connectivity service inherits that supplier’s freedom to change its API or to be acquired by an owner with different intentions, and either event propagates to every unit already in the field.[221] When a cloud service revises its API, shipped appliances that embed a client for it lose the function until their firmware is updated, as when a networked refrigerator could no longer sign in to a calendar service.[278] Features of EDA tools that call distributor web APIs stop working in older tool releases once the distributors change those APIs; Altium’s supplier search and manufacturing-parameter lookup broke in older versions for that reason, which removes staying on a known version as a strategy for avoiding an unfamiliar user interface.[523]
Compatibility can be preserved deliberately. Backwards compatibility across an instrument generation was preserved on the Joulescope JS220 by shipping an adapter layer that presents the previous product’s API on top of the new driver, so existing user scripts and the existing application keep working against new hardware while the new API is taken up incrementally.[607]
Component data and the supply chain
Before programmatic pricing, component quoting was done by emailing spreadsheets to several distributors, comparing the returned prices line by line, and splitting the bill of materials across suppliers where the saving justified the extra purchase orders; the work queued behind whatever one person could process in a day.[411] Instant assembly quoting from uploaded native EDA files became possible only once component price, location and stock could be queried programmatically; Octopart’s API supplied that layer at the time services such as CircuitHub were being built.[411] Component distributors opened programmatic access to their part databases because EDA tool vendors were building parametric search and pricing into design software and needed to query that data directly; a distributor that kept its database closed risked being routed around.[8]
Aggregators sit between the data sources and the tools. Upverter assembled its component data from several sources at once: Octopart’s API, described as the best publicly available API data, supplemented by direct feeds negotiated with distributors including DigiKey, Arrow, Newark and Mouser, and by direct arrangements with semiconductor vendors including TI and Freescale.[163] Dependence on an upstream data provider bounds the downstream tool: a CAD tool whose component library is backed by the Octopart API could not create a part that did not already exist in that upstream database, so the tool’s part coverage was bounded by the data provider’s coverage.[219] PartsBox, a web-based personal parts inventory, pulls component data from distributor APIs so a physical drawer of stock can be searched by specification, by what was paid for it and by remaining quantity, replacing hand-written part numbers on drawer labels.[405]
Access is neither uniform nor guaranteed. Some semiconductor and connector manufacturers publish their specification data through APIs, but many cannot, because growth by acquisition left the data unconsolidated; for those companies, exposing an API is preceded by multi-year internal projects to get the data into a structured form at all.[531] Distributor API access is tiered: DigiKey, Mouser and TI grant different levels of access depending on the account and the customer’s standing, so an ERP integration reaches each one to a different depth.[722] An API advertised as supporting a workflow may not deliver it in practice: a TI backlog account was taken partly to place orders through the vendor’s API, but the ERP integration could not be made to work and was not supported, leaving a semi-manual upload path as the working method.[722]
Supplier catalogue APIs allow live price and lead-time data to be presented at the moment of part selection, so the design engineer sees availability constraints while choosing rather than learning of them from procurement weeks or months later, after the design decision has been made and the context lost.[577] Distributor APIs also let a BOM management system raise obsolescence and lead-time alerts against parts already in a design, and then carry the substitution back through the CAD integration into an automatically populated change order.[577]
Manufacturing and production test
MacroFab built each capability of its manufacturing service as an API first and layered the user interface on top of it, with the work split across a microservice backend; on that division the user interface accounted for a small share of development effort compared with the models and controllers behind it.[243] The service exposes an API endpoint for every function of its web application, so a customer’s own web store can trigger fulfilment of an order against inventory held at the contract manufacturer without a human placing the build request.[315]
The absence of an API is itself a constraint. Production programming and test tools frequently expose only a GUI and no API, so a factory cannot wrap them in a simplified operator interface; the operator wants a single go button with a green or red result, not a panel of a hundred and fifty controls that can be set wrongly.[461] Conversely, exposing test hardware through an API does not remove the labour of using it: a skilled engineer still has to write the automated test against that API and wire it into the build pipeline that runs on code check-in, which keeps such a business engineering-services heavy rather than volume-hardware heavy.[369]
APIs also serve as the seam between enterprise systems. A hardware revision-control service integrates with PLM systems from outside by querying their APIs and using the component information already carried in the CAD design as the link between the two, since PLM systems draw on that same design data.[505] Machine-control software can present one API across pick-and-place machines of different capability, with the per-machine configuration acting as a shim that adapts the differing control interfaces underneath; once a machine is tuned, the operator works against the abstraction rather than the machine.[686]
Connected products and services
Google’s Android Development Kit, announced at Google I/O in 2011, defined an API for an Android phone to talk over USB, with Bluetooth planned later, to an attached Arduino-class board, positioning the phone as the display and control surface for external hardware.[43] Pebble exposed the watch’s Bluetooth connection state to third-party application developers through its SDK, so an app could report to the user whether the watch was still in range of the phone.[175] On the castAR programme, the plan was not to conceal the LED modulation scheme used for tracking and to ship APIs and a prototyping system alongside the product, so that third parties could build their own tracked objects and applications, including uses outside gaming such as surgical simulators and teaching aids.[147]
Home automation integration is per-device work: each bulb or appliance is commissioned separately and exposes its own API, so third-party software in that space exists largely to bind those separate APIs together in the absence of a common standard.[291] Appliance manufacturers including GE, Samsung and Belkin published device APIs into the IFTTT service, making a third-party aggregator the practical integration point for conditional automation between products from different vendors; the result is a common service rather than a standard.[324] Automation services such as IFTTT and Zapier are graphical front ends over vendor APIs; writing directly against those APIs instead removes the intermediary but transfers the maintenance burden, since the upstream API changes and the integration must be kept up to date.[389]
Cloud dependence carries operational risk. Cloud back ends behind device APIs fail more often than device makers expect, and the outage is not signalled to the operator, so every deployed unit can stop receiving data before anyone is aware of it.[272] Opening a device-level API on a mass-market product is in tension with being a viable consumer product: a small number of users exercise it productively while a larger number render units unusable.[295] The cost of an open device-level API is not the engineering but the support structure behind it; for a product installed in a wall, the RMA path itself is expensive, and a six-person team cannot carry that load.[295] On Omer Kilic’s connected-product programme, third-party integration was planned at the API level, preferably on the local network rather than through the cloud, instead of by shipping a C++ SDK, so that integrators would not be bound to one implementation language.[295]
In large LED installation work, Mike Harrison’s practice as controller supplier is to define the control API rather than accept the integrator’s, specifying the packet format and the send sequence and keeping the link one-way; with no return path there is no error handling to implement or to get wrong.[294] Consumer audio makers integrate with one of the three voice-assistant ecosystems — Google, Amazon or Apple — by implementing that vendor’s APIs on a platform layer inside their product, which leaves the audio hardware unchanged and treats the assistant service as a required input path.[560] Professional audio uses OCA, an open control protocol, to make device control interfaces self-describing across manufacturers: a controller from one vendor plugged into a loudspeaker from another discovers that the device has a named gain control and can select which stream it listens to, removing the need to integrate a separate control scheme per vendor.[560]
At the firmware level, a Wi-Fi sensor node spends multiple seconds waking, associating and transmitting before returning to sleep, which dominates its energy budget; on the ESP8266 that wake time was judged reducible to a half or a third by changing a few SDK APIs.[359] Zephyr provides per-subsystem shell commands, covering operations such as an I2C bus scan, sensor reads and GPIO toggles, that are compiled into the image by enabling a configuration symbol; nearly every subsystem has an associated shell.[696] Writing a custom backend for the device shell and carrying it over a cloud remote-procedure-call channel makes a fielded device’s local debug shell reachable from a browser over cellular, so GPIO toggles and serial readbacks can be performed remotely rather than requiring physical UART access.[696]
Interface design practice
Consolidating several near-identical implementations into reusable modules forces the interfaces between them to be defined explicitly; the design work is deciding what abstraction lets a module connect to any other module rather than to one specific counterpart.[522] Rather than inventing a hardware abstraction interface, Fredrik Kensander’s firmware team modelled its module interfaces on Zephyr’s existing abstraction so the modules would carry over if the project later moved to the RTOS, using an established framework as a reference to implement against instead of iterating on a home-grown interface.[522] The same team adopted the abstraction interface without taking the RTOS underneath it, because the firmware is built around fixed-rate interrupts — roughly 1 kHz, 100 Hz and 10 Hz service loops plus a 37 kHz interrupt in the power module that must always be serviced — and an RTOS offered no benefit against that constraint.[522]
Calling an existing upstream API is generally preferable to writing a driver, because upstream code has been tested and already exercised in shipped commercial products; the corresponding shift in higher-level frameworks is that a developer reads more code than they write, where bare-metal work is the reverse.[653] FreeRTOS presents a deliberately minimal API, so building on it is a bottom-up exercise in which the developer writes most of the code; the reading burden appears once third-party libraries are brought in and their APIs and gotchas have to be understood.[581] The Joulescope JS220 driver was rewritten in C around a publish-subscribe API specifically so it could be bound to several languages, with a Python binding shipped against that same interface.[607] Amazon Mechanical Turk’s API lets the requester set the price attached to each task, and that price sets the latency: roughly ten to fifteen minutes at ten cents a job, about ten minutes at twenty-five cents, and seconds at around two dollars.[235]