Search code examples
operating-systemembeddedheap-memorystack-memory

Why are some smaller embedded devices unable to run an operating system (and what exactly do they run off of instead)?


For context, this was taken from an excerpt in a book: Finally, sometimes you can't even use heap memory! If you are programming in Rust for a small embedded device, you are going to have to use only stack memory. There's no operating system to ask for heap memory on a small embedded device.

Coming from someone with limited embedded knowledge, why are some smaller devices unable to run an operating system. Surely there are ultra light-weight operating systems designed for these types of devices?

If there is no operating system, what exactly does the device then run off of?

I suppose any programs running on an operating-system-absent machine will be unable to utilize the heap and must only resort to the stack (is there a workaround; a dummy heap? [or are we then creating an operating system?])?

If there is a lack of context, then we can close this question (since this is all the information the book provided on 'small embedded device' and 'no operating system'), although to me, the question simply becomes, at what point is an embedded device considered to no longer be running on an operation system and instead simply following a set of primitive instructions?


Solution

  • There's no operating system to ask for heap memory on a small embedded device.

    That is the first fallacy. While in systems with an operating system, it is the operating system that provides that memory on demand, it does not follow that without an operating system you cannot have a heap. You can and frequently do. When and whether use of a heap is appropriate in some embedded systems is a different question. There are issues of non-deterministic timing, fragmentation, failure handling and more that do not lend themselves to mission critical, safety critical or real-time critical applications for example. It is often ill-advised to use a heap (or at least the standard heap accessed through the standard library), but lack of an operating system is not one of them.

    why are some smaller devices unable to run an operating system

    Well it depends on your definition of an operating system, but many microcontrollers have only a few tens of kilobytes or less memory. An operating system provides various services perhaps only a small subset of which will be utilised by an application specific embedded system, so it makes sense to only include services that are actually required to minimise footprint.

    That said many RTOS (real-time operating systems) are saleable and link only object code referenced by the application. In that case the RTOS is provided as a regular static link library and the RTOS and the application are a single monolithic linked entity. That may not meet your or the author's definition of an operating system. A minimal RTOS provides a thread scheduling kernel and inter-process communication, timing and synchronisation primitives and can scale to a footprint of < 10Kb of ROM, and support a number of threads limited by available RAM and thread stack size requirement.

    An RTOS will not typically provide such things you might associate with an OS such as a command shell, application loader, filesystem, networking. In a small embedded system such components are often independent of the RTOS and can be added as needed from various third-parties in-house developed. SOme RTOS vendors provide such "middleware" that integrates easily with thier particular kernel.

    Embedding a full OS requires much more resource. A GPOS (General Purpose OS), such as Linux requires in the order of 4Mb ROM and 16Mb RAM for even a minimal system. Also it will boot in tens of seconds rather then tens of milliseconds typical of many simpler embedded systems.

    Surely there are ultra light-weight operating systems designed for these types of devices?

    Yes - there are many RTOS in various levels of sophistication and scalability, from low end such as uC/OS-III, FreeRTOS, ThreadX and embOS to middle-range such as eCOS, to high end such as VxWorks, OS/9 and QNX.

    If there is no operating system, what exactly does the device then run off of?

    Why do you think you need an OS to run code? An OS after all is code. Embedded systems are application specific software running on application specific hardware. The application can embed all the necessary hardware support, and all necessary process timing and management within itself. An operating system may be useful if embedding a COTS (commercial off-the-shelf) board of some standard architecture, but often such support will be provided by the board vendor as an SDK, framework or library rather then a true OS. For example the Arduino and Mbed frameworks run on a number of off-the-shelf embeddable hardware devices.

    I suppose any programs running on an operating-system-absent machine will be unable to utilize the heap and must only resort to the stack (is there a workaround; a dummy heap? [or are we then creating an operating system?])?

    That is as I said not the case. For example a common C library used in embedded systems is Newlib, it includes a heap implementation, and provides a set of user replaceable stubs known as syscalls to map the library to the platform (primarily for memory management and standard I/O). To support a heap it is only necessary to implement the _sbrk() syscall, which ise used to "request" memory for a heap. That might be implemented as a call to an operating system to get memory, or it can be implemented to simply return a static block to use as heap. For example the following is a minimal implementation which requires only linker symbols __heap_start and __heap_end defining the space to be used a a heap to work:

    void* _sbrk (int  incr)
    {
        extern char __heap_start;//set by linker
        extern char __heap_end;//set by linker
    
        static char *heap_end;      /* Previous end of heap or 0 if none */
        char        *prev_heap_end;
    
        if (0 == heap_end) {
            heap_end = &__heap_start;           /* Initialize first time round */
        }
    
        prev_heap_end  = heap_end;
        heap_end      += incr;
        //check
        if( heap_end < (&__heap_end)) {
    
        } else {
            errno = ENOMEM;
            return (char*)-1;
        }
        return (void *) prev_heap_end;
    
    }
    

    If there is a lack of context, then we can close this question (since this is all the information the book provided

    The only lack of context is that you never cited the publication in question. Name, author, edition, ISBN etc. It seems that the book may lack authority, but that may be unfair to the author since we have only your brief summary of what the author says.

    at what point is an embedded device considered to no longer be running on an operation system and instead simply following a set of primitive instructions?

    Not having an operating system does not necessary imply "primitive". Although any successful/efficient large application with no formal operating system will likely essentially be its own application specific OS, with a device/hardware abstraction layer, process scheduling, process communication memory management etc as part of the application.