0% found this document useful (0 votes)
13 views20 pages

sOFTWARE GUIDELINES

The document discusses guidelines and best practices for designing modular software architecture. It covers topics like benefits of modularity, basic software structure, development team roles, reusable code development, software design rules, and embedded C coding guidelines.

Uploaded by

Siva Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views20 pages

sOFTWARE GUIDELINES

The document discusses guidelines and best practices for designing modular software architecture. It covers topics like benefits of modularity, basic software structure, development team roles, reusable code development, software design rules, and embedded C coding guidelines.

Uploaded by

Siva Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 20

MODULAR SOFTWARE A

Release Date: 26 – 02 - 2024

Abstract
[Draw your reader in with an engaging abstract. It is typically a short summary of the
document. When you’re ready to add your content, just click here and start typing.]

SIVAKUMAR
[Email address]
Table of Contents
1. MODULAR SOFTWARE ARCHITECTURE DESIGN................................................................4
1.1 Design Introduction.....................................................................................................................4
1.2 Benefits of Modular Software Architecture.................................................................................4
1.3 Basic Software Code Structure.....................................................................................................4
1.4 Basic Software Architecture.........................................................................................................5
1.5 Team involved in Development Life Cycle...................................................................................5
1.6 Responsibility and Reusable stack Development.........................................................................6
1.6.1 Routine Practise for Software Engineers...............................................................................6
2. DEVELOPERS TERMS AND CONDITIONS.............................................................................7
3. SOFTWARE DESIGN RULES......................................................................................................8
3.1 Modular Design:........................................................................................................................8
3.2 Clear and Meaningful Names:.................................................................................................8
3.3 Avoid Global Variables:............................................................................................................8
3.4 Parameterize Functions:...........................................................................................................8
3.5 Encapsulation:............................................................................................................................8
3.6 Code Reusability through Functions:......................................................................................8
3.7 Use Libraries and Frameworks:................................................................................................8
3.8 Design for Extensibility:............................................................................................................8
3.9 Document Your Code:..............................................................................................................8
3.10 Version Control:......................................................................................................................8
3.11 Test Driven Development (TDD):...........................................................................................9
3.12 Avoid Hard-Coding Values:...................................................................................................9
3.13 Follow Coding Standards:......................................................................................................9
3.14 Design Patterns:......................................................................................................................9
3.15 Refactoring:..............................................................................................................................9
3.16 Error Handling:........................................................................................................................9
3.17 Dependency Injection:............................................................................................................9
3.18 Use Interfaces and Abstract Classes:.....................................................................................9
3.19 Minimize Coupling:.................................................................................................................9
3.20 Continuous Integration (CI) and Continuous Deployment (CD):.......................................9
4. Embedded C Coding Guidelines..............................................................................................10
4.1 Use Meaningful Names:.........................................................................................................10
4.2 Limit Function Length:............................................................................................................10
4.3 Avoid Global Variables:..........................................................................................................10
4.4 Avoid Magic Numbers:...........................................................................................................10
4.5 Use Enums for Constants:......................................................................................................10
4.6 Pointer Declarations:...............................................................................................................10
4.7 Avoid Hard-Coding:................................................................................................................10
4.8 Check Return Values:..............................................................................................................10
4.9 Use const for Constants:.........................................................................................................10
4.10 Error Handling:......................................................................................................................11
4.11 Modularize Code:..................................................................................................................11
4.12 Use stdint.h Types:................................................................................................................11
4.13 Avoid Busy-Wait Loops:.......................................................................................................11
4.14 Understand Bitwise Operations:..........................................................................................11
4.15 Avoid Dynamic Memory Allocation:...................................................................................11
4.16 Use Inline Functions Sparingly:............................................................................................11
4.17 Avoid Floating Point Arithmetic:.........................................................................................11
4.18 Use Compiler-Specific Directives Judiciously:....................................................................11
4.19 Careful Use of Volatile Keyword:.........................................................................................11
4.20 Avoid Function-like Macros:................................................................................................12
4.21 Consistent Indentation:........................................................................................................12
4.22 Limit Function Parameters:..................................................................................................12
4.23 Use static for Internal Linkage:............................................................................................12
4.24 Use #pragma once for Header Guards:..............................................................................12
4.25 Avoid Unnecessary Type Conversions:...............................................................................12
4.26 Use sizeof for Array Sizes:....................................................................................................12
4.27 Prefer switch over Long Chains of if-else:..........................................................................12
4.28 Use const Correctly with Pointers:......................................................................................13
4.29 Avoid Unnecessary Recursion:.............................................................................................13
4.30 Use #error Directive for Compilation Checks:....................................................................13
4.31 Use snprintf Instead of sprintf:............................................................................................13
4.32 Use NULL Pointer Checks:....................................................................................................14
4.33 Avoid Unnecessary Floating-Point Comparisons:.............................................................14
4.34 Group Related Declarations:................................................................................................14
4.35 Avoid Unnecessary Code Duplication:................................................................................14
4.36 Use volatile for Shared Memory:.........................................................................................14
4.37 Document Hardware Dependencies:..................................................................................14
4.38 Use const Correctly for Function Parameters:...................................................................14
4.39 Limit Line Length:..................................................................................................................14
4.40 Avoid Recursion in Interrupt Service Routines (ISRs):.......................................................14
4.41 Use static for Functions with Internal Linkage:..................................................................15
4.42 Avoid Complex Macros:.......................................................................................................15
4.43 Use const Correctly for Pointers:.........................................................................................15
4.44 Use volatile for Register Access:..........................................................................................15
4.45 Minimize Memory Usage:....................................................................................................15
4.46 Use offsetof for Structure Member Offsets:.......................................................................15
4.47 Prefer enum Over #define for Constants:..........................................................................16
4.48 Avoid Unnecessary Compiler Warnings:............................................................................16
4.49 Use const for Function Parameters Where Appropriate:..................................................16
4.50 Handle Endianness Properly:...............................................................................................16
4.51 Use #pragma Directives Sparingly:.....................................................................................16
4.52 Prefer Bitwise Operations for Flags:....................................................................................16
4.53 Use const for Read-Only Data:............................................................................................16
4.54 Use static inline for Small Helper Functions:......................................................................16
4.55 Avoid Unnecessary Type Casting:.......................................................................................17
4.56 Group Related Functions in Source Files:...........................................................................17
4.57 Use __attribute__((packed)) for Packed Structures:...........................................................17
4.58 Avoid Using rand for Critical Applications:........................................................................17
4.59 Limit the Use of goto:...........................................................................................................17
4.60 Comment Clearly and Concisely:.........................................................................................17
4. AVAILABLE SOFTWARE MODULES / STACKS....................................................................18
5. MODULE OWNERS AND INDIVIDUAL RESPOSIBILITIES.................................................19
6. IQ - EXPERTISE AREAS............................................................................................................19
7 IQ - EXPERTISE AREAS............................................................................................................19
1. MODULAR SOFTWARE ARCHITECTURE DESIGN

1.1 Design Introduction

Modular Based software architecture can bring many advantages to software projects, such
as reducing the complexity and risk of designing a individual project architecture from
scratch. Also we can reuse the Modular Software Components as Easier, which is portable
with Common Architecture

1.2 Benefits of Modular Software Architecture

• Maintainability
• Collaboration
• Reusability
• Portability
• Testability
• Platform Independent

1.3 Basic Software Code Structure

Architecture

Modules

Functions

Statement
1.4 Basic Software Architecture

Bootloader Application
Bootloader
Application
S
C J1939
Middle
H Layer J1939 – 71, 73
J1939
E
D BLE J1939 – 21, 81
J1939 – 71, 73
U
J1939 – 21, 81 L Low Level Layer
E EEP CAN
CAN FLASH R
EEP
MCU IVT Timer

Hardware

1.5 Team involved in Development Life Cycle

Software Architect / Lead

Research and Development Team Platform Development Team Application Development Team

HW Module Owners / Developers SW Module Owners / Developers Customer Engg / Developers


1.6 Responsibility and Reusable stack Development

A software development team plays a crucial role in developing modular software


that is maintainable, scalable, and adaptable to changes. The responsibilities of a
software team to develop modular software include:

Controller Dependent Controller Independent

HW Module Lead / SW Module Lead /


Owner Owner

Hardware Module Rack Software Module Rack Stack Module Rack

Software Architecture

HW Module Developer SW Module Developer

Stack Module Rack

HW Module Developer SW Module Developer

Build New Modules Build New Modules

Software Module Rack

HW Module Developer SW Module Developer

Hardware Module Rack

1.6.1 Routine Practise for Software Engineers


a) Requirements Analysis
b) System Architecture Design
c) Modular Coding Practices
d) Code Reviews
e) Version Control
f) Documentation
g) Testing
h) CI/CD
i) Dependency Management
j) Communication and Collaboration
k) Training and Skill Development
l) Performance Optimization
m) Scalability
n) Cross-Functional Collaboration
o) Feedback and Continuous Improvement
p) Adherence to Coding Standards

2. DEVELOPERS TERMS AND CONDITIONS


3. SOFTWARE DESIGN RULES

3.1 Modular Design:


Break your code into small, self-contained modules or functions.
Each module should have a single responsibility.

3.2 Clear and Meaningful Names:


Use descriptive and concise names for functions, variables, and modules.
Names should convey the purpose and functionality of the code.

3.3 Avoid Global Variables:


Minimize the use of global variables.
Pass necessary data through function parameters or use encapsulation.

3.4 Parameterize Functions:


Design functions to be flexible by accepting parameters.
Avoid hardcoding values inside functions when possible.

3.5 Encapsulation:
Encapsulate data and functions into classes or structures.
Use access modifiers to control access to class members.

3.6 Code Reusability through Functions:


Create generic functions that can be reused across different parts of your codebase.

3.7 Use Libraries and Frameworks:


Leverage existing libraries and frameworks for common functionality.
This reduces the need to reinvent the wheel and promotes standardization.

3.8 Design for Extensibility:


Anticipate future changes and design your code to be easily extendable.
Use interfaces, abstract classes, or polymorphism to support future enhancements.

3.9 Document Your Code:


Provide clear documentation for your functions and modules.
Include information on how to use the code and any potential pitfalls.

3.10 Version Control:


Use version control systems like Git to track changes and manage different versions
of your code.

3.11 Test Driven Development (TDD):


Write tests for your code before implementing the functionality.
This ensures that your code meets the specified requirements and is less prone to
bugs.

3.12 Avoid Hard-Coding Values:


Instead, use constants or configuration files.
This makes it easier to adapt your code to different scenarios.

3.13 Follow Coding Standards:


Adhere to coding standards and conventions.
Consistent formatting and naming conventions enhance code readability.

3.14 Design Patterns:


Learn and apply design patterns where appropriate.
Design patterns provide proven solutions to common design problems.

3.15 Refactoring:
Regularly review and refactor your code to improve its structure and maintainability.
Eliminate code smells and improve the design as needed.

3.16 Error Handling:


Implement robust error handling to gracefully handle unexpected situations.
Provide clear error messages for debugging.

3.17 Dependency Injection:


Use dependency injection to inject dependencies into a class rather than hardcoding
them.
This makes your code more modular and testable.

3.18 Use Interfaces and Abstract Classes:


Define interfaces and abstract classes to create a common API for related modules.
Implementations can vary while adhering to the same interface.

3.19 Minimize Coupling:


Reduce dependencies between modules.
High coupling makes it harder to replace or modify one module without affecting
others.

3.20 Continuous Integration (CI) and Continuous Deployment (CD):


Implement CI/CD pipelines to automate testing and deployment processes.
This ensures that your code is consistently tested and deployed.
4. Embedded C Coding Guidelines
4.1 Use Meaningful Names:
Good: int sensorValue;

Bad: int x;

4.2 Limit Function Length:


Good: Functions should have a clear purpose and be relatively short.

Bad: A function that spans hundreds of lines.

4.3 Avoid Global Variables:


Good: Encapsulate data within functions.

Bad: Excessive use of global variables.

4.4 Avoid Magic Numbers:


Good: #define MAX_SPEED 100

Bad: int speed = 100;

4.5 Use Enums for Constants:


enum { RED, GREEN, BLUE };RED, GREEN, BLUE };

4.6 Pointer Declarations:


Good: int *ptr;

Bad: int* ptr;

4.7 Avoid Hard-Coding:


Good: #define MAX_BUFFER_SIZE 256

Bad: int buffer[256];

4.8 Check Return Values:


if (fileOpen(file) != SUCCESS) {

// Handle error

})

4.9 Use const for Constants:


const int MAX_RETRY = 3;

4.10 Error Handling:


Good: Return error codes or use proper exceptions.
Bad: Ignoring errors.

4.11 Modularize Code:


Break code into small, reusable functions.

4.12 Use stdint.h Types:


Good: Use uint8_t, int16_t, etc.

Bad: Reliance on int and char without specifying size.

4.13 Avoid Busy-Wait Loops:


Good: Use timers or interrupts for delays.

Bad: while (1) {}

4.14 Understand Bitwise Operations:


mask = 0x01; // Set the least significant bit

value |= mask; // Set the bit

4.15 Avoid Dynamic Memory Allocation:


Good: Use static memory allocation.

Bad: Frequent use of malloc and free.

4.16 Use Inline Functions Sparingly:


Good: For small, performance-critical code.

Bad: For large or frequently called functions.

4.17 Avoid Floating Point Arithmetic:


Good: Use fixed-point arithmetic or integers.

Bad: Heavy reliance on floating-point calculations.

4.18 Use Compiler-Specific Directives Judiciously:


Good: Employ compiler directives for optimization.

Bad: Excessive use of non-portable features.

4.19 Careful Use of Volatile Keyword:


Good: Use volatile for variables accessed by interrupts.

Bad: Overuse of volatile for all variables.

4.20 Avoid Function-like Macros:


// Good

#define SQUARE(x) ((x) * (x))


// Bad

#define SQUARE(x) x * x (x) x * x

4.21 Consistent Indentation:


Use a consistent and readable indentation style.

4.22 Limit Function Parameters:


Avoid functions with too many parameters.

4.23 Use static for Internal Linkage:


static int internalFunction() {

// Function implementation

} // Function implementation }

4.24 Use #pragma once for Header Guards:


#pragma once

// Header content content

4.25 Avoid Unnecessary Type Conversions:


float result = (float) integerVar;

4.26 Use sizeof for Array Sizes:

int array[10];

size_t arraySize = sizeof(array) / sizeof(array[0]);

4.27 Prefer switch over Long Chains of if-else:

switch (variable) {

case 1:

// Case 1

break;

case 2:

// Case 2

break;

default:
// Default case

break;

4.28 Use const Correctly with Pointers:

const int* readOnlyPtr; // Pointer to constant integer

int const* readOnlyPtr; // Same as above

int* const constantPtr; // Constant pointer to integer

const int* const constPtr; // Constant pointer to constant integer

4.29 Avoid Unnecessary Recursion:


Prefer iterative solutions when recursion is not essential.

4.30 Use #error Directive for Compilation Checks:

#ifdef MY_MACRO

// Code

#else

#error "MY_MACRO must be defined"

#endif

4.31 Use snprintf Instead of sprintf:

char buffer[20];

snprintf(buffer, sizeof(buffer), "%s %d", "Value:", 42);

4.32 Use NULL Pointer Checks:

if (ptr != NULL) {

// Code when pointer is not NULL


}

4.33 Avoid Unnecessary Floating-Point Comparisons:

if (fabs(a - b) < EPSILON) {

// Equal within tolerance

} Equal within tolerance }

4.34 Group Related Declarations:


Group variables and function declarations based on functionality.

4.35 Avoid Unnecessary Code Duplication:


Refactor common code into functions or macros.

4.36 Use volatile for Shared Memory:


When accessing shared variables between threads or ISRs.

4.37 Document Hardware Dependencies:


Clearly document dependencies on specific hardware features.

4.38 Use const Correctly for Function Parameters:

void foo(const int parameter);

4.39 Limit Line Length:


Keep lines within a reasonable length for better readability.

4.40 Avoid Recursion in Interrupt Service Routines (ISRs):


ISRs should be as short and quick as possible.

void ISR_Handler() {

// Avoid recursion or lengthy operations here

4.41 Use static for Functions with Internal Linkage:


static void internalFunction() {

// Function implementation

}
4.42 Avoid Complex Macros:
Keep macros simple and avoid complex expressions.

#define SQUARE(x) ((x) * (x))

4.43 Use const Correctly for Pointers:


int value = 42;

const int* ptrToConst = &value;

int const* ptrToConstSame = &value;

4.44 Use volatile for Register Access:


volatile uint32_t* registerPtr = (uint32_t*)0x40000000;

*registerPtr = 0x12345678;

4.45 Minimize Memory Usage:


Be mindful of memory constraints, especially in embedded systems.

4.46 Use offsetof for Structure Member Offsets:

#include <stddef.h>

struct ExampleStruct {

int a;

char b;

};

size_t offset = offsetof(struct ExampleStruct, b);

4.47 Prefer enum Over #define for Constants:


enum { RED, GREEN, BLUE };\

4.48 Avoid Unnecessary Compiler Warnings:


Keep the code warning-free to catch potential issues early.

4.49 Use const for Function Parameters Where Appropriate:

void processData(const uint8_t* data, size_t length) {


// Function implementation

4.50 Handle Endianness Properly:


Be aware of endianness when working with multi-byte data.

4.51 Use #pragma Directives Sparingly:


Use #pragma directives only when necessary and for compiler-specific
features.

4.52 Prefer Bitwise Operations for Flags:

#define FLAG_BIT_MASK (1 << 2)

uint8_t statusFlags = 0;

statusFlags |= FLAG_BIT_MASK; // Set the flag

4.53 Use const for Read-Only Data:

const char* message = "Hello, World!";

4.54 Use static inline for Small Helper Functions:

static inline int add(int a, int b) {

return a + b;

4.55 Avoid Unnecessary Type Casting:

int result = (int)floatValue; // Only when necessary

4.56 Group Related Functions in Source Files:


Group functions related to a specific module or functionality in the same
source file.
4.57 Use __attribute__((packed)) for Packed Structures:

struct PackedStruct {

char a;

int b;

} __attribute__((packed));

4.58 Avoid Using rand for Critical Applications:


Use a deterministic approach or a better random number generator.

4.59 Limit the Use of goto:


Use structured programming and avoid excessive use of goto.

4.60 Comment Clearly and Concisely:


Good: Clearly explain complex or non-trivial sections of code.

Bad: Excessive or redundant comments.

4. AVAILABLE SOFTWARE MODULES / STACKS

S.NO
5. MODULE OWNERS AND INDIVIDUAL RESPOSIBILITIES
6. IQ - EXPERTISE AREAS

S.NO

7 IQ - EXPERTISE AREAS

You might also like