Support Statistics
¥.00 ·
0times
Text Preview (First 20 pages)
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
Page
1
Reusable Firmware Development A Practical Approach to APIs, HALs and Drivers — Jacob Beningo
Page
2
Reusable Firmware Development A Practical Approach to APIs, HALs and Drivers Jacob Beningo
Page
3
Reusable Firmware Development: A Practical Approach to APIs, HALs and Drivers ISBN-13 (pbk): 978-1-4842-3296-5 ISBN-13 (electronic): 978-1-4842-3297-2 https://doi.org/10.1007/978-1-4842-3297-2 Library of Congress Control Number: 2017961731 Copyright © 2017 by Jacob Beningo This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, logo, or image, we use the names, logos, and images only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights. While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher makes no warranty, express or implied, with respect to the material contained herein. Cover image by Freepik (www.freepik.com) Managing Director: Welmoed Spahr Editorial Director: Todd Green Acquisitions Editor: Steve Anglin Development Editor: Matthew Moodie Technical Reviewers: Ahmed Hag-ElSafi and Rami Zewail Coordinating Editor: Mark Powers Copy Editor: April Rondeau Distributed to the book trade worldwide by Springer Science+Business Media New York, 233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, email orders-ny@springer-sbm. com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation. For information on translations, please email rights@apress.com, or visit http://www.apress.com/ rights-permissions. Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales web page at http://www.apress.com/bulk-sales. Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub via the book’s product page, located at www.apress.com/9781484232965. For more detailed information, please visit http://www.apress.com/source-code. Printed on acid-free paper Jacob Beningo Linden, Michigan, USA
Page
4
To my lovely wife, children, parents, and siblings.
Page
5
v About the Author ��������������������������������������������������������������������������������������������������� xiii About the Technical Reviewers �������������������������������������������������������������������������������xv Acknowledgments �������������������������������������������������������������������������������������������������xvii Preface �������������������������������������������������������������������������������������������������������������������xix Introduction ������������������������������������������������������������������������������������������������������������xxi Table of Contents Chapter 1: Concepts for Developing Portable Firmware ������������������������������������������� 1 Why Code Reuse Matters �������������������������������������������������������������������������������������������������������������� 1 Portable Firmware ������������������������������������������������������������������������������������������������������������������������ 3 Modularity ������������������������������������������������������������������������������������������������������������������������������������� 9 Module Coupling and Cohesion ��������������������������������������������������������������������������������������������������� 10 Following a Standard ������������������������������������������������������������������������������������������������������������������ 12 Portability Issues in C—Data Types �������������������������������������������������������������������������������������������� 13 Portability Issues in C—Structures and Unions �������������������������������������������������������������������������� 14 Portability Issues in C—Bit Fields ����������������������������������������������������������������������������������������������� 15 Portability Issues in C—Preprocessor Directives ����������������������������������������������������������������������� 16 Embedded-Software Architecture ����������������������������������������������������������������������������������������������� 18 Hardware Abstraction Layers (HAL) �������������������������������������������������������������������������������������������� 21 Application Programming Interfaces (APIs) �������������������������������������������������������������������������������� 23 Project Organization �������������������������������������������������������������������������������������������������������������������� 24 Getting Started Writing Portable Firmware ��������������������������������������������������������������������������������� 25 Going Further ������������������������������������������������������������������������������������������������������������������������������ 28
Page
6
vi Chapter 2: API and HAL Fundamentals ������������������������������������������������������������������� 29 The Wonderful World of HALs ������������������������������������������������������������������������������������������������������ 29 APIs Versus HALs ������������������������������������������������������������������������������������������������������������������� 30 The API and HAL Landscape�������������������������������������������������������������������������������������������������������� 31 The Good, Bad, and Ugly ������������������������������������������������������������������������������������������������������������� 33 Potential Issues and the Boogeyman ������������������������������������������������������������������������������������������ 33 Characteristics Every HAL Should Exhibit ����������������������������������������������������������������������������������� 36 Characteristic #1: Contains a Well-Defined Coding Standard ������������������������������������������������ 37 Characteristic #2: Reasonable Documentation and Comments��������������������������������������������� 37 Characteristic #3: Written in C99 ������������������������������������������������������������������������������������������� 38 Characteristic #4: Can Be Compiled in Any Modern Compiler ����������������������������������������������� 38 Characteristic #5: Abstract Useful Hardware Features ���������������������������������������������������������� 39 Characteristic #6: Easily Extensible ��������������������������������������������������������������������������������������� 40 Characteristic #7: Modular and Adaptable ���������������������������������������������������������������������������� 40 Characteristic #8: Deterministic and Well-Understood Behavior ������������������������������������������� 41 Characteristic #9: Error-Handling and Diagnostic Capabilities ���������������������������������������������� 42 Characteristic #10: Integrated Regression Testing ��������������������������������������������������������������� 43 Evaluating HAL Characteristics ��������������������������������������������������������������������������������������������������� 44 To Build or Not to Build ��������������������������������������������������������������������������������������������������������������� 45 A First Look at a HAL ������������������������������������������������������������������������������������������������������������������� 47 The API Scope ����������������������������������������������������������������������������������������������������������������������������� 48 API Characteristics to Look For ��������������������������������������������������������������������������������������������������� 49 Characteristic #1: Using const Frequently ����������������������������������������������������������������������������� 49 Characteristic #2: Easily Understood Naming Conventions ��������������������������������������������������� 50 Characteristics #3: Consistent Look and Feel������������������������������������������������������������������������ 53 Characteristic #4: Well Documented �������������������������������������������������������������������������������������� 53 Characteristic #5: Flexible and Configurable ������������������������������������������������������������������������� 53 Designing Your Own APIs ������������������������������������������������������������������������������������������������������������ 53 A First Look at an API ������������������������������������������������������������������������������������������������������������������ 54 Wrapping APIs ����������������������������������������������������������������������������������������������������������������������������� 55 Table of ConTenTs
Page
7
vii Why Design Your Own APIs and HALs? ��������������������������������������������������������������������������������������� 57 Comparing APIs and HALs ����������������������������������������������������������������������������������������������������������� 58 Going Further ������������������������������������������������������������������������������������������������������������������������������ 58 Chapter 3: Device Driver Fundamentals in C ���������������������������������������������������������� 61 Understanding the Memory Map������������������������������������������������������������������������������������������������� 61 Planning the Driver Interfaces ���������������������������������������������������������������������������������������������������� 64 Design by Contract ���������������������������������������������������������������������������������������������������������������������� 66 Assertion Fundamentals ������������������������������������������������������������������������������������������������������������� 68 Device Driver Models ������������������������������������������������������������������������������������������������������������������ 70 Polling Versus Interrupt-Driven Drivers ��������������������������������������������������������������������������������������� 71 Driver Component Definition ������������������������������������������������������������������������������������������������������� 76 Naming Convention Recommendations �������������������������������������������������������������������������������������� 78 Object-Oriented Programming in C ��������������������������������������������������������������������������������������������� 79 Abstractions and Abstract Data Types (ADTs) ����������������������������������������������������������������������������� 80 Encapsulation and Data Hiding ��������������������������������������������������������������������������������������������������� 86 Callback Functions ���������������������������������������������������������������������������������������������������������������������� 86 Error Handling ����������������������������������������������������������������������������������������������������������������������������� 89 Leverage Design Patterns ����������������������������������������������������������������������������������������������������������� 90 Expected Results and Recommendations ����������������������������������������������������������������������������������� 91 Going Further ������������������������������������������������������������������������������������������������������������������������������ 92 Chapter 4: Writing Reusable Drivers ���������������������������������������������������������������������� 95 Reusable Drivers ������������������������������������������������������������������������������������������������������������������������� 95 Deciphering the extern and static Keywords ������������������������������������������������������������������������������ 95 Deciphering the volatile Keyword ���������������������������������������������������������������������������������������������� 98 Deciphering the const Keyword ������������������������������������������������������������������������������������������������� 99 Memory-Mapping Methodologies ��������������������������������������������������������������������������������������������� 101 Mapping Memory Directly ��������������������������������������������������������������������������������������������������� 101 Mapping Memory with Pointers ������������������������������������������������������������������������������������������ 102 Mapping Memory with Structures ��������������������������������������������������������������������������������������� 105 Using Pointer Arrays in Driver Design ���������������������������������������������������������������������������������� 106 Table of ConTenTs
Page
8
viii Creating a Timer Driver Overview ��������������������������������������������������������������������������������������������� 107 Step #1: Define the Timer’s Configuration Table ������������������������������������������������������������������ 108 Step #2: Define the Timer’s Peripheral Channels ���������������������������������������������������������������� 109 Step #3: Populate the Timer’s Configuration Table �������������������������������������������������������������� 110 Step #4: Create the Timer’s Pointer Arrays �������������������������������������������������������������������������� 111 Step #5: Create the Initialization Function ��������������������������������������������������������������������������� 112 Step #6: Fill in the Timer Driver Interface ���������������������������������������������������������������������������� 116 Step #7: Maintain and Port the Design Pattern ������������������������������������������������������������������ 116 Selecting the Right Driver Implementation ������������������������������������������������������������������������������ 117 Going Further ���������������������������������������������������������������������������������������������������������������������������� 118 Chapter 5: Documenting Firmware with Doxygen ������������������������������������������������ 121 The Importance of Good Documentation ����������������������������������������������������������������������������������� 121 Easing the Documentation Load ����������������������������������������������������������������������������������������������� 122 An Introduction to Doxygen ������������������������������������������������������������������������������������������������������� 124 Installing Doxygen ��������������������������������������������������������������������������������������������������������������������� 126 Documentation Project Setup ��������������������������������������������������������������������������������������������������� 127 Doxygen Comment Fundamentals �������������������������������������������������������������������������������������������� 131 Documenting enum and struct�������������������������������������������������������������������������������������������������� 132 Documenting Functions ������������������������������������������������������������������������������������������������������������ 133 Documenting Modules �������������������������������������������������������������������������������������������������������������� 137 Creating a Reusable Template �������������������������������������������������������������������������������������������������� 139 Generating a Main Page ������������������������������������������������������������������������������������������������������������ 140 Ten Tips for Commenting C Code ���������������������������������������������������������������������������������������������� 142 Tip #1: Explain the Why, Not the How ���������������������������������������������������������������������������������� 143 Tip #2: Comment Before Coding ������������������������������������������������������������������������������������������ 143 Tip #3: Use Doxygen Tags ���������������������������������������������������������������������������������������������������� 144 Tip #4: Adopt a Code Style Guide ����������������������������������������������������������������������������������������� 144 Tip #5: Use a File Header ����������������������������������������������������������������������������������������������������� 145 Tip #6: Create a Commenting Template ������������������������������������������������������������������������������� 145 Table of ConTenTs
Page
9
ix Tip #7: Have a Consistent Comment Location ��������������������������������������������������������������������� 146 Tip #8: Don’t Comment Every Line �������������������������������������������������������������������������������������� 146 Tip #9: Start Mathematical Type Identifiers with the Type ��������������������������������������������������� 146 Tip #10: Update Comments with Code Updates ������������������������������������������������������������������ 147 A Few Final Thoughts on Documentation ���������������������������������������������������������������������������������� 147 Going Further ���������������������������������������������������������������������������������������������������������������������������� 148 Chapter 6: The Hardware Abstraction Layer Design Process ������������������������������� 149 Why Use a HAL? ������������������������������������������������������������������������������������������������������������������������ 149 A Good HAL’s Characteristics ���������������������������������������������������������������������������������������������������� 150 The HAL Design Process ����������������������������������������������������������������������������������������������������������� 151 Step #1: Review the Microcontroller Peripheral Datasheet ������������������������������������������������������ 152 Step #2: Identify Peripheral Features ���������������������������������������������������������������������������������������� 152 Step #3: Design and Create the Interface ��������������������������������������������������������������������������������� 153 Step #4: Create Stubs and Documentation Templates �������������������������������������������������������������� 155 Step #5: Implement for Target Processor(s) ������������������������������������������������������������������������������ 158 Step #6: Test, Test, Test ������������������������������������������������������������������������������������������������������������� 158 Step #7: Repeat for the Next Peripheral ������������������������������������������������������������������������������������ 160 10 Tips for Designing a HAL ������������������������������������������������������������������������������������������������������ 161 Tip #1: Identify Core Features ���������������������������������������������������������������������������������������������� 161 Tip #2: Avoid an All-Encompassing HAL ������������������������������������������������������������������������������ 161 Tip #3: Add Register-Access Hooks ������������������������������������������������������������������������������������� 162 Tip #4: Use Doxygen to Outline the HAL ������������������������������������������������������������������������������ 162 Tip #5: Get a Second Set of Eyes ����������������������������������������������������������������������������������������� 162 Tip #6: Don’t Be Afraid to Iterate ����������������������������������������������������������������������������������������� 163 Tip #7: Keep the View at 30,000 Feet ���������������������������������������������������������������������������������� 163 Tip #8: Use Appropriate Naming Conventions ��������������������������������������������������������������������� 164 Tip #9: Include a Parameter for Initialization ����������������������������������������������������������������������� 164 Tip #10: Deploy on Multiple Development Kits �������������������������������������������������������������������� 164 Going Further ���������������������������������������������������������������������������������������������������������������������������� 165 Table of ConTenTs
Page
10
x Chapter 7: HAL Design for GPIO ���������������������������������������������������������������������������� 167 GPIO Peripherals Overview ������������������������������������������������������������������������������������������������������� 167 Step #1: Review the GPIO Peripheral Datasheet ����������������������������������������������������������������������� 167 Step #2: GPIO Peripheral Features �������������������������������������������������������������������������������������������� 168 Step #3: Design and Create the GPIO HAL Interface ����������������������������������������������������������������� 169 Step #4: Create GPIO Stubs and Documentation Templates ����������������������������������������������������� 172 Step #5: Implement GPIO HAL for Target Processor ������������������������������������������������������������������ 192 Step #6: Test, Test, Test ������������������������������������������������������������������������������������������������������������� 198 Step #7: Repeat for the Next Peripheral ������������������������������������������������������������������������������������ 198 Going Further ���������������������������������������������������������������������������������������������������������������������������� 199 Chapter 8: HAL Design for SPI ������������������������������������������������������������������������������ 201 An Overview of SPI Peripherals������������������������������������������������������������������������������������������������� 201 Step #1: Review the SPI Peripheral Datasheet ������������������������������������������������������������������������� 202 Step #2: SPI Peripheral Features ���������������������������������������������������������������������������������������������� 203 Step #3: Design and Create the SPI HAL Interface �������������������������������������������������������������������� 204 Step #4: Create SPI Stubs and Documentation Templates �������������������������������������������������������� 205 Step #5: Implement SPI HAL for Target Processor �������������������������������������������������������������������� 209 Step #6: Test, Test, Test ������������������������������������������������������������������������������������������������������������� 215 Step #7: Repeat for the Next Peripheral ������������������������������������������������������������������������������������ 216 Going Further ���������������������������������������������������������������������������������������������������������������������������� 216 Chapter 9: HAL Design for EEPROM and Memory Devices ������������������������������������ 219 An Overview of Memory Devices ���������������������������������������������������������������������������������������������� 219 Step #1: Review the EEPROM Peripheral Datasheet ����������������������������������������������������������������� 221 Step #2: EEPROM Peripheral Features �������������������������������������������������������������������������������������� 222 Step #3: Design and Create the EEPROM HAL Interface ����������������������������������������������������������� 224 Step #4: Create EEPROM Stubs and Documentation Templates ����������������������������������������������� 227 Step #5: Implement EEPROM HAL for Target Processor ������������������������������������������������������������ 231 Step #6: Test, Test, Test ������������������������������������������������������������������������������������������������������������� 237 Table of ConTenTs
Page
11
xi Step #7: Repeat for the Next Peripheral ������������������������������������������������������������������������������������ 237 Extending the EEPROM HAL ������������������������������������������������������������������������������������������������������ 237 Going Further ���������������������������������������������������������������������������������������������������������������������������� 240 Chapter 10: API Design for Embedded Applications ��������������������������������������������� 243 Applications Made Easier ���������������������������������������������������������������������������������������������������������� 243 Designing APIs �������������������������������������������������������������������������������������������������������������������������� 245 Application Frameworks ����������������������������������������������������������������������������������������������������������� 246 Creating Your Own APIs ������������������������������������������������������������������������������������������������������������� 247 Common Software Frameworks—RTOS and Schedulers ��������������������������������������������������������� 248 Common Software Frameworks— Console Applications ��������������������������������������������������������� 250 Common Software Frameworks—Bootloaders ������������������������������������������������������������������������ 252 Common Software Frameworks—FAT File System ������������������������������������������������������������������ 254 Going Further ���������������������������������������������������������������������������������������������������������������������������� 256 Chapter 11: Testing Portable Embedded Software ����������������������������������������������� 257 Cross Your Fingers and Pray ����������������������������������������������������������������������������������������������������� 257 Unit Testing ������������������������������������������������������������������������������������������������������������������������������� 258 Taking Advantage of Cyclomatic Complexity for Unit Testing���������������������������������������������������� 260 Standard Interface � � � Standard Tests �������������������������������������������������������������������������������������� 263 Functional Testing ��������������������������������������������������������������������������������������������������������������������� 264 Test-Driven Development ���������������������������������������������������������������������������������������������������� 265 Hardware In-Loop Testing ��������������������������������������������������������������������������������������������������������� 266 Regression Testing �������������������������������������������������������������������������������������������������������������� 268 Automating Tests ����������������������������������������������������������������������������������������������������������������� 269 Using Trace to Verify Application Software ������������������������������������������������������������������������������� 270 A Modern Example: The Renesas Synergy™ Platform ������������������������������������������������������������� 272 Going Further ����������������������������������������������������������������������������������������������������������������������� 274 Table of ConTenTs
Page
12
xii Chapter 12: A Practical Approach to Code Reuse ������������������������������������������������� 277 Being Practical in an Unpractical Environment ������������������������������������������������������������������������� 277 Phases and Baby Steps ������������������������������������������������������������������������������������������������������������� 278 Identifying Desired Results and Outcomes ������������������������������������������������������������������������������� 280 Desired Results: Decreasing Time to Market ����������������������������������������������������������������������� 281 Desired Results: Decreasing Development Costs ���������������������������������������������������������������� 282 Desired Results: Increased Quality �������������������������������������������������������������������������������������� 283 Evaluating Where You Are ��������������������������������������������������������������������������������������������������������� 284 Defining How to Get There �������������������������������������������������������������������������������������������������������� 284 Getting the Most from Metrics �������������������������������������������������������������������������������������������������� 285 Metrics Worth Tracking ������������������������������������������������������������������������������������������������������������� 285 Assess the Results �������������������������������������������������������������������������������������������������������������������� 288 Recognizing Design Patterns ���������������������������������������������������������������������������������������������������� 288 Creating Templates and Checklists ������������������������������������������������������������������������������������������� 289 Version Control Is Your Best Friend ������������������������������������������������������������������������������������������� 292 Tip #1: Commit Frequently��������������������������������������������������������������������������������������������������� 293 Tip #2: Fill in the commit log ����������������������������������������������������������������������������������������������� 293 Tip #3: Don’t forget to add files to the VCS �������������������������������������������������������������������������� 294 Tip #4: Define a commit process ����������������������������������������������������������������������������������������� 294 Tip #5: Lock modules that are in process ���������������������������������������������������������������������������� 294 Tip #6: Utilize the code-comparison tools ��������������������������������������������������������������������������� 295 Tip #7: Don’t fear merging code branches �������������������������������������������������������������������������� 295 What Is the Cost to Do Nothing? ����������������������������������������������������������������������������������������������� 295 Final Thoughts ��������������������������������������������������������������������������������������������������������������������������� 297 Going Further ���������������������������������������������������������������������������������������������������������������������������� 298 Index ��������������������������������������������������������������������������������������������������������������������� 301 Table of ConTenTs
Page
13
xiii About the Author Jacob Beningo is an embedded software consultant with over 15 years of experience in microcontroller-based real- time embedded systems. After spending over ten years designing embedded systems for the automotive, defense, and space industries, Jacob founded Beningo Embedded Group in 2009. Jacob has worked with clients in more than a dozen countries to dramatically transform their businesses by improving product quality, cost, and time to market. He has published more than 200 articles on embedded software development techniques and is a sought-after speaker and technical advisor. Jacob is an avid writer, trainer, consultant, and entrepreneur who transforms the complex into simple and understandable concepts that accelerate technological innovation. Jacob has demonstrated his leadership in the embedded-systems industry by consulting and working as a trusted advisor at companies such as General Motors, Intel, Infineon, and Renesas. Jacob also speaks at and is involved in the embedded track- selection committees at ARM Techcon, Embedded System Conferences, and Sensor Expo. Jacob holds bachelor’s degrees in electrical engineering, physics, and mathematics from Central Michigan University and a master’s degree in space systems engineering from the University of Michigan. In his spare time, Jacob enjoys spending time with his family, reading, writing, and playing hockey and golf. When there are clear skies, he can often be found outside with his telescope, sipping a fine scotch while imaging the sky.
Page
14
xv About the Technical Reviewers Ahmed S. Hag-ElSafi (Khartoum, 1978) holds Bachelor of Science and Master of Science degrees in electronics and communications engineering from the Arab Academy for Science and Technology, earned in 2002 and 2004 respectively. He has 15 years of experience of research and industrial development in the areas of embedded systems and machine learning. He has published more than fifteen papers in the areas of IOT security, biometrics, machine learning, and medical image processing. He is currently the co-founder and principal researcher at Smart Empower Innovation Labs Inc. in Alberta, Canada. Mr. Hag-ElSafi is a member the Smart City Alliance in Alberta, Canada, and the Association of Professional Engineers and Geoscientists of Alberta (APEGA). Rami Zewail received Bachelor of Science and Master of Science degrees in electronics and communications engineering from the Arab Academy for Science and Technology, Egypt, earned in 2002 and 2004 respectively. He earned his PhD in electrical and computer engineering from the University of Alberta, Canada, in 2010. He has over 15 years of academic and industrial R&D experience in the areas of embedded systems and machine learning. He has contributed to the scientific community with a patent and over 19 publications in the areas of embedded computing, machine learning, and statistical modeling. Currently, he is co-founder and staff researcher at Smart Empower Innovations Labs Inc., a Canada-based R&D and consulting corporation specialized in the fields of embedded systems and machine learning.
Page
15
xvi Dr. Zewail is a member of the Institute of Electrical and Electronics Engineers (IEEE), the Association of Professional Engineers & Geoscientists (APEGA), and the Canadian Association for Artificial Intelligence. He also served as a reviewer for the Journal of Electronics Imaging and the Journal of Optical Engineering for the SPIE society in the United States. abouT The TeChniCal RevieweRs
Page
16
xvii Acknowledgments I would like to thank my parents, teachers, and family for inspiring me and encouraging me to pursue my passions. Without their help, this book and the very direction my career has taken would never have happened. I would also like to thank the countless and often nameless software engineers who came before us and laid the foundation upon which this book sits. Without their contributions to this industry and their inspiration, I would never have embarked on such an undertaking. I would also like to thank Salvador Almanza and Benjamin Sweet for acting as sounding boards and reviewing portions of the manuscript. Finally, I would like to thank Max “The Magnificient” Maxfield for encouraging me to write this book and sharing his publishing experiences with me.
Page
17
xix Preface In 2001, when I was a bright-eyed college sophomore, I would spend my evenings doing something a bit unusual—writing embedded software. Writing embedded software is not necessarily unusual, except that any observer would think that I wasn’t writing the software for any particular purpose. I was not designing any specific product or experimenting to understand how things work. Instead, I was focused on understanding how to write portable and reusable software for microcontroller-based systems. My idea and hope was that I could develop libraries and code modules that would allow me to quickly meet any project requirements that might be thrown my way. In theory, these libraries would allow me to get a microcontroller up and running and interface with external communication devices at a fraction of the time and cost that it would take if I started from scratch every time. Looking back on this endeavor, I realize that this was a pivotal period that would permeate my professional career, even now. Unfortunately, as a college student in 2001, the libraries and components that I created were written in assembly and closely tied to a single target device. Assembly language compilers were freely offered in those days, and the preferred C compilers cost several thousand dollars, with no code-size limitation trials. (The microcontrollers I was using did not have a GCC variant available at that time). The fortunes of time have thankfully made C compilers more readily available, and assembly language code has gone nearly the way of the dinosaurs. What is perhaps far more interesting about this tale is that this early interest in developing modular and reusable components in assembly language found its way into my professional career developing embedded software in C/C++. The result has been a steadily improving set of techniques, APIs, HALs, components, and design patterns that can be applied to resource-constrained embedded systems. As a consultant and technical educator, each year I work with companies by the dozens and engineers by the thousands who struggle to develop portable and reusable embedded software. Many efforts are repeated from one project to the next, resulting in wasted time, effort, money, and potential to innovate.
Page
18
xx One of my hopes with this book and the associated API and HAL Standard is to share my experiences and provide a framework that other developers may leverage and use in their own development efforts. My goal is that readers won’t just become better developers but will also be able to keep pace with the demanding modern development cycle and still have time to innovate and push the envelope. Implementing the processes and techniques contained in this book should help any developer decrease their development costs and time to market while improving the portability and reliability of their software. At a minimum, developers will find that they no longer need to keep reinventing the wheel every time a new project starts. Happy coding, Jacob Beningo September 2017 PRefaCe
Page
19
xxi Introduction Since the turn of the twenty-first century, microcontroller-based systems have become extremely complex. Microcontrollers started out as simple 8-bit devices running at bus speeds in the 8 MHz to 48 MHz range. Since then, microcontrollers have become complex and powerful 32-bit devices running at clock speeds faster than 200 MHz with every imaginable peripheral, including USB, TCP/IP, and Wi-Fi, and some microcontrollers now even have an internal cache. This dramatic explosion of capability and complexity has left the embedded software developer scrambling to understand how to do the following: • Shorten time to market • Keep budgets under control • Get to market on time • Manage their system’s complexity • Meet the client’s feature and innovation needs Traditionally, many embedded systems were written in such a way that the code was used once, on a single platform, and then tossed out. Software, for the most part, could be referred to as spaghetti code and did not follow any object-oriented or software-reuse model. In today’s development environment, developers need to write their software with reusability and portability in mind. The teams that are the most successful can leverage existing intellectual property and quickly innovate on it. The purpose of this book is to help the embedded software engineer learn and understand how they can develop reusable firmware that can be used across multiple microcontroller platforms and software products. The fundamental pieces to firmware reuse that we will be focusing on are HALs, APIs, and drivers. These are the core pieces that will allow us to develop a layered software architecture and define how those different layers interact with each other. Chapters 1 through 5 lay the foundation on which a developer can start writing reusable firmware. In these chapters, we examine the C constructs that best lend themselves to portability and define what a hardware abstraction layer (HAL) is and
Page
20
xxii how it differs from application programming interfaces (APIs). We will discuss different design methodologies developers can use to write low-level drivers and examine the design patterns, along with their pros and cons. Along the way, we’ll look at real- world examples and even take a chapter to discuss how reusable firmware should be documented. With the foundation laid, Chapters 6 through 10 examine the processes that can be followed to create HALs and APIs. We examine common elements, such as GPIO, SPI, and external memory devices, before moving on to looking at high-level application frameworks that can aid reuse and accelerate software design. Chapter 11 discusses how developers should develop tests to ensure that their reusable software remains usable with a minimal bug count. Finally, Chapter 12 walks developers through how they can start developing reusable software no matter the environment or challenges that they may be facing and how they can succeed in those environments. The chapters don’t necessarily need to be read in order, but they are put together in an order that builds upon what came before. A developer with reasonable experience developing reusable software could easily skip around whereas developers new to writing reusable software should read the chapters in order. inTRoduCTion
Comments 0
Loading comments...
Reply to Comment
Edit Comment