[fpc-devel] Patch for uf2 support in freePascal
Michael Ring
mail at michael-ring.org
Fri Jan 22 23:37:52 CET 2021
Hi Florian, im Anhang der Path für den UF2 Support in freepascal, ich
hoffe er passt so für Dich...
Das UF2 File wird nur erzeugt wenn die Startadresse ungleich $00000000
ist da normalerweise der UF2 Bootloader ab Addresse 0 steht und es damit
keinen sinnmacht ein uf2 file zu erzeugen wenn die Startaddresse auf
default für Arm steht da dann der uf2 loader mit dem eigentlichen code
kollidiert.
Der Fall das eine Startadresse via -Ttext angepasst wird ist auch mit
drin, habe ich noch was vergessen?
Für den vollen Support muss auch noch das vtor Register umgeschrieben
werden damit man interrupt-Handler im eigenen Code definieren kann, ich
habe dazu bei mir den Startup Code for cortex M0,M3,M4F angepasst, keine
Ahnung warum dieser Teil in dem {$ifdef REMAP_VECTTAB} define steht,
denn dies muss dann in jeder Unit für einen Controller gesetzt werden
obwohl bei den default Einstellungen der Remap korrekt ist.
Hast Du eine Ahnung warum das so gemacht wurde?
Ist nur ein Detail, wenn ich in der unit für den Raspi Pico den wert
definiere dann wird vtor ja richtig gesetzt.
Michael
Mein Startup Code:
ldr r0, .Lvtor
ldr r1, .Ltext_start
str r1, [r0]
bl PASCALMAIN
b HaltProc
.balign 4
.L_bss_start:
.long _bss_start
.L_bss_end:
.long _bss_end
.L_etext:
.long _etext
.L_data:
.long _data
.L_edata:
.long _edata
.Lvtor:
.long 0xE000ED08
statt original startup Code:
{$ifdef REMAP_VECTTAB}
ldr r0, .Lvtor
ldr r1, .Ltext_start
str r1, [r0]
{$endif REMAP_VECTTAB}
bl PASCALMAIN
b HaltProc
.L_bss_start:
.long _bss_start
.L_bss_end:
.long _bss_end
.L_etext:
.long _etext
.L_data:
.long _data
.L_edata:
.long _edata
{$ifdef REMAP_VECTTAB}
.Lvtor:
.long 0xE000ED08
-------------- next part --------------
diff --git a/compiler/systems/t_embed.pas b/compiler/systems/t_embed.pas
index 1b6d8d0065..c52fb4903e 100644
--- a/compiler/systems/t_embed.pas
+++ b/compiler/systems/t_embed.pas
@@ -39,6 +39,7 @@ implementation
TlinkerEmbedded=class(texternallinker)
private
Function WriteResponseFile: Boolean;
+ Function GenerateUF2(binFile,uf2File : string;baseAddress : longWord):boolean;
public
constructor Create; override;
procedure SetDefaultInfo; override;
@@ -2847,6 +2848,10 @@ begin
success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+
FixedExeFileName+' '+
maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,'.bin'))),true,false);
+ if success then
+ success := GenerateUF2(maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,'.bin'))),
+ maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,'.uf2'))),
+ embedded_controllers[current_settings.controllertype].flashbase);
{$ifdef ARM}
if success and (current_settings.controllertype = ct_raspi2) then
success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+ FixedExeFileName + ' kernel7.img',true,false);
@@ -2863,6 +2868,105 @@ function TLinkerEmbedded.postprocessexecutable(const fn : string;isdll:boolean):
end;
+function TlinkerEmbedded.GenerateUF2(binFile,uf2File : string;baseAddress : longWord):boolean;
+type
+ TFamilies= record
+ k : String;
+ v : longWord;
+ end;
+ tuf2Block = record
+ magicStart0,
+ magicStart1,
+ flags,
+ targetAddr,
+ payloadSize,
+ blockNo,
+ numBlocks,
+ familyid : longWord;
+ data : array[0..255] of byte;
+ padding : array[0..511-256-32-4] of byte;
+ magicEnd : longWord;
+ end;
+
+const
+ Families : array of TFamilies = (
+ (k:'SAMD21'; v:$68ed2b88),
+ (k:'SAML21'; v:$1851780a),
+ (k:'SAMD51'; v:$55114460),
+ (k:'NRF52'; v:$1b57745f),
+ (k:'STM32F0';v:$647824b6),
+ (k:'STM32F1';v:$5ee21072),
+ (k:'STM32F2';v:$5d1a0a2e),
+ (k:'STM32F3';v:$6b846188),
+ (k:'STM32F4';v:$57755a57),
+ (k:'STM32F7';v:$53b80f00),
+ (k:'STM32G0';v:$300f5633),
+ (k:'STM32G4';v:$4c71240a),
+ (k:'STM32H7';v:$6db66082),
+ (k:'STM32L0';v:$202e3a91),
+ (k:'STM32L1';v:$1e1f432d),
+ (k:'STM32L4';v:$00ff6919),
+ (k:'STM32L5';v:$04240bdf),
+ (k:'STM32WB';v:$70d16653),
+ (k:'STM32WL';v:$21460ff0)
+ );
+
+var
+ f,g : file;
+ uf2block : Tuf2Block;
+ totalRead,numRead : longWord;
+ familyId,i : longWord;
+ ExtraOptions : String;
+
+begin
+ if pos('-Ttext=',Info.ExtraOptions) > 0 then
+ begin
+ ExtraOptions := copy(Info.ExtraOptions,pos('-Ttext=',Info.ExtraOptions)+7,length(Info.ExtraOptions));
+ for i := 1 to length(ExtraOptions) do
+ if pos(copy(ExtraOptions,i,1),'0123456789abcdefxABCDEFX') = 0 then
+ ExtraOptions := copy(ExtraOptions,1,i);
+ baseAddress := StrToIntDef(ExtraOptions,0);
+ end;
+
+ familyId := 0;
+ for i := 0 to length(Families)-1 do
+ begin
+ if pos(Families[i].k,embedded_controllers[current_settings.controllertype].controllerunitstr) = 1 then
+ familyId := Families[i].v;
+ end;
+
+ if (baseAddress and $07ffffff) <> 0 then
+ begin
+ totalRead := 0;
+ assign(f,binfile);
+ reset(f,1);
+ assign(g,uf2file);
+ rewrite(g,1);
+
+ repeat
+ fillchar(uf2block,sizeof(uf2block),0);
+ uf2block.magicStart0 := $0A324655; // "UF2\n"
+ uf2block.magicStart1 := $9E5D5157; // Randomly selected
+ if familyId = 0 then
+ uf2block.flags := 0
+ else
+ uf2block.flags := $2000;
+ uf2block.targetAddr := baseAddress + totalread;
+ uf2block.payloadSize := 256;
+ uf2block.blockNo := (totalRead div sizeOf(uf2block.data));
+ uf2block.numBlocks := (filesize(f) + 255) div 256;
+ uf2block.familyId := familyId;
+ uf2block.magicEnd := $0AB16F30; // Randomly selected
+ blockRead(f,uf2block.data,sizeof(uf2block.data),numRead);
+ blockwrite(g,uf2block,sizeof(uf2block));
+ inc(totalRead,numRead);
+ until (numRead=0) or (NumRead<>sizeOf(uf2block.data));
+ close(f);
+ close(g);
+ end;
+ Result := true;
+end;
+
{*****************************************************************************
TlinkerEmbedded_SdccSdld
*****************************************************************************}
More information about the fpc-devel
mailing list