Issues in porting c/c++ code to VxWorks - c++

I need to port a c/c++ codebase that already supports Linux/Mac, to VxWorks. I am pretty new to VxWorks. Could you let me know what are the possible issues that could arise?

We recently did the opposite conversion - we ported code from a PowerPC machine running VxWorks to an Intel system running Linux. I don't remember hitting many snags as far as the differences between the operating systems. Obviously any call to an OS specific API will have to change and we were not making extensive use of these functions.
Our biggest problem was not the difference between the operating systems, but rather the difference between PowerPC and Intel hardware. PowerPC is Big Endian and Intel is Little Endian. Our software is written in C and made many assumptions as to the order of bytes and this was an absolute nightmare to get it working smoothly again. There were literally hundreds of structures that defined bitfields and needed to be re-ordered to work correctly. We ended up implementing a #pragma in GCC that reversed these bitfields at their definition (#pragma reverse_bitfields).

Much depends on which version of VxWorks you're targeting, and the actual target processor itself. One thing you will have to deal with is that there is no paged memory system or virtual memory--you have what's there. The environment itself is far more constrained than a linux system. Sometimes the work involved in porting applications goes all the way back to the architecture level because resources are not as unlimited as they are in linux.
Some other tips:
license vxworks such that you have the source code available
use a real, physical target as soon as possible in the development cycle; do not count on the simulators accurately emulating the target
use TSRs (technical support requests) as necessary; I don't know how they structure the purchase of the right to create TSRs, but don't let anybody cheap out on these

Depending on what processor you are running with VxWorks endianness, structure packing, and memory alignment could all be issues. The last time I used VxWorks it supported a pthreads, sockets, and mutex layer that mimicked the unix environments easily enough.

It's difficult to tell, without knowing more about the application that you're porting: What linux libraries and api calls does it use? Is it self-contained, or does it rely on slews of linux command-line tools and scripts to do its job?
As Average says, endianness can cause you way more problems than you expect - particularly if you're not prepared for it.

Related

Can an x86 executable run on any x86 platform given the right runtime libraries?

While I did find similar-ish questions, they did not really answer this specific question.
Can a compiled x86 executable run on any x86 platform given the right runtime libraries?
Say I make a C++17 program without dependencies, could I run this program on Windows 95 or is there some sort of support required by the OS?
I also heard that RTTI (in the case of C++) may not be supported everywhere, is this only due to the processor having to support this feature or does the OS play a role in that? This would imply that new features would maybe not be supported by, e.g., Windows 95.
Edit
What I'm after is whether an executable (e.g., x86) can run on any platform supporting that instruction set or wether certain features, like RTTI, need specific OS support and thus are not available on all platforms supporting that instruction set.
In general you cannot, even if you restricted your universe to x86 hardware - at least not without some conversion of the binary or some platform-specific "loader" for each target platform.
For exmaple a typical binary emitted by a C or C++ compiler1 will have some minimal dependency on the OS and runtime, for example to load and do runtime linking on the executable. Different platforms have different binary formats (such as PE/COFF on Windows or ELF across various UNIX flavors and Linux) and there isn't any common "x86 format" that would work directly on any platform.
Furthermore, any non-trivial program and in many cases any program, trivial or not, is going to have platform-specific dependencies on the the langauge runtime. For example, even an empty main() function often requires runtime support to get from the OS-defined "start" method to the main method, and without unusual build options there are often calls at startup to initialize parts of the standard library.
Finally, as you alluded to with your comment about RTTI, various language or platform features may essentially be compiled into the binary and require OS support. RTTI probably doesn't obviously fall into this category, but things like position-independent code, thread-local storage and stack-unwinding support for exception handling often do. The compiled x86 code that uses such features may be quite different on different platforms since it needs to build in assumptions of how those work.
In principle, however, you could imagine this working, at least for some limited subset of programs. For example, while the various executable formats are in practice incompatible, they aren't that different and tools exist to convert between them. So you could certainly implement a minimal runtime on your platform of interest that takes an x86 executable compiled to whatever fixed format you choose and converts at runtime to the local format and runs it.
Beyond that actually trying to map even standard library calls would be quite difficult since different operating systems using different calling conventions, but it could be possible for "C" functions using some thunks to put things in the right place. C++ is pretty much right out because the ABI there is much more complex, compiler-and-platform specific and much of the implementation detail is already compiled-in for stuff implemented in headers.
In fact, the idea that (a subset of) x86 might provide a interesting intermediate language for cross-platform execution is exactly the idea behind exploited in Google's [NaCl project]. Essentially, the NaCl runtime provides platform agnostic "loading" capabilities which allow x86 code to run more-or-less natively on various platforms. Subsequently other native formats such as ARM were added, but it started as an x86 sandbox. A large part of the project deals with running code that provably safe (i.e., sandboxed) - but it shows that with some infrastructure you can write "portable" x86. A standard C or C++ compiler isn't going to emit NaCl compatible code directly, however.
1 Really, any compiler that compiles to a native format. I just call out C and C++ since they seem like the ones you are interested in and are widely familiar.
This question misses the point. C++ is, first and foremost, a language to describe the behaviour of a computer program.
Using a compiler to create a native binary executable file to produce that behaviour on an actual computer is the typical way of using the language.
Once you have the binary file, all traces of the source code used to produce it are gone (unless you have built a special version for debugging purposes). The compatibility of the binary file with specific hardware or operating systems is beyond the scope of C++ itself.
The same is true for C, or any other programming language which typically gets compiled to native binary code.
Or, to answer the question more briefly:
Can compiled C++/C code (i.e. an executable) run anywhere given the right runtime libraries?
No.
Can a compiled x86 executable run anywhere given the right runtime libraries?
No, it will only work on x86 hardware, or other hardware (or software, such as a virtual machine) that emulates the x86 instruction set (such as a x64 CPU). In practice, that's very likely to be a far cry from "anywhere."
And even if the hardware matches, an x86 executable will have operating system dependencies. A Windows binary won't run on Linux, even if the hardware is the same. There are various strategies that can make things like this "work" in some situations, Microsoft's Linux Subsystem for Windows is one recent example which allows Linux binaries to run unchanged on Windows. Again, a fry cry from "anywhere."

Running ELF binaries on ReactOS

Please be patient in answering as I am new to all this and want to get my basics 100 percent right. I am a Mechanical Engineer, so do not be harsh. I am learning about some very basic low level stuff and was interested in understanding a concept related to compiler backends. The C/C++ compiler output is probably the machine code specifically tailored for the computer architecture. This also means that it should be same in Windows and Linux if both run on the same hardware, say, i7 processor. But there is another layer of difference in the form of binary format. That is, we have ELF(Executable and Linkable Format) on Linux and PE/COFF(Portable Executable) on Windows.
Thus, I feel, the compilers on Linux and Windows have backends that work differently and emit binaries in ELF or PE/COFF format.
ReactOS is a clone of Windows and is binary compatible to an extent with Windows.
Is it theoretically possible to have a LOADER in ReactOS that understands ELF and loads it properly?
I understand that we need to have a layer of software that maps the Linux APIs to ReactOS APIs. If such a mapping layer exists, does my question make sense?
Loader is not enough.
Operating systems have their own system call interface. I don't know too much about Linux and Windows binary APIs, last time I was using system calls directly was MS-DOS.
In MS-DOS, you can call DOS function by loading function code to AH register, then call INT 21H. Register AL is often used as sub-function or primary parameter. E.g. I can recall how to exit a program:
MOV AX,4C01H ; funciton AH = $4C (exit), error code is AH = 1
INT 21H
; program gets never here
So, other operating systems provide other fashion interface. E.g. AmigaDOS has exec.library's address on the absolute address of 4 (yep, $00000004), and library functions can be accessed thru a jump table located to negative offsets to library's "base" address (-4, -8 etc.). Other libraries' pointer can be asked from exec.library, by using open function.
Okay, MS-DOS and AmigaDOS runs on different architectures, but it's a good example of how operating system calls may differ. Software interrupts vs. library addresses provided by the first library.
Sometimes, difference is a luck. When the different operating system calls does not interfere, it's possible to write a wrapper, which receives alien operating system calls, and transforms them to host operating system. It would be perfect, if operating systems APIs would differ only the order of parameters of system calls - but the situation is more difficult. Simpler function can be mapped to other OS's flavour, but more complex functions - with callbacks! - are harder. Wrappers may emulate not only functions, but bugs of the operating system.
Anyway, there are some good stuff in this genre.
A good example is CygWin, which let you run Linux programs under Win32. When I last used it, there were no problems running any command-line stuff, even with threads, network etc. EDITED: it requires re-compiling and libs as #fortran says.
For Linux, WINE is a nice effort to run Win32 apps. There are even official Linux versions of commercial software, which use WINE! If your program doesn't utilize the lastest Windows API calls, WINE should work.
As Linux and BSD are both POSIX compatible operating systems, it's no surprise, that such a thing, like Linux Compatibility Layer for BSD exists.

How can I make a portable executable?

It's there a way to compile a c/c++ source file to output a .exe file that can be run on other processors on different computers ?
I am asking this for windows platform.
I know it can be done with java or c# , but it uses virtual machine.
PS: For those who said that it can be done just with virtual machines or the source cod must be compiled on every machine , i am asking if all viruses are written in java or c# and you need a vm machine to be infected or you need to compile source cod of worm on your machine to be infected ? (i am not trying to make a virus, but is a good example :) )
Different computers use different instruction sets, OS system calls, etc., which is why machine code is platform specific. This is why various technologies like byte code, virtual machines, etc., have been developed to allow portable executables. However, generally C/C++ compiles directly to platform-specific machine code.
So a Windows exe simply won't run on another platform without some kind of emulation layer.
However, you can make your C/C++ source code portable. This means all you need to do to make your application run on another platform is to compile it for that platform.
Yes, you can, but it's not necessarily a good idea.
Apple introduced the idea of a fat binary when they were migrating from the Motorola 68000 to the PowerPC chips back in the early 90s (I'm not saying they invented it, that's just the earliest incarnation I know of). That link also describes the FatELF Linux universal binaries but, given how little we hear about them, they don't seem to have taken off.
This was a single file which basically contained both the 68000 and PowerPc executables bundled into one single file and required some smarts from the operating system so it could load and execute the relevant one.
You could, if you were so inclined, write a compiler which produced a fat binary that would run on a great many platforms but:
it would be hideously large; and
it would almost certainly require special loaders on each target system.
Since gcc has such a huge amount of support for different platforms and cross-compiling, it would be where I would concentrate the effort, were I mad enough to try :-)
The short answer is - you can't. Longer answer is write in portable (standard) C/C++ and compile on the platforms you need.
You can, however, do it in a different language. If you need something to run on multiple platforms, I suggest you investigate Java. Similar language to c/c++, and you can "compile" (sort of) programs to run on pretty much any computer.
Do not confuse processor platforms with OS platforms.
for different OS platforms, machine binaries are altogether different. even not possible to make one-to-one instruction mapper. it is beacause whole instruction set architecture may be different, and different instruction groups may have totally different instruction format, and even some instructions may be missing or target platform.
Only an emulator or virtual machine can do this.
Actually, some operating systems support this; it is usually called a "fat binary".
In particular, Mac OS uses (used) it to support PowerPC and x86 in one binary.
On MS Windows however, this is not possible as the OS does not support it.
Windows can run 32bit executables in 64bit mode with no problem. So your exe will be portable if you compile it in 32bit mode. Or else you must release 2 versions of your executable. If you use Java or C# (or any bytecode-compiled language), the JIT/interpreter can optimize your code for the current OS's mode, so it's fully portable. But on C++, since it produces native code, I'm afraid this can't be done except using 2 versions of your binary.
The trick to do this, is to create a binary which has machine instructions which will be emulated in a virtual machine on the operating systems and processors you want to support.
The most widely spread such virtual machine are variants of the Java virtual machine. So my suggestion would be to look at a compiler which compiles C code to Java byte code.
Also, Windows once upon a time treated x86 as a virtual machine on other (Alpha) architectures.
To summarize the other answers, if you want to create a single executable file that can be loaded and run on multiple platforms, you basically have two options:
Create a "fat binary", which contains the machine code for multiple platforms. This is not normally supported by most development tools and may require special loaders on the target platform;
Compile to a byte code for the JVM or for .Net. I've heard of one C compiler that generates Java byte code (can't remember the name offhand), but never used it, nor do I have any idea what the quality of the implementation would be.
Normally, the procedure for supporting multiple platforms in C is to generate different executables for each target, either by using a cross compiler or running a compiler on each platform. That requires you to put some thought into how you write and organize your source code so that the platform-specific bits can be easily swapped out without affecting the overall program logic, for varying degrees of "easily".
The short answer is you can't, The long answer is there are several options.
Fat Binary. Downside is that this requires OS support. The only user level OS I know of that supports it is OS X for their power pc to Intel migration.
On the fly cross translation. As used by Transmeta and Apple. Again no general solution provider that I know of.
a C\C++ interpreter. There is at least one I am aware of Ch. It runs on Windows, Linux, OS X. Note Ch is not fully C++ compatible.
This question likes to that ask "Is there a way can travel from Canada to another city in the world?"
And answer is: "yes there is."
for compiling a C/C++ Source code to an Executable file on Windows Platform without any virtual machine you can use Windows Legacy API or MFC (specially with use MFC in a Static Library instead in Dll). This executable file approximately runs on all PCs that have windows, because windows runs on only 3 platforms (x86, x64, IA64; except windows 8 & 8.1 that supports ARMs).Of course you should compile your source to x86 codes to run on 32 bit and x86-64 platforms and Itaniums can run your exe in emulation. But about all Processors that runs windows as their OS (Like ARMS in mobiles) you should compile that for the Windows Phone or Windows CE.
You can write a mid-library~ such as:
[ Library ]
[ mid-library]
[linux part] [windows part]
then, you can use library, your app will be portable~~

Why does the chip control the language to choose

I've asked the question before what language should I learn for embedded development. Most embedded engineers said c and c++ are a must, but also pointed out that it depends on the chip.
Can someone clarify? Is it a compiler issue or what? Do chips come with their own specific compilers (like a c compiler or c++ compiler) and that's why you have to use the language the compiler knows? Is it not possible to code and compile it elsewhere, then burn it to the chip directly in its compiled state? (I think I heard an acquaintance say something to this effect)
I'm not sure how this works, as clearly I don't know much embedded systems or how they work. It's probably an easy answer for those of you who know.
Probably, they meant some toolchains do not support C++. Yes, many chips and boards do come with their own toolchains. Different processors have different instruction sets, which means a different compiler (or more specifically a different backend). That doesn't mean you always have to relearn everything. Many of these are based on GCC (often considered the most ported compiler). The final executable/image formats also vary, so you need a specific linker. Most likely, you will be (cross-)compiling the chip on a "regular" computer, then burning it to the chip. However, that doesn't mean you can use a typical compiler and linker targeted towards a desktop operating system.
It "depends on the chip" in three possible ways:
Some very constrained architectures are not suited to C++, or at least C++ provides constructs not suited to such architectures so offers no benefit over C. Most 8 bit devices fall into this category, but by no means all; I have seen useful C++ code implemented on MegaAVR for example.
Some devices are not supported by a C++ compiler. For example Microchip's dsPIC/PIC24 compiler is C only (third-party tools may have C++ support).
The chip architecture is designed specifically for a particular language; for example INMOS Transputers invariably ran OCCAM.
As well as C, C++, other possibilities are assembler, Forth, Ada, Pascal and many others, but C is almost ubiquitous; few chip vendors will release a new architecture or device without a C compiler being available from day-one. For other languages you will generally have to wait until a third-part decides to develop one, and that wait may be forever for a niche architecture.
Is it not possible to code and compile it elsewhere, then burn it to the chip directly in its compiled state?
That is called cross-compilation or cross-development, and is the usual development method for embedded systems. Most embedded systems lack the OS, file, performance and memory resources to self-host a compiler, and most developers want the comfort of a sophisticated development environment with IDEs, debuggers etc. in a familiar user-oriented desktop OS.
I'm not sure how this works, as
clearly I don't know much embedded
systems or how they work.
Get up-to-speed with some of these:
http://www.state-machine.com/arm/Building_bare-metal_ARM_with_GNU.pdf
http://www.eetimes.com/design/embedded
http://www.amazon.com/exec/obidos/ASIN/020179523X
http://www.amazon.com/Embedded-Systems-Firmware-Demystified-CD-ROM/dp/1578200997
Yes, there are many architectures for which a C compiler exists but a C++ compiler does not. The smaller and less fully-featured a processor you choose, the more likely this situation is to occur.
For embedded development, you almost always compile the code 'elsewhere', as you say, and then send it to the chip for execution/debugging. The process of compiling code for a different architecture than the compiler itself is built for is called 'cross-compiling'.
You are correct: chips have variations on compilers. Most/many modern chips have a gcc port; but not all.
The term 'embedded' is used to describe a vast range of hardware. Most embedded software engineering will consist of writing C/C++ code to produce a binary for a target microprocessor, but there are devices that you may work with that are not coded with compiled binary.
One example is a Programmable Logic Controller (PLC). These devices use a language called "Ladder Logic". It's a wonderful language. I have enjoyed working with it in the past.
Another thing you may encounter, as I have in the past, is devices that have interpreted BASIC emulators. Hopefully that is rare today.
C/C++ are a very good choice for firmware development. So the software you make will run on a embedded CPU/Microcontroller. In order to proper programmer the device, you will need to know the language and the device architecture.
The same code probably will not work in different devices. So, you have to learn the language, and the device architecture.
Another options are FPGAs, which are not microcontroller. FPGA are devices with specialized cell capable to transform itself in any type of synchronous circuit, including microcontroller. FPGAs are programed with Hardware Description languages, like verilog and VHDL. The "compiled" (synthesized) version of the software are called gateware.
The HDLs are the same languages used for ASICs designe also. The path to properly learn
the language are long. So I recommend start with C/C++ with pic form Microchip, which is a
low cost and highly accepted microcontroller.
If you intend to do FPGA development, the knowledge gained with C/C++/pic will be helpfull and important, because must FPGAs have embedded CPU/Microcontroller inside.
There is no direct scientific reason for it. In a lot of cases it has to do with the management and politics of the specific company.
Some companies are driven to create a turn key system and force you to buy that system and pay for maintenance. It locks out the individual developers, but there are many companies and esp government agencies that prefer this model because the support is often much better and you can often drive the direction of their products to suit your needs.
Other companies do not have the staff or the talent and outsource the solution and sometimes take whatever they can get. And you might end up with a one time developed tool that after the contractor leaves is never updated or fixed again, or if it is fixed it is a patch job by someone else. It takes money to make money, but if you run out of money before you can sell your product you still fail.
Sometimes you have companies that both have a staff that maintains their in-house must buy from them tool AND has individuals that also contribute to open tools like gcc.
Sometimes the politics or management in the company have individuals that have a strong opinion of how the world must be and only allow tools to be developed for a specific language. Or perhaps they are owned by or partner with or just like a company that has a specific language and this chip product came to be simply to support that language.
On top of all of this you have the very real technical problems of memory space, the quality and efficiency of the instruction set and how compiler friendly it is. Some architectures may be fine for assembler, but higher level compiled code chews up the limited memory resources too quickly.
Gcc in particular has a lot of problems internally (not as a people but the software/source code itself). I challenge you to write a back end, even with the tutorials that are out there. A company requires specialised talent in order to create and then maintain a gcc backend year after year, otherwise you get dumped. if your chip architecture is not 32 bit or bigger you are already fighting a losing battle with gcc, your chip architecture might be compiler friendly but just not friendly with the popular compilers design.
In the near future llvm is going to shine as a cross compiler relative to gcc because it has not yet built this internal bulk, and perhaps because the internal guts are themselves a defined language/system it may never suffer what has happened to gcc. As more folks get comfortable with llvm we will see a number of architectures ported to it. The msp430 backend was done specifically to demonstrate that you can add a target literally in an afternoon. By the end of next month, some motivated individual could have all of the targets most of us have ever heard of ported to llvm. And you dont have to build a cross compiler it is always a cross compiler. I only mention llvm because the door is now open for targets that have suffered from bad tools to recover.
Some companies, microcontrollers in particular, can and will make the programming interface proprietary so that you must use their programming tool (and or hack it and take your chances with publishing those results and or a cat and mouse of them changing it to defeat you). And they may have only made tools for Windows leaving the linux and apple folks hanging in the wind. Or they make it so that the only binaries it will load are the ones generated by their tools, here again you may hack through the binary format allowing an alternate compiler, and they may or may not work to defeat you.
Despite the technical problems the biggest is the companies politics, management, marketing teams, and supply of or lack of talent in the engineering staff. The bottom line, follow the dollars not the technology or science to understand why this language is supported and not that, or the support for this language is good, bad, or marginal.
What language to learn as a result of all of this? Start with assembler on at least three different architectures. Then C and then C++ if you feel you really need it. C and assembler are your primary languages for embedded (depending on your definition of embedded). No, we write assembler mostly for initial boot code and to support C, interrupt stuff or special instructions that are needed that the compiler cannot create. There are places like microcontrollers where it may very well make sense to use assembler for various reasons like tools, limited chip resources, etc. Even if you dont use assembler knowing it makes you a much better high level programmer.
You do need to decide what your definition of embedded is. Is it api and library calls for an application on a(n embedded) linux system (indistinguishable from the same program/calls on a desktop system). Or at the other end of the spectrum are you talking a microcontroller with maybe 256 or 1024 bytes (not mega or giga, but bytes) of program space? Or something in the middle? The majority of the "embedded" folks out there are closer to the api calls for applications on an operating system (rtos, linux, wince, etc), than the deeply embedded, so that means C, maybe C++ (always be able to fall back on C), trying to avoid python and other scripty languages that are resource hogs.
Some 8-bit parts cannot efficiently access data from a stack. Instead of using a stack to pass parameters, auto-variables and parameters are statically allocated; typically, a linker allocates the automatic variables for main() at one end of memory, and then allocate the variables for functions that are called by main and nothing else, then allocate the variables for functions that are called by those functions and nothing else, etc. This will yield an optimal allocation fairly easily, subject to some caveats:
Recursion can only be supported by adding code to explicitly copy variables onto some sort of stack arrangement; in many compilers, it's simply not supported at all.
If a function looks like it "might" call another function, the linker will assume it can do so in all cases (e.g. it may be that when 'foo' calls 'bar', one of its parameters might always have a value such that 'bar' won't call 'boz', but the linker won't know that).
Any call to a function pointer with a certain signature will be regarded as a call to all functions with the same signature whose address is taken.
If the evaluation of more than one parameter to a function requires making additional function calls, additional temporary storage must generally be pessimistically allocated even if optimal placement of the parameter storage could have avoided that.
There are many types of C programs for which the above restrictions pose no problem at all, and many more for which they pose a nuisance but not a huge one (e.g. by adding dummy parameters or return values to ensure different classes of indirectly-called functions have different signatures). Unfortunately, the code generated by an C++ to C pre-compiler will almost always involve function pointers whose call graph cannot be reasonably divined, so using C++ on such a platform is apt to be difficult if not impossible.

resources for embedded projects

Can anyone suggest links/resources for sample project implementations of embedded projects using c++ or gcc.
Many resources are target specific, so you will have to be more specific if you want a specific answer. However http://embedded.com/ is a good general resource, and depending on your geographical location, you may qualify for a free subscription to Embedded Systems Design or Embedded Systems Design Europe paper publications.
Apart from Atmel AVR, GCC is targetted for 16/32bit targets, and C++ is generally ambitious and unnecessary for 8 bit, so I am guessing we are considering 16/32bit targets?
You might also take a look at:
Martin Thomas's ARM-Projects, including a GCC toolchain for Windows.
http://embdev.net/ which includes an embedded GCC forum.
Building Bare-Metal ARM Systems with GNU A description of bringing up a system using GCC with C and C++
FreeRTOS a well respected and widely used open-source RTOS kernel
eCos another open-source RTOS, but somewhat more than a scheduler kernel.
There are many many many resources....the question is too broad. Do you have a particular embedded micro you are targetting?
different embedded apps have different concerns
real time concerns?
extremely limited memory / resources?
OS? no OS?
Security?
Failsafe?
Device Drivers?
Question is incomplete, you have to provide all information, like product summary, hardware you want to use. But I guess you are porting some linux kernel to some embedded device.
For application program, easiest is to cross compile your code from your local system for specific arch and then transfer the binary to your embedded product.