B# - A programming language for small footprint embedded systems applications: Part 1
By Michel de Champlain, DeepObjectKnowledge and Brian G. Patrick, Trent University
B# (pronounced “be sharp”) is a tiny, object-oriented, and
multi-threaded programming language that is specially dedicated for
small footprint embedded systems.
Because B# has its roots in the C family of languages, it will be
immediately familiar to C, C++, Java, and C# programmers. In addition
to supporting modern object-oriented features such as namespaces,
abstract and concrete classes, interfaces, and delegates, the B#
language caters to the embedded systems programmer with efficient
boxing/unboxing conversions, multi-threading statements, field
properties, device addressing registers, interrupt handlers, and
deterministic memory defragmenter.
Each of these features is directly supported by the constructs of B#
and its underlying virtual machine in order to create, use, and reuse
more portable and decoupled software components across different
embedded systems applications. This series of articles highlights and
illustrates these key B# concepts with short programming excerpts, but
leaves the details of other more common features to a more complete
overview.
Motivation and Unique Key Features
Despite the evolution of object-orientation and the development of
advanced language features such as interfaces, delegates, and
properties, the linga franca for embedded systems programmers continues
to be the C programming language. Developed in the early 1970’s, the C
language has maintained its foothold over the years for four key
reasons: availability, portability, flexibility, and accessibility.
It has also served, at least syntactically, as the foundation for
C++, Java, and C#, among many other experimental languages. C is no
doubt venerable, but it is also old [1, 2]. And, unfortunately , C++
and Embedded C++ are often not
suitable for small-scale architectures with tight memory (<
64KBytes) constraints.
Our programming language called B# (pronounced “be sharp”)
introduces embedded
systems developers to a fully-fledged, object-oriented programming
language that is designed explicitly for small footprint embedded
systems [3, 4].
In addition to the traditional object-oriented features of
encapsulation, inheritance, and polymorphism, the B# language includes
efficient boxing/ unboxing conversions, field properties, device
addressing registers, interrupt
handlers, deterministic memory defragmenter, and multi-threading
capabilities.
In order to support these features efficiently, high-level B# code
is mapped directly to a compact instruction set which is interpreted by
an optimized embedded virtual machine called B#EVM. The intermediary of
a stack-based virtual machine allows the embedded systems developer to
write interrupt handlers and to access device registers in a uniform
manner, independent of the underlying target architecture
(memory-mapped or port-mapped).
Several advantages accrue. First, resultant B# binary code is more
compact. The stack architecture of B#EVM precludes specifying registers
and addressing modes. Hence, the opcode of B#EVM is reduced to only
eight bits from the 16- or 32-bit opcodes of several modern
microcontrollers. Second, the B#EVM which directly supports
object-oriented features promotes the reusability of software
components expressed in binary format on any architecture where the
B#EVM is
available. It is worth noting that the implementation of the B#EVM,
written in full ANSI C, is the only porting effort required for each
specific architecture.
Third, not being dedicated to any specific microcontroller
architecture, the development of a toolkit (compiler, assembler,
monitor, and so on) for a virtual machine like B#EVM is far easier to
test, debug, and maintain and therefore, far more cost effective with
respect to the development of embedded
systems applications.
Finally , B#EVM has its own multi-threading kernel and avoids the
inclusion of third party kernels.
The paper is divided into two main sections. In this first part in a
series, an overview of the key and unique features of the B# language
itself are reviewed, while Part 2 outlines outlines the three major
components of the embedded virtual machine B#EVM.
The B# Language
Each B# program consists of one or more source files.Eac h file is
composed
of types which, in turn, are composed of members.Classes, interfaces,
and delegates are examples of different types and fields, methods,
properties, interrupt handlers, and device registers are examples of
different members. Classes are grouped into namespaces that may extend
beyond a single file, but unlike C#, namespaces cannot be nested.
Unified Type
System. B# has a unified type system. All B# types inherit from
a single root object type. Thus, all types share a set of common
operations and values of any type can be manipulated in a consistent
manner. B# is also strongly-typed and supports both value and reference
types.
Value Types.
B# has five value types: boolean (bool),
character (char), signed
integer (int), unsigned integer
(uint), and floating-point (float). For the sake of simplicity
and internal stack evaluation efficiency, the five value types are all
represented and manipulated as (maximum) 32-bit values.
Reference Types.
Whereas value types contain variable data, reference types contain
addresses of objects. B# provides a set of predefined reference types
familiar to Java or C# developers including object, array, and string. Two additional types, delegate and ioreg for device addressing, are
also included. The object type is similar to the untyped pointer (void*) in the C programming
language.
Efficient
Boxing/Unboxing Conversions. The type system of B# has the
ability to obtain type information of every variable at runtime and to
treat value types as objects. These runtime capabilities are achieved
by keeping minimal information on types in order to provide efficient
and flexible boxing/unboxing conversions.
These conversions are an elegant mechanism inspired from C# and
adapted for our needs. Consider the use of boxing/unboxing in the B#
example below:

An int value is converted to object and back again to int. Boxing happens when a
valuetype variable is converted to a reference type. Unlike C#, an
object box is already allocated and therefore, the value does not need
to be copied into the box. Unboxing is the complementary process, but
contrary to C#. B# avoids copying a value into and out of a box by
providing a pre-allocated wrapping mechanism within the B#EVM stack.
This wrapping mechanism uses a tag that is set for each variable and
identifies its type. When a value-type variable is converted to a
reference type (or vice versa), the tag field is reset. In this way,
the unified type systems of B# provides value types with the benefits
of reference types without introducing unnecessary overhead.
Expressions and
Multi-threading Statements. The operators of B#, their
precedence and associativity, are identical to those in C. Only the
pointer operators *, &,
and -> are excluded and
only the operators, new for
object creation and is for type
testing, are also included. Expressions are formed by combining literal
values and variables with B# operators.
B# also borrows several sequential statements from C including
statement lists,
block statements, expression statements,
return, if, while, and break.
In addition, the lock and start statements of B# are inspired
from Edison.
The lock statement, originally called when in Edison, is used for
mutual exclusion and synchronization. The start statement, originally called cobegin in Edison, is used to
initiate threads. The addition of multi-thread and synchronization
statements facilitates the development of embedded systems
where concurrent activities are often implicit.
In the following example, two threads, SerialPortThread and ParallelPortThread, are initiated
with access to a shared buffer.

Classes and
Objects. In B#, classes are the most fundamental types.A class
type defines a data structure that contains data members (fields) and
function members (methods, properties, and others). A class provides a
specification for dynamically created instances of the class, also
known as objects.
Classes support inheritance and polymorphism, mechanisms whereby
derived classes can extend and specialize base classes. New classes are
created using
class declarations. A class declaration starts with a header that
specifies the modifiers of the class, the name of the class, the base
class (if any), and the interfaces implemented by the class.
Class Members.
In B#, the members of a class are either static members or instance
members. Static members belong to classes and instance members belong
to objects (instances of classes). The following table provides an
overview of the kinds of members a class can contain.
 |
| Table
1. Class Members in B# |
Field
Properties. A field property is a natural extension of fields
and is similar to properties in C#. In addition to declaring a field, a
field property also specifies the read and/or write access to the field
itself using the get and set accessors, respectively.
Each accessor is defined as a block statement which is executed when
the field value is read or written. In essence, therefore, a field
property is a field declaration followed by a get and/or set accessor.
In the following example, the Device
module defines a Status field
property. A property is always assumed to be an implicit private field with public accessors. Unlike C#, field
properties in B# denote storage locations.Therefore, it is unnecessary
to declare the private field status.

The value of a field property can be read by invoking the get accessor or written by invoking
the set accessor. In a set accessor, the new value for the
field property is passed via an implicit parameter named value. Accessing a field property is
like getting or setting the value itself. For example, the Status property can be read and
written in the same way that fields can be read and written:

Device Registers.
The type ioreg represents input/output device register addressing for
embedded processors based on the ISO/IEC standard.It is used for both
port- and memory mapped device registers, but submerges the distinction
between the two kinds of registers to the level of the virtual machine
B#EVM.
Therefore, the embedded systems developer is not required to specify
whether or not a device is either port- or memory-mapped: the ioreg provides a uniform way of
handling both. The type ioreg
is the base class of three other predefined classes, ioreg8, ioreg16, and ioreg32, which allow read/write
access from/to
8-bit, 16-bit, and 32-bit device registers, respectively.
Access to the device registers is defined using a mechanism similar
to field properties. The only difference between the two is that the
address of a ioreg field must
be initialized at declaration. The following example declares three
device registers as read only, write only, and read/write:

Interrupt Handlers.
An interrupt handler (also called an interrupt service routine) is a
special method which is executed when an external hardware interrupt is
triggered. Each handler is specified by adding the interrupt keyword in
front of a method, making it implicitly static and internal with no
return value.
The interrupt number is declared after the name of the handler and
is mapped internally by the B#EVM.The following method is a real-time
clock handler set to the interrupt vector 8:

Later, in the second part in this series, we will discuss the inner
workings of the embedded virtual machine B#EVM.
Michel de Champlain will present a full day tutorial at the
Embedded Systems Conference (ESC-504: Java Jumpstart in Room C2)
starting at 8:30 a.m. on April 7. At 4:30 p.m. after the class, he will
present a 30 minute presentation on B#.
Michel is chief scientist of DeepObjectKnowledge Inc., an
object-oriented training/mentoring firm located in Montreal, Quebec,
Canada. He is also a former associate professor in Computer Engineering
at Concordia University and a regular speaker at the Embedded Systems
Conference. He can be contacted at mdec@DeepObjectKnowledge.com.
Brian is an associate professor of Computer Science/Studies at Trent
University located in Peterborough, Ontario, Canada. His main research
interests are programming languages and parallel job scheduling. He can
be contacted at bpatrick@trentu.ca.
References
[1] M.Barr, Is C Passing?, Embedded.com,
May 2002.
[2] J.W. Grenning, Why are you still using C?, Embedded.com,
April 2003.
[3] M.de Champlain, B# Grammar, presents the grammatical summary of the
B# programming language. Its syntax is described in a concise fashion
using the EBNF notation. www.DeepObjectKnowledge.com\BSharpProject
or www.BSharpLanguage.org.
[4] M.de Champlain and B.G Patrick, B# Project: Object Design for
Developping Small Embedded Systems Applications, will be published by
Newnes/Elsevier, Fall 2006.