This is Part 2 of a two-part series on how to create a SDK. In Part 1, I gave an overview of the benefits and the design principles of SDK. Here, I will discuss SDK design considerations, including architecture and file structure. I will also discuss the SDK development and distribution process using an example.
Architecture
Before creating the SDK, the architect should consider the following:
- What platforms will the SDK run on?
- What is the runtime model?
- What are the major components?
- What are the target applications?
SDK should have a Platform Layer, the foundation on which the SDK builds on. The platforms could be hardware, software or both, and they may change. For example, a SDK built for the ARM core may need to be ported to a MIPS core; a SDK that runs on PS3 maybe ported to Xbox. To facilitate porting, all platform-specific components should be contained within the Platform Layer. A hardware abstraction layer (HAL) is an example of Platform Layer that contain the drivers for the hardware peripherals. Figure 1 is an example of HAL that contains I2C, ADC, timer, DMA and Flash drivers. The Platform Layer components should export a set of application programming interfaces (API) consistent across different platforms. Having a consistent API will make platform porting a trivial exercise. For C implementation, macros are often used as “shims”, such that the actual APIs behind the macros can be replaced without impacting the caller.
SDK should have a Platform Layer…
For SDK components to work in harmony at runtime, they must adhere to policies governing their interactions. The Framework Layer defines the runtime interactions. Examples of framework components include real-time operating system (RTOS), inter-process communication (IPC) library, and C Runtime library (CRT). The RTOS, for instance, enforces task scheduling policy, and presents a set of API to wait on semaphores, adjust priorities, start and terminate tasks. The IPC enables tasks to signal each other with thread-safe protection. The CRT provides ubiquitous utility functions. The framework layer generally has some platform dependency, such as hardware interrupt, timer and memory management.
The Framework Layer defines the runtime interaction policies
Most data-in, data-out processing modules should be placed in the Component Layer. These are often the components that contain the priced IPs. For the robot controller example of Figure 1, the Component Layer contains a protocol stack for communication, a kinematics library for geometric computation, and a vision library for image processing and scene analysis. These algorithms are likely the competitive differentiators for the robot maker and must be protected. Being data-in, data-out, the Component Layer is the most portable layer, because it is platform agnostic.
The Component Layer is the most portable layer …
As discussed in Part 1, SDK is like a software LEGO set, and is not the end product by itself. Developers using the SDK must combine the SDK with their contribution to create the end product. The Project Layer contains the user code, which defines the unique personality of the application. Putting the user code in a separate layer isolates it from the SDK for mutual IP protection. This separation also helps to preserve the quality heritage of SDK.
The Project Layer holds the code that defines the unique personality of the application
File Structure
The SDK file structure should consider the following:
- System architecture
- Source visibility
- Release extraction
- Version control
In this section I offer an example file structure implementing a robot controller, whose architecture is shown in Figure 1. The architecture has multiple layers for portability, change isolation and IP protection. The file structure should work in tandem with the system architecture to realize these purposes.
The file structure for the Figure 1 architecture is shown in Figure 2. The top level directories include documentation, source code, include files, libraries, project-specific files and tools. The src
directory is subdivided into framework
, component
and platform
, each matching their corresponding layer in Figure 1. Source code files contributed by the users to implement a specific project are kept under the proj
directory. This is necessary to create the IP separation discussed earlier.
To protect the IP, the src
directory is not extracted for distribution. Instead, the src
directory is compiled into one or more libraries placed in the lib
directory. The proj
directory, on the other hand, is always distributed in source code form, and initially may contain example code that illustrates how to use the SDK to build a working end product. The SDK users should place their contribution under the proj
directory.
The file structure also plays a part in version control strategy. As discuss earlier, SDK’s modular architecture enables each component to have its own quality heritage. Field-proven components do not need retest if left untouched. New components, however, may have multiple revisions before reaching a stable quality level. Therefore, each component should have its own directory to hold the implementation files; this will make component-level version control easier.
Development Process
In my experience, the SDK development process can be divided into four phases:
- Scaffolding Phase
- Building Phase
- Integration Phase
- Quality Phase
The scaffolding phase is when the system architecture, framework and file structure are decided. It’s called scaffolding because the activity is analogous to erecting the frames of a building before the walls, rooms and other facilities are added. At the end of this phase, a “hollow” runtime environment should be implemented, with the components defined and API stubbed, but not yet implemented. The file structure should be laid out.
The building phase is when the development forks into several parallel activities. Potentially, each layer will have its own development branch, and each component under it has a sub-branch. Well-designed file structure will align the directory structure with the branch structure, allowing mixing of components with independent version history.
The integration phase begins when the components are merged back to the main branch for integration. The integration usually starts with the Platform Layer components and gradually builds up to other layers. The order of integration matters, as the goal is to progressively add new functionality while maintaining testability, start from the foundation and up.
The quality phase begins when the SDK is fully integrated. One or more example end applications should be included in the proj
directory to help verify the SDK. The end applications should be sufficiently complete to reflect typical target applications. The quality phase involves several quality stages, and they are described in detail in my article, Quality Speaking.
Distribution
Depending on the license agreement, different components are included in the distribution package. This requires extraction. The license agreement, including any Open Source licenses, should be included, along with the SDK distribution, release notes and known-issue list. Some SDKs use the “click-wrap” license method, where the acceptance of End-User License Agreement (EULA) is required step of the installation process. Prior to distribution, export control compliance must be verified. Export control regulates external transfer of technologies, especially to countries under export restriction. The physical packaging of the SDK can be done with an installer tool, such as the Windows Installer, rpm
or apt
. In some cases, a simple ZIP file is reasonable if IP protection is not an issue.
Summary
SDKs are used by many, but less known is how the SDKs are created. In this two-part series, I shared my experience in SDK creation using a robot controller SDK as an example. The Part 1 of this article discussed the benefits and key design principles of SDK. In Part 2, I elaborated the thought process behind the SDK design, including considerations for architecture, file structure, development process and distribution. I hope this two-part series will help the readers in their own SDK development.
Further Reading:
- Three Rules of SDK Design
- SDK Fundamentals – (telecommunication)
- Export Control Basics
- Software Licenses
- 10 Commandment of Software Packaging
- Windows Installer
- Advanced Packaging Tool (APT)
- RPM Package Manager (RPM)
(The above article is solely the expressed opinion of the author and does not necessarily reflect the position of his current and past employers)
Thanks for sharing, It is very informative and presented in a very good and understandable way.