CSharp on RPi

From eLinux.org
Revision as of 19:49, 11 March 2013 by JoeStrout (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

C# can be used, in both compiled and interactive mode, on the Raspberry Pi via Mono. However, different Linux distributions differ in how floating-point parameters are passed to functions, resulting in some complications for JIT-compiled languages like Mono. See below for details.

Hard/Soft Float ABI Issue

There are two different versions of the ABI (application/binary interface) calling convention for ARM. The "hardfloat" convention means that floating-point parameters may be passed between functions in the floating-point registers. The "softfloat" convention means that floating point parameters may only be passed using integer registers.

Mono for ARM is written to use the softfloat ABI (which is the standard on iPhone and Android, for example). Unfortunately, the standard Raspberry Pi distributions (such as Raspian) use the hardfloat convention. On such a distro, Mono will install and run, but some functions generate incorrect results, and many apps will simply crash. See the official bug reports: [1], [2], and [3].

If you have Mono installed, you can test whether you are affected by this problem by executing the "csharp" command, and entering the code "Math.Pow(2,4)". If this returns 16, your installation is working correctly. If it returns some other number (such as 0.000746999867260456), then your installation has tripped over the hardfloat/softfloat issue.

Solution 1: Use a Softfloat Distro

To use the standard builds of Mono requires a distribution compiled with the softfloat ABI. This does not mean it can't use hardware floating-point operations; it's only the passing of floating-point values to functions that matters. In practice, though, current distributions built with the "soft float" settings do not make use of the floating-point hardware at all. This avoids the problem, but also reduces performance on floating-point operations substantially.

On the Raspberry Pi Downloads page, select a "soft float" distribution, such as "Soft-float Debian 'wheezy'."

Solution 2: Patch Mono

A patch to Mono is available to make it work on hardfloat ARM is available here [4]. This patch is for Mono 2.x; you can check what version of Mono you have with "mono --version".

In addition, it may be that this patch is not right or is incomplete for armv6 (the chip used in the Raspberry Pi). More details are needed.

Installation

To use C#, you must first install the mono-complete package. Under Debian:

sudo apt-get install mono-complete

Under Arch:

sudo pacman -S mono-complete

Usage

To use the interactive C# environment [5], simply type "csharp" at a command prompt. Enter some C# code, and it will be executed or evaluated immediately. Press Ctrl+D (or enter "quit;") to exit.

To compile, use the "mcs" (Mono C Sharp) command [6], specifying the name of your source file. This produces a new file with a ".exe" extension; run this executable with the "mono" command. For example:

mcs HelloWorld.cs mono HelloWorld.exe

Examples

Hello World (Interactive)

The following shows how to launch the C# interactive environment and get it to print "Hello world!"

$ csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> print("Hello world!");
Hello world!
csharp>

Hello World (Compiled)

Put the follow code in a text file called "HelloWorld.cs" (using your favorite text editor; "nano" [7] comes standard). Compile with "mcs HelloWorld.cs" and run with "mono HelloWorld.exe".

using System;

public class HelloWorld {
	public static void Main() {
		Console.WriteLine("Hello world!");
	}
}

Serial Port (Interactive)

This example shows creating the serial port by name (the standard name for the UART on the expansion header is /dev/ttyAMA0), checking its status, opening it, and finally writing some data.

csharp> using System.IO.Ports;
csharp> SerialPort sp = new SerialPort("/dev/ttyAMA0", 9600);
csharp> sp.IsOpen;
false
csharp> sp.Open();
csharp> sp.IsOpen; 
true
csharp> sp.WriteLine("Hello world!");