Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Introduction to Embedded Systems Programming (Ada) (adacore.com)
135 points by gusthoff on Nov 22, 2022 | hide | past | favorite | 19 comments


This seems like a great tutorial for both Ada and embedded systems in general. I'm definitely going to have to check this out more.

Can someone speak, at a high-level, on how Ada manages memory? I'm gonna read the docs, but if anyone has a good explanation here, that would be appreciated!

In general, I'm interested in learning more about embedded languages that are not C/C++ or Rust. To give some context, my dream embedded language is one like F# or OCaml that can be embedded (i.e., has manual memory management or some other solution).


> Can someone speak, at a high-level, on how Ada manages memory?

It is low level ;). There is a function like malloc that allocates memory, but there is no free, since re-using freed memory is a common source of bugs in C programs. The idea is that you do all your memory allocation (buffers etc.) during program startup. If an allocation fails, you log the error and exit. Once the program is up and running, you don't allocate any more. Embedded systems, remember. You do everything in fixed memory regions. In critical systems there are some tools that make sure your stack allocations never exceed whatever. Ada programs are not allowed to crash.

That said, most Ada implementations do have something like free, but it is not part of the standard and you are supposed to be very careful with it.

You might like this, "random walk through Ada": http://cowlark.com/2014-04-27-ada/index.html


People keep repeating Ada 83 features, as if nothing has changed.

Ada has free() via "Unchecked_Dealocation", which since Ada 95 is hardly directly called, beacause the language introduced support for RAII via controlled types.

Many data types like strings and vectors are capable of dynamic managing memory themselves, thus no need for the malloc()/free() dance like in C.

When stack allocations, or other kinds of allocations fail from those dynamic types, an exception is thrown, that can be caught and the same operation retried with smaller sizes.

With SPARK integration into standard Ada, formal proofs can be used to handle how memory and other resources are being managed.

Finally, due to Rust's sucess bringing affine types into the mainstream, Ada is also having a go into affine types, influenced by ParaSail experiment whose author now works at AdaCore (not to forget the remaining 6 Ada vendors still in business).


Not to be nitpicking, but there is a free(), and it is called "Unchecked deallocation".

See https://www.adaic.org/resources/add_content/standards/05aarm....


Also I think Ada is more memory safe than both C++ and rust! (with SPARK!)


Checkout Nim! I've used it to great effect for embedded programming. It has memory management system based on non-atomic reference counting (arc) so its fast and deterministic. It has optional cycle collection too (orc). Its easy to mixin manual memory as well.

I used F# a bit and learned a lot from it, and the same with Elixir and Nerves. Nim is procedural but it has an "enlightened procedural" take that feels like functional programming in some ways. Partly thats due to the very powerful type system - for example Nim lets you define custom distinct (not aliased) number types just like F#. Nim also inherits a fair bit from Pascal and so shares points with Ada like ints with custom ranges. Theres some rough points, but largely its made me enjoy programming again.

The esp32 is a good intro route since they're easy to setup. I wrote a wrapper for esp-idf which is used in production in at least two embedded shops: https://github.com/elcritch/nesper (its stable but I haven't had time to update docs for a ehile)

You can run it on Arduinos as well. Theres a pure Nim setup called Ratel and a rp2040 wrapper too. :)


Heres the rp2040 wrapper someone else did: https://github.com/EmbeddedNim/picostdlib


I'm not the person you were replying to, but you have my thanks! I've played around with Nim and read a few pages of Nim in Action. I really hope it will get more mainstream recognition because from what I've seen presented at NimConf it appears (to me at least) to have a lot of potential in the embedded space.


Ada’s memory management is a mix of memory pools, RAII, and manual memory management.

It often isn’t necessary to explicitly use pointers to dynamically allocated memory. For example, Ada lets you return an array of unknown size by value from a function. These unconstrained objects are stored on what is called a “secondary stack”, which is basically a special allocation pool for holding these objects managed by the language runtime.

When you do use pointers, the compiler is very strict to try and avoid dangling pointers. You can also create custom pointer types and assign them to memory pools, so dynamic allocations of that pointer type get made in the pool (and not in the normal heap).

You can also use manual memory management (using the `new` keyword and the `Unchecked_Deallocation` function similar to malloc() and free()).

There is also a finalizer class you can inherit from that adds a destructor to record types, so you can use RAII, too.


If you haven't already, the Nerves Project which is an embedded systems/IoT platform based on Elixir, might interest you.

https://www.nerves-project.org/


Yep! I love Elixir and am definitely aware of it. I haven't used Nerves proper yet, just some of the libraries that it's associated with, but I'd like to at one point. However, it is limited to soft real-time systems.


AdaCore's docs are fantastic for understanding why things are done the way they are. However, when I'm learning a new platform or language I prefer to see a lot of practical examples first. That's what I tried to do with my "Ada on the Raspberry Pi Pico" project:

https://pico-doc.synack.me/


This is really cool. Thanks for sharing this. Is this a workable solution for the Raspberry Pi or is it more of a proof of concept? I need to learn Ada, but I'm really not a fan of C/C++ or Python, so I haven't gotten to join in on the fun of the Pico, yet.


It's more than a proof of concept; there are lots of examples, unit tests, and the linked documentation.

Pico Keys (https://www.tindie.com/products/fabien-c/pico-keys/) is a good example of a complex project built with rp2040_hal.

Note that this library is specific to the RP2040, not the larger Raspberry Pi boards. Some Ada drivers for those exist, but are not as well documented.

I also gave a short talk about some of the challenges I encountered earlier this year: https://youtu.be/Pwd9Q5ELAGM


Rosetta code is also a great help for classic stuff (not specifically embedded I mean).


Seems like an interesting language to learn. But I am getting PTSD from writing VHDL which is based on Ada. Is pure Ada's syntax as inconsistent as VHDL's?


On the left side of the page, click "Introduction to Ada" and then "Imperative Language" for some syntax.


Ada is great, I just want to understand how streams work! I can't find good examples or explanations.


By chance have you tried reading the Ada wikibooks page? https://en.wikibooks.org/wiki/Ada_Programming/Libraries/Ada....




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: