Ocaml for ARM cortex M4? - arm

I would like to know if it would be possible to cross-compile application written in Ocaml on processor like STM32F407 (1MB Flash, 196kB RAM) ? (without OS).
I have read Cross-compiling ocaml apps for ARM ; the experiment seems to have been done on beaglebone; so more powerfull than STM32, and with Linux as OS.
There is also OcaPIC (http://www.algo-prog.info/ocaml_for_pic/web/index.php?id=ocapic) - which is meant for PIC processors.
Is there any similar port for ARM Cortex M4 ?

I'm not aware of a port, but see the related mailing list thread 1,2.
To get started you could use the same toolchain that you use for building a C or Arduino code to cross-compile the OCaml bytecode interpreter (ocamlrun), and then run 32-bit OCaml bytecode.
The tricky part would be to port the runtime to work without an OS (allocating memory, etc.). Projects like Mirage have done that for Xen based partially on Xen's miniOS.
Perhaps you could use FreeRTOS, ChibiOS, etc. to get started.
Once that works you can look at native code with ocamlopt, it supports armv4 to armv7, but I don't know if ARMv7E-M is a superset of that or not.
Or you could write a DSL embedded in OCaml that generates C code which you would finally run on your MCU, like Haskell does with Ivory3 and Atom4.

Related

Will all ARM compilers produce the same Assembly code and run on various CPUs?

I have been developing code for an older device which has an NXP i.MX28 single core CPU which is ARM-based. The device runs Embedded Linux.
I am now upgrading to a better device which has an NXP i.MX6UL quad core processor, of course ARM-based also, and also running Embedded inux.
Is it normal that the same toolchain which I was using for the for building the code for the i.MX28 will also work for the i.MX6UL, even though the i.MX6UL is more advanced with more cores etc.?
I have built my code now for a test with the same compiler and even run it on a Rasberry Pi which seems to run ok. The Rasberry Pi uses a Broadcom BCM2711 SoC with an ARM Cortex-A72 processor which again is a different CPU.
I therefore must ask, will any ARM toolchain build code and be able to run on any type of ARM device regardless?
CPUs differ by the core architecture (incl. instruction set) and set of peripherals. Difference in the peripherals is solved by drivers and HALs. Difference in core arch is solved by the toolchain.
If the toolchain "knows" new arch it will emit the corresponding assembly code, that will run on the new CPU. So, compilers will not produdce the same assembly, but the same source code will run after rebuild, that's the idea of high-level languages.
Problems emerge when old code contains an inline assembly, or uses some specific DSP instructions or libraries

aurel32 qemu images arm vs mips

I am currently learning how to emulate both mips(el) and arm architecture using Qemu. The images which I used for both architecture is by aurel32 from this website, https://people.debian.org/%7Eaurel32/qemu/
I noticed that the mips images does not have initrd while the arm images have initrd. I am unsure why arm requires initrd when running Qemu but mips does not.
Anyone know why this is the case?
Thanks for the help!
There is no inherent reason -- you can build an Arm kernel with enough devices built-in to not need an initrd, and you can build a MIPS kernel that does require an initrd. You'd have to ask Aurelien why the two sets of images he built had different configs (assuming he even remembers 6 years later!), but I suspect it's just that for MIPS he was able to use the stock Debian kernel whereas for Arm he had to compile his own kernel, and so the configuration choices for the two weren't identical.

Is it possible to build C source code written for ARM to run on x86 platform?

I got some source code in plain C. It is built to run on ARM with a cross-compiler on Windows.
Now I want to do some white-box unit testing of the code. And I don't want to run the test on an ARM board because it may not be very efficient.
Since the C source code is instruction set independent, and I just want to verify the software logic at the C-level, I am wondering if it is possible to build the C source code to run on x86. It makes debugging and inspection much easier.
Or is there some proper way to do white-box testing of C code written for ARM?
Thanks!
BTW, I have read the thread: How does native android code written for ARM run on x86?
It seems not to be what I need.
ADD 1 - 10:42 PM 7/18/2021
The physical ARM hardware that the code targets may not be ready yet. So I want to verify the software logic at a very early phase. Based on John Bollinger's answer, I am thinking about another option: Just build the binary as usual for ARM. Then use QEMU to find a compatible ARM cpu to run the code. The code is assured not to touch any special hardware IO. So a compatible cpu should be enough to run all the code I think. If this is possible, I think I need to find a way to let QEMU load my binary on a piece of emulated bare-metal. And to get some output, I need to at least write a serial port driver to bridge my binary to the serial port.
ADD 2 - 8:55 AM 7/19/2021
Some more background, the C code is targeting ARMv8 ISA. And the code manipulates some hardware IPs which are not ready yet. I am planning to create a software HAL for those IPs and verify the C code over the HAL. If the HAL is good enough, everything can be purely software and I guess the only missing part is a ARMv8 compatible CPU, which I believe QEMU can provide.
ADD 3 - 11:30 PM 7/19/2021
Just found this link. It seems QEMU user mode emulation can be leveraged to run ARM binaries directly on a x86 Linux. Will try it and get back later.
ADD 4 - 11:42 AM 7/29/2021
An some useful links:
Override a function call in C
__attribute__((weak)) and static libraries
What are weak functions and what are their uses? I am using a stm32f429 micro controller
Why the weak symbol defined in the same .a file but different .o file is not used as fall back?
Now I want to do some white-box unit testing of the code. And I don't want to run the test on an ARM board because it may not be very efficient.
What does efficiency have to do with it if you cannot be sure that your test results are representative of the real target platform?
Since the C source code is instruction set independent,
C programs vary widely in how portable they are. This tends to be less related to CPU instruction set than to target machine and implementation details such as data type sizes, word endianness, memory size, and floating-point implementation, and implementation-defined and undefined program behaviors.
It is not at all safe to assume that just because the program is written in C, that it can be successfully built for a different target machine than it was developed for, or that if it is built for a different target, that its behavior there is the same.
I am wondering if it is possible to build the C source code to run on x86. It makes debugging and inspection much easier.
It is probably possible to build the program. There are several good C compilers for various x86 and x86_64 platforms, and if your C code conforms to one of the language specifications then those compilers should accept it. Whether the behavior of the result is representative of the behavior on ARM is a different question, however (see above).
It may nevertheless be a worthwhile exercise to port the program to another platform, such as x86 or x86_64 Windows. Such an exercise would be likely to unmask some bugs. But this would be a project in its own right, and I doubt that it would be worth the effort if there is no intention to run the program on the new platform other than for testing purposes.
Or is there some proper way to do white-box testing of C code written for ARM?
I don't know what proper means to you, but there is no substitute for testing on the target hardware that you ultimately want to support. You might find it useful to perform initial testing on emulated hardware, however, instead of on a physical ARM device.
If you were writing ARM code for a windows desktop application there would be no difference for the most part and the code would just compile and run. My guess is you are developing for some device that does some specific task.
I do this for a lot of my embedded ARM code. Typically the core algorithms work just fine when built on x86 but the whole application does not. The problems come in with the hardware other than the CPU. For example I might be using a LCD display, some sensors, and Free RTOS on the ARM project but the code that runs on Windows does not have any of these. What I do is extract important pieces of C/C++ code and write a test framework around it. In the real ARM code the device is reading values from a sensor and doing something with it. In the test code that runs on a desktop the code reads from a data file with fake sensor values and writes its output to a datafile that can be analyzed. This way I can have white box tests for the most complicated code.
May I ask, roughly what does this code do? An ARM processor with no peripherals would be kind of useless. Typically we use the processor to interact with some other hardware like a screen, some buttons, or Bluetooth. It's those interactions that are going to be the most problematic.

What are the conditions to make the embedded C code written for one processor to work on another processor (when architecture is same)?

I am reading a primer text on embedded C programming (it is: Barr & Massa, 2007). For companion hardware board to run examples, they recommend Arcom VIPER-Lite. But I do already have Beaglebone Black (BBB) board and I don't want to buy a new board.
The two boards have same architecture, namely, ARM but BBB uses TI AM3358BZCZ100 processor, clocked at 1GHz, whereas VIPER-Lite uses Intel's PXA255 processor, clocked at 200MHz. The BBB board has more memory and basically more of everything.
My question is, can I follow and execute embedded C code examples given in this book on my BBB board? Does embedded C code depend on processors or architecture or something else? I understand that very specific examples addressing particular peripherals/drivers may not be portable from one platform to next but is entire embedded code like this? I am hope I am making sense.
Intel X-Scale is not the same as Cortex-A8 - ARM architecture has been through a number of versions since then, and Intel implemented some proprietary features too. Moreover ARM licencees are free to implement proprietary peripheral sets and subsets of the core architecture.
In particular for board bring-up the PLL and SDRAM controller will be entirely different between different vendor's devices and even between different generations of device from the same vendor.
If you are running code on an already implemented OS (BeagleBone is delivered with Linux already installed), then you will not need to worry about board bring up and peripheral support; but you will also miss out in learning a great deal about embedded systems (other than perhaps embedded systems that run pre-installed or vendor supplied Linux distros, which is a small subset or all embedded systems).
Beyond board bring up the boards will have entirely different peripheral sets, different on-board devices, and differing I/O at different addresses and with different register sets - no code that directly accesses the I/O is will work. Code accessing devices through a standard Linus device driver interface may well work because an abstraction to a common interface is provided by the OS and board vendor or third party device drivers.
If you are not running the code on Linux - or are implementing low-level device drivers, then the programming environment in terms of memory map, MMU, PLL, I/O control, peripherals, and even instruction set will be different and any code will require adaptation, and you will need to get familiar with the corresponding data sheets or reference manuals and also the ARM technical reference.
So the answer is that it depends largely on where you are starting from; bare-metal or Linux.
There are resources related to "bare-metal" development on BeagleBone Black in particular TI's own bare-metal StarterWare library.
The concept you learn from most good text books can be applied any microprocessor or micro controller at a very high level. But if you want learn embedded system programming using Beagle Bone Black I suggest the following youtube links from Prof Derek Molloy. Prof Molloy does a fantastic job of teaching embedded System programming using BBB. Here are few links for you to get started.
The Beaglebone - Unboxing, Introduction Tutorial and First Example
Beaglebone: C/C++ Programming Introduction for ARM Embedded Linux Development using Eclipse CDT
Beaglebone: GPIO Programming on ARM Embedded Linux
The one problem you might want to be aware is that the video were based on Angstrom Distribution. The current BBB is shipped with Debian Distribution.
Also if you want to learn bare-metal embedded system program you might want check out
Embedded Systems - Shape The World
You might also want to take look at the following link for more material.
Beginning with programming microcontrollers
The xscale although ARM instruction set derived is not ARM in the sense that you want to use it. For some reason the native mode is big endian and normal ARM native mode is little endian. But more important the core processor is not insignificant, but not the bulk if the porting effort, most of not all of the peripherals are expected to differ between those two chips, most of the code would need a re-write unless it is a purely portable C program that runs on any say linux, then arm, xscale, x86 are completely irrelevant to the discussion. I suspect you are not in that situation. Even compiled as a generic command line linux app would still have problems in this situation with the endianness.
Basically you are saying I have two fords and I want to take the wheels off of one and put them on the other, without understanding that one is a ford festiva and the other is lets say an F350 pickup. Just because they have the same looking tiny ford badge on them, doesnt mean that the entirety of their components are identical.
If you are desperate to re-use these binaries, you are better off finding or making a simulator for the prior platform and then you can run that on anything.

How to start ARM programming in linux?

I was using PIC micro controller for my projects. Now I would like to move to ARM based Controllers. I would like to start ARM using Linux (using C). But I have no idea how to start using Linux. Which compiler is best, what all things I need to study like a lot of confusions. Can you guys help me on that? My projects usually includes UART, IIC, LCD and such things. I am not using any RTOS. Can you guys help me?
Sorry for my bad English
Once you put a heavyweight OS like Linux on a device, the level of abstraction from the hardware it provides makes it largely irrelevant what the chip is. If you want to learn something about ARM specifically, using Linux is a way of avoiding exactly that!
Morover the jump from PIC to ARM + Linux is huge. Linux does not get out of bed for less that 4Mb or RAM and considerably more non-volatile storage - and that is a bare minimum. ARM chips cover a broad spectrum, with low-end parts not even capable of supporting Linux. To make Linux worthwhile you need an ARM part with MMU support, which excludes a large range of ARM7 and Cortex-M parts.
There are plenty of smaller operating systems for ARM that will allow you to perform efficient (and hard real-time) scheduling and IPC with a very small footprint. They range form simple scheduling kernels such as FreeRTOS to more complete operating systems with standard device support and networking such as eCOS. Even if you use a simple scheduler, there are plenty of libraries available to support networking, filesystems, USB etc.
The answer to your question about compiler is almost certainly GCC - thet is the compiler Linux is built with. You will need a cross-compiler to build the kernel itself, but if you do have an ARM platform with sufficient resource, once you have Linux running on it, your target can host a compiler natively.
If you truly want to use Linux on ARM against all my advice, then the lowest cost, least effort approach to doing so is perhaps to use a Raspberry Pi. It is an ARM11 based board that runs Linux out of the box, is increasingly widely supported, and can be overclocked to 900MHz
You can also try using the Beagle Bone development board. To start with it has few features like UART I2C and others also u can give a try developing the device driver modules for the hardware.
ARM Linux compilers and build toolchains are provided by many vendors. Below are your options which I know of:
1.ARM themselves in form of their product DS-5 ;
2.Codesourcery now acquired by Mentor graphics. See some instructions to obtain & install, codesourcery toolchain for ARM linux here
3.To first start programming using ARM (C , assembly ) I find this Windows-Cygwin version of ARM linux tool chain very helpfull. Here. These are prebuilt executables which work under Cygwin(A Posix shell layer) on Windows.
4.Another option would be to cross compile gcc/g++ toolchain on Linux for ARM target of your choice. Search and web will have information about how it is done. But this could be a slightly mroe involved and long-winding process.
enjoy ARM'ing.
First, you should question yourself if you really need to program assembly language, most modern compilers are hard to beat when it comes to generating optimized code.
Then if you decide you really need it, you can make life easier for your self by using inline assembler, and let the compiler write the glue code for you, as shown in this wikipedia article.
Then the compiler to use: For free compilers there are practically only two choices: either gcc or clang.
There is also a non free toolchain from arm which when i last tried, 5 years ago, produced about 30% faster code than gcc at the time. I have not used it since.
The latest version of this compiler can be found here
You can also write standalone assembler code in .s files, both gcc and clang can compile .s into .o in the same way you would compile a .c or .cpp file.
Compile
If you are using a STM32 based microcontroller you need to get CMSIS and GNU arm-non-eabi-gcc package installed. Then you need to write your own makefile to pass your c codes into arm gcc compiler.
Programming
For the programming step you need to install openocd and configure that for your specific programmer. You can find a full description on how to do that on my blog
http://bijan.binaee.com/index.php/2016/04/14/how-to-program-cortex-m-under-gnulinux-arch/ and in my GitHub repository.
IDE
I'm using vim with CTags but you can use gEdit with the Shortcut plugin if you need a simpler text editor.

Resources