Linux C++ drivers
C++ drivers are compiled into the instrument server. Public member functions become commands callable from Python and TypeScript.
Add a driver to an instrument
List driver files in config.mk:
DRIVERS += $(PROJECT_PATH)/fft.hpp
DRIVERS += $(PROJECT_PATH)/fft.cpp
Board-level drivers can be included from a board make fragment:
include $(SDK_PATH)/boards/alpha250/drivers/drivers.mk
Build only the server while developing C++ code:
make -j CFG=examples/alpha250/fft/config.mk server
Include runtime and memory headers
A driver can include the runtime driver manager and generated memory access headers:
#include "server/runtime/driver_manager.hpp"
#include "server/hardware/memory_manager.hpp"
Board drivers may be included as needed:
#include "boards/alpha250/drivers/clock-generator.hpp"
#include "boards/alpha250/drivers/power-monitor.hpp"
Minimal driver skeleton
#include "server/runtime/driver_manager.hpp"
#include "server/hardware/memory_manager.hpp"
#include <cstdint>
class MyInstrument
{
public:
MyInstrument()
: ctl(hw::get_memory<mem::control>())
, sts(hw::get_memory<mem::status>())
{}
void set_output(uint32_t value) {
ctl.write<reg::digital_outputs>(value);
}
uint32_t get_input() {
return sts.read<reg::digital_inputs>();
}
private:
hw::Memory<mem::control>& ctl;
hw::Memory<mem::status>& sts;
};
The exact mem::... and reg::... identifiers come from memory.yml.
Memory access flow
A memory region declared in memory.yml:
memory:
- name: control
offset: 0x4000_0000
range: 4K
registers:
- digital_outputs
generates C++ identifiers such as mem::control and reg::digital_outputs.
Reuse another driver
Drivers can access other drivers through the runtime driver manager:
auto& power = rt::get_driver<PowerMonitor>();
auto supplies = power.get_supplies_ui();
Command API design
Public driver methods are exported in generated driver metadata. During the server build, the SDK generates C++ dispatch headers under tmp/<project>/server/, builds a metadata dumper, and writes tmp/<project>/server/drivers.json; the instrument ZIP packages that file as drivers.json.
Clients use this metadata to map class and function names to command IDs.
Examples of exported methods:
void set_input_channel(uint32_t channel);
uint32_t get_fft_size() const;
std::array<int32_t, prm::n_adc> get_adc_raw_data(uint32_t n_avg);
auto get_control_parameters();
Use fixed-width integer types such as uint32_t where possible to avoid ambiguity in the client protocol.
Return types
Clients support common scalar types such as integers, floating-point values and booleans. They also support arrays, vectors, tuples and strings when the C++ return type is exposed in the generated command metadata.