Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-07

Cross compiling Windows to arm-linux

4 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

John Hansen

I am working on an API library for the new LEGO MINDSTORMS EV3 programmable brick.  The brick is running Linux on a TI AM1808 ARM chip.  I built a Free Pascal cross compiler using 2.7.1 source code along with the CodeSourcery Lite, 2009q1 cross compiler (arm-2009q1-203-arm-none-linux-gnueabi.exe on Windows).  Both of these compilers are integrated into my Bricx Command Center (BricxCC) IDE for programming LEGO MINDSTORMS programmable bricks.  I have successfully compiled and ran arm-linux binaries on the EV3 via my BricxCC IDE.  The goal, ultimately, is to have a full library of C/C++ and Pascal API functions for creating native arm-linux applications to control your LEGO MINDSTORMS EV3 creations and so far I have been making very good progress in that direction. So far I can control LEDs, read button presses, and control motors in C, C++, or Pascal using these cross compilers.

Yesterday, however, I tried to run a binary for the first time that used TThread and I got a run-time error message that, via Google, told me I needed to use cthreads as the first unit in my program source code.  After adding that to my uses statement I now get linker errors.

lcd_test.dpr: warning: 31: "crti.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtbegin.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtend.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtn.o" not found, this will probably cause a linking failure D:\FPC\2.7.1\units\arm-linux\rtl\cprt0.o: In function `_haltproc_eabi': (.text+0x88): undefined reference to `_fini'
D:\FPC\2.7.1\units\arm-linux\rtl\cprt0.o: In function `_haltproc_eabi': (.text+0x90): undefined reference to `_init'

Yesterday I tried a lot of -X options of various sorts based on things I found via Google but so far I haven not had much luck getting past these errors.  I have now added paths to units using -Fu for a folder(s) under my CodeSourcery Lite install where I found the 4 files mentioned above.  That gets rid of the warnings but I still get either the above error or "undefined reference to `__aeabi_unwind_cpp_pr0'"

I have spent the better part of two days solid trying to find a solution on the web and so far nothing has fixed the problem. I have turned on --verbose to see what the linker is doing and I have looked at the link.res file.  

Does anyone have any idea what is going wrong and how to fix this problem?  It sounds like it might be that I need to have the order that it tries to link the files and libraries modified so that it links the C runtime .o files after my own code or something like that.  But how do I accomplish that feat?

John Hansen

Carsten Bager
to John Hansen

For some years ago I had a similar problem.
I solved it by forcing the use of specific libs.
See my old test programme below.
Carsten

lcd_test.dpr: warning: 31: "crti.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtbegin.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtend.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtn.o" not found, this will probably cause a linking failure
program testthreads;
{$mode objfpc}
{$RANGECHECKS ON}
{$OVERFLOWCHECKS ON}
{$S+ STACK CHECKING ON}
{$SMARTLINK ON}
{$TYPEINFO ON}
{$LONGSTRINGS OFF}
uses
  cthreads,
  sysutils,
  dos;
{$IFDEF ARM9LINUX}
  {$IFDEF Ulibc}
    {$linklib ulibc}                {Force use of uLibC}
    {$linklib gcc_s}                {Force use of gcc_s}
    {$linklib pthread}       {Force use of pthread-0.9.27}
    {$DEFINE IO_WORKAEAROUND}
  {$ENDIF}
{$ENDIF}
const
  threadcount = 10;
var
  finished : longint;
  ta:array[1..threadcount] of LongWord;
(*
{$I-}    {Input/output checking}
Function FileExists(s:shortstring):integer;
var
  f:file;
  mvi:integer;
Begin
  assign(f,s);
  reset(f);
  FileExists:=ioResult;
  close(f);
  mvi:=ioResult;
End;
{$I+}    {Input/output checking}
*)
(*
Function FileExists(s:shortstring):boolean;
Begin
    Exec('/bin/ls',s+'>NULL');
    FileExists:=Lo(DosExitCode)=0;
End;
  *)
function fu(p : pointer) : longint;
Var
  f:file;
Begin
  finished:=succ(finished);
  Writeln('thread ',finished,' started');
  assign(f,IntToStr(finished));
  rewrite(f);
  close(f);
  sleep(1000+finished*1000);
  Writeln('thread ',finished,' stopped');
  finished:=pred(finished);
End;
var
  i : longword;
  b:boolean;
Begin
  WriteLn('<0>',paramstr(0));
  WriteLn('<1>',paramstr(1));
  WriteLn('<2>',paramstr(2));
  WriteLn('<E>',GetEnv('USER'));
  WriteLn(fileExists('1'));
  WriteLn(fileExists('11'));
  finished:=0;
  for i:=1 to threadcount do
  begin
    BeginThread(@fu,nil,ta[i]);
  end;
  sleep(1000);
  while finished>0 do;
  Writeln(finished);
  try
  b:=fileExists('1');
  except
    WriteLn('-------------------');
  end;
  WriteLn(b);
  try
  b:=fileExists('11');
  except
    WriteLn('-------------------');
  end;
  WriteLn(b);
End.
Mark Morgan Lloyd
to John Hansen: I am working on an API library for the new LEGO MINDSTORMS EV3 programmable brick.  The…
John Hansen wrote 10 lines
lcd_test.dpr: warning: 31: "crti.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtbegin.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtend.o" not found, this will probably cause a linking failure lcd_test.dpr: warning: 31: "crtn.o" not found, this will probably cause a linking failure D:\FPC\2.7.1\units\arm-linux\rtl\cprt0.o: In function `_haltproc_eabi': (.text+0x88): undefined reference to `_fini' D:\FPC\2.7.1\units\arm-linux\rtl\cprt0.o: In function `_haltproc_eabi': (.text+0x90): undefined reference to `_init' Does anyone have any idea what is going wrong and how to fix this problem? It sounds like it might be that I need to have the order that it tries to link the files and libraries modified so that it links the C runtime .o files after my own code or something like that. But how do I accomplish that feat?

This is a placeholder pending somebody more experienced commenting. A number of people have reported similar problems over the last few months, e.g.
http://comments.gmane.org/gmane.comp.compilers.free-pascal.general/32106

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Michael Schnell
to John Hansen: I am working on an API library for the new LEGO MINDSTORMS EV3 programmable brick.  The…
John Hansen wrote
I am working on an API library for the new LEGO MINDSTORMS EV3 programmable brick. The brick is running Linux on a TI AM1808 ARM chip.

Does the EV3 provide any graphic ? If not, you will need to set up a remote debugging environment, best using Lazarus. In theory this should be possible in two ways:
- using gdbserver on the target and a "cross gdb" on the PC, the two connected via the gdb-propriety protocol (here stopping a running project from the PC other than on a breakpoint is not possible ) , or
- using standard ARM gdb on the target and access same from Lazarus using SSH (no such limitations, but Lazarus does not provide this "out of the box" (AFAIR, the appropriate code is not decently tested and commented out).

AFAIK neither way has been set up successfully yet.

A friend of mine and myself tried to do this for our ARM based NAS devices by QNAP, but while we did not give up at the moment the project is stalled

If the EV3 is powerful enough to run a VNC server, same can be used an X Server for a GUI interface and that way you might be able to run the Lazarus IDE native on the device to do comfortable debugging.

I tried to run a binary for the first time that used TThread and I got a run-time error message that, via Google, told me I needed to use cthreads as the first unit in my program source code. After adding that to my uses statement I now get linker errors. lcd_test.dpr: warning: 31: "crti.o" not found, this will probably cause a linking failure ...

I ran into a similar problem, doing native compiling on the ARM, trying to compile a project that includes Synapse. I found that the "crt" stuff is necessary for attaching to dynamic libraries (.so files in Linux). It is linked in, when the project might _possibly_ intend to attach to a dynamic library.

I was able to link the project by providing some (AFAIR *.so) files and set the linker path appropriately.

If you in fact want to use TThread, there are some additional considerations:

The normal "Lazarus" programming way is to have a MainThread and Worker threads. The main thread in "normal" Lazarus applications is based on an event queue, so that the application programmer can do "event driven programming" and does not have to bother about a "main loop". The worker threads can notify the main thread by pushing events into the queue.

Unfortunately, in Lazarus, none of the multiple "LCL Widget Type"s is able to _not_ attach to a GUI API of the system it runs on, while providing the said event queue. (Of course when using a GUI, events generated by TThread instances are merged with events generated by the GUI. )

So you you are on your own when using threads on non-GUI enabled systems.

-Michael