The process involved in architecting, designing, and writing embedded software and firmware is complicated, but I believe may be guided with a set of questions which must be continually evaluated by the engineering team as software development proceeds forward. This post provides a few of the questions I might be considering during my personal process.
Architecture and System
- Are product requirements substantially complete or will the product requirements likely change frequently? How does this impact the architecture?
- Will this product be a one-off design or create the foundation for a family of related products?
- Do the documented requirements represent only the end-user product expectations? What other users might have an interest in the software and product requirements?
- Factory/manufacturing? Calibration? Configuration?
- Serial numbers? Unique IDs?
- Technical support?
- Internal QA?
- Internal Engineering debug?
- Electronic/hardware required functionality?
- Certifying authorities?
- Business partners?
- Government entities?
- Does the product potentially impact human lives or safety?
- Does the product manage sensitive data, such as financial or medical information? How should the architecture support protecting such information?
- What specific functionality is required by the electronic/hardware design?
- Does the product support networking or other electronic access? How will the architecture secure the network interface to prevent illicit access?
- Does the product require real-time responsiveness? Are those requirements enumerated and justified?
- What are the reliability requirements?
- Will the product operate 24×7?
- Which software language(s) will be required?
- What open-source software will be included and how will the software architecture ensure license requirements are respected?
- What is the size of the software engineering team? How does this impact the architecture documentation and review process?
- Will the product and associated architecture require supporting software, such as custom packaging tools to create software update files?
- What other system components will interact with the product? What requirements are derived from that system? Do the external system components provide a development environment? If not, how will the product engineering team confirm and test behavior without disrupting existing services?
- What are the project management priorities: schedule, cost, or quality? Pick two. How does this impact the software architecture?
Would your team benefit from expert software architecture and design guidance? If so, please consider our architecture design service.
- Does the module being designed have a clear purpose?
- What is the role of the module being designed within the enclosing application?
- What is the role of the module within the system?
- What resources will this module require? What are the limits on those resources?
- Which requirements will this module support or implement?
- Does this software module violate or support the DRY principle?
- Do any certifying authorities require design and requirements traceability?
- How will (or will) the design be approved or reviewed by peers?
- Does this module require repeated and ongoing use of dynamic memory? If so, why? How does this impact real-time requirements? Does this impact reliability requirements?
- Are the methods or APIs of this module clear and easy to use correctly?
- Does this module make use of any units of measurement? Are the units documented clearly, and if possible, enforced by the build system to prevent errors, including catastrophic errors?
- Is this design over-engineered?
- Should this module be refactored?
- How large should the stack be for this module/thread? How will I test and confirm stack usage?
- Did I write a test before coding? If not, why not? How will I test this code?
- How will I debug this code?
- Why is this code required?
- Is there a coding standard? If not, why not? If not, will I create my own standard for this project?
- Is this variable/function/class/method named clearly? Will I understand the name 9 months from now?
- Does this section of code implement a documented industry standard? Do the code comments properly reference the standard?
- Did this code “hack” around some hardware deficiency? Do the comments note the issue and why the hack was required?
- Does this code operate in a multi-threaded environment? If so, how many threads might access this portion of the code? Is the code thread-safe? Can I prove it?
- Will the code as written help prevent maintenance errors in the future?
- Will this simple integer increment overflow? Do I care?
- Did I just use CTRL+C and CTRL+V to author new code? Why? Should this code be refactored instead?
- Is this routine too long?
- Did I just use a magic number? Why? If the magic number is required by some hardware setup and configuration, does the code document the hardware reference where the magic number was found?
- Am I proud of this code? Or would I feel compelled to offer excuses when the code is exposed to a peer?
- Does this code impact the product’s real or soft timing requirements? How will the code contribute to the requirement? How will this be measured?
- Did I just fix a bug reported by the end user or customer? How did I create that bug in the first place? How can I prevent the creation of that bug in the future? Have other bugs recently been fixed in this same code?
- Does the code use recursion? Why? What is the impact on stack usage?
- Can I read this code easily or do I need a reference book to comprehend the acronym soup?
- Are the code comments professional and clean? Would I be comfortable with a jury of my peers reading those comments in a court of law?
- Are the code comments providing appropriate meta-information, or are they simply repeating what is evident from the code itself?
- Does the code use various C string functions, potentially exposing end customers to serious security flaws?
- Does this code have an off-by-one error?
- Is it time to stop thinking and start writing code?
- Did I stop thinking too soon?
- The code written allocates an object on the stack. How large is that object? Is that acceptable in this thread’s stack context?
- That C struct allocated on the stack: was it initialized correctly? Was every field initialized correctly?
- Did function correctly check the bounds of the input arguments? Are the inputs valid?
- What is the context of this code? A thread? An interrupt service routine (ISR)? A Timer callback? What are the coding requirements when writing code in this context?
That list seems long enough for now! What would you add to the list?
Would your team benefit from decades of experience in coding embedded software and firmware? If so, please consider our contracting and consulting services.
Related post: The Matthew Test: 15 Steps to Better Embedded Software (and Firmware)
Photo by mari lezhava on Unsplash