10 ms·
The same is true for the software that runs many satellites. Use of the STL is prohibited. The main issue is mission assurance. Using the stack or the heap m
by anonymousiam 11mo ago
The same is true for the software that runs many satellites. Use of the STL is prohibited.
The main issue is mission assurance. Using the stack or the heap means your variables aren't always at the same memory address. This can be bad if a particular memory cell has failed. If every variable has a fixed address, and one of those addresses goes bad, a patch can be loaded to move that address and the mission can continue.
- Thaxll 11mo agoCan't this be done at runtime? Like the underlying calls can black list hardware address on read/write faults?
- amluto 11mo agoIf you have memory to spare and are using hardware with an MMU, you can remap your logical address to a different page. Linux can do this, but only for user memory.
- anonymousiam 11mo agoThis assumes that the operating system can run. If the memory corruption impacts the OS, then it may be impossible to recover. As the systems (and software) have become more complex, keeping these Mission Assurance best practices becomes more important, but the modern generation of developers sometimes loses sight of this. A good example of what I'm talking about is a program that I was peripherally involved with about 15 years ago. The lead wanted to abstract the mundane details from the users (on the ground), so they would just "register intent" with the spacecraft, and it would figure out how to do what was wanted. The lead also wanted to eliminate features such as "memory dump", which is critical to the anomaly resolution process. If I had been on that team, I would have raised hell, but I wasn't, and at the time, I needed that team lead as an ally.
- d-lisp 11mo agoWow, but how did they deal with anomalies ? I mean, even when I have the codebase readily accessible and testable in front of my eyes, I never trust the tests to be enough ? I often spot forgotten edge cases and bugs of various sort in C/embedded projects BECAUSE I run the program, can debug and spot mem issues and whole a lot of other things for which you NEED to gather the most informations you can in order to find solutions ?
- charcircuit 11mo ago>This assumes that the operating system can run. So does being able to download a new version of software that uses different memory addresses. The point is if you are able to patch software, you are able to patch memory maps.
- amluto 11mo agoOh, to be clear, I would not do this if I needed that degree of reliability. Or maybe I would use an MMU but drive it with a kernel written in the old fashioned way with no allocation. It would depend on what hardware I had available and what faults I wanted to survive. (I’m not an aerospace software developer.)
- 5d41402abc4b 11mo ago>This assumes that the operating system can run. You could have two copies of the OS mapped to different memory regions. The CPU would boot with the first copy, if it fails watchdog would trigger and the CPU could try to boot the second copy.
- dahart 11mo agoDo satellite embedded satellite systems usually have an OS these days? Is this a custom made OS, or do you have any examples of an OS that honors the no stack/heap and fixed address requirements you mentioned? What does the OS do? I don’t know about aerospace specifically, but plenty of embedded microcontroller systems don’t have an OS, and I would assume that having an OS is a massive risk against any mission assurance goals, no?
- 11mo ago
- coppsilgold 11mo ago> This can be bad if a particular memory cell has failed. If every variable has a fixed address, and one of those addresses goes bad, a patch can be loaded to move that address and the mission can continue. This seems like a rather manual way to go about things for which an automated solution can be devised. Such as create special ECC memory where you also account for entire cell failure with Reed-Solomon coding or some boot process which blacklists bad cells etc.
- j16sdiz 11mo agoIt is more than that. This is what make remote debugging possible. It is impossible to do interactive remote debugging over a ultra low bandwidth link. If everything have static address and deterministic static, you can have a exact copy on ground and debug there.
- varjag 11mo agoInteractive debugging is apparently possible and was reportedly done on Deep Space One mission. One of developers involved frequents HN I believe.
- unloader6118 11mo agoKind of. That took hours of not days. A local exact replica with deterministic state save lots of time.
- coppsilgold 11mo ago> If everything have static address and deterministic static, you can have a exact copy on ground and debug there. You can also have deterministic dynamic - the satellite could transmit its dynamic state (a few bits signifying which memory cells failed) and then you proceed deterministically on the ground.
- 5d41402abc4b 11mo ago> Using the stack or the heap means your variables aren't always at the same memory address Where do you place the variables then? as global variables? and how do you detect if a memory cell has gone bad?
- cminmin 11mo agoyour programs have a data segment. its not the heap nor the stack... and it can be (depending on loader/linker) a source of reliable object->address mappings as its not dynamically populated.
- repelsteeltje 11mo agoThat sounds like your answer is: "Yes, global variables". That may be a perfectly good solution in many embedded environments, but in most other context's global variables are considered bad design or very limiting and impractical.
- izacus 11mo agoThey're considered impractical mostly because language tooling doesn't support them appropriately.
- repelsteeltje 11mo agoCan you elaborate? For instance, how would better tooling help with storing a TCP buffer in global memory?
- deleted 11mo ago[deleted]
- tatjam 11mo agoAs a quick example, compare doing embedded work with a C static uint8_t[MAX_BUFFER_SIZE] alongside a FreeRTOS semaphore and counter for the number of bytes written, vs using Rust's heapless::Vec<u8, MAX_BUFFER_SIZE>, behind a embassy Mutex. The first will be a real pain, as you now have 3 global variables, and the second will look pretty much like multi-threaded Rust running on a normal OS, but with some extra logic to handle the buffer growing too big. You can probably squeeze more performance out of the C code, specially if you know your system in-depth, but (from experience) it's very easy to lose track of the program's state and end up shooting your foot.
- menaerus 11mo agoSo none of the functions you implement have in/out parameters?
- cminmin 11mo agoif you use few you can have em all in the registers perhaps (not sure what arch they rollin?)
- quietbritishjim 11mo ago> Using the stack or the heap means your variables aren't always at the same memory address. Your mention of STL makes it sound like you're talking about C++. But I don't know of any C++ compiler that lets you completely avoid use of the stack, even if you disable the usual suspects (RTTI and exceptions). Sure, you'd have to avoid local variables, defined within a function's body (or at block scope), but that's nowhere near enough. * The compiler would need to statically allocate space for every function's parameters and return address. That's actually how early compilers did work, but today it would be inefficient because there are surely so many functions defined in a program's binary compared to the number being executed at any given time. (Edit: I suppose you already need the actual code for those functions, so maybe allocating room for their parameters is not so bad.) * It would also mean that recursion would not work, even mutual recursion (so you'd need runtime checks because this would be hard to detect at compile/link time), although I suspect this is less of a problem than it sounds, but I'm not aware of a C++ compiler that supports it. * You'd also need to avoid creating any temporary variables at all e.g. y = a + b + c would not be allowed if a,b,c are non-trivial types. (y = a + b would be OK because the temporary could be constructed directly into y's footprint, or stored temporarily in the return space of the relevant operator+(), which again would be statically allocated). Is that really what you meant? I suspect not, but without all that your point about avoiding the stack doesn't make any sense.
- RealityVoid 11mo agoYour points are correct, but recursion is banned anyway in safety critical applications. The main issue is determinism. The fact you have to use the stack for call stacks is correct OP seems misinformed.
- adrian_b 11mo agoYou have to use the stack for procedure calls on x86/x86-64 CPUs, where the hardware enforces this. In most other surviving CPU ISAs the return address is saved in a register and it is easy to arrange in a compiler to use only procedure arguments that are passed in registers, the only price being paid for this being a reasonable upper limit for the number of parameters of a function, e.g. 12 or 24, depending on the number of general-purpose registers (e.g. 16 or 32). For the very rare case when a programmer would want more parameters, some of them should be grouped into a structure. With this convention, which normally should not be a problem, there is no need for a call stack. There can be software managed stacks, which can be used even for implementing recursion, when that is desired. The use of static memory for passing function arguments was necessary only in the very early computers, which were starved in registers.
- RealityVoid 11mo agoYou can definitely have local variables on the stack. I don't know where you got that you don't use the stack. Heap is kind of a no-no, although memory pools are used. > If every variable has a fixed address, and one of those addresses goes bad, a patch can be loaded to move that address and the mission can continue. You can and do put the stack and heap pool at fixed memory ranges, so you can always do this. I'm not sold at all with this reasoning.
- 0xffff2 11mo agoFor what it's worth, I am an active developer of space flight software. This might be true somewhere, but it's not true anywhere I've ever encountered. The contortions required to avoid using the stack would be insane and cause far more bugs than it could ever prevent. I'm pretty confident asserting that this is simply not a thing. Even heap allocation is very often allowed, but restricted to program initialization only. Furthermore, these rules are relaxing all the time. I am aware of at least one mission currently in space that is flying the C++14 STL with no restrictions on heap allocation and exceptions enabled. Unmodified `std::map` is currently flying in space with no ill effects.
- anonymousiam 10mo agoI'm guessing that you work for SpaceX.