[fpc-devel] Embedded Strings on nRF51-DK

Georg Hieber georg at ghgrp.com
Fri Apr 17 00:38:56 CEST 2015

a few comments from somebody who is not a compiler developer, but who 
very recently started to get fpc running for another embedded platform, 
the avr.

1) you write somewhere that you ported things from c, and your examples 
start as
   "function main: integer ..."
    which looks to me exactly like int main().
   In pascal, there is no need to declare a "function main". it is 
created automatically by the runtime system and contains the begin .. 
end block of your pascal program. In an embedded environment it is 
called immediately after some essential initialization (stack pointer, 
zeroing menory etc.), and if it returns, control goes to a system halt 

2) if you build your crosscompiler with the command
     make clean all OS_TARGET=embedded CPU_TARGET=my_cpu
make will not only build you a compiler but also a basic rtl (without, 
for example, file handling, as that needs an underlaying operating 
system), but which includes things like simple string handling. What 
this system includes and what not is controlled by the file 
<fpcbase>/rtl/embedded/rtl.cfg. For the beginning leave the default, 
minimal settings.

3) avoid ansistrings. They need heap management which is probably not 
available in the basic system, and consume much more resources than 
short strings.

4) how good (in the sense of efficient, short and fast execution code) 
or bad the rtl thus constructed is depends on how much work has already 
gone into porting fpc to the cpu / system combination you use. The rtl 
building process is using a clever sequence of conditional compiles to 
check if a certain function has already been implemented cpu and/or 
opsys specific, and if that is not the case, falls back to a generic 
procedure written in pascal that does the job, however not always in the 
most elegant way. The good part is, that from the beginning you will 
have a rtl that works.

5) unlike C, the fpc compiler depends on the existence of at least a 
minimal rtl (unit system), even if you don't call library functions 
explicitely. There are actually a lot of routines in system.pp and it's 
include files that are declared with the qualifier "compilerproc" which 
makes them invisible for the application program. Calls to these 
functions, however, appear, inserted directly by the compiler

6) there is no need to mess around with linker scripts etc. As long as 
you stay inside the "pascal world", i.e. write your application as a 
pascal program that can (or not) use several units, and do any necessary 
assembler programming using fpc's inline assembler, fpc will take care 
of the linking process. Either completely behind the scene, or, if you 
define so, by creating a linker script you can use. And even if you use 
external references (third party libraries, for example), if they are 
referenced by correctly declared pascal external functions, this should 

7) the rtl unit system will be (smart-)linked automatically to your 
program, every other rtl unit has to be requested explicitely by a uses 
clause if their functionality is needed.

8) does your program have a "program", i.e. a main file that adheres to 
the syntax

program myprog

I have only seen a "unit main", which for the fpc system is nothing more 
than one of probably many units, but which does not tell the compiler to 
link to the rtl (to be precise, to the unit system). The "program" does 
exactly that.

your examples look to me as if you are following your C habits, just 
writing in pascal. If that's correct - don't do it. Most likely, the 
problems you are encountering will dissapear as soon as you just let fpc 
and the basic rtl do their jobs. Do the following:

     - build a compiler and rtl using OS_TARGET=embedded and CPU_TARGET 
whatever is closest to your actual cpu, which seems to be some arm variety.
     - write your "main" as the begin .. end block of a program
     - let fpc take care of the linking.

I hope what I wrote helps a little and does not bore too much,


Am 16.04.2015 um 15:29 schrieb Jeppe Johansen:
> On 04/16/2015 12:49 PM, Paul Michell wrote:
>> I assume this is because string handling support is not included in the
>> embedded RTL generated with the compiler, or that I am not linking 
>> the right
>> object files if I need to do this by hand?  What would be the best 
>> way to
>> enable string handling? Even short string handling would make FPC far 
>> more
>> preferable to C for me for embedded work.
> You would make it a whole lot easier for yourself if you just used the 
> Embedded target and added an actual controller type for that specific 
> microcontroller. Then you wouldn't need to play around with linker 
> scripts and manually including and trimming RTL files.
> Adding the controller type is about 5-10 lines of code. Then the RTL 
> unit can be a stub for now which basically just initializes .data and 
> .bss.
> If you have the name of the controller I can add it?
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

More information about the fpc-devel mailing list