swdesign&coding
DESCRIPTION
Software Design and CodingTRANSCRIPT
-
SW Design and Coding Principles
Razvan Ardelean
Architecture DesignScope of Architecture Design:defines the SW Components of the system, their interfaces and interaction, communication between componentsdefine a layer structureViews of ArchitectureFunctional Architecture and Physical Architecture (Diagrams: UML, Use Case, Component, Interaction, State)Specific SW Architecture Activities
Impact FactorsAvailable resources, requested performance, functional safety issues, reuse, maintainability
Razvan Ardelean
Architecture DesignSW Architecture Concepts: Layering
Architecture vs Detailed Design
Architecturebuilding blocks of the system, their interfaces, interactions, global concepts involving more componentsDetailed Designrealization of the internals of the building blocks, describes the detailed interfaces for each component
Razvan Ardelean
Detailed DesignCommon stepsAnalyze the architectural description to understand the context of the SW component under designAnalyze SW component specific requirementsIdentify additional functions from the relevant function area and are not necessarily covered by the requirementsDeal with complexity (if SW component complexity is high, divide in several SW subcomponents)Consider reuse of SW-components (already tested, save time)Define Quality criteria prioritization (memory consumption, CPU load, maintainability, reusability)Decision for structured design or object oriented designStructured Designperform functional decomposition (support encapsulation, minimize dependencies, maintainability, testability)static view by static function tree (function call overview)design the functions behavior (consider design rules, maximum complexity)categories of interfaces: global data, interface busses (CAN, LIN, SPI), services (callback functions)traceability from the detailed SW design to the SW architecture description and requirements specification
Razvan Ardelean
Detailed DesignMapping to the file structureFor each detailed SW design at least one source code file is requiredEach source code file refers to exactly one SWDDMacrossometimes are necessary: reduce stack overhead, provide variability at compile-time, performance and ROM size, define constantsModule global variablesrespect naming convention and standardized typeswhere shared variables can not be avoided, a risk analysis is mandatory (protection needed?)Function description and dynamic behaviordynamic behavior - the principle workflow of a function and the relation between input and output parametersfor each function: signature, return value, list of parameters, description, precondition, post conditionMultitasking specificreentrance and task safety, initialization of data, identify critical sections, shared variables analysis
Razvan Ardelean
Code according to Designalready studied different possibilities to write the codebased on timing requirements already know in which tasks and interrupts the code will execute internal breakdown in modules and functions already done, interfaces are clarifiedusage of Abstract Data Type (ADT): set of data and set of operations performed on datadata is kept private inside SW componentprovide an interface to other SW components (xx.h file with get, set and other access functions)data consistency and protectionvarious implementations while keeping the same interfaceshared data analyzed and critical sections identifiedthinking on next steps: unit testing, integration testingnumber of internal interfaces as small as possible (integration effort)simple functions, simple conditions (code coverage)macros shall not generate code (breakpoints)use data structures (struct ) and types (enum) (useful in the watch window)
Razvan Ardelean
Code according to Designa module should be structured in a body (.c) and a header part (.h)each module shall include its own header filein a .h or .c file, include all .h files that declare symbols used by the file.(no unnecessary header files inclusion)a ".c" file shall not be included in another file: it shall be compiled and provided as an object modulethere shall be no definitions of objects or functions in a header filefunctions shall have prototype declarations, the prototype shall be visible at both the function definition and callthe cyclomatic complexity number for a function should be smaller than 15 (>30 high risk; hard to test)the static storage class specifier shall be used in definitions of objects and functions that have internal linkageautomatic variables defined inside functions must be initialized in the definitionobjects shall be defined at block scope if they are only accessed from within single functionshared variables used in different preemptive tasks must be qualified as volatile (avoid unexpected optimization)critical inputs and data must be checked for valid boundary valuesenums should be used when defining groups of related integer constants instead of a series of #definesidentifiers in an inner scope shall not use the same name as an identifier in an outer scope, (name hiding)
Razvan Ardelean
Embedded softwareThe application is in close connection with the electronics or hardwareThe target is a microcontroller specific for a functionality, not a PC with a general purpose processorInputs and outputs are signals, communication busses CAN, LIN, SPIThe application may be reused from one microcontroller to another (code according to ANSI C standard)Special care for CPU load (execution time is critical)Response time to signals is very important (real time response)Power management is important for battery powered devices (transition low power - high power)Why C language?PortabilityCode shall be efficient (real time)Code shall be small (generated executable is small)Hardware interfaces (direct access by addressing)A compiler is available for every microcontroller
Razvan Ardelean
Embedded softwareLayering: Platform (HW dependent: scheduler, drivers) and Application (less HW dependent)Define common types in platform, for portability we cannot relay on standard data types of the C languageAwareness of endian-nes: big/little endian (avoid unions for portability)Special keywords:volatile - prevents compiler optimizations (mandatory to be used for shared variables)register - try to keep that variable in a CPU register (forces compiler optimizations)static - used for a global variable, for a function, for a local variableinline - the code of the function is inserted at the caller point instead of using the stack overheadconst - declare that a variable or a function parameter is constantBit manipulation: RAM space is small, every bit can be used (implementation: structure with bitfields)Write efficient code: binary math (shift), avoid complex addressing and unsafe pointer arithmeticAwareness of stack consumption: parameters and local variablesKeep the functions simple: no more than 100 ELOC, cyclomatic complexity smaller than 15
Razvan Ardelean
Safe code and robustnessThe main requirement regarding the code : no bugs, specially those which can cause human injuryBug classification:by appearance: systematic, sporadicby severity: minor, major, fatalConsequences: cost of finding cause, cost of fixing and testing again, recall products, human injuryUsage of a well established process: SWDD, TDD (Test Driven Development), Code review, static code analyzerFollow some coding rules -> reliability, portability, testability, customer satisfactionCoding rules help prevent bugsArithmetic: division by zero, overflow/underflowSyntax: = vs ==, missing ()Logical: infinit loops, recusivityPointers: indexing, pointer arithmeticResource: local variables initializationMultitasking: shared variables
Razvan Ardelean
Safe code and robustnessMISRA (Motor Industry Software Reliability Association): 2004 standard (121 required rules, 20 advisory rules)All code shall conform to ISO 9899 Standard C, with no extensions permittedPrecaution shall be taken in order to prevent the contents of a header file being included twiceAssembly language shall be encapsulated and isolatedC macros shall only expand to a braces initialiser, a constant, a parenthesized expression, a type qualifier, a storage class specifier, or a do-while-zero constructIn the definition of a function-like macro each instance of a parameter shall be enclosed in parentheses unless it is used as the operand of # or ##.Unions shall not be usedFunctions shall not be defined with variable numbers of argumentsFunctions shall not call themselves, either directly or indirectlyIdentifiers shall be given for all of the parameters in a function prototype declarationThe number of arguments passed to a function shall match the number of parametersAll exit paths from a functions with non-void return type shall have an explicit return statementIf a function returns error information, then that error information shall be tested
Razvan Ardelean
Safe code and robustnessA function shall have a single point of exit at the end of the functionFunctions shall have prototype declarations and the prototype shall be visible at both the function definition and callThe static storage class specifier shall be used in definitions and declarations of objects and functions that have internal linkageIdentifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifierThe address of an object with automatic storage shall not be assigned to another object which may persist after the first object has ceased to existAll automatic variables shall have been assigned a value before being usedArray indexing shall be the only allowed form of pointer arithmeticIf the bitwise operators ~ and