Raspberry Pi 2 ARM embedded target lazarus / 79-Embedded - ARM ---------------------------------------------------------------------- rca · 2020-05-04 21:16 I found this information, where the author "Robert Roland" has managed that add Raspberry Pi 2 ARM embedded target. https://bugs.freepascal.org/view.php?id=35236 https://github.com/graemeg/freepascal/commit/f06ffad7f6044d167ea206afd 26d8c1f5dd979b1 How can it be used? Some example? Could it be extended to a Raspberry Pi 3? ---------------------------------------------------------------------- avra · 2020-05-04 23:55 Quote from: rca on May 04, 2020, 11:16:54 pmCould it be extended to a Raspberry Pi 3?Are you aware of Ultibo? https://wiki.lazarus.freepascal.org/Ultibo_core https://wiki.lazarus.freepascal.org/Ultibo_Quick_Start ---------------------------------------------------------------------- rca · 2020-05-05 02:02 Quote from: avra on May 05, 2020, 01:55:58 amAre you aware of Ultibo? https://wiki.lazarus.freepascal.org/Ultibo_core https://wiki.lazarus.freepascal.org/Ultibo_Quick_Start If I know him, Ultibo is very good. I was struck that now formally fpc, has included the Raspi 2 like ARM embedded target. And I would really like to try and understand how to use it. Although at the moment I only have Rpi3+ and Rpi4. ---------------------------------------------------------------------- Thaddy · 2020-05-05 06:37 Build a cross compiler for arm-embedded and also install the toolchain. Use it for Armv6. Here is a good article on which files are needed to bootstrap: https://www.studica.com/blog/program-embedded-systems-raspberry-pi ---------------------------------------------------------------------- rca · 2020-05-09 16:05 Quote from: Thaddy on May 05, 2020, 08:37:29 amHere is a good article on which files are needed to bootstrap: https://www.studica.com/blog/program-embedded-systems-raspberry-pi Thanks for excellent article. I have read it these days and now it is more understandable how it works. And I'm doing some tests. With lazarus-freepascal, when compiling a arm-embedded program, files are automatically generated: name.bin name.elf name.hex To generate the kernel7.img file, I have done: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i arm-none- eabi-objcopy name.elf -O binary kernel7.img and I have verified that the new file 'kernel7.img', is the same file 'name.bin' Is there a way to automatically change name.bin to name.img when compiling? Or does it automatically generate name.img as well? ---------------------------------------------------------------------- rca · 2020-05-09 22:38 After doing some research, I've already figured out how to automatically create the 'img' extension. Inside the file: compiler/systems/t_embed.pas Found 'Post process': Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       if success then        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+        ChangeFileExt(current_module.exefilename,'.elf')+' '+          ChangeFileExt(current_module.exefilename,'.bin'),true,false); You can add: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       if success then        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+        ChangeFileExt(current_module.exefilename,'.elf')+' '+          ChangeFileExt(current_module.exefilename,'.img'),true,false); ---------------------------------------------------------------------- avra · 2020-05-10 14:19 If you use ifdefs to properly isolate a case where IMG should be used instead of BIN, then it would be nice if you could create a patch for compiler/systems/t_embed.pas and report it to the bugtracker so others could benefit from your findings. ---------------------------------------------------------------------- rca · 2020-05-11 00:48 Following the suggestions of @avra For the Raspberry we only need the file with the extension '.img', the other files with the extension '.bin', '.hex' and '.elf' are not necessary. I have modified compiler/systems/t_embed.pas I have added a variable:   Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i OnlyExtImg: boolean = False; And changing this Original part Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   if success and (target_info.system in [system_arm_embedded,system_avr_emb edded,system_mipsel_embedded,system_xtensa_embedded]) then    begin    success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+        FixedExeFileName+' '+        maybequoted(ScriptFixFileName(ChangeFileE xt(current_module.exefilename,'.hex'))),true,false);      if success then        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+          FixedExeFileName+' '+          maybequoted(ScriptFixFileNa me(ChangeFileExt(current_module.exefilename,'.bin'))),true,false);    end; For this other: Resolving that it only affects when we are compiling for the raspberry: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   if success and (target_info.system in [system_arm_embedded,system_avr_emb edded,system_mipsel_embedded,system_xtensa_embedded]) then    begin    {$ifdef ARM}      if (current_settings.controllertype = ct_raspi2) then OnlyExtImg := True;          {$endif ARM}      if OnlyExtImg then      begin        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+        FixedExeFileName+' '+          maybequoted(ScriptFixFileName(ChangeFil eExt(current_module.exefilename,'.img'))),true,false);          DeleteFile(FixedExeFileName);        end                     else     begin             success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+           FixedExeFileName+' '+           maybequoted(ScriptFi xFileName(ChangeFileExt(current_module.exefilename,'.hex'))),true,fals e);         if success then           success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+           FixedExeFileName+' '+             maybequoted(ScriptFixFileName(Ch angeFileExt(current_module.exefilename,'.bin'))),true,false);        end;    end; Sorry, but I don't know how to create a patch and I don't know how to report it to the bugtracker. Perhaps some other user can collaborate to do so. ---------------------------------------------------------------------- avra · 2020-05-11 08:57 Quote from: rca on May 11, 2020, 02:48:48 amFor the Raspberry we only need the file with the extension '.img', the other files with the extension '.bin', '.hex' and '.elf' are not necessary. I have modified compiler/systems/t_embed.pas I have added a variable:   Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i OnlyExtImg: boolean = False;...No, do not change more then really needed. I meant something like Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       if success then        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+        ChangeFileExt(current_module.exefilename,'.elf')+' '+         {$ifdef ARM}          ChangeFileExt(current_module.exefilename,'.img'),true,false);         {$else}          ChangeFileExt(current_module.exefilename,'.bin'),true,false);         {$endif ARM} but that would change extension for all ARM processors and not just for Pi. If that is what it should be then fine. If there are ARMs that need different file extension then maybe it would be easier for you if you simply create a batch command to rename file extension after compilation. You can set it to be called here: Project / Project Options / Compiler Options / Compiler Commands / Execute After / Command. Quote from: rca on May 11, 2020, 02:48:48 amSorry, but I don't know how to create a patch and I don't know how to report it to the bugtracker.Those are very useful skills that you should learn sooner or later. I am not pushing - it's really up to you and your priorities... Quote from: rca on May 11, 2020, 02:48:48 amPerhaps some other user can collaborate to do so.If I was certain it was a good change I would do that. Unfortunately I am not familiar enough with that particular topic to be confident that such change is good and take the responsibility for the action. ---------------------------------------------------------------------- ccrause · 2020-05-11 13:01 Quote from: avra on May 11, 2020, 10:57:14 am... but that would change extension for all ARM processors and not just for Pi. If that is what it should be then fine. If there are ARMs that need different file extension then maybe it would be easier for you if you simply create a batch command to rename file extension after compilation.I suspect the .img extension is a convention used by the RPi bootloader and not a general requirement for ARM systems.  Other people use FPC on embedded ARM, so perhaps they can chip in with real information here. Another alternative you have is to specify the name (and extension) to your kernel image in config.txt on the boot card. ---------------------------------------------------------------------- rca · 2020-05-11 18:54 Currently, the changes that Robert Roland made in freepascal are compatible with the file that Raspberry recognizes by default 'kernel7.img' without changing or adding the config.txt file. The compiler is expected to automatically generate the file 'kernel7.img' like other bare metal compilers including "Ultibo". For Raspberry, the other files generated with the extension '.bin', '.hex' and '.elf' are not necessary. That is why I made this simple change, which only affects when compiling for the Raspberry: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       {$ifdef ARM}      if success then      begin               if (current_settings.controllertype = ct_raspi2) then          begin          success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+ FixedExeFileName + ' kernel7.img',true,false);            DeleteFile(FixedExeFileName);            DeleteFile(current_module.exefilename + '.hex');            DeleteFile(current_module.exefilename + '.bin');          end;      end;                                       {$endif ARM} Currently, the original is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   if success and (target_info.system in [system_arm_embedded,system_avr_emb edded,system_mipsel_embedded,system_xtensa_embedded]) then    begin    success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+        FixedExeFileName+' '+        maybequoted(ScriptFixFileName(ChangeFileE xt(current_module.exefilename,'.hex'))),true,false);      if success then        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+          FixedExeFileName+' '+          maybequoted(ScriptFixFileNa me(ChangeFileExt(current_module.exefilename,'.bin'))),true,false);    end; Now it remains: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   if success and (target_info.system in [system_arm_embedded,system_avr_emb edded,system_mipsel_embedded,system_xtensa_embedded]) then    begin    success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+        FixedExeFileName+' '+        maybequoted(ScriptFixFileName(ChangeFileE xt(current_module.exefilename,'.hex'))),true,false);      if success then        success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+          FixedExeFileName+' '+          maybequoted(ScriptFixFileNa me(ChangeFileExt(current_module.exefilename,'.bin'))),true,false);    {$ifdef ARM}      if success then      begin                 if (current_settings.controllertype = ct_raspi2) then          begin          success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+ FixedExeFileName + ' kernel7.img',true,false);            DeleteFile(FixedExeFileName);            DeleteFile(current_module.exefilename + '.hex');            DeleteFile(current_module.exefilename + '.bin');          end;      end;                                       {$endif ARM}    end; And I've verified that that change is only reflected when I compile for Raspberry (-WpRASPI2). For everyone else, it remains the same. ---------------------------------------------------------------------- rca · 2020-05-11 20:01 Also, I already generated the respective patch and reported it: https://bugs.freepascal.org/view.php?id=37052 ---------------------------------------------------------------------- Thaddy · 2020-05-12 06:55 This is not complete, since the Rasberry Pi 2 v 1.2 also supports AARCH64 which may be of interest for embedded. ---------------------------------------------------------------------- ccrause · 2020-05-12 07:28 Quote from: rca on May 11, 2020, 08:54:15 pmThe compiler is expected to automatically generate the file 'kernel7.img' like other bare metal compilers including "Ultibo".A good point, the Ultibo version of FPC does not modify t_embed.pas the way you propose.  I'm not familiar with the design of Ultibo, but it may be worth looking at that project to see how they prepare binaries and rename for RPi. ---------------------------------------------------------------------- rca · 2020-05-12 12:50 Quote from: Thaddy on May 12, 2020, 08:55:58 amThis is not complete, since the Rasberry Pi 2 v 1.2 also supports AARCH64 which may be of interest for embedded. Since Rasberry Pi 2 v1.2, it allows to run in AArch32 or AArch64 mode. For those raspberry models, in AArch32 mode, they support 'kernel7.img' and in AArch64 mode, they support 'Kernel8.img'. In other words, a Raspberry Pi 3 or Pi 4 works correctly in AArch32 mode. Multiple bare metal compilers have the option to choose to compile for AArch32 or AArch64 mode. In the case of Ultibo, currently only AArch32 mode works. And it is still very complete and functional. Also, from what I understand, freepascal does not support aarch64-embedded. Quote from: ccrause on May 12, 2020, 09:28:19 amA good point, the Ultibo version of FPC does not modify t_embed.pas the way you propose. That's because Ultibo developed an independent RTL: https://github.com/ultibohub/Core/tree/master/source/rtl/ultibo ---------------------------------------------------------------------- PascalDragon · 2020-05-13 07:25 Quote from: rca on May 12, 2020, 02:50:26 pmQuote from: ccrause on May 12, 2020, 09:28:19 amA good point, the Ultibo version of FPC does not modify t_embed.pas the way you propose. That's because Ultibo developed an independent RTL: https://github.com/ultibohub/Core/tree/master/source/rtl/ultibo t_embed.pas is part of the compiler, not part of the RTL. Also developing a custom RTL does not change what the compiler outputs. ---------------------------------------------------------------------- rca · 2020-05-13 12:18 Quote from: PascalDragon on May 13, 2020, 09:25:38 amt_embed.pas is part of the compiler, not part of the RTL. Also developing a custom RTL does not change what the compiler outputs. You're right. It was my mistake, assuming that from RTL indirectly called 't_ultibo' The correct thing is that Ultibo does not use the file 'compiler/systems/t_embed.pas' Use one created by them: 'compiler/systems/t_ultibo.pas' And note that they only generate the file 'kernel7.img': https://github.com/ultibohub/FPC/blob/master/source/compiler/systems/t _ultibo.pas#L903 ---------------------------------------------------------------------- ccrause · 2020-05-13 15:32 Quote from: rca on May 13, 2020, 02:18:51 pmUse one created by them: 'compiler/systems/t_ultibo.pas' And note that they only generate the file 'kernel7.img': https://github.com/ultibohub/FPC/blob/master/source/compiler/systems/t _ultibo.pas#L903 Thanks for finding this information.  It seems like there is then a precedent for your proposal.  Will add a note to your bug report. ---------------------------------------------------------------------- rca · 2020-05-14 22:54 Good news, the freepascal team applied the patch I proposed, although they removed the deletion part of the intermediate files. I think it's great. Since it now automatically generates the expected 'kernel7.img' file for the Raspberry. ---------------------------------------------------------------------- ccrause · 2020-05-15 07:30 Well done! Perhaps you can also port the other Pi variants from Ultibo, now that your first patch is done? ---------------------------------------------------------------------- rca · 2020-05-15 13:37 Quote from: ccrause on May 15, 2020, 09:30:39 amWell done! Perhaps you can also port the other Pi variants from Ultibo, now that your first patch is done? Thank you. I have not tried to port Ultibo features, as it is very complex to understand what they did internally. They modified many files ... Ultibo currently does not support RPi4. Now my purpose is to add the build for Raspberry Pi3 and Pi4. With the original 'raspi2.pp' file introduced by Robert Roland. My RPi3 and RPi4 do not work. I am currently testing and creating two files 'raspi3.pp' and 'raspi4.pp', with the respective internal modifications and in the necessary files. Investigating how they do it in assembly language, the boot modes ... I have started with the most basic and that is to work with the 'GPIO' peripherals as input and output. Create a gpiorpi.pas unit. And I made them work on RPi3 and RPi4. This is how it goes so far: Example, blinker: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program example1; uses gpiorpi; var  Rpi : TBoardPi; begin   Rpi.ModeGPIO[17] := mOutput;   while (true) do  begin      Rpi.GPIO[17] := True;      some_delay;      Rpi.GPIO[17] := False;      some_delay;  end; end. Example of input and output: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program example2; uses gpiorpi; var  Rpi : TBoardPi; begin   Rpi.ModeGPIO[17] := mOutput;  Rpi.ModeGPIO[27] := mInput;   while (true) do  begin    if (Rpi.GPIO[27]) then         Rpi.GPIO[17] := True      else         Rpi.GPIO[17] := False;  end; end. ---------------------------------------------------------------------- rca · 2020-05-15 13:40 Much remains to be learned and implemented: Timers, UART, SPI, I2C, framebuffer, memory, USB ... And when I add other units that help me to this purpose, then it doesn't work anymore. Let me explain, just by adding the 'math' unit in the 'uses' section to the previous examples, compile OK, file size 'kernel7.img' increases but stops working. The same thing happens if I add 'sysutils'. Something similar I read here that happens on other embedded systems: https://forum.lazarus.freepascal.org/index.php/topic,47555.0.html Therefore, some functions must be performed manually. ---------------------------------------------------------------------- DonAlfredo · 2020-05-15 13:59 Try to add the heapmanager: uses   HeapMgr, ---------------------------------------------------------------------- Laksen · 2020-05-15 14:01 Floating point on embedded probably needs a lot of control registers setup properly. At the very least you need to enable the FPU Check here for a start (look in the last section) http://infocenter.arm.com/help/topic/com.arm.doc.dai0425/ch04s09s01.ht ml I don't know if you would need more than that Another pitfall is that the RTL will want to enable FPU exceptions by default, so you should either disable that or install a FPU exception handler. ---------------------------------------------------------------------- rca · 2020-05-15 14:34 Quote from: DonAlfredo on May 15, 2020, 03:59:23 pmTry to add the heapmanager: uses   HeapMgr, I did, but it still doesn't work. Quote from: Laksen on May 15, 2020, 04:01:17 pmFloating point on embedded probably needs a lot of control registers setup properly. At the very least you need to enable the FPU Check here for a start (look in the last section) http://infocenter.arm.com/help/topic/com.arm.doc.dai0425/ch04s09s01.ht ml I don't know if you would need more than that Another pitfall is that the RTL will want to enable FPU exceptions by default, so you should either disable that or install a FPU exception handler. I will investigate about it. ---------------------------------------------------------------------- rca · 2020-05-18 10:25 I have managed to run 'SysUtils', 'Math' and other units for the Raspberry. Inside the rtl/embedded/system.cfg file, you will find: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #ifdef CPUARM-SfSOFTFPU-SfCLASSES-SfEXCEPTIONS-SfANSISTRINGS-SfRTTI- SfWIDESTRINGS-SfDYNARRAYS-SfTHREADING-SfVARIANTS-SfOBJECTS- SfCOMMANDARGS-SfRANDOM-SfRESOURCES#endif CPUARM  In testing, removing the option: '-SfTHREADING', units work. And in order for the 'Consoleio' unit to work, I've added the '-SfCONSOLEIO' option. With 'SysUtils', I have successfully tested the IntToStr and ToString functions. This unit adds 'heapmgr' as suggested by @DonAlfredo. @DonAlfredo, is it possible to add the cross compiler aarch64-embedded to Fpcupdeluxe? Aarch64-none-elf would be needed with their respective libraries and all their magic to make it. With 'Math', I successfully tried the DivMod function. As suggested by @Laksen it was necessary to enable the fpu of the Raspberry. And that part is in the original raspi2.pp file. With 'Consoleio', I successfully tried redirect the StdOut to serial port from the miniUART. Just like raspi2.pp does. For example: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i WriteLn('Hello World'); // that message comes out of the miniUART. Also I found that it only works with shortstring, I fix it by adding {$H-} ---------------------------------------------------------------------- PascalDragon · 2020-05-18 11:18 Quote from: rca on May 18, 2020, 12:25:45 pm@DonAlfredo, is it possible to add the cross compiler aarch64-embedded to Fpcupdeluxe? Aarch64-none-elf would be needed with their respective libraries and all their magic to make it. FPC currently does not support/provide aarch64-embedded. ---------------------------------------------------------------------- Laksen · 2020-05-18 16:16 Did you add any heap space? You both have to include HeapMgr and assign it memory (-Ch4096 gives it 4kb of heap memory for example). That's a prerequisite for using ansistrings ---------------------------------------------------------------------- rca · 2020-05-18 21:50 Quote from: PascalDragon on May 18, 2020, 01:18:12 pmFPC currently does not support/provide aarch64-embedded. Ok. Thank you. Quote from: Laksen on May 18, 2020, 06:16:18 pmDid you add any heap space? You both have to include HeapMgr and assign it memory (-Ch4096 gives it 4kb of heap memory for example). That's a prerequisite for using ansistrings Thanks for the suggestion. I tried different sizes, but it didn't work.