Author Topic: How you usually start architecturing your firmware ?  (Read 4627 times)

0 Members and 1 Guest are viewing this topic.

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: How you usually start architecturing your firmware ?
« Reply #25 on: December 25, 2023, 07:56:02 pm »
Your misconception is a pretty common one, especially in C, and usually leads to crappy code which misses the opportunities to make the code more readable by making it high level, a specification of the intended behavior of the program, written for humans, not computers or compilers.

It is the opposite of that. The common misconception is that the compiler will do wonders for you. It won't. Design is independent of the compiler. Say, you may decide you need a FIFO in some place, same as an architect may decide he needs a wall in certain place. This decision is independent of the language - you may write your FIFO code in C, or you may implement it with DMA. The C compiler won't override your implementation decision, will merely write assembler code for you which does exactly what you told it to do.

The important thing is your design - you did some analysis, designed how things will flow, and based on that decided to use FIFO. The design is 80% of the success. Good design will make things flow smoothly, will make code writing easier, and will minimize probability of bugs. Bad design will lead to implementation where your requirements are not meant and you have to write patchy awkward code to somehow fill in the gaps. This produces discombobulated code which is very hard to work with.

The implementation - how exactly you write your FIFO code, is of much less importance - the code with an awkward FIFO implementation is not that bad overall - it will work somehow and can easily be rewritten if need be.

How C optimizes your code is not important at all, unless you bloat your code so much that it doesn't fit into your part and needs to be optimized.
 

Offline shtirka

  • Contributor
  • Posts: 16
  • Country: se
Re: How you usually start architecturing your firmware ?
« Reply #26 on: December 25, 2023, 09:06:25 pm »
There are a lot of good suggestions in this thread already but the one thing I'm missing is making an estimation of the amount of processor power needed. This is something that I try to get clear when developing embedded firmware so I can make an estimation on whether code needs to be super efficient (with the extra time spend) or the processor is fast enough without having to care much about execution speed. Usually it is simpler both in writing and readability of the resulting code to use floating point (even simulated) compared to using fixed point calculations.

I am only speaking for myself here (and I might be wrong here, of course), but in my personal experience (especially over the last 5-10 years), the only applications where you probably would want to make an estimate like that would be niche applications (like supporting high data bandwidths say in telecom/video processing, or specific scientific applications with some very specific DSP) where people would be in the know about it anyway and quite possibly choose tools like FPGA's anyway. In the normal/commercial applications that I personally stumbled upon, I was able to successfully use either Cortex-M0+ or a 120Mhz CortexM3/4 for the simple reason that most of the processing isnt actually done on such systems and you'd be doing a lot of simpler tasks like data collection/shaping/filtering before its actually forwarded to the system that will do the actual serious work, or youre doing some sort of system control/communication that doesnt really need high data bandwith anyhow. I have also quite often used the combo of microcontroller/RTOS to increase the bandwidth so to speak

Ilya
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How you usually start architecturing your firmware ?
« Reply #27 on: December 25, 2023, 09:07:31 pm »
There are a lot of good suggestions in this thread already but the one thing I'm missing is making an estimation of the amount of processor power needed.

This, plus, often even more importantly, what peripherals are needed, what are available, and if peripherals mentioned on datasheet can actually be used or not (due to limited pin routing options, limited DMA mappings available and so on). There can be quite serious consequences on the choice of the whole product family, or even the manufacturer, which can then affect the code quite a bit, because sometimes you don't want and cannot do layered abstraction but some of the hardware "leaks" into the higher level code, no matter how unelegant that sounds to software scientists.

Yep.  I often use a microcontroller to interface to sensors and temporary tools, providing the data using a simple USB Serial connection.  To find out the practical bandwidth limits of that, I created (and recently updated) an Arduino Teensy sketch and corresponding Linux C program, to measure the practical amount of data a Teensy 4.x sketch can provide to a normal Linux program using USB Serial.  To ensure there are no shenanigans, it uses an excellent pseudo-random number generator – high 32 bits of Xorshift64*, passing all tests in the BigCrunch tests, noting that even Mersenne Twister fails one or two! – to generate the data on the Teensy microcontroller using a seed provided by host, with the host both reading the data and verifying it is correct.

(For anyone interested, depending on the host, one can expect Teensy to be able to provide 23 to 29 megabytes per second over USB serial, in practice; but only if you write arrays of data with at least 32 bytes at a time, instead of single bytes or characters.  The above-linked example is easy to modify to test specific sizes of write chunks.  It only tests Teensy sending data to a host, though; with only the initial request in the other direction.)

The underlying transport (USB 2.0 High Speed) is 480 Mbit/s, but is not full duplex (so transfers in different directions reduce the total bandwidth available), and there is also quite a bit of overhead.  You need dedicated chips or very finely-tuned USB subsystem handling to reach the 40 megabytes per second or so that USB 2.0 High Speed can do in practice, so a generic i.MX RT1062 USB implementation reaching 23-29 megabytes per second, with actual generated data, with standard USB Serial transport, gives a practical idea of what is feasible.  (With USB bulk transfers, one can probably get somewhat better as the tty layer is a bit of a bottleneck for USB Serial in Linux and BSDs, but I haven't bothered to check. Yet.)

My point is, I (have to) do practical tests to find those limits.  I do them early on, in the design phase, because the practical results feed back to my design, and those design changes often need new practical tests.  I don't need exact bounds, just their practical estimates.

This isn't really test driven development, because there is no development yet at this early design phase.  Test-guided design, TGD, maybe? ;)
« Last Edit: December 25, 2023, 09:15:24 pm by Nominal Animal »
 

Offline YTusernameTopic starter

  • Regular Contributor
  • *
  • Posts: 83
  • Country: tr
    • Atadiat
Re: How you usually start architecturing your firmware ?
« Reply #28 on: December 26, 2023, 06:10:32 am »
This isn't really test driven development, because there is no development yet at this early design phase.  Test-guided design, TGD, maybe? ;)

Yeah, I think there is no way to avoid such experiments at a pre-architecturing phase. The term TGD is nice :). I think this is in the research phase where you need to make sure your hardware is capable to provide the enough performance.

I would like to add the following qoutations from Jacob Beningo's Book (Embedded Software Design: A Practical Approach to Architecture, Processes, and Coding Techniques):

Quote
If I could describe my first few years as an embedded software engineer, I would use the words “code first, architect second.” I could simplify this statement further to “There is only code!”. Creating a software architecture was honestly a foreign concept, and it was an industry-wide issue, not just for me. When a task needed to be done, we would jump into our IDE and start coding. For simple projects, this wasn’t an issue. Everything that needed to be done could be kept straight in our minds; however, as projects became more complex, the rework required to add features ballooned out of control.

Quote
I can’t tell you a single system I’ve ever worked on where we got all the details up front, and nothing changed. Software design, by nature, is an exercise in managing the unknown unknowns. To manage them properly, the software architecture must quickly evolve with minimal labor.

Quote
embedded software developers skip the modeling and simulation and go directly to the hardware. The tradition dates to the early days of embedded software when the software was tightly coupled to the hardware, and the use of objects, abstractions, encapsulation, and other modern software techniques wasn’t used.
As a result, developers had no choice but to get the hardware running first and then work on the application. Unfortunately, going this route often leads to lower-quality application code
« Last Edit: December 26, 2023, 06:28:02 am by YTusername »
 
The following users thanked this post: Nominal Animal

Offline tellurium

  • Regular Contributor
  • *
  • Posts: 229
  • Country: ua
Re: How you usually start architecturing your firmware ?
« Reply #29 on: December 26, 2023, 08:26:56 pm »
The important thing is your design - you did some analysis, designed how things will flow, and based on that decided to use FIFO. The design is 80% of the success. Good design will make things flow smoothly, will make code writing easier, and will minimize probability of bugs. Bad design will lead to implementation where your requirements are not meant and you have to write patchy awkward code to somehow fill in the gaps. This produces discombobulated code which is very hard to work with.

I second that.

It is pretty much irrelevant, what are you going to code - a GUI app, a flashing utility, or an MCU firmware. The approach is the same for me. Design a flow, and a corresponding data structures + API. That's key. It has a tremendous impact down the road. Especially, how big a tech debt is going to be.

Personally, I make quick sketches in a notebook : it is fast and helps me visualise things. I have dozens of used notebooks lying around, with hundreds of sketches.
Open source embedded network library https://mongoose.ws
TCP/IP stack + TLS1.3 + HTTP/WebSocket/MQTT in a single file
 
The following users thanked this post: YTusername

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19513
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: How you usually start architecturing your firmware ?
« Reply #30 on: December 26, 2023, 10:21:16 pm »
The important thing is your design - you did some analysis, designed how things will flow, and based on that decided to use FIFO. The design is 80% of the success. Good design will make things flow smoothly, will make code writing easier, and will minimize probability of bugs. Bad design will lead to implementation where your requirements are not meant and you have to write patchy awkward code to somehow fill in the gaps. This produces discombobulated code which is very hard to work with.

I second that.

It is pretty much irrelevant, what are you going to code - a GUI app, a flashing utility, or an MCU firmware. The approach is the same for me. Design a flow, and a corresponding data structures + API. That's key. It has a tremendous impact down the road. Especially, how big a tech debt is going to be.

Personally, I make quick sketches in a notebook : it is fast and helps me visualise things. I have dozens of used notebooks lying around, with hundreds of sketches.

I'll add that it is helpful to decide on how you are modelling the problem and therefore solution, identify appropriate design patterns (real time as well as GoF), and use them.

Oh yes, event=>interrupt=>FIFO, FSM, half-sync half-async, no caches, one thread per FSM, only one priority.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: YTusername

Offline nigelwright7557

  • Frequent Contributor
  • **
  • Posts: 690
  • Country: gb
    • Electronic controls
Re: How you usually start architecturing your firmware ?
« Reply #31 on: December 29, 2023, 06:02:24 pm »
Always read the errata sheets on the microcontroller you use.

I chose a PIC because it had USB. I found I couldnt get USB to work.
I got in touch with microchip and apparently the 64 pin version of microcontroller USB doesnt work !
This is despite datasheet saying it did and so did RS Components part description.
I had to move up 100 pin version to get a working USB.

For another project I wanted to move up from current microcontroller to next faster one.
The pin out was the same.
I couldnt get one pin to output data. Turned out that pin is now an input only !

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf