Integrating GMSL UDDF Drivers with SIPL#

This page explains how to make your GMSL UDDF drivers discoverable to the Safe Image Processing Library (SIPL). The integration mechanism is the same for all UDDF driver types: name matching between the DriverInfo.name exported by the driver library and specific fields in the SIPL JSON configuration.

For the general UDDF driver model, see Guide to Writing UDDF Drivers. For the CoE driver integration pattern, see Integrating UDDF Drivers with SIPL.

Driver Name Matching#

SIPL uses string comparison to connect driver libraries to JSON configuration entries. Each driver type is referenced from a different JSON field:

Driver Type

JSON Field

JSON File

Deserializer

transportSettings.deserInfo.name

Platform transport settings

Deserializer power

powerControlInfo.deserializerInfo.name

Platform transport settings

Module power

powerControlInfo.moduleInfo.name

Platform transport settings

Camera module drivers and serializer sub-components are not referenced by name in the transport settings. Instead, SIPL creates the module driver instance using the name from the camera module config file (cameraModules[].name), which must match a DriverInfo.name in one of the loaded driver libraries.

All name comparisons are case-sensitive.

Example: Deserializer Driver#

Driver library code:

static const uddf::ddi::DriverInfo g_deserInfo = {
    .name        = "Max96724GmslDeserializer",  // ← This name is the key
    .description = "MAX96724 GMSL2 Deserializer",
    .vendor      = "NVIDIA Corporation",
    .revision    = "1.0.0",
};

Matching transport settings JSON:

{
    "transportSettings": [
        {
            "type": "GMSL",
            "deserInfo": {
                "name": "Max96724GmslDeserializer",  // ← Must match DriverInfo.name
                "i2cAddress": "0x27"
            }
        }
    ]
}

Example: Power Drivers#

Driver library code:

static const uddf::ddi::DriverInfo g_deserPwrInfo = {
    .name = "TegraDeserPowerDriver",   // ← Deserializer power driver name
    ...
};

static const uddf::ddi::DriverInfo g_modulePwrInfo = {
    .name = "MAX20087",                // ← Module power driver name
    ...
};

Matching transport settings JSON:

{
    "powerControlInfo": {
        "deserializerInfo": {
            "name": "TegraDeserPowerDriver",  // ← Must match DriverInfo.name
            "gpioPinIndex": 7
        },
        "moduleInfo": {
            "name": "MAX20087",               // ← Must match DriverInfo.name
            "i2cAddress": "0x29"
        }
    }
}

Example: Camera Module Driver#

The camera module driver name is matched via the camera module config file, not directly from the transport settings. The cameraModules[].name field in the platform config selects a module config record, and the module config "name" must in turn match a DriverInfo.name in the loaded driver libraries.

Driver library code:

static const uddf::ddi::DriverInfo g_moduleInfo = {
    .name = "C2SIM623S2RU1195NB20",  // ← Module driver name
    ...
};

Matching platform config JSON:

{
    "cameraModules": [
        {
            "linkIndex": 0,
            "name": "C2SIM623S2RU1195NB20"  // ← Must match DriverInfo.name
        }
    ]
}

Important

All driver names are case-sensitive. A mismatch results in SIPL failing to find the driver at startup, with an error message in the runtime log that includes the unresolved name.

Driver Library Entry Point#

Every GMSL driver library must export uddf_discover_drivers() with C linkage. The function returns an IDriverEnumerator that describes all drivers in the library.

A single library may expose any combination of driver types. The sample library in uddf/samples/libraries/gmsl/SampleGmslLibrary.cpp packages all four types (deserializer, module, deserializer power, module power) in one library:

extern "C" {
    uddf::ddi::DriverEnumeratorPtr uddf_discover_drivers() {
        return std::make_unique<SampleGmslLibraryEnumerator>();
    }
}

For the full IDriverEnumerator implementation pattern, see Guide to Writing GMSL UDDF Drivers.

Installation Path#

SIPL automatically discovers driver libraries from the following standard path:

/usr/lib/nvsipl_drv

Install your compiled GMSL driver shared library to this directory. SIPL scans all .so files in this directory at startup, calls uddf_discover_drivers() on each, and builds an internal registry of available drivers.

Configure your build system to install the compiled library to this path:

CMake:

install(TARGETS my_gmsl_driver_lib
        DESTINATION /usr/lib/nvsipl_drv)

Makefile:

install: my_gmsl_driver_lib.so
    install -m 0644 $< /usr/lib/nvsipl_drv/

Multiple Driver Libraries#

Multiple driver libraries can coexist in /usr/lib/nvsipl_drv. SIPL loads all of them and merges their driver registries. There is no conflict as long as no two drivers export the same DriverInfo.name for the same driver type.

It is valid to split your drivers across libraries. For example, you might ship one library with the deserializer driver (provided by the chip vendor) and a separate library with your camera module driver. As long as the names in both libraries match the JSON configuration, SIPL will assemble the complete camera pipeline correctly.

Verification#

To verify that your drivers are loaded correctly:

  1. Set the SIPL log level to INFO or DEBUG before starting your application.

  2. Check the startup log for messages confirming that each driver library was loaded and each driver name was matched to a JSON configuration entry.

  3. If a driver is not found, the log will include the unresolved DriverInfo.name. Cross- reference it against the JSON field value and check for case differences or typos.

  4. Confirm that the library is in /usr/lib/nvsipl_drv and is readable by the process.

  5. Use ldd to verify that all shared library dependencies of your driver library are resolved on the target system.