As the processing capability of embedded systems increases, design software plays an increasingly important role in the productivity of the design engineer and, ultimately, the success of the end product. When a design engineer has effective development tools at his disposal and can easily reuse previously developed software – even if developed on different processor architectures- he/she is well-positioned to achieve faster time to market. Integrated development environments (IDEs) have evolved to include productivity-enhancing resources such as software frameworks that minimize much of the low-level coding in a design, freeing the engineer to focus on design differentiation.
How software frameworks address design complexity
Figure 1: Context-aware code editing in Atmel Studio 6.
Microcontroller (MCU) vendors have continued integrating more functions into their platforms, bringing greater complexity to the design process. Additionally, moving to a new MCU could require downloading new support code archives and documentation, and learning new application programming interfaces (APIs). At the same time, the market environment demands rapid scaling as well as the ability to tune offerings to react swiftly to changing market requirements. Faced with these pressures, embedded developers are realizing that increasing their code reuse is the most pragmatic way to achieve higher levels of productivity. Embedded development teams can now find their solution in a comprehensive platform-independent software framework.
An example of this approach is the Atmel Software Framework (ASF), which is integrated into the new Atmel Studio 6 IDE. The ASF facilitates a top-down design approach to embedded systems development that fully leverages the accumulated IP and expertise of the organization by avoiding the requirement to rewrite significant portions of the code for each port to a different MCU variant or architecture.
Supports design portability across different MCUs
Figure 2. Example of a software framework – Atmel Software Framework architectural design.
ASF has been architected from the ground-up to provide a clean interface between user application code and the software stacks that enable the application to run on a variety of different embedded target MCUs. The production-ready ASF provides everything required between the application and the hardware design. The functions and code examples that use them are all optimized for code size for each target architecture and work with a range of ANSI-C compilers. The ASF code is also architecture-optimized by Atmel experts, ensuring not just high performance but low power. The functions take full advantage of Atmel MCU features such as low-power modes and the Peripheral Event System.
Chip-specific features in the protocol stacks and functions are used in a way that maximizes portability for application-level code. But the functions are implemented using a common API that abstracts away the target-specific details, allowing developers to take code developed on one Atmel device and compile it for a new Atmel target, practically unchanged.
For example, the API uses an intuitive format in which devices are programmed using function calls that follow a consistent naming convention: <device>_init(); <device>_enable(); <device>_disable(); <device>_start(); <device>_stop(); <device>_read(); <device>_write(); etc.Efficiency in application code
ASF modules are arranged in a layered architecture that allows application code to call functions that are most appropriate to the task at hand. This architecture also makes it easy to add support for complex protocols, such as USB, to a product. There are four types of layers: component, service, peripheral and board.
The component and service modules are called directly by the application, unless it needs direct access to low-level device functions provided by the peripheral and board layers. The service layer provides the user with application-oriented software stacks such as USB class drivers, file systems, architecture-optimized digital signal processing functions and graphics libraries. This layer also takes advantage of the MCU's hardware features. Components are high-level drivers that provide intuitive and direct control over MCU and board-level peripherals, such as display, sensors and wireless interfaces. The code in the component layer is written with a focus on providing the functionality that a typical user will need in each of the on-chip peripherals. If the application calls for a peripheral to operate in a way that is not directly supported by the component layer, it is easy for the user to modify the existing source code, or add an extra function to the API.
The component and service modules communicate with low-level drivers in the peripheral layer that provide register-level control over hardware interfaces. Applications can also call these drivers directly to facilitate tight hardware integration in a way that maximizes portability between members of the Atmel MCU portfolio.