Shop Learn P1 Docs P2 Docs
flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 102 — Parallax Forums

flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

1979899100102

Comments

  • RaymanRayman Posts: 12,926
    edited 2022-11-20 18:16

    @ersmith Have two strange issues with the Wiznet code.

    First one is that in this function (in fptd.c) with C++ style reference:
    void scan_files(const char* filename, char *dbuf, uint16_t& size)
    this doesn't work:
    size +=s;
    but this does:
    size = size + s;

    Second issue is something strange with printf() after I call scan_files().
    The code is printing the value of size, but it doesn't print correctly.
    Seems to be printing the value of size before scan_files() was called.
    Added a printf() inside scan_files() and it shows the correct value.
    Also, the actual value is correct, it's just not printing correctly...
    Here's example output:

    s=21, Size= 1666
    s=19, Size= 1685
    s=18, Size= 1703
    s=21, Size= 1724
    returned size: 6

    The second issue is fixed by changing optimization level from 2 to 1.
    Not the first issue though...

  • ersmithersmith Posts: 5,516

    @Rayman : thanks for the bug report, there was indeed a problem with compiling the assignment operators like +=, -=, *=, etc. when the LHS was a reference. That should be fixed in the github source now, so the solutions are either to update or to re-write the assignment operators to be plain operators.

    As for the -O2 problem, I cannot reproduce it (I don't have Wiznet hardware so your sample program won't run for me), but in general I would suggest not using -O2 for big projects and complicated C code. -O2 is somewhat experimental (more likely to be buggy) and also produces bigger code, so for now I think your best bet is to stick with -O1.

  • Perhaps note that you can try to narrow down the problematic part of -O2 by disabling its constituent flags individually. I.e. try

    • -O2,~cse (this is the culprit most of the time)
    • -O2,~inline-single
    • -O2,~loop-reduce
    • -O2,~remove-bss
  • Christof Eb.Christof Eb. Posts: 773
    edited 2022-11-21 09:22

    Hi,
    question about fstat(). What must I do to use this function in FlexProp?
    Thank you!

    Edit: I use the shell.c example of FlexProp with its filesystem as a basis.

  • ersmithersmith Posts: 5,516

    Unforunately fstat() is not implemented. The work-arounds are either (1) to use stat() on the file name used to open the file, or (2) if it's only the size of the file that's needed, to use fseek()/ftell() to find the size instead of fstat().

  • RaymanRayman Posts: 12,926

    @Wuerfel_21 Indeed -O2,~cse does fix the printf() issue.
    Maybe I'll stick with that for now try to remember to drop to -O1 if anything else goes wrong...

  • pik33pik33 Posts: 1,818

    When the code is somewhat bigger, the -o2 ends with this:

    error: Internal error exceeded local register limit, possibly due to -O2 optimization needing additional registers or code being too complicated

    Some time ago I gave up and I don't even try to use -o2.

  • JRoarkJRoark Posts: 1,152

    @pik33 I encounter this issue too. Eric suggested it can be avoided by breaking things up into smaller chunks of code (subroutines) and reducing complexity. This has helped me a lot. YMMV

  • Christof Eb.Christof Eb. Posts: 773
    edited 2022-11-23 10:45

    Hi,
    is there a way to restart a program, that has been loaded with "Compile & Run on P2", without loading it again?
    Thanks! Christof

    Edit: This is a modified shell program. Tried to use the "exec" _execve(arg1, 0, 0);
    Is there a special way needed to compile the binary for this? Or is the size limited for this?

    Is there a command to completely reboot the P2? Found this, and will try it:
    https://p2docs.github.io/hubctrl.html#software-reset

    • Hm, did not work here, perhaps the /host thing gets crumbled.
  • pik33pik33 Posts: 1,818

    Here is the main program for my MicroDOS. The program allows selecting and running other programs using PSRAM as temporary storage so it can run near all sizes of program (tested on ***yumes, works)

    The idea is simple: (1) display a screen (2) list all bin files found in 'microDOS' directory on the SD (3) allow to select one with a keyboard

    After the file is selected, it is loaded from SD into PSRAM.

    Then all cogs are stopped and the assembly program is started inside a cog. The assembly program overvrites the hub with the binary, then stops PSRAM driver (the last working cog), coginit #0,#0 and stops itself.

    ' MicroDOS - a binary loader for a PSRAM P2 system
    ' v. 0.02- 20220614
    ' Piotr Kardasz, pik33@o2.pl
    ' MIT license
    ' For better effect compile with -DFF_USE_LFN 
    '-----------------------------------------------------------------------------------------------
    
    const _clkfreq = 336956522  ' don't change, video drivers will set it to this
    
    const pin=8         ' VGA pin
    const hpin=0            ' HDMI pin
    const up_key=$51        ' define your keys here
    const down_key=$50
    const w_key=$77
    const s_key=$73
    const enter_key=$0D
    const v_back_color=147      ' Display colors for VGA and HDMI. Drivers use Atari type palette, 16 colors on high nibble, 16 luminances on low nibble, 32 is red, 112 is blue, 192 is green
    const v_write_color=154
    const h_back_color=147-16
    const h_write_color=154-16
    const v_vspace=40
    const h_vspace=20
    
    
    '-----------------------------------------------------------------------------------------------
    
    #include "dir.bi"
    
    dim v as class using "vg001.spin2"      ' VGA driver
    dim h as class using "hg008.spin2"      ' HDMI driver
    dim psram as class using "psram.spin2"      ' PSRAM driver
    
    '' All drivers are hacked for this. VGA and HDMI has to have separated buffers, PSRAM mailbuffers are moved to S7FF00 to make loading size as big as possible
    
    
    '-----------------------------------------------------------------------------------------------
    
    ' Replace this with your keyboard driver. It has to provide readkey() which returns the pressed key code or zero if no key pressed
    ' To do: add a standard USB keyboard driver here.
    
    dim kbd as class using "keyboard.spin2"
    
    '-----------------------------------------------------------------------------------------------
    
    dim videocog as integer
    dim hdmicog as integer
    dim base as ulong
    dim mbox as ulong
    
    dim files$(27)
    dim shortfiles$(27)
    dim filebuf(16383) as ubyte
    let title$="P2 MicroDOS v. 0.03 - 20220614"
    
    ' Start cogs
    
    let kbdcog=kbd.start()
    psram.startx(0, 0, 12, 7)
    mbox=psram.getMailbox(0)
    videocog=v.start(pin,mbox)
    v.cls(v_write_color,v_back_color)
    hdmicog=h.start(hpin,mbox)
    h.cls(h_write_color,h_back_color)
    
    ' Initialize the display
    
    waitms(100)
    v.setfontfamily(4)
    v.outtextxycz(960-16*len(title$),v_vspace,title$,v_write_color,v_back_color,4,2)
    h.setfontfamily(4)
    h.outtextxycz(512-8*len(title$),h_vspace,title$,h_write_color,h_back_color,2,1)
    
    mount "/sd", _vfs_open_sdcard()
    chdir "/sd/microDOS"
    let currentdir$="/sd/microDOS/"
    
    let pos=3*v_vspace : let hpos=3*h_vspace
    let filenum=0
    
    ' Find and list filenames (*.binary)
    
    let filename$ = dir$("*", fbNormal)
    while filename$ <> "" andalso filename$ <> nil
      let ext$=right$(filename$,7)
      if ext$=".binary" then
        files$(filenum)=currentdir$+filename$
        filename$=left$(filename$,len(filename$)-7)
        shortfiles$(filenum)=replacechar$(filename$,"_"," "): filenum+=1
      endif
      filename$ = dir$()
    end while
    
    let title$="W,S or up,down arrow to select, Enter to run"
    v.outtextxycz(960-16*len(title$),1080-2*v_vspace,title$,v_write_color,v_back_color,4,2)
    h.outtextxycz(512-8*len(title$),576-2*h_vspace,title$,h_write_color,h_back_color,2,1)
    
    h.outtextxycz(512-4*len(shortfiles$(0)),hpos,shortfiles$(0),h_back_color,h_write_color,1,1) : hpos+=h_vspace
    v.outtextxycz(960-8*len(shortfiles$(0)),pos,shortfiles$(0),v_back_color,v_write_color,2,2) : pos+=v_vspace
    for i=1 to filenum-1: h.outtextxycz(512-4*len(shortfiles$(i)),hpos,shortfiles$(i),h_write_color,h_back_color,1,1) : hpos+=h_vspace : next i
    for i=1 to filenum-1: v.outtextxycz(960-8*len(shortfiles$(i)),pos,shortfiles$(i),v_write_color,v_back_color,2,2) : pos+=v_vspace : next i
    
    ' Wait for a keyboard input, highlight the selected name
    
    let filepos=0
    do: loop until kbd.readkey()=0
    do 
      let key=kbd.readkey() 
      if key=down_key orelse key=s_key then
        key=0
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_write_color,v_back_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_write_color,h_back_color,1,1) 
        filepos+=1
        if filepos>=filenum-1 then filepos=filenum-1
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_back_color,v_write_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_back_color,h_write_color,1,1) 
      endif  
    
      if key=up_key orelse key=w_key then
        key=0
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_write_color,v_back_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_write_color,h_back_color,1,1) 
        filepos-=1
        if filepos<0 then filepos=0
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_back_color,v_write_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_back_color,h_write_color,1,1) 
      endif  
    
    ' if enter, load the file
    
      if key=enter_key then
        let title$="Loading: " + files$(filepos)
        v.box(0,1080-64,1919,1080-33,v_back_color)
        v.outtextxycz(960-16*len(title$),1080-2*v_vspace,title$,v_write_color,v_back_color,4,2)
        h.box(0,576-32,1023,576-17,h_back_color)
        h.outtextxycz(512-8*len(title$),576-2*h_vspace,title$,h_write_color,h_back_color,2,1)
        key=0
    
    ' now upload it to PSRAM
    
        open files$(filepos) for input as #9
        let pos=1: let r=0 : let psramptr=0
        do
          get #9,pos,filebuf(0),16384,r : pos+=r    
          psram.write(addr(filebuf(0)),psramptr,16384)  
          psramptr+=r                                                            ' move the buffer to the RAM and update RAM position. Todo: this can be done all at once
        loop until r<>16384  orelse psramptr>=$7C000                             ' do until eof or memory full
    
    ' stop all driver cogs except PSRAM
    
        cpustop(kbdcog)
        cpustop(videocog)
        cpustop(hdmicog)
    
    'start loading cog
    
        let loadingcog=cpu(@loadcog,@filebuf) 
    
    ' stop itself
    
        cpustop(cpuid())
    
      endif  
    loop
    
    '--------------------------- THE END OF THE MAIN PROGRAM ------------------------------------------------------
    
    '----- addr: the helper function, return ulong instead of pointer
    
    function addr(byref v as const any) as ulong
    return(cast(ulong,@v))
    end function
    
    
    '----- the loader cog
    
            asm shared
    
                    org
    loadcog         cogid   t1                      ' get a cogid
                    mul     t1, #12                         ' compute the offset to PSRAM mailbox 
                    add     mailbox, t1                     ' add offset to find this COG's mailbox
    
                    mov     psramaddr,#0
    
    p101            mov     buf1,psramaddr          ' psramaddr=hubaddr
                    mov     buf2,##16384            ' loading size
                    mov     cmd,psramaddr                   ' set the address for reading
                    setnib  cmd, #%1011, #7                 ' attach the command - read burst
                    setq    #2              ' write 3 longs to the mailbox
                    wrlong  cmd, mailbox            ' read the PSRAM
    p102            rdlong  cmd, mailbox                    ' poll mailbox for result
                    tjs     cmd, #p102                  ' retry until valid 
    
                    add     psramaddr,##16384
            cmp     psramaddr,##$7C000 wcz
        if_lt   jmp     #p101               ' loop until full hub loaded
    
                    cogstop #7              ' stop psram driver
                    cogid   t1              ' get id
                    coginit #0,#0           ' start the new program
                    cogstop t1              ' stop the loader
    
    t1      long    0
    mailbox     long    $7FF00
    psramaddr   long    0
    
    cmd             long    0
    buf1            long    0
    buf2            long    1024
    
            end asm
    
    '----- The end ---------------------------------------------------------------------------------------------------
    
    
  • ersmithersmith Posts: 5,516

    @"Christof Eb." : In general no, there is no way to restart a program that has been loaded without loading it again. If the program is carefully written to avoid any reliance on the initial values of any variables, then it could restart itself with coginit. Or, if it knows its own path, it could exec itself (although in some sense this is "loading it again").

    At present exec() requires that both the original and new program fit into memory at the same time (the original program loads the new one, then copies it down to execute at 0). So for a program to exec itself it must be less than 256K long.

    Another option for running programs is to compile it to run at a different address (using something like -E -H 0x10000) and have the original shell remain resident and running while the new program runs in a different COG at a different address.

    Finally, if all of this is in service of your new Swieros based code, wouldn't you actually want the bytecode emulator to stay resident and to run programs that have been compiled into bytecode themselves? So you wouldn't be running multiple Prop binaries, just the emulator.

  • @ersmith said:

    Finally, if all of this is in service of your new Swieros based code, wouldn't you actually want the bytecode emulator to stay resident and to run programs that have been compiled into bytecode themselves? So you wouldn't be running multiple Prop binaries, just the emulator.

    Yes this is the idea.
    Unfortunately this compiler mallocs several times but does not free and therefore the ram gets lost. So I wanted to have a workaround.
    I think I will need a table for each program to keeping track of the mallocs and then free everything after finish.
    Thank you, for the answer!

  • Wuerfel_21Wuerfel_21 Posts: 3,310
    edited 2022-11-23 12:59

    @"Christof Eb." said:
    Unfortunately this compiler mallocs several times but does not free and therefore the ram gets lost. So I wanted to have a workaround.

    You can try using the garbage-collector. Change malloc to _gc_alloc_managed. The "actual" solution would be write some sort of zone allocator to auto-free the memory when it's done, but that's more difficult IG.

  • @Wuerfel_21 said:

    @"Christof Eb." said:
    Unfortunately this compiler mallocs several times but does not free and therefore the ram gets lost. So I wanted to have a workaround.

    You can try using the garbage-collector. Change malloc to _gc_alloc_managed. The "actual" solution would be write some sort of zone allocator to auto-free the memory when it's done, but that's more difficult IG.

    _gc_alloc_managed() did indeed solve the problem. Many thanks!
    I am a little bit frightened, if the P2 really knows, what is not needed any more....

  • @pik33 said:
    Here is the main program for my MicroDOS. The program allows selecting and running other programs using PSRAM as temporary storage so it can run near all sizes of program (tested on ***yumes, works)

    The idea is simple: (1) display a screen (2) list all bin files found in 'microDOS' directory on the SD (3) allow to select one with a keyboard

    After the file is selected, it is loaded from SD into PSRAM.

    Then all cogs are stopped and the assembly program is started inside a cog. The assembly program overvrites the hub with the binary, then stops PSRAM driver (the last working cog), coginit #0,#0 and stops itself.

    ' MicroDOS - a binary loader for a PSRAM P2 system
    ' v. 0.02- 20220614
    ' Piotr Kardasz, pik33@o2.pl
    ' MIT license
    ' For better effect compile with -DFF_USE_LFN 
    '-----------------------------------------------------------------------------------------------
    
    const _clkfreq = 336956522    ' don't change, video drivers will set it to this
    
    const pin=8           ' VGA pin
    const hpin=0          ' HDMI pin
    const up_key=$51      ' define your keys here
    const down_key=$50
    const w_key=$77
    const s_key=$73
    const enter_key=$0D
    const v_back_color=147        ' Display colors for VGA and HDMI. Drivers use Atari type palette, 16 colors on high nibble, 16 luminances on low nibble, 32 is red, 112 is blue, 192 is green
    const v_write_color=154
    const h_back_color=147-16
    const h_write_color=154-16
    const v_vspace=40
    const h_vspace=20
    
    
    '-----------------------------------------------------------------------------------------------
    
    #include "dir.bi"
    
    dim v as class using "vg001.spin2"        ' VGA driver
    dim h as class using "hg008.spin2"        ' HDMI driver
    dim psram as class using "psram.spin2"        ' PSRAM driver
    
    '' All drivers are hacked for this. VGA and HDMI has to have separated buffers, PSRAM mailbuffers are moved to S7FF00 to make loading size as big as possible
    
    
    '-----------------------------------------------------------------------------------------------
    
    ' Replace this with your keyboard driver. It has to provide readkey() which returns the pressed key code or zero if no key pressed
    ' To do: add a standard USB keyboard driver here.
    
    dim kbd as class using "keyboard.spin2"
    
    '-----------------------------------------------------------------------------------------------
    
    dim videocog as integer
    dim hdmicog as integer
    dim base as ulong
    dim mbox as ulong
    
    dim files$(27)
    dim shortfiles$(27)
    dim filebuf(16383) as ubyte
    let title$="P2 MicroDOS v. 0.03 - 20220614"
    
    ' Start cogs
    
    let kbdcog=kbd.start()
    psram.startx(0, 0, 12, 7)
    mbox=psram.getMailbox(0)
    videocog=v.start(pin,mbox)
    v.cls(v_write_color,v_back_color)
    hdmicog=h.start(hpin,mbox)
    h.cls(h_write_color,h_back_color)
    
    ' Initialize the display
    
    waitms(100)
    v.setfontfamily(4)
    v.outtextxycz(960-16*len(title$),v_vspace,title$,v_write_color,v_back_color,4,2)
    h.setfontfamily(4)
    h.outtextxycz(512-8*len(title$),h_vspace,title$,h_write_color,h_back_color,2,1)
    
    mount "/sd", _vfs_open_sdcard()
    chdir "/sd/microDOS"
    let currentdir$="/sd/microDOS/"
    
    let pos=3*v_vspace : let hpos=3*h_vspace
    let filenum=0
    
    ' Find and list filenames (*.binary)
    
    let filename$ = dir$("*", fbNormal)
    while filename$ <> "" andalso filename$ <> nil
      let ext$=right$(filename$,7)
      if ext$=".binary" then
        files$(filenum)=currentdir$+filename$
        filename$=left$(filename$,len(filename$)-7)
        shortfiles$(filenum)=replacechar$(filename$,"_"," "): filenum+=1
      endif
      filename$ = dir$()
    end while
    
    let title$="W,S or up,down arrow to select, Enter to run"
    v.outtextxycz(960-16*len(title$),1080-2*v_vspace,title$,v_write_color,v_back_color,4,2)
    h.outtextxycz(512-8*len(title$),576-2*h_vspace,title$,h_write_color,h_back_color,2,1)
    
    h.outtextxycz(512-4*len(shortfiles$(0)),hpos,shortfiles$(0),h_back_color,h_write_color,1,1) : hpos+=h_vspace
    v.outtextxycz(960-8*len(shortfiles$(0)),pos,shortfiles$(0),v_back_color,v_write_color,2,2) : pos+=v_vspace
    for i=1 to filenum-1: h.outtextxycz(512-4*len(shortfiles$(i)),hpos,shortfiles$(i),h_write_color,h_back_color,1,1) : hpos+=h_vspace : next i
    for i=1 to filenum-1: v.outtextxycz(960-8*len(shortfiles$(i)),pos,shortfiles$(i),v_write_color,v_back_color,2,2) : pos+=v_vspace : next i
    
    ' Wait for a keyboard input, highlight the selected name
    
    let filepos=0
    do: loop until kbd.readkey()=0
    do 
      let key=kbd.readkey() 
      if key=down_key orelse key=s_key then
        key=0
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_write_color,v_back_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_write_color,h_back_color,1,1) 
        filepos+=1
        if filepos>=filenum-1 then filepos=filenum-1
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_back_color,v_write_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_back_color,h_write_color,1,1) 
      endif  
    
      if key=up_key orelse key=w_key then
        key=0
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_write_color,v_back_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_write_color,h_back_color,1,1) 
        filepos-=1
        if filepos<0 then filepos=0
        v.outtextxycz(960-8*len(shortfiles$(filepos)),v_vspace*(3+filepos),shortfiles$(filepos),v_back_color,v_write_color,2,2) 
        h.outtextxycz(512-4*len(shortfiles$(filepos)), h_vspace*(3+filepos),shortfiles$(filepos),h_back_color,h_write_color,1,1) 
      endif  
    
    ' if enter, load the file
    
      if key=enter_key then
        let title$="Loading: " + files$(filepos)
        v.box(0,1080-64,1919,1080-33,v_back_color)
        v.outtextxycz(960-16*len(title$),1080-2*v_vspace,title$,v_write_color,v_back_color,4,2)
        h.box(0,576-32,1023,576-17,h_back_color)
        h.outtextxycz(512-8*len(title$),576-2*h_vspace,title$,h_write_color,h_back_color,2,1)
        key=0
    
    ' now upload it to PSRAM
    
        open files$(filepos) for input as #9
        let pos=1: let r=0 : let psramptr=0
        do
          get #9,pos,filebuf(0),16384,r : pos+=r  
          psram.write(addr(filebuf(0)),psramptr,16384)    
          psramptr+=r                                                              ' move the buffer to the RAM and update RAM position. Todo: this can be done all at once
        loop until r<>16384  orelse psramptr>=$7C000                               ' do until eof or memory full
    
    ' stop all driver cogs except PSRAM
    
        cpustop(kbdcog)
        cpustop(videocog)
        cpustop(hdmicog)
    
    'start loading cog
    
        let loadingcog=cpu(@loadcog,@filebuf) 
    
    ' stop itself
        
        cpustop(cpuid())
    
      endif  
    loop
    
    '--------------------------- THE END OF THE MAIN PROGRAM ------------------------------------------------------
    
    '----- addr: the helper function, return ulong instead of pointer
    
    function addr(byref v as const any) as ulong
    return(cast(ulong,@v))
    end function
    
    
    '----- the loader cog
    
          asm shared
    
                  org
    loadcog       cogid   t1                      ' get a cogid
                    mul     t1, #12                         ' compute the offset to PSRAM mailbox 
                    add     mailbox, t1                     ' add offset to find this COG's mailbox
    
                    mov     psramaddr,#0
    
    p101            mov     buf1,psramaddr            ' psramaddr=hubaddr
                    mov     buf2,##16384          ' loading size
                    mov     cmd,psramaddr                   ' set the address for reading
                    setnib  cmd, #%1011, #7                 ' attach the command - read burst
                    setq    #2                ' write 3 longs to the mailbox
                    wrlong  cmd, mailbox          ' read the PSRAM
    p102            rdlong  cmd, mailbox                  ' poll mailbox for result
                    tjs     cmd, #p102                    ' retry until valid 
    
                    add   psramaddr,##16384
          cmp     psramaddr,##$7C000 wcz
      if_lt   jmp     #p101               ' loop until full hub loaded
    
                    cogstop #7                ' stop psram driver
                    cogid     t1              ' get id
                    coginit #0,#0         ' start the new program
                    cogstop t1                ' stop the loader
    
    t1        long    0
    mailbox   long    $7FF00
    psramaddr     long    0
    
    cmd             long    0
    buf1            long    0
    buf2            long    1024
    
          end asm
          
    '----- The end ---------------------------------------------------------------------------------------------------
    
    

    Thank you!
    At the moment I use a kiss board and I do not plan to have psram added.

  • evanhevanh Posts: 13,855

    Christof Eb,
    You might find using __builtin_alloca() to be an advantage. It's the only allocator I use now. It automatically frees upon function return. And if you want the allocation to stick around then place it in main().

  • RaymanRayman Posts: 12,926

    @ersmith Happy Thanksgiving! I should be up watching the dog show with family, but instead working on Wiznet :(

    Anyway, this code was working fine with my custom uSD pinout and at 250 MHz.
    Changed pins for P2 Eval board and it wouldn't work.
    Works when I drop clock rate to 160 MHz (in Platform.h).
    How is this even possible? Has me stumped...

  • RaymanRayman Posts: 12,926
    edited 2022-11-24 20:14

    it's the scan_files() method where it can't read Eval SD at high clock rate.
    But, if I call that method right after mounting, then it works at 300 MHz
    Added this to start of code:

        uint16_t i=0;
        scan_files("/SD", (char*) g_ftp_buf, i);
        printf("Size=%d\n", i);
    

    Actually, just doing "opendir("/SD");" at start of code makes it work...

  • RaymanRayman Posts: 12,926
    edited 2022-11-24 20:42

    Think I've isolated the issue to the DNS code. If I comment that section out, it works...
    Maybe I should have troubleshooted some more before posting about this...

  • RaymanRayman Posts: 12,926
    edited 2022-11-24 20:49

    Ok, nevermind, nothing to see here...

    Found the problem... Seems one should call DNS_init() before using DNS. Guess that makes sense...
    Was using a buffer pointer that wasn't initialized...

  • ersmithersmith Posts: 5,516

    @Rayman : glad you were able to find it!

  • Hi,
    ...still fighting with memory allocation...
    I am now working with a separate memory allocation table for each process of aPropOs , using malloc() and at the finish of the process free(). It seems to work most times, but from time to time, I get "corrupted heap". The functions may be called from different cogs.
    Is there a limit for or what is the possible maximum number of calls of malloc()? I think, I might need 100 in total.
    Is there something more to know about heap: What can cause "corrupted heap"?
    Thank you!
    Christof

  • evanhevanh Posts: 13,855

    I'm not sure but you might be required to use the garbage collection functions.

  • @"Christof Eb." said:
    Is there something more to know about heap: What can cause "corrupted heap"?

    Corrupting the heap, somewhat obviously. In particular, it prints that message when it happens across an allocation block that is of zero size (as presumably occurs when you overwrite the allocation header with zeroes).

  • ersmithersmith Posts: 5,516

    @"Christof Eb." :
    "Corrupted heap" is normally caused by writing past the end of an allocated area, e.g. allocating 100 bytes and then writing 120 to it.

    There's no intrinsic limit on the number of mallocs, except that the total size of the allocation is limited by the heap size. What value are you using for _HEAPSIZE?

    Are you making sure to check the value returned by malloc for errors?

  • Christof Eb.Christof Eb. Posts: 773
    edited 2022-11-26 17:13

    Thanks for the answers! At the moment the problem is gone. Unfortunately I am not sure, why. I am not aware of overwriting the end or begin.
    I had used
    int *i=malloc(x); .... free(i);
    Now I use void *i , but I can't reproduce the problem with int *i .
    Good to know, that there is no limit for the number of memory slices.
    At the moment I can use 300kBytes for heap, as much as possible.

    Perhaps the following code snippet is useful for somebody to explore the biggest slice available:
    `mFree()
    {
    int dsize= HEAPSIZE, size=0;
    void *mem;

    while(dsize>512){
    dsize=dsize/2;
    size+=dsize;
    mem= malloc(size);
    if(!mem) size-=dsize;
    free(mem);
    }
    printf("Free Memory: %d kByte\n", size/1024);
    }
    `

  • Sorry for the stupid question, but is there a documentation for "command line idiots" of how to build the compiler on a Windows PC? I have TDM-GCC-32 installed which is part of my Code::Blocks IDE I use everyday. I thought this should be compatible to mingw but there seems to be something missing.

    E:\Projekte\Parallax-Obex\spin2cpp-master>mingw32-make all
    /usr/bin/sh: fgrep: command not found
    gcc -O1 -Wall -fwrapv -I. -I./backends -I./frontends -I./build -DFLEXSPIN_BUILD
    -o build/testlex.exe testlex.c build/lexer.o build/uni2sjis.o build/symbol.o bui
    ld/ast.o build/expr.o build/dofmt.o build/flexbuf.o build/lltoa_prec.o build/str
    upr.o build/strrev.o build/strdupcat.o build/to_utf8.o build/from_utf8.o build/p
    reprocess.o -lm
    build/lexer.o:lexer.c:(.text+0x21f): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    build/symbol.o:symbol.c:(.text+0x134): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    build/ast.o:ast.c:(.text+0x778): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    build/expr.o:expr.c:(.text+0x101): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    c:/programme/tdm-gcc-32/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.
    exe: C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o: bad reloc address 0x2f4 in s
    ection `.data'
    collect2.exe: error: ld returned 1 exit status
    Makefile:160: recipe for target 'build/testlex.exe' failed
    mingw32-make: *** [build/testlex.exe] Error 1
    
  • @ManAtWork said:
    Sorry for the stupid question, but is there a documentation for "command line idiots" of how to build the compiler on a Windows PC? I have TDM-GCC-32 installed which is part of my Code::Blocks IDE I use everyday. I thought this should be compatible to mingw but there seems to be something missing.

    E:\Projekte\Parallax-Obex\spin2cpp-master>mingw32-make all
    /usr/bin/sh: fgrep: command not found
    gcc -O1 -Wall -fwrapv -I. -I./backends -I./frontends -I./build -DFLEXSPIN_BUILD
    -o build/testlex.exe testlex.c build/lexer.o build/uni2sjis.o build/symbol.o bui
    ld/ast.o build/expr.o build/dofmt.o build/flexbuf.o build/lltoa_prec.o build/str
    upr.o build/strrev.o build/strdupcat.o build/to_utf8.o build/from_utf8.o build/p
    reprocess.o -lm
    build/lexer.o:lexer.c:(.text+0x21f): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    build/symbol.o:symbol.c:(.text+0x134): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    build/ast.o:ast.c:(.text+0x778): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    build/expr.o:expr.c:(.text+0x101): multiple definition of `FindSymbol'
    C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o:testlex.c:(.text+0x413): first def
    ined here
    c:/programme/tdm-gcc-32/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.
    exe: C:\DOKUME~1\Besitzer\LOKALE~1\Temp\ccvhlR6w.o: bad reloc address 0x2f4 in s
    ection `.data'
    collect2.exe: error: ld returned 1 exit status
    Makefile:160: recipe for target 'build/testlex.exe' failed
    mingw32-make: *** [build/testlex.exe] Error 1
    

    Install a GCC that's not ancient.

    I think the meaning of inline changed at some point and old GCC inexplicably generates an export symbol for every time the inline function is defined.

  • Wuerfel_21Wuerfel_21 Posts: 3,310
    edited 2022-12-01 17:25

    @ManAtWork you may also try to mingw32-make all OPT="-Og -g -std=gnu11" (after mingw32-make clean of course)

    That parameter should probably be enshrined in the makefile itself.

  • ersmithersmith Posts: 5,516

    @ManAtWork I'm surprised your version of gcc had trouble with the inline, but that was a slightly complicated case, so I've changed it to a #define in the most recent source.

Sign In or Register to comment.