Modeling C applications in UML with files and structures
As DSP applications become more complex, the benefits of modeling the applications increase. While implementing models in an object-oriented language is easier, C developers can implement their models using either object-oriented or functional techniques.
Code is intrinsically complex, and Digital Signal Processor (DSP) code is even more convoluted because of the environment its code is executed in. DSP code interacts directly with hardware, has real-time constraints coupled with size, and memory limits - which makes designing, reviewing, and reusing DSP code a challenge.
Fortunately, modeling technologies such as the Unified Modeling Language (UML) help software engineers understand applications by clearly showing structure and behavior; unfortunately, many DSP developers believe that they cannot use UML to design their applications. The basis for this belief is that UML is designed for object-oriented appli-cations, and C code does not support object-oriented approaches. In actuality, using a functional UML approach is natural to C programmers, and modeling C applications in UML with files and structures is consistent with the way many seasoned C programmers design their applications today.
DSP application developers give many reasons why they cannot model their applications, and managers and developers need to weigh them against development costs and concerns. Companies invest heavily in the Intellectual Property (IP) that makes up these complex applications. These investments include not only development time, but testing, main-taining, and enhancing the IP, which are all areas where the abstraction and organizational benefits of a modeling process can be beneficial. While DSP development has unique historical reasons as to why they have not embraced modeling, the increase in power and complexity necessitates a new paradigm in DSP application development. Specifically, new DSP development challenges require a solution that will enable reuse (to overcome the fact that each chipset has a unique interface) and one that leverages increased DSP power, too.
The new paradigm that DSP developers are using is modeling the application using UML files, allowing them to work in the manner to which they are accustomed. Modeling reduces development time: it makes the design of the program's structure easier to understand, facilitates collaboration among team members, simplifies reuse, and allows testing to take place earlier in the development process.
Improving design and development
UML formalizes the graphics that DSP application developers already use. Engineers are visual people, and communicate using pictures. Long before there was a UML, engineers used graphics to design applications. Even developers unfamiliar with UML use flow charts, state machines, and sequence diagrams to design their DSP applications. Many use diagrams akin to UML object model diagrams that show the application's structure. Figure 1 shows a sample of a statechart diagram for a sensor controller.
UML object model diagrams show what functions each C file contains and the signatures of those functions. They also show the application's data structures. In one view, a developer sees both the data structures and the functions, without having to page through multiple code files. Even for small applications, this one advantage saves significant development time.
On many DSP projects, few people understand the entire scope. New team members require extensive mentoring and training before becoming productive - mentoring that takes the experienced developer away from developing the new application.
Using UML allows all team members to understand critical design concepts and the application's structure quickly. When team members understand the design beyond their own areas, they can collabo-rate on complex part designs. Design reviews can then concentrate on finding exception conditions and logic errors, not just coding standards violations.
Developers see the advantages of reusing existing designs and code, but they often cannot see what features exist in the current code base because they are buried in pages of text. By reverse engineering existing applications into a model, developers get a graphical representation of the existing code. This visualization helps them make informed decisions about which files should be included in a new model and which functionality they have to redevelop.
For new development, modeling helps the developers see generalized functionality that should be abstracted. For example, most DSP applications interact with hardware. By abstracting the interface to the hardware, the reusable IP does not change each time the hardware changes. Thus, the function enumStatus analogRead(unsigned int* theInput) has to be implemented for each version of hardware, but the reusable IP calls this the same function regardless which hardware the application uses.
Traditionally, DSP developers do not begin testing until the hardware becomes available, which usually happens late in the development cycle. Even with hardware, physical limitations of the environment (for example: temperatures or speed of events) limit the range that the application is tested. But by abstracting the IP from the hardware, developers can test IP thoroughly and earlier in the development cycle. If the modeling tool produces sequence diagrams as the code runs and animates statecharts during execution, testers can compare these model outputs directly to the test case designs, proving that they meet requirements. The net effect of improved testing on the DSP development process is a higher quality product that meets all of the customer's stated requirements.
Modeling function-based designs
One reason that DSP and C developers have been slow to adopt modeling is because they are accustomed to function-based programming. Even though UML was designed for object-oriented programming, C developers can still use UML concepts to model their applications. By representing C files, functions, and data structures as UML classes, developers show C language constructs on UML class diagrams, activity diagrams, sequence diagrams, and statechart diagrams.
The UML element "file" becomes the basic entity for functional designs. A UML file represents the source files. These files contain all elements that C developers use: variables, functions, types, and structures.
Figure 2 shows how files look on an Object model diagram, an Object model diagram showing C files instead of classes. Figure 3 shows that code generated from Telelogic Rhapsody, a UML modeling environment, is the same as handwritten code, a Header file showing the attribute CurVal and functions get CurrentValue() and reset(). All pictures in this article were created in Telelogic Rhapsody.
UML includes the concept that data and functions are either public or private. Any program object may manipulate public data or call public functions; only functions within the file may use private data and private functions. In C, private attributes map to variables defined in the file's implementation (the .c file); private operations map to functions defined in the file's implementation. Public attributes and public operations map to variables and functions defined in the file's specification (its .h file).
C programmers represent composite data as structures. In UML, a file or class without any operations represents a structure. Frequently, developers manipulate a structure's data via functions (for example, range checking or ensuring data consistency). The designer may model the structures and the supporting functions in the same file or in different files; however, including the structure and functions in the same file simplifies maintenance and configuration management.
Modeling keeps it simple
Developers can use the UML file construct to model C applications without changing the format of their code. Modeling simplifies the development process, facilitates collaboration, and enables reuse. As DSP applications become more complex, the benefits of modeling the applications increase.