Firmware Design & Development
- The embedded firmware is responsible for controlling the various peripherals of the embedded hardware and generating responses.
- The embedded firmware is the master brain of the embedded system.
- The product starts functioning properly once the intelligence imparted to the product, by embedding the firmware in the hardware.
- The product will continue serving the assigned task till hardware breakdown occurs or corruption in embedded firmware.
- The embedded firmware is usually stored in permanent memory (ROM) and it cannot be altered by end-users.
- Designing Embedded firmware requires an understanding of the particular embedded product hardware, like various component interfacing, memory map details, I/O port details, configuration and register details of various hardware chips used and some programming language (either low-level Assembly Language or High-level languages or a combination of the two).
- The embedded firmware development process starts with the conversion of the firmware requirements into a program model using various modelling tools like UML or flow chart based representation.
Design Approaches
There exist two basic approaches for the design and implementation of embedded firmware, namely;
The Super loop-based approach
The Embedded Operating System-based approach
The decision on which approach needs to be adopted for firmware development is purely dependent on the complexity and system requirements.
Super loop-based approach
- This approach is suitable for applications that are not time-critical and where the response time is not so important.
- It is very similar to conventional procedural programming where the code is executed task by task.
- The tasks are executed in a never-ending loop.
- The task listed on top on the program code is executed first and the tasks just below the top are executed after completing the first task.
- The priorities are fixed and the order of the task to be executed is also fixed.
# A typical super loop implementation will look like:
1. Configure the common parameters and perform initialization for various hardware components like memory, registers, etc.
2. Start the first task and execute it
3. Execute the second task
4. Execute the next task
5. :
6. :
7. Execute the last defined task
8. Jump back to the first task and follow the same flow.
# The ‘C’ program code for the super loop is given below,
void main ()
{
configurations ();
initializations ();
while (1)
{
Task 1 ();
Task 2 ();
:
Task n ();
}
}
Since the task is running inside an infinite loop, the only way to come out of the loop is either,
# Hardware reset
# Interrupt assertion
Hardware reset brings the program execution back to the main loop, whereas the interrupt,
suspend the task execution temporarily and perform the corresponding
interrupt routine and on completion of the interrupt routine, it
restarts the task execution from the point where it got interrupted.
Pros
- Doesn’t require an Operating System for task scheduling and monitoring and free from OS related overheads
- Simple and straight forward design
- Reduced memory footprint
Cons
- Non-Real time in execution behaviour (As the number of tasks increases the frequency at which a task gets CPU time for execution also increases)
- Any issues in any task execution may affect the functioning of the product (This can be effectively tackled by using WatchDog Timers for task execution & monitoring)
- May cause additional hardware cost and firmware overhead
Embedded Operating System-based approach
- The Embedded OS is responsible for scheduling the execution of user tasks and the allocation of system resources among multiple tasks.
- The embedded device contains an Operating System which can be either a,
# Real-Time Operating System (RTOS)
# General Purpose Operating System (GPOS)
- GPOS is used for systems/applications that are not time-critical and are not always based on the priority of the applications or processes. Example:- Windows, Linux, Unix, etc.
- RTOS is used for time-critical systems and always utilizes priority-based scheduling. Example:- VxWorks, uCos, etc.
Firmware Development Languages
For embedded firmware development you can use either,
- Assembly Language
- High-Level Language
- Combination of Assembly & High-level Language
Assembly Language
- Assembly Language is the human-readable notation of machine language (processor understandable language).
- Machine language is a binary representation and it consists of 1s and 0s.
- Assembly language and machine languages are processor/controller dependent.
- An Assembly language program written for one processor/controller family will not work with others.
- Assembly language programming is the process of writing processor-specific machine code in mnemonic form, converting the mnemonics into actual processor instructions (machine language) and associated data using an assembler.
- The general format of an assembly language instruction is an Opcode followed by Operands.
- The Opcode tells the processor/controller what to do and the Operands provide the data and information required to perform the action specified by the opcode.
The 8051 Assembly Instruction,
MOV A, #30
Moves decimal value 30 to the Accumulator register. Here MOV A is the
Opcode and 30 is the operand (single operand). The same instruction,
when written in machine language, will look like
01110100 00011110
The first 8-bit binary value 01110100 represents the opcode MOV A and
the second 8-bit binary value 00011110 represents the operand 30.
- Assembly language instructions are written one per line.
- A machine code program consists of a sequence of assembly language instructions, where each statement contains a mnemonic (Opcode + Operand).
- Each line of an assembly language program is split into four fields as:
- LABEL (Optional Filed)
- OPCODE
- OPERAND
- COMMENTS
- LABEL is an identifier used extensively in programs to reduce the reliance on programmers for remembering where data or code is located. LABEL is commonly used for representing, a memory location, address of a program, sub-routine, code portion, etc.
- The maximum length of a label differs between assemblers.
- Assemblers insist on strict formats for labelling.
- Labels are always suffixed by a colon and begin with a valid character.
- Labels can contain a number from 0 to 9 and special character _ (underscore).
DELAY: MOV R0, #255 ; Load Register R0 with 255
DJNZ R1, DELAY ; Decrement R1 and loop till R1= 0
RET ; Return to calling program
- The symbol ; represents the start of a comment.
- Assembler ignores the text in a line after the ; symbol while assembling the program.
- DELAY is a label for representing the start address of the memory location where the piece of code is located in code memory.
- The above piece of code can be executed by giving the label DELAY as part of the instruction. E.g. LCALL DELAY; LMP DELAY
Source File to Hex File Translation
- The software utility called ‘Assembler’ performs the translation of assembly code to machine code.
- The
assemblers for a different family of target machines are different, A51
Macro Assembler from Keil software is a popular assembler for the 8051
family microcontroller.
- Each source file can be assembled separately to examine the syntax errors and incorrect assembly instructions.
- Assembling of each source file generates a corresponding object file.
- The
object file does not contain the absolute address of where the
generated code needs to be placed (a re-locatable code) on the program
memory.
- The
software program called the linker/locater is responsible for assigning
an absolute address to object files during the linking process.
- A
software utility called ‘Object to Hex file converter’ translates the
absolute object file to the corresponding hex file (binary file).
Advantages
# Efficient Code Memory & Data Memory Usage (Memory Optimization)
- The
developer is well aware of the target processor architecture and memory
organization, so an optimized code can be written for performing
operations.
- This leads to less utilization of code memory and efficient utilization of data memory.
# High Performance:
- Optimized code not only improves the code memory usage but also
improves the total system performance.
- Through effective assembly coding, optimum performance can be
achieved for a target processor.
# Low-level Hardware Access
- Most
of the code for low-level programmings like accessing external
device-specific registers from OS kernel, device drivers, and low level
interrupt routines, etc are making use of direct assembly coding.
# Code Reverse Engineering
- It is the process of understanding the technology behind a product by extracting the information from the finished product.
- It can easily be converted into an assembly code using a dis-assembler program for the target machine.
Drawbacks
# High Development time
- The
developer takes a lot of time to study the architecture, memory
organization, addressing modes, and instruction set of target
processor/controller.
- More lines of assembly code are required for performing a simple action.
# Developer dependency
- There is no common written rule for developing assembly language-based applications.
# Non-portable
- Target
applications written in assembly instructions are valid only for that
particular family of processors and cannot be re-used for other target
processors/controllers.
- If
the target processor/controller changes, a complete re-writing of the
application using assembly language for a new target
processor/controller is required.
High-Level Language
- High-level languages like C, C++, are used for embedded firmware development.
- A software utility called ‘cross-compiler’ converts the high-level language to target processor-specific machine code.
- The cross-compilation of each module generates a corresponding object file.
Advantages
- Reduced Development time: Developer requires less or little knowledge on internal hardware details and architecture of the target processor/Controller.
- Developer independency:
The syntax used by most of the high-level languages are universal and a
program is written high level can easily understand by a second person
knowing the syntax of the language.
- Portability:
An Application written in high-level language for a particular target
processor /controller can be easily be converted to another target
processor/controller specific application with little or less effort.
Disadvantages
- The cross compilers may not be efficient in generating the optimized target processor-specific instructions.
- Target images created by such compilers may be messy and nonoptimized in terms of performance as well as code size.
- The
investment required for high-level language-based development tools
(IDE) is high compared to Assembly Language-based firmware development
tools.
- The developer is well aware of the target processor architecture and memory organization, so an optimized code can be written for performing operations.
- This leads to less utilization of code memory and efficient utilization of data memory.
# High Performance:
- Optimized code not only improves the code memory usage but also improves the total system performance.
- Through effective assembly coding, optimum performance can be achieved for a target processor.
# Low-level Hardware Access
- Most of the code for low-level programmings like accessing external device-specific registers from OS kernel, device drivers, and low level interrupt routines, etc are making use of direct assembly coding.
# Code Reverse Engineering
- It is the process of understanding the technology behind a product by extracting the information from the finished product.
- It can easily be converted into an assembly code using a dis-assembler program for the target machine.
Drawbacks
# High Development time
- The developer takes a lot of time to study the architecture, memory organization, addressing modes, and instruction set of target processor/controller.
- More lines of assembly code are required for performing a simple action.
# Developer dependency
- There is no common written rule for developing assembly language-based applications.
# Non-portable
- Target applications written in assembly instructions are valid only for that particular family of processors and cannot be re-used for other target processors/controllers.
- If the target processor/controller changes, a complete re-writing of the application using assembly language for a new target processor/controller is required.
High-Level Language
- High-level languages like C, C++, are used for embedded firmware development.
- A software utility called ‘cross-compiler’ converts the high-level language to target processor-specific machine code.
- The cross-compilation of each module generates a corresponding object file.
Advantages
- Reduced Development time: Developer requires less or little knowledge on internal hardware details and architecture of the target processor/Controller.
- Developer independency: The syntax used by most of the high-level languages are universal and a program is written high level can easily understand by a second person knowing the syntax of the language.
- Portability: An Application written in high-level language for a particular target processor /controller can be easily be converted to another target processor/controller specific application with little or less effort.
Disadvantages
- The cross compilers may not be efficient in generating the optimized target processor-specific instructions.
- Target images created by such compilers may be messy and nonoptimized in terms of performance as well as code size.
- The investment required for high-level language-based development tools (IDE) is high compared to Assembly Language-based firmware development tools.
No comments:
Post a Comment