comp.lang.ada
 help / color / mirror / Atom feed
From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: Adapting an Ada compiler to generate 8051 code (Again?! ;-)
Date: Tue, 30 Mar 2021 13:40:51 +0300	[thread overview]
Message-ID: <icgdhjF3j1eU1@mid.individual.net> (raw)
In-Reply-To: <41bc7a62-9c70-466d-b316-5fc74a3ee845n@googlegroups.com>

On 2021-03-30 12:04, mockturtle wrote:
> Dear.all, 
> or a project related to a possible start-up, we need to program a 
> Flash controller that has a 8051 core (as many other controllers).
> I would like using Ada for that, but I discovered (also by browsing 
> cc.l.a.) that there is no Ada compiler producing 8051 code. >
> I am considering involving some university colleagues of mine to
> start a project aimed to having an Ada compiler for 8051, possibly
> leveraging some existing compiler.  According to some post read here,
> I understand that it is not totally impossible, if we are willing to
> accept some limitations.


I advise against that approach. The 8051 architecture is far too limited 
and quirky (and ancient) to waste such a major effort on.

However, you might have a look at the HAC compiler. AIUI, it generates 
code for a virtual machine, and it might be easier to implement that 
virtual machine in 8051 code than it would be to generate 8051 code from 
the compiler.


> I did not study (yet) in detail the 8051, but as I understand it is a
> small 8-bit processor, with flash memory for code and data and  a
> small amount of RAM onboard (but maybe this depends on the specific
> controller).


There are many, many variants of the "8051". What they mostly have in 
common is a small "internal" on-chip RAM of 128 or 256 octets, and an 
optional, larger, but still usually at most 64 KiO, "external" RAM that 
can also be on-chip in current variants. There is a separate code 
memory, usually mask-PROM or flash, also at most 64 KiO, with Harvard 
architecture (separate code and data address spaces). The internal and 
external RAM are also separate address spaces, with separate 
instructions for reading and writing internal vs external RAM.

There is also a third type of memory, IIRC called "paged" RAM, but not 
often used today, I believe.

While the variants all have a similar basic instruction set, there are 
extensions and variations also in the instruction set. For example, the 
basic 8051 has a single Data Pointer (DPTR) register, which is the only 
register (apart from the PC) that has 16 bits and can be used to address 
external RAM. The memcpy routine on such an 8051 is not simple, nor 
fast. Some 8051 variants have added one or several other DPTR registers 
and instructions to manage them.

Finding out the actual properties of the "8051" in your flash controller 
is the first thing you should do.


> My knowledge about compilers is superficial, but I
> guess we should give up to some Ada features like
> 
> *   Multitasking (maybe only non preemptive policy, single priority, 
> no dynamic task allocation? Kind of coroutines...)

The larger forms of the 8051 can certainly run multi-tasking kernels. I 
don't see why a Ravenscar kernel could not be implemented.

However, a major limitation of the 8051 architecture is that the HW 
stack (call-return stack) can exist only in the 256-octet internal RAM. 
C compilers for the 8051 go to great lengths to reduce the amount of 
stack needed by a task. Real-time kernels for the 8051 sometimes resort 
to treating the entire stack of a task as a shared resource, spilling 
the whole stack into external RAM when the task is suspended or 
preempted, and filling it back from external to internal RAM when the 
task is resumed.


> *    Dynamic memory allocation


Should not be a problem, in the external RAM.


> *   Exception raising, but not handling, an exception would stop the
> execution (I guess having an exception inside a microcontroller is
> not a nice idea...  This sounds like a job for Spark to be sure that
> no exception will happen)


You could take the approach used by GNAT in simple run-times: exceptions 
can be raised and handled by _local_ handlers, in the same subprogram or 
block, but cannot propagate up to outer scopes (whether statically or 
dynamically nested). Then raising a locally-handled exception can be 
compiled to a jump instruction, and raising a locally-unhandled 
exception becomes a jump or call to the last-chance handler (followed by 
program abort and restart).


> *   OOP?  Some of that can be retained?


You can keep as much of OOP as is consistent with your memory (code and 
data) and processing-time resources. However, the compiler may have to 
generate more 8051 instructions for eg. dispatching calls than it 
generates for a more powerful instruction set.


> *   Run-time check of contracts (maybe can be kept active during
> development and debugging)


Same as for OOP.

I think you have two options:

1. Use HAC and implement the HAC VM in 8051 code, either in C or in 
assembler.

2. Pay for the AdaCore Ada-to-C compiler and use an 8051 C compiler as a 
back end.

Because of the internal/external RAM architecture of the 8051, efficient 
C code usually needs additional annotations to tell the compiler that a 
certain variable should be stored in internal RAM, or in external RAM, 
or that a certain pointer always points to internal RAM or to external 
RAM, or might point to either one. This could be a problem for the 
Ada-to-C compiler approach, as you would want to write the annotations 
in the Ada source and have them passed through to the generated C source.

There are some free 8051 C compilers (for example SDCC, Small Device C 
Compiler), but most professional programming for the 8051 uses 
commercial compilers such as the ARM/Keil compiler or the IAR compiler. 
You could try SDCC first, but if you get problems with eg. using too 
much internal RAM, the commercial compilers might help.

I have often wished that there would be Ada compilers for more 
microcontrollers, but I understand why there aren't. An Ada-to-C 
compiler seems the most promising route.

  parent reply	other threads:[~2021-03-30 10:40 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-30  9:04 Adapting an Ada compiler to generate 8051 code (Again?! ;-) mockturtle
2021-03-30  9:56 ` Dmitry A. Kazakov
2021-03-30 11:24   ` Gautier write-only address
2021-03-30 11:27   ` mockturtle
2021-03-30 12:01     ` Dmitry A. Kazakov
2021-03-31 23:08       ` Randy Brukardt
2021-03-31 23:06   ` Randy Brukardt
2021-03-30 10:40 ` Niklas Holsti [this message]
2021-03-30 11:32   ` mockturtle
2021-03-31 23:14   ` Randy Brukardt
2021-04-01 15:07     ` Niklas Holsti
2021-04-01 23:34       ` Randy Brukardt
2021-03-30 11:24 ` Luke A. Guest
2021-03-30 13:28   ` Luke A. Guest
2021-03-30 12:45 ` Björn Lundin
2021-03-30 15:49 ` Shark8
2021-03-30 19:16 ` Paul Rubin
2021-03-30 21:28   ` Luke A. Guest
2021-03-30 21:48     ` Paul Rubin
2021-03-31  4:46       ` Luke A. Guest
2021-03-31  7:19         ` Simon Wright
2021-03-31 23:20         ` Randy Brukardt
2021-04-01 12:22           ` Luke A. Guest
2021-04-01 23:43             ` Randy Brukardt
2021-04-02  0:41               ` Luke A. Guest
2021-03-31  8:23     ` Niklas Holsti
2021-03-31 20:46 ` Gautier write-only address
2021-03-31 21:14   ` Shark8
2021-03-31 21:25     ` Gautier write-only address
2021-03-31 21:46       ` Shark8
2021-03-31 23:22       ` Randy Brukardt
2021-04-01 13:19   ` Luke A. Guest
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox