How do you structure large embedded projects? [closed]How do you go about designing a circuit?Designing Embedded SoftwareDesigning FPGA code in block diagramsWhy is hardware multithreading not more common in embedded systems?CPLD: my first projectDo Electrical Engineers use microcontrollers?How to create an embeded system for LCD GUI design? How to choose an MCU?Confused what computer architecture is in realSTM32 timing critical ADC outline codeIs it Possible to Design an Entire Operating System or App using ASIC Chips?

How did Biff return to 2015 from 1955 without a lightning strike?

Gold Battle KoTH

Patio gate not at right angle to the house

Stationing Callouts using VBScript Labeling in ArcMap?

Can I shorten this filter, that finds disk sizes over 100G?

When did J.K. Rowling decide to make Ron and Hermione a couple?

What is the term for completing a route uncleanly?

What is the range of a Drunken Monk's Redirect attack?

Would people understand me speaking German all over Europe?

LWC: Removing a class name on scroll

Move arrows along a contour

Should 2FA be enabled on service accounts?

My employer is refusing to give me the pay that was advertised after an internal job move

Create and use Object Variable

Russian pronunciation of /etc (a directory)

How to get Planck length in meters to 6 decimal places

What clothes would flying-people wear?

Word for giving preference to the oldest child

Why didn't General Martok receive discommendation in Star Trek: Deep Space Nine?

How can a class have multiple methods without breaking the single responsibility principle

NULL value causes blank row in SELECT results for text concatenation

How to prevent a single-element caster from being useless against immune foes?

What do the novel titles of The Expanse series refer to?

Password management for kids - what's a good way to start?



How do you structure large embedded projects? [closed]


How do you go about designing a circuit?Designing Embedded SoftwareDesigning FPGA code in block diagramsWhy is hardware multithreading not more common in embedded systems?CPLD: my first projectDo Electrical Engineers use microcontrollers?How to create an embeded system for LCD GUI design? How to choose an MCU?Confused what computer architecture is in realSTM32 timing critical ADC outline codeIs it Possible to Design an Entire Operating System or App using ASIC Chips?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








20












$begingroup$


Background:



Junior R&D electronics engineer (the only EE in the company) -
the hardware and the coding is not the problem. My biggest issue is getting a proper overview of the project, and where to start.



So far I've only made minor software projects (sub 500 lines of code), but I can't envision myself doing larger projects without losing overview of the functionality or lack of functionality.



How do you best structure / what tools do you use to structure large embedded software systems?



What I'm currently doing:



I usually start out, by sketching the functionality of the project.
It could be one to many layered flow charts or related diagrams (block diagrams, etc.) and doing some research of the components/chips. Then I jump straight into coding (fail fast I guess) while referencing the datasheets / Internet,
Coding one functionality at a time and testing it with dummy data, or similar test. It could be writing data to a MEM chip, and then if that works then
it could be an SPI driver between the main chip and the MEM chip.



What answer I'm looking for:



Anything really. I will sort out what I find sensible. It could be a book, an article, personal experience, recommendations, etc.



I'm very interested in knowing how seniors tackle this.




Edit



First off, thank you for sharing your years of experience! All the answers are much appreciated. My take from this is;



  • Create a clear and precise specification document.

  • Create a software design document. (Something I will now add)
    Design doc templates

  • Think in modules how ever redundant it may seem. (Something I need to focus more on)

  • Follow a coding standard for structuring header/source files. (Never did this)
    Barr Group C standard

  • Focus on creating the low level implementations first. (Communication etc.)

  • Implement design patterns where ever possible/sensible.
    Design patterns

  • Set up something for revision control (Github etc. - never used this much)

  • Research continuous integration / continuous deployment (Something new I stumbled upon)
    CI & CD basics









share|improve this question











$endgroup$




closed as primarily opinion-based by Elliot Alderson, filo, pipe, Dmitry Grigoryev, dim Jul 23 at 11:01


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.














  • 4




    $begingroup$
    This question does not belong here... May be on softwareengineering.stackexchange.com
    $endgroup$
    – Swanand
    Jul 22 at 7:25






  • 11




    $begingroup$
    Maybe this question does belong here. I honcho'd a multiple-chip design team, decades ago, and we tracked the progress by decomposing each of the chips into the various functions, and then estimating the weeks needed for (a team of newbies, motivated, but newbies) understanding/design/testing/reviewing of each of the 60+ functions. Even tho we did not meet the original management-imposed schedule, management was patient because they could easily track progress thru the 60+ functions we knew we needed to design and then integrate.
    $endgroup$
    – analogsystemsrf
    Jul 22 at 7:30







  • 13




    $begingroup$
    @Swanand I disagree. The on-topic FAQ says "[questions about...] the writing of firmware for bare-metal or RTOS applications" - I would say this definitely also includes the planning phase. The question specifically states "large embedded systems".
    $endgroup$
    – Araho
    Jul 22 at 7:55






  • 2




    $begingroup$
    While firmware programming is on-topic here, a good way to see if a question is too broad and opinion-based is the number of answers in a short time period. This is definitely too broad. The help section says something like "if a book can be written..", and books have been written about this!
    $endgroup$
    – pipe
    Jul 22 at 20:33






  • 2




    $begingroup$
    OP has created a good summary. I would just like to emphasize to them that GitHub is not the only way to run a Git repository. You can do so locally, with or without a special Git server running. Git is not the only form of Source Control System (SCS) / Version Control System (VCS) but it is a very popular one now. When I started as an EE with lots of C and C++ training I had zero exposure to such things.
    $endgroup$
    – TafT
    Jul 23 at 7:59

















20












$begingroup$


Background:



Junior R&D electronics engineer (the only EE in the company) -
the hardware and the coding is not the problem. My biggest issue is getting a proper overview of the project, and where to start.



So far I've only made minor software projects (sub 500 lines of code), but I can't envision myself doing larger projects without losing overview of the functionality or lack of functionality.



How do you best structure / what tools do you use to structure large embedded software systems?



What I'm currently doing:



I usually start out, by sketching the functionality of the project.
It could be one to many layered flow charts or related diagrams (block diagrams, etc.) and doing some research of the components/chips. Then I jump straight into coding (fail fast I guess) while referencing the datasheets / Internet,
Coding one functionality at a time and testing it with dummy data, or similar test. It could be writing data to a MEM chip, and then if that works then
it could be an SPI driver between the main chip and the MEM chip.



What answer I'm looking for:



Anything really. I will sort out what I find sensible. It could be a book, an article, personal experience, recommendations, etc.



I'm very interested in knowing how seniors tackle this.




Edit



First off, thank you for sharing your years of experience! All the answers are much appreciated. My take from this is;



  • Create a clear and precise specification document.

  • Create a software design document. (Something I will now add)
    Design doc templates

  • Think in modules how ever redundant it may seem. (Something I need to focus more on)

  • Follow a coding standard for structuring header/source files. (Never did this)
    Barr Group C standard

  • Focus on creating the low level implementations first. (Communication etc.)

  • Implement design patterns where ever possible/sensible.
    Design patterns

  • Set up something for revision control (Github etc. - never used this much)

  • Research continuous integration / continuous deployment (Something new I stumbled upon)
    CI & CD basics









share|improve this question











$endgroup$




closed as primarily opinion-based by Elliot Alderson, filo, pipe, Dmitry Grigoryev, dim Jul 23 at 11:01


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.














  • 4




    $begingroup$
    This question does not belong here... May be on softwareengineering.stackexchange.com
    $endgroup$
    – Swanand
    Jul 22 at 7:25






  • 11




    $begingroup$
    Maybe this question does belong here. I honcho'd a multiple-chip design team, decades ago, and we tracked the progress by decomposing each of the chips into the various functions, and then estimating the weeks needed for (a team of newbies, motivated, but newbies) understanding/design/testing/reviewing of each of the 60+ functions. Even tho we did not meet the original management-imposed schedule, management was patient because they could easily track progress thru the 60+ functions we knew we needed to design and then integrate.
    $endgroup$
    – analogsystemsrf
    Jul 22 at 7:30







  • 13




    $begingroup$
    @Swanand I disagree. The on-topic FAQ says "[questions about...] the writing of firmware for bare-metal or RTOS applications" - I would say this definitely also includes the planning phase. The question specifically states "large embedded systems".
    $endgroup$
    – Araho
    Jul 22 at 7:55






  • 2




    $begingroup$
    While firmware programming is on-topic here, a good way to see if a question is too broad and opinion-based is the number of answers in a short time period. This is definitely too broad. The help section says something like "if a book can be written..", and books have been written about this!
    $endgroup$
    – pipe
    Jul 22 at 20:33






  • 2




    $begingroup$
    OP has created a good summary. I would just like to emphasize to them that GitHub is not the only way to run a Git repository. You can do so locally, with or without a special Git server running. Git is not the only form of Source Control System (SCS) / Version Control System (VCS) but it is a very popular one now. When I started as an EE with lots of C and C++ training I had zero exposure to such things.
    $endgroup$
    – TafT
    Jul 23 at 7:59













20












20








20


11



$begingroup$


Background:



Junior R&D electronics engineer (the only EE in the company) -
the hardware and the coding is not the problem. My biggest issue is getting a proper overview of the project, and where to start.



So far I've only made minor software projects (sub 500 lines of code), but I can't envision myself doing larger projects without losing overview of the functionality or lack of functionality.



How do you best structure / what tools do you use to structure large embedded software systems?



What I'm currently doing:



I usually start out, by sketching the functionality of the project.
It could be one to many layered flow charts or related diagrams (block diagrams, etc.) and doing some research of the components/chips. Then I jump straight into coding (fail fast I guess) while referencing the datasheets / Internet,
Coding one functionality at a time and testing it with dummy data, or similar test. It could be writing data to a MEM chip, and then if that works then
it could be an SPI driver between the main chip and the MEM chip.



What answer I'm looking for:



Anything really. I will sort out what I find sensible. It could be a book, an article, personal experience, recommendations, etc.



I'm very interested in knowing how seniors tackle this.




Edit



First off, thank you for sharing your years of experience! All the answers are much appreciated. My take from this is;



  • Create a clear and precise specification document.

  • Create a software design document. (Something I will now add)
    Design doc templates

  • Think in modules how ever redundant it may seem. (Something I need to focus more on)

  • Follow a coding standard for structuring header/source files. (Never did this)
    Barr Group C standard

  • Focus on creating the low level implementations first. (Communication etc.)

  • Implement design patterns where ever possible/sensible.
    Design patterns

  • Set up something for revision control (Github etc. - never used this much)

  • Research continuous integration / continuous deployment (Something new I stumbled upon)
    CI & CD basics









share|improve this question











$endgroup$




Background:



Junior R&D electronics engineer (the only EE in the company) -
the hardware and the coding is not the problem. My biggest issue is getting a proper overview of the project, and where to start.



So far I've only made minor software projects (sub 500 lines of code), but I can't envision myself doing larger projects without losing overview of the functionality or lack of functionality.



How do you best structure / what tools do you use to structure large embedded software systems?



What I'm currently doing:



I usually start out, by sketching the functionality of the project.
It could be one to many layered flow charts or related diagrams (block diagrams, etc.) and doing some research of the components/chips. Then I jump straight into coding (fail fast I guess) while referencing the datasheets / Internet,
Coding one functionality at a time and testing it with dummy data, or similar test. It could be writing data to a MEM chip, and then if that works then
it could be an SPI driver between the main chip and the MEM chip.



What answer I'm looking for:



Anything really. I will sort out what I find sensible. It could be a book, an article, personal experience, recommendations, etc.



I'm very interested in knowing how seniors tackle this.




Edit



First off, thank you for sharing your years of experience! All the answers are much appreciated. My take from this is;



  • Create a clear and precise specification document.

  • Create a software design document. (Something I will now add)
    Design doc templates

  • Think in modules how ever redundant it may seem. (Something I need to focus more on)

  • Follow a coding standard for structuring header/source files. (Never did this)
    Barr Group C standard

  • Focus on creating the low level implementations first. (Communication etc.)

  • Implement design patterns where ever possible/sensible.
    Design patterns

  • Set up something for revision control (Github etc. - never used this much)

  • Research continuous integration / continuous deployment (Something new I stumbled upon)
    CI & CD basics






microcontroller embedded design software






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 23 at 6:29







Sorenp

















asked Jul 22 at 7:18









SorenpSorenp

35212 bronze badges




35212 bronze badges





closed as primarily opinion-based by Elliot Alderson, filo, pipe, Dmitry Grigoryev, dim Jul 23 at 11:01


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.











closed as primarily opinion-based by Elliot Alderson, filo, pipe, Dmitry Grigoryev, dim Jul 23 at 11:01


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.









closed as primarily opinion-based by Elliot Alderson, filo, pipe, Dmitry Grigoryev, dim Jul 23 at 11:01


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.









  • 4




    $begingroup$
    This question does not belong here... May be on softwareengineering.stackexchange.com
    $endgroup$
    – Swanand
    Jul 22 at 7:25






  • 11




    $begingroup$
    Maybe this question does belong here. I honcho'd a multiple-chip design team, decades ago, and we tracked the progress by decomposing each of the chips into the various functions, and then estimating the weeks needed for (a team of newbies, motivated, but newbies) understanding/design/testing/reviewing of each of the 60+ functions. Even tho we did not meet the original management-imposed schedule, management was patient because they could easily track progress thru the 60+ functions we knew we needed to design and then integrate.
    $endgroup$
    – analogsystemsrf
    Jul 22 at 7:30







  • 13




    $begingroup$
    @Swanand I disagree. The on-topic FAQ says "[questions about...] the writing of firmware for bare-metal or RTOS applications" - I would say this definitely also includes the planning phase. The question specifically states "large embedded systems".
    $endgroup$
    – Araho
    Jul 22 at 7:55






  • 2




    $begingroup$
    While firmware programming is on-topic here, a good way to see if a question is too broad and opinion-based is the number of answers in a short time period. This is definitely too broad. The help section says something like "if a book can be written..", and books have been written about this!
    $endgroup$
    – pipe
    Jul 22 at 20:33






  • 2




    $begingroup$
    OP has created a good summary. I would just like to emphasize to them that GitHub is not the only way to run a Git repository. You can do so locally, with or without a special Git server running. Git is not the only form of Source Control System (SCS) / Version Control System (VCS) but it is a very popular one now. When I started as an EE with lots of C and C++ training I had zero exposure to such things.
    $endgroup$
    – TafT
    Jul 23 at 7:59












  • 4




    $begingroup$
    This question does not belong here... May be on softwareengineering.stackexchange.com
    $endgroup$
    – Swanand
    Jul 22 at 7:25






  • 11




    $begingroup$
    Maybe this question does belong here. I honcho'd a multiple-chip design team, decades ago, and we tracked the progress by decomposing each of the chips into the various functions, and then estimating the weeks needed for (a team of newbies, motivated, but newbies) understanding/design/testing/reviewing of each of the 60+ functions. Even tho we did not meet the original management-imposed schedule, management was patient because they could easily track progress thru the 60+ functions we knew we needed to design and then integrate.
    $endgroup$
    – analogsystemsrf
    Jul 22 at 7:30







  • 13




    $begingroup$
    @Swanand I disagree. The on-topic FAQ says "[questions about...] the writing of firmware for bare-metal or RTOS applications" - I would say this definitely also includes the planning phase. The question specifically states "large embedded systems".
    $endgroup$
    – Araho
    Jul 22 at 7:55






  • 2




    $begingroup$
    While firmware programming is on-topic here, a good way to see if a question is too broad and opinion-based is the number of answers in a short time period. This is definitely too broad. The help section says something like "if a book can be written..", and books have been written about this!
    $endgroup$
    – pipe
    Jul 22 at 20:33






  • 2




    $begingroup$
    OP has created a good summary. I would just like to emphasize to them that GitHub is not the only way to run a Git repository. You can do so locally, with or without a special Git server running. Git is not the only form of Source Control System (SCS) / Version Control System (VCS) but it is a very popular one now. When I started as an EE with lots of C and C++ training I had zero exposure to such things.
    $endgroup$
    – TafT
    Jul 23 at 7:59







4




4




$begingroup$
This question does not belong here... May be on softwareengineering.stackexchange.com
$endgroup$
– Swanand
Jul 22 at 7:25




$begingroup$
This question does not belong here... May be on softwareengineering.stackexchange.com
$endgroup$
– Swanand
Jul 22 at 7:25




11




11




$begingroup$
Maybe this question does belong here. I honcho'd a multiple-chip design team, decades ago, and we tracked the progress by decomposing each of the chips into the various functions, and then estimating the weeks needed for (a team of newbies, motivated, but newbies) understanding/design/testing/reviewing of each of the 60+ functions. Even tho we did not meet the original management-imposed schedule, management was patient because they could easily track progress thru the 60+ functions we knew we needed to design and then integrate.
$endgroup$
– analogsystemsrf
Jul 22 at 7:30





$begingroup$
Maybe this question does belong here. I honcho'd a multiple-chip design team, decades ago, and we tracked the progress by decomposing each of the chips into the various functions, and then estimating the weeks needed for (a team of newbies, motivated, but newbies) understanding/design/testing/reviewing of each of the 60+ functions. Even tho we did not meet the original management-imposed schedule, management was patient because they could easily track progress thru the 60+ functions we knew we needed to design and then integrate.
$endgroup$
– analogsystemsrf
Jul 22 at 7:30





13




13




$begingroup$
@Swanand I disagree. The on-topic FAQ says "[questions about...] the writing of firmware for bare-metal or RTOS applications" - I would say this definitely also includes the planning phase. The question specifically states "large embedded systems".
$endgroup$
– Araho
Jul 22 at 7:55




$begingroup$
@Swanand I disagree. The on-topic FAQ says "[questions about...] the writing of firmware for bare-metal or RTOS applications" - I would say this definitely also includes the planning phase. The question specifically states "large embedded systems".
$endgroup$
– Araho
Jul 22 at 7:55




2




2




$begingroup$
While firmware programming is on-topic here, a good way to see if a question is too broad and opinion-based is the number of answers in a short time period. This is definitely too broad. The help section says something like "if a book can be written..", and books have been written about this!
$endgroup$
– pipe
Jul 22 at 20:33




$begingroup$
While firmware programming is on-topic here, a good way to see if a question is too broad and opinion-based is the number of answers in a short time period. This is definitely too broad. The help section says something like "if a book can be written..", and books have been written about this!
$endgroup$
– pipe
Jul 22 at 20:33




2




2




$begingroup$
OP has created a good summary. I would just like to emphasize to them that GitHub is not the only way to run a Git repository. You can do so locally, with or without a special Git server running. Git is not the only form of Source Control System (SCS) / Version Control System (VCS) but it is a very popular one now. When I started as an EE with lots of C and C++ training I had zero exposure to such things.
$endgroup$
– TafT
Jul 23 at 7:59




$begingroup$
OP has created a good summary. I would just like to emphasize to them that GitHub is not the only way to run a Git repository. You can do so locally, with or without a special Git server running. Git is not the only form of Source Control System (SCS) / Version Control System (VCS) but it is a very popular one now. When I started as an EE with lots of C and C++ training I had zero exposure to such things.
$endgroup$
– TafT
Jul 23 at 7:59










6 Answers
6






active

oldest

votes


















21












$begingroup$

There are several aspects influencing the grade of detail the structuring of a project needs. For me one of the main factors is whether I'm the only one coding (what seems to be the case for you as you write you're the only EE) or if there are others involved.
Then there's the question of what "large" actually means. Usually I divide the design process into the following steps:



Requirement definition
If you get proper software specification to work with a lot of planning is already done. If you just get vague requirements, the first thing you have to do is to sort out what the customer actually wants (sometimes they don't really know in the first place). I know it's tempting to just jump right into coding, but that brings the risk of missing an important feature that might was not obvious in the first place and can't just be easily squeezed into your code just somewhere in the middle of development.



System boundaries and maintainability
In embedded systems you often have some system interfaces, some to the outside (operator) but also on the inside. Define these well and try to keep dependencies as low as possible, this will simplify continuous engineering and maintainability. Also comment/document code where needed, you never know who else will have to work with it, (s)he will be happy to not have to dig though a dozen layers of code before actually knowing what a function does.



Define verifiable tasks
Especially if other developers are working on the same code base it's inevitable to define clear tasks (features) and the required interfaces between them. Whenever possible the individual features should be tested/verified independent from others, that's where you need the interfaces well defined so you can define your test cases.



One feature after the other
People like progress, so if you have a variety of tasks they usually work on whatever promises the most progress. I usually try to finish a task and bring it to a verified and tested state before I start with the next one. This allows your code to be tested by others and you not ending up forgetting something.



Revision Control
During the life of a project you sometimes need older versions, maybe to identify a bug introduced with some new release or just to build a device that behaves exactly the same way as one you shipped 3 years ago. Make sure you have clear build revisions and tags in your code. Git is definitely your friend here.






share|improve this answer











$endgroup$










  • 3




    $begingroup$
    Especially the requirements! Nothing like building a product or function that does the wrong thing.
    $endgroup$
    – ConcernedHobbit
    Jul 22 at 17:19



















12












$begingroup$

Humpawumpa wrote a great answer! I just want to supplement some of his points, but since this is too long to be a comment, I'll write a separate answer.



I was once in the OP's position — not the only EE, but the only EE who had done any MCU development in a small company.



I can't emphasize the importance of modularity enough, even if you're the only developer. It's the only way to stay sane as the project grows. You need to be strict about writing modules that handle only one functional concept each, and keep their external interfaces as minimal as possible. High-level modules will correspond to functional requirements, while low-level modules will have close ties to hardware resources (i.e., device drivers).



I spent a lot of time maintaining a detailed data flow diagram1, which showed precisely how the various modules shared information. Some features will have very different requirements in terms of real-time performance; make sure you know how the information sharing affects that. The diagram had boundaries drawn across it that separated the non-interrupt code from the various interrupt-driven domains.




1 Very different from a flowchart, which is focused on control flow.






share|improve this answer









$endgroup$






















    11












    $begingroup$

    For any large project, I plan it as if there were multiple developers involved even if I intend to do the whole thing myself.



    The reasons are simple:



    1 Complexity. A large project will always have complexities involved. Having planned the project as if there were multiple teams involved means that complexity has been considered and documented. The number of times I have seen large projects run into problems is high and usually because something 'slipped through the cracks'. Do not forget that mechanical assembly must also be considered and not simply for the size of the box - will there be a need for heat sinks? Must the box be earthed for safety? There are many questions in this category alone.



    2 Requirements. Assuming multiple people are involved means that the top level requirements (which I often challenge as they may bring unnecessary complexity and cost) must be broken down into the various smaller required and achievable tasks (which could be fed to a another team in a larger organisation) rather than just looking at a single blob.



    3 Partitioning. There are two primary types of partitioning; hardware functionality and hardware / software. The first type is to determine what separate (but communicating) functional blocks need to be present. The second is a trade-off of simpler (sometimes) hardware and software but keep in mind that simply moving more things to software will not necessarily fix a hardware problem. Moving more into software can actually vastly increase hardware complexity in some circumstances (more processing horsepower, more complex interfaces and more).



    4 Interfaces. The partitioning process will help define internal interfaces; external interfaces are usually part of the overall requirements (although not always). There are many ways for different parts of a system to co-operate which may be a complex communications protocol or simply good / bad signalling.



    5 Verification. This is a mixture of low level testing (for hardware and drivers) and system level. Having done the project in well defined blocks permits robust verification (which may be by analysis or actual test and is usually a mixture of the two; updates to designs may use similarity arguments).



    6 Standards. I use coding and drawing standards as if it were a larger team. I use Barr group's coding standards as they are not too onerous but do prevent many classes of bug being in the code. For PCB output documentation I follow IPC-D-326 (which calls up IPC-D-325) as that is a proven method of communicating my intent to PCB fabricators and assemblers. This may seem strange but having the discipline to follow a number of standards means that the quality is consistent.



    7 Version control. I use revision control for all parts of the project (system, hardware, software. mechanical, test requirements - everything). The CAD tools I use support such versioning as do all the software and FPGA build tools.



    I have worked on many embedded projects (as have many of the experienced folk around here) and the team sizes have varied from 1 (myself) to dozens (or hundreds on a particular set of projects) spread across multiple disciplines and sometimes other geographically remote sites. Using the same over-arching approach (that is known to work) means I can pick up a particular task in relative isolation and complete it and thoroughly test it as a stand-alone part of the larger project. It also means I can sub some things out on occasion if necessary.



    Doing all these things adds a bit of up-front time but is ultimately a faster route for complex embedded systems.






    share|improve this answer









    $endgroup$






















      5












      $begingroup$

      The other answers give many great tips. Here are two that I've found the most important in my embedded development career:



      1. Make as much of the code into separate, well defined modules as possible.

      2. Make the modules automatically testable on PC.

      That's what you need for doing "continuous integration" style development on embedded systems. There will always be some amount of code that is too tightly tied to hardware for automatic testing, but try to minimize it. You can get quite far by using simulated data or data captures from actual hardware, which you then feed into the test system.






      share|improve this answer









      $endgroup$






















        4












        $begingroup$

        To add to existing answers...



        I always start from the bottom up. From your hardware design, you know what your I/O is. Start by building driver modules which encapsulate that I/O, so that your high level code doesn't have to know too much about the low level stuff.



        When you're building the low level interfaces, of course you need a test harness. If you design this to hook up to the PC from the start (perhaps with an RS-232 port, perhaps USB, perhaps telnet over Ethernet) then you can keep this test harness interface in place as you build your application. You can keep adding more test harness hooks as the application takes shape, and that'll let you regression-test your code as you go on as well.






        share|improve this answer









        $endgroup$






















          3












          $begingroup$

          I tend to think in four questions. The first two belong to the start of a systems project, the two next towards the end.



          1. Do they actually want the system? Will the system solve the customers problem, at a time and cost scale they will accept? A common problem is building systems that the customer will not use.


          2. Can we actually build that system? Will it be possibly to deliver the necessary performance, precision, power usage, ... ?



          Creating early prototypes is a good way to answer these two first questions. Risk mitigation is extremely important in the early phases.




          The next two questions are more targeted at the later phases of the the project:



          1. are we actually finished? Everything designed, coded, tested, delivered


          2. Do they actually use the system?






          share|improve this answer











          $endgroup$























            6 Answers
            6






            active

            oldest

            votes








            6 Answers
            6






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            21












            $begingroup$

            There are several aspects influencing the grade of detail the structuring of a project needs. For me one of the main factors is whether I'm the only one coding (what seems to be the case for you as you write you're the only EE) or if there are others involved.
            Then there's the question of what "large" actually means. Usually I divide the design process into the following steps:



            Requirement definition
            If you get proper software specification to work with a lot of planning is already done. If you just get vague requirements, the first thing you have to do is to sort out what the customer actually wants (sometimes they don't really know in the first place). I know it's tempting to just jump right into coding, but that brings the risk of missing an important feature that might was not obvious in the first place and can't just be easily squeezed into your code just somewhere in the middle of development.



            System boundaries and maintainability
            In embedded systems you often have some system interfaces, some to the outside (operator) but also on the inside. Define these well and try to keep dependencies as low as possible, this will simplify continuous engineering and maintainability. Also comment/document code where needed, you never know who else will have to work with it, (s)he will be happy to not have to dig though a dozen layers of code before actually knowing what a function does.



            Define verifiable tasks
            Especially if other developers are working on the same code base it's inevitable to define clear tasks (features) and the required interfaces between them. Whenever possible the individual features should be tested/verified independent from others, that's where you need the interfaces well defined so you can define your test cases.



            One feature after the other
            People like progress, so if you have a variety of tasks they usually work on whatever promises the most progress. I usually try to finish a task and bring it to a verified and tested state before I start with the next one. This allows your code to be tested by others and you not ending up forgetting something.



            Revision Control
            During the life of a project you sometimes need older versions, maybe to identify a bug introduced with some new release or just to build a device that behaves exactly the same way as one you shipped 3 years ago. Make sure you have clear build revisions and tags in your code. Git is definitely your friend here.






            share|improve this answer











            $endgroup$










            • 3




              $begingroup$
              Especially the requirements! Nothing like building a product or function that does the wrong thing.
              $endgroup$
              – ConcernedHobbit
              Jul 22 at 17:19
















            21












            $begingroup$

            There are several aspects influencing the grade of detail the structuring of a project needs. For me one of the main factors is whether I'm the only one coding (what seems to be the case for you as you write you're the only EE) or if there are others involved.
            Then there's the question of what "large" actually means. Usually I divide the design process into the following steps:



            Requirement definition
            If you get proper software specification to work with a lot of planning is already done. If you just get vague requirements, the first thing you have to do is to sort out what the customer actually wants (sometimes they don't really know in the first place). I know it's tempting to just jump right into coding, but that brings the risk of missing an important feature that might was not obvious in the first place and can't just be easily squeezed into your code just somewhere in the middle of development.



            System boundaries and maintainability
            In embedded systems you often have some system interfaces, some to the outside (operator) but also on the inside. Define these well and try to keep dependencies as low as possible, this will simplify continuous engineering and maintainability. Also comment/document code where needed, you never know who else will have to work with it, (s)he will be happy to not have to dig though a dozen layers of code before actually knowing what a function does.



            Define verifiable tasks
            Especially if other developers are working on the same code base it's inevitable to define clear tasks (features) and the required interfaces between them. Whenever possible the individual features should be tested/verified independent from others, that's where you need the interfaces well defined so you can define your test cases.



            One feature after the other
            People like progress, so if you have a variety of tasks they usually work on whatever promises the most progress. I usually try to finish a task and bring it to a verified and tested state before I start with the next one. This allows your code to be tested by others and you not ending up forgetting something.



            Revision Control
            During the life of a project you sometimes need older versions, maybe to identify a bug introduced with some new release or just to build a device that behaves exactly the same way as one you shipped 3 years ago. Make sure you have clear build revisions and tags in your code. Git is definitely your friend here.






            share|improve this answer











            $endgroup$










            • 3




              $begingroup$
              Especially the requirements! Nothing like building a product or function that does the wrong thing.
              $endgroup$
              – ConcernedHobbit
              Jul 22 at 17:19














            21












            21








            21





            $begingroup$

            There are several aspects influencing the grade of detail the structuring of a project needs. For me one of the main factors is whether I'm the only one coding (what seems to be the case for you as you write you're the only EE) or if there are others involved.
            Then there's the question of what "large" actually means. Usually I divide the design process into the following steps:



            Requirement definition
            If you get proper software specification to work with a lot of planning is already done. If you just get vague requirements, the first thing you have to do is to sort out what the customer actually wants (sometimes they don't really know in the first place). I know it's tempting to just jump right into coding, but that brings the risk of missing an important feature that might was not obvious in the first place and can't just be easily squeezed into your code just somewhere in the middle of development.



            System boundaries and maintainability
            In embedded systems you often have some system interfaces, some to the outside (operator) but also on the inside. Define these well and try to keep dependencies as low as possible, this will simplify continuous engineering and maintainability. Also comment/document code where needed, you never know who else will have to work with it, (s)he will be happy to not have to dig though a dozen layers of code before actually knowing what a function does.



            Define verifiable tasks
            Especially if other developers are working on the same code base it's inevitable to define clear tasks (features) and the required interfaces between them. Whenever possible the individual features should be tested/verified independent from others, that's where you need the interfaces well defined so you can define your test cases.



            One feature after the other
            People like progress, so if you have a variety of tasks they usually work on whatever promises the most progress. I usually try to finish a task and bring it to a verified and tested state before I start with the next one. This allows your code to be tested by others and you not ending up forgetting something.



            Revision Control
            During the life of a project you sometimes need older versions, maybe to identify a bug introduced with some new release or just to build a device that behaves exactly the same way as one you shipped 3 years ago. Make sure you have clear build revisions and tags in your code. Git is definitely your friend here.






            share|improve this answer











            $endgroup$



            There are several aspects influencing the grade of detail the structuring of a project needs. For me one of the main factors is whether I'm the only one coding (what seems to be the case for you as you write you're the only EE) or if there are others involved.
            Then there's the question of what "large" actually means. Usually I divide the design process into the following steps:



            Requirement definition
            If you get proper software specification to work with a lot of planning is already done. If you just get vague requirements, the first thing you have to do is to sort out what the customer actually wants (sometimes they don't really know in the first place). I know it's tempting to just jump right into coding, but that brings the risk of missing an important feature that might was not obvious in the first place and can't just be easily squeezed into your code just somewhere in the middle of development.



            System boundaries and maintainability
            In embedded systems you often have some system interfaces, some to the outside (operator) but also on the inside. Define these well and try to keep dependencies as low as possible, this will simplify continuous engineering and maintainability. Also comment/document code where needed, you never know who else will have to work with it, (s)he will be happy to not have to dig though a dozen layers of code before actually knowing what a function does.



            Define verifiable tasks
            Especially if other developers are working on the same code base it's inevitable to define clear tasks (features) and the required interfaces between them. Whenever possible the individual features should be tested/verified independent from others, that's where you need the interfaces well defined so you can define your test cases.



            One feature after the other
            People like progress, so if you have a variety of tasks they usually work on whatever promises the most progress. I usually try to finish a task and bring it to a verified and tested state before I start with the next one. This allows your code to be tested by others and you not ending up forgetting something.



            Revision Control
            During the life of a project you sometimes need older versions, maybe to identify a bug introduced with some new release or just to build a device that behaves exactly the same way as one you shipped 3 years ago. Make sure you have clear build revisions and tags in your code. Git is definitely your friend here.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 22 at 12:06









            Dave Tweed

            132k11 gold badges165 silver badges283 bronze badges




            132k11 gold badges165 silver badges283 bronze badges










            answered Jul 22 at 10:25









            HumpawumpaHumpawumpa

            1,6384 silver badges17 bronze badges




            1,6384 silver badges17 bronze badges










            • 3




              $begingroup$
              Especially the requirements! Nothing like building a product or function that does the wrong thing.
              $endgroup$
              – ConcernedHobbit
              Jul 22 at 17:19













            • 3




              $begingroup$
              Especially the requirements! Nothing like building a product or function that does the wrong thing.
              $endgroup$
              – ConcernedHobbit
              Jul 22 at 17:19








            3




            3




            $begingroup$
            Especially the requirements! Nothing like building a product or function that does the wrong thing.
            $endgroup$
            – ConcernedHobbit
            Jul 22 at 17:19





            $begingroup$
            Especially the requirements! Nothing like building a product or function that does the wrong thing.
            $endgroup$
            – ConcernedHobbit
            Jul 22 at 17:19














            12












            $begingroup$

            Humpawumpa wrote a great answer! I just want to supplement some of his points, but since this is too long to be a comment, I'll write a separate answer.



            I was once in the OP's position — not the only EE, but the only EE who had done any MCU development in a small company.



            I can't emphasize the importance of modularity enough, even if you're the only developer. It's the only way to stay sane as the project grows. You need to be strict about writing modules that handle only one functional concept each, and keep their external interfaces as minimal as possible. High-level modules will correspond to functional requirements, while low-level modules will have close ties to hardware resources (i.e., device drivers).



            I spent a lot of time maintaining a detailed data flow diagram1, which showed precisely how the various modules shared information. Some features will have very different requirements in terms of real-time performance; make sure you know how the information sharing affects that. The diagram had boundaries drawn across it that separated the non-interrupt code from the various interrupt-driven domains.




            1 Very different from a flowchart, which is focused on control flow.






            share|improve this answer









            $endgroup$



















              12












              $begingroup$

              Humpawumpa wrote a great answer! I just want to supplement some of his points, but since this is too long to be a comment, I'll write a separate answer.



              I was once in the OP's position — not the only EE, but the only EE who had done any MCU development in a small company.



              I can't emphasize the importance of modularity enough, even if you're the only developer. It's the only way to stay sane as the project grows. You need to be strict about writing modules that handle only one functional concept each, and keep their external interfaces as minimal as possible. High-level modules will correspond to functional requirements, while low-level modules will have close ties to hardware resources (i.e., device drivers).



              I spent a lot of time maintaining a detailed data flow diagram1, which showed precisely how the various modules shared information. Some features will have very different requirements in terms of real-time performance; make sure you know how the information sharing affects that. The diagram had boundaries drawn across it that separated the non-interrupt code from the various interrupt-driven domains.




              1 Very different from a flowchart, which is focused on control flow.






              share|improve this answer









              $endgroup$

















                12












                12








                12





                $begingroup$

                Humpawumpa wrote a great answer! I just want to supplement some of his points, but since this is too long to be a comment, I'll write a separate answer.



                I was once in the OP's position — not the only EE, but the only EE who had done any MCU development in a small company.



                I can't emphasize the importance of modularity enough, even if you're the only developer. It's the only way to stay sane as the project grows. You need to be strict about writing modules that handle only one functional concept each, and keep their external interfaces as minimal as possible. High-level modules will correspond to functional requirements, while low-level modules will have close ties to hardware resources (i.e., device drivers).



                I spent a lot of time maintaining a detailed data flow diagram1, which showed precisely how the various modules shared information. Some features will have very different requirements in terms of real-time performance; make sure you know how the information sharing affects that. The diagram had boundaries drawn across it that separated the non-interrupt code from the various interrupt-driven domains.




                1 Very different from a flowchart, which is focused on control flow.






                share|improve this answer









                $endgroup$



                Humpawumpa wrote a great answer! I just want to supplement some of his points, but since this is too long to be a comment, I'll write a separate answer.



                I was once in the OP's position — not the only EE, but the only EE who had done any MCU development in a small company.



                I can't emphasize the importance of modularity enough, even if you're the only developer. It's the only way to stay sane as the project grows. You need to be strict about writing modules that handle only one functional concept each, and keep their external interfaces as minimal as possible. High-level modules will correspond to functional requirements, while low-level modules will have close ties to hardware resources (i.e., device drivers).



                I spent a lot of time maintaining a detailed data flow diagram1, which showed precisely how the various modules shared information. Some features will have very different requirements in terms of real-time performance; make sure you know how the information sharing affects that. The diagram had boundaries drawn across it that separated the non-interrupt code from the various interrupt-driven domains.




                1 Very different from a flowchart, which is focused on control flow.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jul 22 at 12:44









                Dave TweedDave Tweed

                132k11 gold badges165 silver badges283 bronze badges




                132k11 gold badges165 silver badges283 bronze badges
























                    11












                    $begingroup$

                    For any large project, I plan it as if there were multiple developers involved even if I intend to do the whole thing myself.



                    The reasons are simple:



                    1 Complexity. A large project will always have complexities involved. Having planned the project as if there were multiple teams involved means that complexity has been considered and documented. The number of times I have seen large projects run into problems is high and usually because something 'slipped through the cracks'. Do not forget that mechanical assembly must also be considered and not simply for the size of the box - will there be a need for heat sinks? Must the box be earthed for safety? There are many questions in this category alone.



                    2 Requirements. Assuming multiple people are involved means that the top level requirements (which I often challenge as they may bring unnecessary complexity and cost) must be broken down into the various smaller required and achievable tasks (which could be fed to a another team in a larger organisation) rather than just looking at a single blob.



                    3 Partitioning. There are two primary types of partitioning; hardware functionality and hardware / software. The first type is to determine what separate (but communicating) functional blocks need to be present. The second is a trade-off of simpler (sometimes) hardware and software but keep in mind that simply moving more things to software will not necessarily fix a hardware problem. Moving more into software can actually vastly increase hardware complexity in some circumstances (more processing horsepower, more complex interfaces and more).



                    4 Interfaces. The partitioning process will help define internal interfaces; external interfaces are usually part of the overall requirements (although not always). There are many ways for different parts of a system to co-operate which may be a complex communications protocol or simply good / bad signalling.



                    5 Verification. This is a mixture of low level testing (for hardware and drivers) and system level. Having done the project in well defined blocks permits robust verification (which may be by analysis or actual test and is usually a mixture of the two; updates to designs may use similarity arguments).



                    6 Standards. I use coding and drawing standards as if it were a larger team. I use Barr group's coding standards as they are not too onerous but do prevent many classes of bug being in the code. For PCB output documentation I follow IPC-D-326 (which calls up IPC-D-325) as that is a proven method of communicating my intent to PCB fabricators and assemblers. This may seem strange but having the discipline to follow a number of standards means that the quality is consistent.



                    7 Version control. I use revision control for all parts of the project (system, hardware, software. mechanical, test requirements - everything). The CAD tools I use support such versioning as do all the software and FPGA build tools.



                    I have worked on many embedded projects (as have many of the experienced folk around here) and the team sizes have varied from 1 (myself) to dozens (or hundreds on a particular set of projects) spread across multiple disciplines and sometimes other geographically remote sites. Using the same over-arching approach (that is known to work) means I can pick up a particular task in relative isolation and complete it and thoroughly test it as a stand-alone part of the larger project. It also means I can sub some things out on occasion if necessary.



                    Doing all these things adds a bit of up-front time but is ultimately a faster route for complex embedded systems.






                    share|improve this answer









                    $endgroup$



















                      11












                      $begingroup$

                      For any large project, I plan it as if there were multiple developers involved even if I intend to do the whole thing myself.



                      The reasons are simple:



                      1 Complexity. A large project will always have complexities involved. Having planned the project as if there were multiple teams involved means that complexity has been considered and documented. The number of times I have seen large projects run into problems is high and usually because something 'slipped through the cracks'. Do not forget that mechanical assembly must also be considered and not simply for the size of the box - will there be a need for heat sinks? Must the box be earthed for safety? There are many questions in this category alone.



                      2 Requirements. Assuming multiple people are involved means that the top level requirements (which I often challenge as they may bring unnecessary complexity and cost) must be broken down into the various smaller required and achievable tasks (which could be fed to a another team in a larger organisation) rather than just looking at a single blob.



                      3 Partitioning. There are two primary types of partitioning; hardware functionality and hardware / software. The first type is to determine what separate (but communicating) functional blocks need to be present. The second is a trade-off of simpler (sometimes) hardware and software but keep in mind that simply moving more things to software will not necessarily fix a hardware problem. Moving more into software can actually vastly increase hardware complexity in some circumstances (more processing horsepower, more complex interfaces and more).



                      4 Interfaces. The partitioning process will help define internal interfaces; external interfaces are usually part of the overall requirements (although not always). There are many ways for different parts of a system to co-operate which may be a complex communications protocol or simply good / bad signalling.



                      5 Verification. This is a mixture of low level testing (for hardware and drivers) and system level. Having done the project in well defined blocks permits robust verification (which may be by analysis or actual test and is usually a mixture of the two; updates to designs may use similarity arguments).



                      6 Standards. I use coding and drawing standards as if it were a larger team. I use Barr group's coding standards as they are not too onerous but do prevent many classes of bug being in the code. For PCB output documentation I follow IPC-D-326 (which calls up IPC-D-325) as that is a proven method of communicating my intent to PCB fabricators and assemblers. This may seem strange but having the discipline to follow a number of standards means that the quality is consistent.



                      7 Version control. I use revision control for all parts of the project (system, hardware, software. mechanical, test requirements - everything). The CAD tools I use support such versioning as do all the software and FPGA build tools.



                      I have worked on many embedded projects (as have many of the experienced folk around here) and the team sizes have varied from 1 (myself) to dozens (or hundreds on a particular set of projects) spread across multiple disciplines and sometimes other geographically remote sites. Using the same over-arching approach (that is known to work) means I can pick up a particular task in relative isolation and complete it and thoroughly test it as a stand-alone part of the larger project. It also means I can sub some things out on occasion if necessary.



                      Doing all these things adds a bit of up-front time but is ultimately a faster route for complex embedded systems.






                      share|improve this answer









                      $endgroup$

















                        11












                        11








                        11





                        $begingroup$

                        For any large project, I plan it as if there were multiple developers involved even if I intend to do the whole thing myself.



                        The reasons are simple:



                        1 Complexity. A large project will always have complexities involved. Having planned the project as if there were multiple teams involved means that complexity has been considered and documented. The number of times I have seen large projects run into problems is high and usually because something 'slipped through the cracks'. Do not forget that mechanical assembly must also be considered and not simply for the size of the box - will there be a need for heat sinks? Must the box be earthed for safety? There are many questions in this category alone.



                        2 Requirements. Assuming multiple people are involved means that the top level requirements (which I often challenge as they may bring unnecessary complexity and cost) must be broken down into the various smaller required and achievable tasks (which could be fed to a another team in a larger organisation) rather than just looking at a single blob.



                        3 Partitioning. There are two primary types of partitioning; hardware functionality and hardware / software. The first type is to determine what separate (but communicating) functional blocks need to be present. The second is a trade-off of simpler (sometimes) hardware and software but keep in mind that simply moving more things to software will not necessarily fix a hardware problem. Moving more into software can actually vastly increase hardware complexity in some circumstances (more processing horsepower, more complex interfaces and more).



                        4 Interfaces. The partitioning process will help define internal interfaces; external interfaces are usually part of the overall requirements (although not always). There are many ways for different parts of a system to co-operate which may be a complex communications protocol or simply good / bad signalling.



                        5 Verification. This is a mixture of low level testing (for hardware and drivers) and system level. Having done the project in well defined blocks permits robust verification (which may be by analysis or actual test and is usually a mixture of the two; updates to designs may use similarity arguments).



                        6 Standards. I use coding and drawing standards as if it were a larger team. I use Barr group's coding standards as they are not too onerous but do prevent many classes of bug being in the code. For PCB output documentation I follow IPC-D-326 (which calls up IPC-D-325) as that is a proven method of communicating my intent to PCB fabricators and assemblers. This may seem strange but having the discipline to follow a number of standards means that the quality is consistent.



                        7 Version control. I use revision control for all parts of the project (system, hardware, software. mechanical, test requirements - everything). The CAD tools I use support such versioning as do all the software and FPGA build tools.



                        I have worked on many embedded projects (as have many of the experienced folk around here) and the team sizes have varied from 1 (myself) to dozens (or hundreds on a particular set of projects) spread across multiple disciplines and sometimes other geographically remote sites. Using the same over-arching approach (that is known to work) means I can pick up a particular task in relative isolation and complete it and thoroughly test it as a stand-alone part of the larger project. It also means I can sub some things out on occasion if necessary.



                        Doing all these things adds a bit of up-front time but is ultimately a faster route for complex embedded systems.






                        share|improve this answer









                        $endgroup$



                        For any large project, I plan it as if there were multiple developers involved even if I intend to do the whole thing myself.



                        The reasons are simple:



                        1 Complexity. A large project will always have complexities involved. Having planned the project as if there were multiple teams involved means that complexity has been considered and documented. The number of times I have seen large projects run into problems is high and usually because something 'slipped through the cracks'. Do not forget that mechanical assembly must also be considered and not simply for the size of the box - will there be a need for heat sinks? Must the box be earthed for safety? There are many questions in this category alone.



                        2 Requirements. Assuming multiple people are involved means that the top level requirements (which I often challenge as they may bring unnecessary complexity and cost) must be broken down into the various smaller required and achievable tasks (which could be fed to a another team in a larger organisation) rather than just looking at a single blob.



                        3 Partitioning. There are two primary types of partitioning; hardware functionality and hardware / software. The first type is to determine what separate (but communicating) functional blocks need to be present. The second is a trade-off of simpler (sometimes) hardware and software but keep in mind that simply moving more things to software will not necessarily fix a hardware problem. Moving more into software can actually vastly increase hardware complexity in some circumstances (more processing horsepower, more complex interfaces and more).



                        4 Interfaces. The partitioning process will help define internal interfaces; external interfaces are usually part of the overall requirements (although not always). There are many ways for different parts of a system to co-operate which may be a complex communications protocol or simply good / bad signalling.



                        5 Verification. This is a mixture of low level testing (for hardware and drivers) and system level. Having done the project in well defined blocks permits robust verification (which may be by analysis or actual test and is usually a mixture of the two; updates to designs may use similarity arguments).



                        6 Standards. I use coding and drawing standards as if it were a larger team. I use Barr group's coding standards as they are not too onerous but do prevent many classes of bug being in the code. For PCB output documentation I follow IPC-D-326 (which calls up IPC-D-325) as that is a proven method of communicating my intent to PCB fabricators and assemblers. This may seem strange but having the discipline to follow a number of standards means that the quality is consistent.



                        7 Version control. I use revision control for all parts of the project (system, hardware, software. mechanical, test requirements - everything). The CAD tools I use support such versioning as do all the software and FPGA build tools.



                        I have worked on many embedded projects (as have many of the experienced folk around here) and the team sizes have varied from 1 (myself) to dozens (or hundreds on a particular set of projects) spread across multiple disciplines and sometimes other geographically remote sites. Using the same over-arching approach (that is known to work) means I can pick up a particular task in relative isolation and complete it and thoroughly test it as a stand-alone part of the larger project. It also means I can sub some things out on occasion if necessary.



                        Doing all these things adds a bit of up-front time but is ultimately a faster route for complex embedded systems.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Jul 22 at 13:07









                        Peter SmithPeter Smith

                        16.2k1 gold badge15 silver badges43 bronze badges




                        16.2k1 gold badge15 silver badges43 bronze badges
























                            5












                            $begingroup$

                            The other answers give many great tips. Here are two that I've found the most important in my embedded development career:



                            1. Make as much of the code into separate, well defined modules as possible.

                            2. Make the modules automatically testable on PC.

                            That's what you need for doing "continuous integration" style development on embedded systems. There will always be some amount of code that is too tightly tied to hardware for automatic testing, but try to minimize it. You can get quite far by using simulated data or data captures from actual hardware, which you then feed into the test system.






                            share|improve this answer









                            $endgroup$



















                              5












                              $begingroup$

                              The other answers give many great tips. Here are two that I've found the most important in my embedded development career:



                              1. Make as much of the code into separate, well defined modules as possible.

                              2. Make the modules automatically testable on PC.

                              That's what you need for doing "continuous integration" style development on embedded systems. There will always be some amount of code that is too tightly tied to hardware for automatic testing, but try to minimize it. You can get quite far by using simulated data or data captures from actual hardware, which you then feed into the test system.






                              share|improve this answer









                              $endgroup$

















                                5












                                5








                                5





                                $begingroup$

                                The other answers give many great tips. Here are two that I've found the most important in my embedded development career:



                                1. Make as much of the code into separate, well defined modules as possible.

                                2. Make the modules automatically testable on PC.

                                That's what you need for doing "continuous integration" style development on embedded systems. There will always be some amount of code that is too tightly tied to hardware for automatic testing, but try to minimize it. You can get quite far by using simulated data or data captures from actual hardware, which you then feed into the test system.






                                share|improve this answer









                                $endgroup$



                                The other answers give many great tips. Here are two that I've found the most important in my embedded development career:



                                1. Make as much of the code into separate, well defined modules as possible.

                                2. Make the modules automatically testable on PC.

                                That's what you need for doing "continuous integration" style development on embedded systems. There will always be some amount of code that is too tightly tied to hardware for automatic testing, but try to minimize it. You can get quite far by using simulated data or data captures from actual hardware, which you then feed into the test system.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Jul 22 at 18:40









                                jpajpa

                                1,7467 silver badges12 bronze badges




                                1,7467 silver badges12 bronze badges
























                                    4












                                    $begingroup$

                                    To add to existing answers...



                                    I always start from the bottom up. From your hardware design, you know what your I/O is. Start by building driver modules which encapsulate that I/O, so that your high level code doesn't have to know too much about the low level stuff.



                                    When you're building the low level interfaces, of course you need a test harness. If you design this to hook up to the PC from the start (perhaps with an RS-232 port, perhaps USB, perhaps telnet over Ethernet) then you can keep this test harness interface in place as you build your application. You can keep adding more test harness hooks as the application takes shape, and that'll let you regression-test your code as you go on as well.






                                    share|improve this answer









                                    $endgroup$



















                                      4












                                      $begingroup$

                                      To add to existing answers...



                                      I always start from the bottom up. From your hardware design, you know what your I/O is. Start by building driver modules which encapsulate that I/O, so that your high level code doesn't have to know too much about the low level stuff.



                                      When you're building the low level interfaces, of course you need a test harness. If you design this to hook up to the PC from the start (perhaps with an RS-232 port, perhaps USB, perhaps telnet over Ethernet) then you can keep this test harness interface in place as you build your application. You can keep adding more test harness hooks as the application takes shape, and that'll let you regression-test your code as you go on as well.






                                      share|improve this answer









                                      $endgroup$

















                                        4












                                        4








                                        4





                                        $begingroup$

                                        To add to existing answers...



                                        I always start from the bottom up. From your hardware design, you know what your I/O is. Start by building driver modules which encapsulate that I/O, so that your high level code doesn't have to know too much about the low level stuff.



                                        When you're building the low level interfaces, of course you need a test harness. If you design this to hook up to the PC from the start (perhaps with an RS-232 port, perhaps USB, perhaps telnet over Ethernet) then you can keep this test harness interface in place as you build your application. You can keep adding more test harness hooks as the application takes shape, and that'll let you regression-test your code as you go on as well.






                                        share|improve this answer









                                        $endgroup$



                                        To add to existing answers...



                                        I always start from the bottom up. From your hardware design, you know what your I/O is. Start by building driver modules which encapsulate that I/O, so that your high level code doesn't have to know too much about the low level stuff.



                                        When you're building the low level interfaces, of course you need a test harness. If you design this to hook up to the PC from the start (perhaps with an RS-232 port, perhaps USB, perhaps telnet over Ethernet) then you can keep this test harness interface in place as you build your application. You can keep adding more test harness hooks as the application takes shape, and that'll let you regression-test your code as you go on as well.







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Jul 22 at 20:29









                                        GrahamGraham

                                        3,2146 silver badges13 bronze badges




                                        3,2146 silver badges13 bronze badges
























                                            3












                                            $begingroup$

                                            I tend to think in four questions. The first two belong to the start of a systems project, the two next towards the end.



                                            1. Do they actually want the system? Will the system solve the customers problem, at a time and cost scale they will accept? A common problem is building systems that the customer will not use.


                                            2. Can we actually build that system? Will it be possibly to deliver the necessary performance, precision, power usage, ... ?



                                            Creating early prototypes is a good way to answer these two first questions. Risk mitigation is extremely important in the early phases.




                                            The next two questions are more targeted at the later phases of the the project:



                                            1. are we actually finished? Everything designed, coded, tested, delivered


                                            2. Do they actually use the system?






                                            share|improve this answer











                                            $endgroup$



















                                              3












                                              $begingroup$

                                              I tend to think in four questions. The first two belong to the start of a systems project, the two next towards the end.



                                              1. Do they actually want the system? Will the system solve the customers problem, at a time and cost scale they will accept? A common problem is building systems that the customer will not use.


                                              2. Can we actually build that system? Will it be possibly to deliver the necessary performance, precision, power usage, ... ?



                                              Creating early prototypes is a good way to answer these two first questions. Risk mitigation is extremely important in the early phases.




                                              The next two questions are more targeted at the later phases of the the project:



                                              1. are we actually finished? Everything designed, coded, tested, delivered


                                              2. Do they actually use the system?






                                              share|improve this answer











                                              $endgroup$

















                                                3












                                                3








                                                3





                                                $begingroup$

                                                I tend to think in four questions. The first two belong to the start of a systems project, the two next towards the end.



                                                1. Do they actually want the system? Will the system solve the customers problem, at a time and cost scale they will accept? A common problem is building systems that the customer will not use.


                                                2. Can we actually build that system? Will it be possibly to deliver the necessary performance, precision, power usage, ... ?



                                                Creating early prototypes is a good way to answer these two first questions. Risk mitigation is extremely important in the early phases.




                                                The next two questions are more targeted at the later phases of the the project:



                                                1. are we actually finished? Everything designed, coded, tested, delivered


                                                2. Do they actually use the system?






                                                share|improve this answer











                                                $endgroup$



                                                I tend to think in four questions. The first two belong to the start of a systems project, the two next towards the end.



                                                1. Do they actually want the system? Will the system solve the customers problem, at a time and cost scale they will accept? A common problem is building systems that the customer will not use.


                                                2. Can we actually build that system? Will it be possibly to deliver the necessary performance, precision, power usage, ... ?



                                                Creating early prototypes is a good way to answer these two first questions. Risk mitigation is extremely important in the early phases.




                                                The next two questions are more targeted at the later phases of the the project:



                                                1. are we actually finished? Everything designed, coded, tested, delivered


                                                2. Do they actually use the system?







                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Jul 22 at 22:04

























                                                answered Jul 22 at 16:24









                                                ghellquistghellquist

                                                2011 silver badge4 bronze badges




                                                2011 silver badge4 bronze badges
















                                                    Popular posts from this blog

                                                    Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

                                                    Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

                                                    Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?