Analysis of High-Level Programming Languages for Embedded Systems
2026-04-06 08:17:55··#1
Abstract: With the popularization and promotion of embedded technology, high-level language programming for embedded systems is inevitable. However, people often have a lot of randomness when choosing a language system. They consider factors such as price and ease of acquisition more, but less about the technical factors of the language itself. This article starts with the characteristics of high-level programming languages for embedded systems, briefly summarizes the basic performance of high-level languages, analyzes and compares the basic technical performance of several popular embedded system programming languages - Ada, C/C++, Modula-2; and gives a brief introduction to Java. Keywords: high-level language for embedded systems, basic performance, programming characteristics I. Characteristics of high-level language programming for embedded systems With the continuous expansion of the application scope of embedded systems and the widespread use of embedded real-time operating systems (RTOS), high-level language programming has become an inevitable trend in embedded system design. Because assembly language is closely related to the hardware structure of specific microprocessors, it has poor portability and is not suitable for use in complex systems, nor is it convenient to achieve software reuse; while high-level languages have good versatility and rich software support, are easy to promote and easy to maintain. Therefore, high-level language programming has many advantages. (1) Strong versatility. With the continuous development of microprocessor technology, its functions are becoming more and more specific and the types are increasing. Different types of microprocessors have their own dedicated assembly languages. This sets up a huge obstacle for system developers, making system programming more difficult and software reuse impossible. High-level languages are generally less related to the hardware structure of specific machines. Popular high-level languages have good support for most microprocessors and are more versatile. (2) Easy to program. With the continuous expansion of the application scope and the continuous deepening of the application level of embedded systems, the system scale is getting larger and larger, the structure is getting more and more complex, and the design is getting more and more difficult. It is common for a system to have multiple microprocessors. At this time, programming in assembly language not only requires programmers to be familiar with the assembly language of all microprocessors, but also makes it extremely difficult to implement large-scale tasks in assembly language as the complexity of tasks increases. High-level languages have a higher semantic level and rich program library support, so it is relatively simple to write more complex programs. Using high-level languages for programming can not only speed up the system development process and save a lot of time, but also facilitate system debugging and maintenance. (3) Easy to read. Because assembly language has a low semantic level, when reading assembly language programs, a lot of effort is often spent analyzing "details", such as why a piece of data is transferred to a register, or why a certain flag is cleared. When attention is focused on these "details", the main thread of the program is often forgotten. Therefore, assembly language programs are not only difficult to write, but also difficult to read. High-level languages can solve these problems well. Because high-level languages have a high semantic level and their expression is closer to people's daily thinking methods, some mathematical expressions can be directly expressed in a single statement, and the program's logic is clearer and more concise. Therefore, the program is easier to read. (4) Good portability. Because assembly language is closely related to specific microprocessors, programs designed for a certain microprocessor cannot be directly ported to another different type of microprocessor, so the portability is poor; while high-level languages are universal for all microprocessors, so programs can run on different microprocessors, and the portability is better. This is the basis for realizing software reuse. (5) Good maintainability. High-level language programs are often modularly designed, and the interfaces between modules are fixed. Therefore, when a problem occurs in the system, the problem can be quickly located in a certain module and resolved as soon as possible. In addition, modular design also facilitates the expansion and upgrading of system functions. (6) Directly support interrupt management. Interrupts are the most important and most commonly used information exchange method in embedded systems. Therefore, whether the interrupt system is flexible and whether the interrupt function is powerful has a great impact on the system performance. In high-level languages, there are generally powerful interrupt management mechanisms to build efficient and flexible interrupt systems; while in assembly languages, interrupt management is generally done by the programmer. This not only increases the difficulty of programming, but the effect is not necessarily good. (7) Support software reuse. Due to the poor portability of assembly language, its software reuse is seriously hindered; while high-level languages have better universality and portability, which makes high-level language programs share between different times, different places, different systems, and different people, realizing software reuse. This can not only improve product quality, shorten the development cycle, and reduce product costs, but also make software development take the road of standardization and industrialization[1]. II. Overview of High-Level Programming Languages for Embedded Systems Over the past 40 years, dozens of computer languages have been developed, but only a few have achieved widespread adoption. This highlights the difficulty of choosing a suitable language system. In small embedded systems, there is usually only one microprocessor, and its primary function is often control rather than computation; therefore, a language with strong control capabilities should be chosen. In large embedded systems, multiple microprocessors or computers often work in parallel, forming a multi-machine system. Some operate in true embedded mode, while others perform pure information processing. In this case, system programming becomes quite complex, and different tasks may require different languages. Therefore, large systems are often multi-language systems. Language selection for such "hybrid" systems requires even more careful consideration. Currently, many languages are used in embedded system development, but only a few have achieved widespread application. This paper selects Ada, C/C++, and Modula-2 as the subjects of discussion and provides a brief introduction to Java. Ada is a powerful general-purpose system development language developed and implemented by the U.S. Department of Defense in the 1970s, initially named Ada83. It supports modularity, independent compilation, and coprocessing. Its reliability, maintainability, and readability are all quite good. Later, in order to better support OOP (Object-Oriented Programming), it was improved, forming the widely used Ada95. Using the Ada language can greatly improve the system's clarity, reliability, maintainability, and other performance indicators [2,3]. It is the only language designated by the U.S. Department of Defense for use in military system development. The C language is a system programming language developed and put into use by Dennis Richie at AT&Bell Laboratories in 1972. Its design goal is to make C have both the efficiency of assembly language and the programmability of high-level language. Its most representative application is the UNIX operating system. Since the mid-1980s, C language has been widely welcomed after being involved in real-time systems. It is currently the most widely used embedded system programming language. C++ was developed and put into use by Bjarne Stroustrup at Bell Laboratories in 1995. C++ has made significant improvements over C in terms of supporting modern software engineering, OOP, and structured programming, but it is less efficient than C in terms of program code size, execution speed, and program complexity [2,4,5]. Modula-2 is a system design language developed by Nicklans Wirth in the late 1970s based on Pascal and Modula. Its main goal is to improve Pascal in terms of modularity, system programming, and coprocessing. Modula-2 has strong type checking capabilities and rich low-level function support. Therefore, it can be used to design a complete real-time program without the support of assembly language. Modula-3 is a system development language developed and put into use in 1988 by DEC (Digital Equipment Company) and ORC (Olivetti Research Center) based on Modula-2. Its goal is to design a powerful but simple general-purpose programming language. It has improved upon Modula-2 in terms of coprocessing, OOP, automatic garbage collection, and support for C and UNIX [6]. To determine whether a language is suitable, multiple aspects need to be considered. Different languages have their own characteristics. It is difficult to make a comprehensive comparison. In addition, the running characteristics of any language are closely related to the running environment. Therefore, when choosing a language, we should take into account all factors. For ease of description, we divide the performance of a language into two aspects: basic performance and running performance. (1) Basic performance The basic performance of a language mainly refers to the inherent characteristics of the language itself, or static characteristics, that is, the characteristics of the components that make up the language. It not only determines the usability, applicability, and reliability of the language, but also has a certain impact on the development output, portability, maintainability, and security of application programs. It is the core and foundation of a language. The basic performance of a language is examined from the following aspects: interface with assembly language/machine language, direct addressing, hardware control, bit operations, interrupt handling, pointer operations, support and detection of data types, support and detection of control structures, modular support, independent compilation support, task structure support, exception handling, mathematical model support, syntax and overall structure, multi-tasking support, standard program library, object-oriented programming (OOP) structure, etc. (2) Runtime performance The runtime performance of a language refers to the behavioral characteristics of its application software during actual operation. It is a dynamic characteristic of a language. It has a great impact on the applicability, practicality and usability of the language. It is mainly reflected in several aspects such as task deadline setting, simple evaluation of code execution time, selection of scheduling strategy, and support for timing analysis. Since the runtime performance of a language is closely related to the runtime environment, such as CPU speed, memory size, hard disk speed, operating system, compilation environment, etc., the evaluation of the runtime performance of a language should be linked to the specific application environment. Any theoretical evaluation has little practical significance. Therefore, this article will not discuss this aspect. III. Basic performance of commonly used high-level programming languages for embedded systems The basic performance of a language is the basic element that constitutes the language and is the key factor that determines its performance. Therefore, it is very necessary to carefully study the basic performance of a language. The basic performance of the above-mentioned popular embedded system programming languages is analyzed and compared in a simple way [7]. (1) Interface with assembly language and machine code In the Ada language, the assembly language and machine code can be accessed through the subroutine function. The standard package MACHINE-CODE supports this function. In C, assembly language can be defined as an asm module embedded in the C source code, or it can be written as an independent external process that communicates using function calls. Macros can also be used to provide assembly language operations. The language itself does not provide this mechanism; it is provided by the compiler. (2) Direct addressing Ada addresses absolute addresses through the Address class in the SYSTEM package; C/C++ completes absolute addressing through pointers, and in C++, memory addressing can also be completed through Peek and Poke operations; Modula-2 supports absolute addressing through the SYSTEM module. (3) Access and control of hardware Ada maps Ada code to specific devices through statement clauses; C/C++ completes hardware operations through pointers; in Modula-2, devices are identified as objects with absolute addresses, and these objects are accessed through assignment statements. (4) Bit operations Ada can specify specific bits in statement clauses, and multiple independent bits can also form a logical word, which can be processed through logical operations. Bit operations are a strength of C; logical operations and shift operations can all be implemented as bit operations. In C++, more bit operation functions can be implemented by defining the "bitfields" structure. Modula-2 uses the "SET" structure to handle bit operations. The most useful structure in embedded applications is "BITSET", which can be used to easily implement various bit operations. (5) Interrupt handling Ada implements interrupt handling through interrupt handling tasks. An interrupt task is closely related to an interrupt vector, and the interrupt task entry address is stored at the interrupt vector address. C/C++ languages themselves do not provide a standard interrupt handling mechanism, and users can handle it themselves. Modula-2 implements interrupt handling through the IOTRANSFER process in the SYSTEM module. Users can also write their own interrupt handling programs. (6) Pointers All three languages provide strong pointer operations. (7) Data type detection Ada has a strict data type detection mechanism. Mixed types are prohibited, and data type conversion is allowed, but with strict specifications. C language's data type detection function is weak, and errors may occur during data type conversion. C++ has improvements. Modula-2 is strict on data type detection and does not allow ambiguous data type conversions. (8) Program Control Structures: Ada provides a complete set of strict program control structures to support branching, looping, and other functions, as well as unconditional transfers; C/C++ provides branching, looping, and other control structures, which are convenient and flexible, but care should be taken to avoid unsafe factors when using them; Modula-2 is very strict in terms of branching and looping control, but care should be taken when using the CASE-ELSE structure. When transferring unconditionally, use EXIT to exit the loop and RETURN to terminate the process. Extra caution should be taken when using it. (9) Module Structure and Independent Compilation: The basic units of Ada programs are subprogram, package, task, and generic, while the basic units of compilation are subprogram and package. All program units can be compiled independently, with strict type checking and no shared data area. The basic unit of a C program is a function. External variables are global variables, and internal variables are local variables; a C++ program is a collection of several compiled files. Each file can define types such as class, function, and global variables, and each file can be compiled independently. The main program of Modula-2 consists of several program modules and library modules. The program module is the highest level of program units, and each module can be compiled independently. (10) Exception Handling: Ada provides a comprehensive error handling mechanism to handle exceptions caused by the language itself and by the user; C/C++ does not provide a direct exception handling mechanism, which must be handled by the user; C++ (V3.0) provides direct exception handling functionality; PIM Modula-2 does not provide exception handling functionality, but some other compilation systems provide runtime error detection and handling mechanisms. (11) Task Structure Support: "Task" is a standard component of Ada programs and is an important and inseparable part of the language; C does not have an independent "task" structure, but it can be implemented through "function"; in C++, it can be implemented through "classes"; Modula-2 does not have an independent "task" structure, but it can be implemented using the "PROC" structure. (12) Mathematical Model Support: Ada provides good mathematical model support, and its program behavior is strictly checked regardless of the microprocessor on which it runs; C/C++ supports fixed-point and floating-point operations. However, the mathematical model is not perfect and is prone to some undefined behaviors, such as division by zero or overflow; the mathematical model of PIM Modula-2 is related to the runtime environment, and the new standard is improving. (13) Syntax and structure Ada has an English-style structure and syntax, and the program is easy to read and understand; C/C++ is a concise language, and the program is relatively difficult to read, and C++ is even more difficult to read; Modula-2 has a clear definition of language structure, and the program is easy to read. (14) Multitasking support Multitasking support is a major feature of the Ada language and is an integral part of it; C/C++ does not support multitasking; Modula-2 supports multitasking through mechanisms such as "Coroutines". (15) Standard library Ada has a rich library of basic functions; C/C++ has a very rich library program, but compatibility should be considered in application; Modula-2 has a relatively rich library program, but compatibility should also be considered. (16) OOP structure support Ada83 is an OOP language, and Ada95 has been enhanced; C does not support OOP, C++ has strong OOP function; Modula-2 does not support OOP, Modula-3 supports OOP. IV. About Java Java is an object-oriented programming language released by Sun Microsystems on the Internet in 1995. Its main developer is Gosling. His goal is to design a language system that can run in a large-scale, geographically distributed, and heterogeneous network environment to complete the communication and collaborative work between multiple electronic devices. Gosling adopted the virtual machine code method in the design, that is, the Java language is compiled into a virtual machine, which runs on an interpreter, and the interpreter is used to interpret the program compiled by the Java compiler. This makes Java a platform-independent computer language, that is, Java applications can run on different hardware and software platforms without modification. Thus, "write once, run anywhere" is realized, which makes the Java language quickly popular all over the world, and some people even say it is a revolution[8]. (1) Characteristics of Java Java is a network language, but it is not limited to this. In the past two years, Java has developed rapidly and is widely used in many fields. This shows that Java does indeed have distinctive features. First, Java is simple. It removes some things that are not absolutely necessary in high-level languages, such as operator overloading, header files, pointer arithmetic, implicit type conversion, multiple inheritance, etc., and greatly simplifies the memory management work of programmers through automatic garbage collection, making program design simple. Second, Java is object-oriented. The design of the Java language focuses on objects and their interfaces. It provides a simple class mechanism and a dynamic interface model. Objects encapsulate their state variables and corresponding methods, achieving modularity and information hiding; while classes provide a prototype of a type of object, and through inheritance, subclasses can use the methods of the parent class, achieving code reuse. Third, Java's architecture is neutral. Generally speaking, networks are composed of machines with different architectures, and CPUs and job structures are different. Running applications on machines with different architectures is difficult; however, the Java compiler can produce an architecture-neutral object file format, allowing the compiled code to run on different processors. Fourth, Java is robust. Java checks for potential problems during compilation and execution to prevent errors. When an exception occurs, Java discards it to prevent the computer system from crashing. Fifth, Java is secure. Java does not support pointer operations, avoiding the drawbacks of pointer operations. Java has multiple layers of interlocking protection measures, which can effectively prevent the intrusion and destructive behavior of viruses. Bytecode verification is used by web browsers to ensure that small programs are virus-free. Sixth, Java is multithreaded. Java can execute multiple threads simultaneously, such as interacting with the user while performing calculations. Usually, writing multithreaded programs is difficult; but Java provides easy-to-use synchronization mechanisms, making program design convenient and easy. Seventh, Java is extensible. Java's design enables it to adapt to the ever-evolving environment. New methods and instance variables can be freely added to the class library without affecting the execution of the user program. At the same time, Java supports multiple inheritance through interfaces, making it more flexible and extensible than strict class inheritance. (2) Java and Embedded Systems Java is a network language, while embedded systems have special requirements in terms of functionality, price, size, power consumption, and time to market. Therefore, due to its limitations in speed and code size, the Java language is not inherently suitable for embedded systems. However, Sun Microsystems was unwilling to abandon this potentially huge market and released J2ME (Java 2 Micro Edition) after improving Java. It is a subset of the Java API, containing only Java's key features, and is specifically designed for embedded systems with stringent memory requirements. J2ME roughly divides application objects into two categories: devices with 128KB to 512KB of memory and devices with more than 512KB of memory, providing different user interfaces and software packages for each category. However, due to the special nature of embedded systems, some features considered excellent in Java become very challenging in embedded systems. For example, the lack of pointer addressing and the security features of running in the Java Virtual Machine mode make it difficult for Java to directly control the hardware; automatic garbage collection deprives applications of real-time decision-making capabilities, meaning it cannot process a specific section of code in a predictable and repeatable manner. In fact, Java pauses the execution of the entire application during garbage collection, so developers have almost no control over the timing of garbage collection. Encouragingly, these problems have been or are being solved. Both just-in-time (JIT) and ahead-of-time (AOT) compilers can improve the execution speed of Java code. For example, New Monic's Real-Time Executive and Wind River's Fast J can guarantee the development of applications requiring absolute time decision-making to a certain extent. On the other hand, to better support Java in hardware, many manufacturers are dedicated to developing Java chips to fully leverage the compact and flexible features of embedded Java and expand into the embedded market. For instance, HP is developing and improving its own compilation tools and Java Virtual Machine. The goal is to embed Java into devices such as printers, medical monitors, and ATMs, giving these devices a degree of intelligence, increasing manageability and availability, and significantly improving their efficiency. Sun Microsystems announced that it will define API components for each domain in J2ME in the form of profiles. Java TV is one such API component for two-way digital television. Sun stated that Java TV technology will provide the basic environment, security, scalability, and portability required for two-way television. Through Java TV technology, developers can create more attractive information content and services. Sun also announced a partnership with General Motors to jointly establish Java standards for the automotive industry. Once Java becomes the standard computer language in the automotive industry, it will add millions of users. In the past year, J2ME has received significant attention and widespread application in the field of wireless communications. This is because J2ME includes a Java Virtual Machine that can run on most consumer devices, dedicated API function libraries, and tools for development and setup. As a result, mobile phone manufacturers have launched internet-enabled phones for users to choose from. In control systems, Java allows all operations to be completed on a panel provided by a standard web browser. These control panels are Java Applets. Web browsers can be used to monitor or configure the system. These monitoring and configuration operations can be performed remotely over the network, making the system easier to manage, especially for devices located in dangerous, remote, or inaccessible areas where Java is particularly needed. Java is not just a language, but a way of thinking. It will fundamentally change software development in terms of design style, design methods, design goals, and design processes. It will become the foundation for software reimplementation, the core of future operating systems, and the development platform and implementation environment for various application software. However, Java is not a panacea; it has its own application scope. Java excels in network management, network applications, object-oriented applications, visual operations, and interactive applications. But in real-time control fields, such as rocket control, sensor control, and spacecraft orientation control, C or assembly language remain the best choices. In summary , Computer languages have developed rapidly in recent years. New languages are constantly emerging; popular languages are continuously improved and perfected; and unsuitable languages are gradually being eliminated. The development of computer languages presents a vibrant picture. With the development of embedded technology, high-level programming languages for embedded systems have received much attention, gradually forming a diverse and competitive landscape. It is still difficult to predict which programming language will dominate the future of embedded systems. Ada is a strictly defined, easy-to-read, and easy-to-understand language with rich library support. It is currently widely used in defense, aviation, and aerospace fields and will continue to hold an important position in these fields in the future. C has extensive library support and is currently the most widely used programming language in embedded systems, and will continue to hold an important position in embedded system applications in the future. C++ is an important programming language in both PC systems and workstation systems. Visual C++ will play a significant role in graphical user interfaces (GUIs). However, C++ target code is often large and complex, a factor that should be fully considered in embedded system applications. Modula-2 is clearly defined, offers rich support, and has a good modular structure, making it widely used in teaching and research. Although its development and application have been relatively slow, it has seen a resurgence in Europe in the last two years. Java is a relatively young language, but its development momentum is strong. Its "write once, use anywhere" characteristic makes it popular in many fields. With the continuous development of network and embedded technologies, the application of Java and embedded Java will become increasingly widespread. In terms of runtime characteristics, Ada has better runtime behavior. Because it is less dependent on the runtime environment and the language itself is strictly defined, its runtime behavior is quite excellent. The runtime behavior of C/C++ programs is highly dependent on the hardware environment and compilation system, which can lead to many unexpected problems. A program running in a certain environment may produce errors on a different machine or with a different compilation system. Therefore, both C and C++ have several pages of documentation on undefined behavior. Modula-2 also has relatively good runtime behavior and is still being improved. Java employs virtual machine technology, making its applications platform-independent and thus possessing excellent runtime characteristics. Although we have only discussed the basic characteristics of three languages—Ada, C/C++, and Modula-2—and provided a brief introduction to Java, this is sufficient to remind us that in embedded system development and applications, we should highly value the advantages of high-level languages in embedded system programming and rationally select, research, develop, and apply high-level programming languages suitable for our specific embedded systems. This is not only the future direction of embedded system development and applications but also of great significance to the development of embedded technology in my country. MES References 1 Kernebeck U.Component libraries for software re-use.Microprocessors and Microsystems, 1997, 21(1):49~54 2 Hill A D.The choice of programming languages for highly reliable software-a comparison of C and Ada.Ada user, 1991(3):11~103 3 http://www.ada-usa.com/about-ada-page.html/ 4 Stroustrup B.The C++ programming language.3rdedn, Reading MA:Addison-Wesly, 1997 5 KH Ha.C language for finite element programming.Comput.Struct,1990,37(4):873~880 6 Wirth W.Programming in modula-2.Springer-verlag, Berlin, 4thedn, 1988 7 Cooling J E.Languages for the programming of real-time embedded systems-a survey and comparison.Microprocessors and Microsystems, 1996,20(1):67~77 8 http://www.computerworld.com.cn/search/theme/themefile.asp?themeID=327/ 9 Fazio P, Gowri K.Structural Analysis Software and C Programming Language.Comput Struct, 1987,25(2): 463