Shop OBEX P1 Docs P2 Docs Learn Events
PropBASIC Questions: - Page 2 — Parallax Forums

PropBASIC Questions:

24

Comments

  • ersmithersmith Posts: 6,053
    edited 2015-04-12 15:10
    And to avoid hijacking this thread any further, I'll post a description of the COG debug protocol implemented by PropGCC in another thread...
  • jmgjmg Posts: 15,173
    edited 2015-04-12 15:28
    While some people like GDB because it is all they know, GDB has to be one of the worst debuggers on any platform (it requires the cooperation of the program, and does not have any means to do real debugging).
    However, the ideal of 'real debugging' needs silicon support, which the Prop lacks, so Software has to step in.
    The challenge is then how to make Prop debug as workable (small/fast) as practical, given the constraints.
  • BeanBean Posts: 8,129
    edited 2015-04-12 16:24
    LMM code generation is for code. Normal VAR variables are always stored in COG ram for speed.
    PropBASIC does support WATCH debugging with ViewPort, but it requires extra code that copies the value in the VAR variables into HUB ram every time they are modified.
    It's not too bad if you are only WATCHing a couple variables, but if you have many WATCHes it really increases the code size, and slows down execution time.

    That being said, the "hooks" are already in the compiler to do this, so a different debugger could probably be supported without too much work. (Famous last words...)

    Bean
  • jmgjmg Posts: 15,173
    edited 2015-04-12 16:55
    Bean wrote: »
    LMM code generation is for code. Normal VAR variables are always stored in COG ram for speed.
    PropBASIC does support WATCH debugging with ViewPort, but it requires extra code that copies the value in the VAR variables into HUB ram every time they are modified.
    It's not too bad if you are only WATCHing a couple variables, but if you have many WATCHes it really increases the code size, and slows down execution time.

    Sounds nifty, and gives an (almost) live watch too. Used with care, it would be better than scattering prints...
    Once a Var is in HUB, any other COG can read it, so existing Debug tools could be used there.

    Bean wrote: »
    That being said, the "hooks" are already in the compiler to do this, so a different debugger could probably be supported without too much work. (Famous last words...)
    Current gdb patches into the PropGCC-LMM kernal, so if your LMM was similar, (identical?) that support should be OK to port, giving the same LMM mode debug features as PropGCC.

    Also required for source level step, is a Debug map report from the compiler, with PC:Line number records, Var:Address records (ideally with Type info for smarter watch), and Source file names.
  • BeanBean Posts: 8,129
    edited 2015-04-12 17:04
    Variable WATCHing can be turned on and off at will using WATCH and UNWATCH so only the section that you are interested in generates the extra code.

    There is no support for code debugging / stepping. So that will probably be quite a bit of work to implement.

    Bean
  • jmgjmg Posts: 15,173
    edited 2015-04-12 17:11
    Bean wrote: »
    Variable WATCHing can be turned on and off at will using WATCH and UNWATCH so only the section that you are interested in generates the extra code.
    Yes, I figured that. It would be a compile time decision what the user wanted to WATCH
    Bean wrote: »
    There is no support for code debugging / stepping. So that will probably be quite a bit of work to implement.
    How similar is your LMM mode, to PropGCC LMM ?
  • BeanBean Posts: 8,129
    edited 2015-04-12 18:37
    jmg wrote: »
    Yes, I figured that. It would be a compile time decision what the user wanted to WATCH


    How similar is your LMM mode, to PropGCC LMM ?

    Here is a small program in LMM:
    ''  *** COMPILED WITH PropBasic VERSION 00.01.42  Aug 25, 2013 ***
    
    
    CON                                                          'DEVICE P8X32A, XTAL1, PLL16X
      _ClkMode = XTAL1 + PLL16X                                 
    
      _XInFreq =   5000000                                       'FREQ 80_000_000
    
    
    ' LED             PIN 15                                     'LED             PIN 15
    
    
    PUB __Program | __VarsPtr                                    'PROGRAM Start LMM
      __VarsPtr := 0                                            
      __OFFSET := @__Init                                       
      CogInit(0, @_LMM_Entry, __VarsPtr)                        
                                                                
    DAT                                                         
                      org           0                           
    __Init                                                      
    __RAM                                                       
                      mov           dira,__InitDirA             
                      mov           outa,__InitOutA             
                      rdlong        __PC,__PC                   
                      long          @@@Start                    
    
    
    ' temp            VAR LONG                                   'temp            VAR LONG
    
    
    Start                                                        'Start:
    
    __DO_1                                                       '  DO
    
                      or            dira,LED                     '    TOGGLE LED
                      xor           outa,LED                    
    
                      mov           __temp2,_1000                '    PAUSE 1000
                      mov           __temp1,_1mSec              
                      add           __temp1,cnt                 
    __L0001                                                     
                      waitcnt       __temp1,_1mSec              
                      djnz          __temp2,#_LMM_JUMP          
                      long          @@@__L0001                  
    
                      rdlong        __PC,__PC                    '  LOOP
                      long          @@@__DO_1                   
    __LOOP_1                                                    
    
                      mov           __temp1,#0                   'END
                      waitpne       __temp1,__temp1             
    
    
    DAT                                                         
      '-------------------------------------------------------------------------------------------
      'LMM Execution code                                       
      ' -------------------------------------------------------------------------------------------
                                                                
      ORG 0                                                     
                                                                
    _LMM_Entry                                                  
                      mov           __PC,__OFFSET               
                                                                
    _LMM_LOOP                                                   
                      rdlong        __INSTR1,__PC               
                      add           __PC,#4                     
    __INSTR1                                                    
                      nop           ' Placeholder for LMM instruction
                                                                
                      rdlong        __INSTR2,__PC               
                      add           __PC,#4                     
    __INSTR2                                                    
                      nop           ' Placeholder for LMM instruction
                                                                
                      rdlong        __INSTR3,__PC               
                      add           __PC,#4                     
    __INSTR3                                                    
                      nop           ' Placeholder for LMM instruction
                                                                
                      rdlong        __INSTR4,__PC               
                      add           __PC,#4                     
    __INSTR4                                                    
                      nop           ' Placeholder for LMM instruction
                                                                
                      jmp           #_LMM_LOOP                  
                                                                
    _LMM_JUMP                                                   
                      rdlong        __PC,__PC                   
                      jmp           #_LMM_LOOP                  
                                                                
    _LMM_CALL                                                   
                      movd          $+2,__STACKPTR              
                      add           __STACKPTR,#1               
                      mov           0-0,__PC                    
                      rdlong        __PC,__PC                   
                      jmp           #_LMM_LOOP                  
                                                                
    _LMM_RET                                                    
                      sub           __STACKPTR,#1               
                      movs          $+2,__STACKPTR              
                      mov           __PC,#4                     
                      add           __PC,0-0                    
                      jmp           #_LMM_LOOP                  
                                                                
    _LMM_MOVS                                                   
                      rdlong        __MOVS,__PC                 
                      movs          __MOVS,__INDEX              
                      add           __PC,#4                     
    __MOVS                                                      
                      nop           ' Placeholder for LMM instruction
                      jmp           #_LMM_LOOP                  
                                                                
    _LMM_MOVD                                                   
                      rdlong        __MOVD,__PC                 
                      movd          __MOVD,__INDEX              
                      add           __PC,#4                     
    __MOVD                                                      
                      nop           ' Placeholder for LMM instruction
                      jmp           #_LMM_LOOP                  
                                                                
                      '             Variables for LMM execution code
    __INDEX          LONG 0  ' Used by MOVS and MOVD            
    __OFFSET         LONG 0-0' Set by spin                      
    __PC             LONG 0  ' Program counter                  
    __STACKPTR       LONG __STACK  ' Stack pointer              
    __STACK          LONG 0[16] ' Return stack                  
    '**********************************************************************
    __InitDirA       LONG %00000000_00000000_00000000_00000000
    __InitOutA       LONG %00000000_00000000_00000000_00000000
    _1000            LONG 1000
    LED              LONG 1 << 15
    _1mSec           LONG 80000
    _FREQ            LONG 80000000
    
    ____STRING_adr   LONG 0
    __clkfreq_adr    LONG 0
    
    __remainder
    __temp1          RES 1
    __temp2          RES 1
    __temp3          RES 1
    __temp4          RES 1
    __temp5          RES 1
    __param1         RES 1
    __param2         RES 1
    __param3         RES 1
    __param4         RES 1
    __paramcnt       RES 1
    temp             RES 1
    
    FIT 492
    
    CON
      LSBFIRST                         = 0
      MSBFIRST                         = 1
      MSBPRE                           = 0
      LSBPRE                           = 1
      MSBPOST                          = 2
      LSBPOST                          = 3
    
    DAT
    __DATASTART
    
    

    Bean
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-12 19:35
    ersmith wrote: »
    While GDB certainly has its flaws, what on earth do you mean by "requires the cooperation of the program" and "does not have any means to do real debugging"?
    Real debugging requires some level of HW support (not present in the Propeller as far as I know).

    Real debugging is two fold:
    First is watching values change (this can be done with out HW support, though requires extra code to do so with out the help of HW).
    And:
    Tracing execution of the binary code instruction by instruction. This requires some means of stopping native code after each instruction (or a specified number of instructions), dumping the values of registers, and returning to execution. Think about DOS Debug.exe, or the 32 BIT machine language DPMI program debuggers, or any of the good old Atari ST/TT/Falcon debuggers (other than GDB), or any of the good old Apple II debuggers, or most of the good old 68K Macintosh debuggers.

    Unfortunately people do not like machine language debugging anymore, mostly because they never learned how to do it correctly. Now days people prefer the code supported methods provided by the likes of gdb.

    OK, gdb can be used to step through instructions one by one, or several at a time and dump the registers, though it is much more difficult to use for that than the better native debuggers.

    Unfortunately with the propeller there is no good way to implement true debugging. There is a reason that it is often heard for programs to work great when compiled with debugging enabled, and fail when compiled normaly. The code added by compiling for debugging changes the flow, sometimes in subtle ways that will break the program when removed, this is very common. And the only way we have to debug on the prop is to insert debugging code :(.

    I like the Propeller, though it would be nice to be able to interrupt the code ruining in a cog, dump all 512 registers to hub, and resume on command. That would make true debugging possible, with unmodified binaries. Though that is the only good use of an interrupt on the propeller that I can see.
  • Heater.Heater. Posts: 21,230
    edited 2015-04-13 02:14
    I have never used debuggers much. Not since the days of setting break points in assembly code using the in ROM debug monitors of 8 bit systems.

    Often I found that by the time a bug was hard enough to find to want to use a debugger then using the debugger made it even harder to find! As you say, debuggers require the code to be compiled differently can they can mess with the timing thus hiding or moving the problem.

    Even those expensive in circuit emulators from people like Intel proved troublesome that way even though they were supposed to be full speed non-intrusive debugging support.

    Any way I'm curious, what processor is there that can watch variables for changes in hardware and raise an interrupt when they occur? I have never worked with such a machine.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-13 04:06
    Heater. wrote: »
    I have never used debuggers much. Not since the days of setting break points in assembly code using the in ROM debug monitors of 8 bit systems.

    Often I found that by the time a bug was hard enough to find to want to use a debugger then using the debugger made it even harder to find! As you say, debuggers require the code to be compiled differently can they can mess with the timing thus hiding or moving the problem.

    Even those expensive in circuit emulators from people like Intel proved troublesome that way even though they were supposed to be full speed non-intrusive debugging support.

    Any way I'm curious, what processor is there that can watch variables for changes in hardware and raise an interrupt when they occur? I have never worked with such a machine.
    The HW can not. Though you can use a separate debug application to step through your code with out having to compile it any differently on any machine with soft interrupts, do to being able to break the flow of execution. And you can watch variables, so long as you know the address with out changing the code of the program being tested.

    I very rarely use debuggers of any kind myself, though that is just me.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-13 04:20
    Heater. wrote: »
    I have never used debuggers much. Not since the days of setting break points in assembly code using the in ROM debug monitors of 8 bit systems.

    Often I found that by the time a bug was hard enough to find to want to use a debugger then using the debugger made it even harder to find! As you say, debuggers require the code to be compiled differently can they can mess with the timing thus hiding or moving the problem.

    Even those expensive in circuit emulators from people like Intel proved troublesome that way even though they were supposed to be full speed non-intrusive debugging support.

    Any way I'm curious, what processor is there that can watch variables for changes in hardware and raise an interrupt when they occur? I have never worked with such a machine.
    There are certainly processors with "data breakpoints" that monitor reads and/or writes to a handful of locations and stop the program when one occurs.
  • KeithEKeithE Posts: 957
    edited 2015-04-13 14:04
    David Betz wrote: »
    There are certainly processors with "data breakpoints" that monitor reads and/or writes to a handful of locations and stop the program when one occurs.

    I've worked with an 8051 that could do this. Here's a blurb about the debugging IP:

    http://fs2.com/snav-cast51.html

    I've also used more sophisticated systems that output real-time instruction trace, and have talked to people who also had data trace. This is trace data that's streamed off the chip with no impact on the execution flow.

    Whenever we worked on custom ASICs with embedded CPUs, we tried to give good hardware debugging support to our software engineers. (We had to do hardware patching too.)

    Edite to add a reference to real-time trace: http://www2.lauterbach.com/pdf/training_trace.pdf
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-13 17:07
    @Bean:
    You asked me to keep tracked of the things that seem to be lacking in the PropBASIC Documentation.

    So far I have found the following things:
      Better and more complete documentation of the usage of task blocks is needed. Better documentation of the serial IO commands parameters, especially the baud rate parameters (acceptable values and limits). Some description of the usage of the I2C and SPI commands. A mention of the limits of ON GOTO and ON GOSUB.

    Otherwise your documentation seems fairly complete so far.

    It may be helpful to some to see more small code examples in the manual as well.
  • BeanBean Posts: 8,129
    edited 2015-04-13 17:59
    Agreed, Thanks.

    Bean
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-15 21:11
    @Bean:
    It seems that I wasted a few days of coding. The ON GOTO, and ON GOSUB statements seem to be failing some times (I have some serial output strings for debugging at present). I can not seem to find where things are going wrong.

    If I can not figure this out soon I will either have to do a complete rewrite of large portions using long if then chains (that may not compile small enough), or look at a different language (like C).
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-16 03:54
    @Bean:
    It seems that I wasted a few days of coding. The ON GOTO, and ON GOSUB statements seem to be failing some times (I have some serial output strings for debugging at present). I can not seem to find where things are going wrong.

    If I can not figure this out soon I will either have to do a complete rewrite of large portions using long if then chains (that may not compile small enough), or look at a different language (like C).
    Can you post your code so we can see what you're trying to do?
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 04:31
    There are alot of places in the code that seem to compile, though the ON GOSUB does not call the procedures. The first example in the G-Code parser is:
    '...
    GCmd:
    ON GPar = 0, 1, 4, 20, 21, 28, 90, 91, 92, 162 GOSUB Move, Move, Dwell, Inches, Millimeters, AbsP, RelP, MaxMov
    '...
    

    It does not matter what procedures are targeted, or what the control variable is, about 90% of the ON GOSUB statements do not word. There is only one ON GOTO Statement, and it actually does seem to work.

    As PropBASIC does not support CASE statements, I have to use ON GOSUB for that purpose (which should do that job well).
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-16 04:37
    There are alot of places in the code that seem to compile, though the ON GOSUB does not call the procedures. The first example in the G-Code parser is:
    '...
    GCmd:
    ON GPar = 0, 1, 4, 20, 21, 28, 90, 91, 92, 162 GOSUB Move, Move, Dwell, Inches, Millimeters, AbsP, RelP, MaxMov
    '...
    
    Don't the identifiers after "GOSUB" need to be labels not procedure names? Or is there no difference in PropBASIC. Hmmm... Maybe I'd better let Bean answer this. My memory of ON GOSUB was back when Basic had line numbers! :-)
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 04:50
    David Betz wrote: »
    Don't the identifiers after "GOSUB" need to be labels not procedure names? Or is there no difference in PropBASIC. Hmmm... Maybe I'd better let Bean answer this. My memory of ON GOSUB was back when Basic had line numbers! :-)
    With traditional BASIC you would be correct. Though the PropBASIC manual says that GOSUB has to target a procedure.
  • VonSzarvasVonSzarvas Posts: 3,450
    edited 2015-04-16 06:04
    With traditional BASIC you would be correct. Though the PropBASIC manual says that GOSUB has to target a procedure.

    Hi David,

    Did you try a label anyhow? The version of the PropBASIC manual I have seems to suggest GOSUB targets labels.

    Attached to this post... page 42 and 59 seem to cover GOSUB

    Hope you can solve - sounds like a neat project.

    Michael.

    PropBASIC_Syntax_Guide_0x15.pdf
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 06:32
    VonSzarvas wrote: »
    Hi David,

    Did you try a label anyhow? The version of the PropBASIC manual I have seems to suggest GOSUB targets labels.

    Attached to this post... page 42 and 59 seem to cover GOSUB

    Hope you can solve - sounds like a neat project.

    Michael.

    PropBASIC_Syntax_Guide_0x15.pdf
    I will give that an attempt, at least that is only about a hundred lines of code to change.

    I really would like to see it complete in PropBASIC just to show the ability of PropBASIC.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 06:52
    As I have not gotten far enough to actually run it:

    How dose this cut of code look for controling a stepper (forward movement in this case):
    TASM Srp_Main
    XPos HUB LONG
    StepperX PIN 3..0 'Stepper X pins.
    tmp VAR LONG
    tmp1 VAR LONG
    '... other Pin assignments and variables.
    
    LP:
    '... Code to decide when to step, and loop.
    
    
    
    FWDX:
      IF curstpx = 12 THEN
        curstpx = 0
      ELSE
        curstpx = curstpx + 4
      ENDIF
    
      tmp = stps << curstpx
      tmp = tmp & 15
    
      StepperX = tmp
    
      RDLONG XPos, tmp
      tmp = tmp + 1
      WRLONG XPos, tmp
    
      GOTO LP
    
    
    
    '... More stepper control code.
    
    Obviously I left out everything except for the basic output code, I hope the comments that I just inserted help.
  • BeanBean Posts: 8,129
    edited 2015-04-16 07:20
    David,
    Are you using Native code or LMM code when using ON..GOSUB ?
    I'll take a look at the output of a simple test program and see if I notice anything.

    Bean
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 08:30
    Bean wrote: »
    David,
    Are you using Native code or LMM code when using ON..GOSUB ?
    I'll take a look at the output of a simple test program and see if I notice anything.

    Bean
    I am using some in LMM, and some in COG native.

    Thank you.
  • BeanBean Posts: 8,129
    edited 2015-04-16 11:18
    David,
    I must admit I don't use ON...GOSUB often. I've looked at the generated code, but I don't see anything that jumps out at me as being wrong.
    Would it be possible to post a small program that has the problem ?

    Bean
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 14:53
    Bean wrote: »
    David,
    I must admit I don't use ON...GOSUB often. I've looked at the generated code, but I don't see anything that jumps out at me as being wrong.
    Would it be possible to post a small program that has the problem ?

    Bean
    No problem, give me a few minutes to whip up something small enough to be easy to read on the forums.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 15:22
    Bean wrote: »
    David,
    I must admit I don't use ON...GOSUB often. I've looked at the generated code, but I don't see anything that jumps out at me as being wrong.
    Would it be possible to post a small program that has the problem ?

    Bean
    I have also figured it out, if there are more than some number of parameters it will refuse to work (do not know why, maybe I should look at the PASM). I do not know what the threshhold is, though it is as it is. Unfortunately there are many points where I use between 20 and 40 branch targets in the ON GOSUB, I have not yet com

    Here is an example, though as I just looked at the PASM output I do not know why it is a problem. Just insert some serial output just before the ON GOSUB and in each subroutine before compiling, and remember to rename most of the _ret symbols in the PASM output (so it will compile with out complaint).
    PROGRAM Start
    x VAR LONG
    
    Start:
      x = 0
      ON x GOSUB PR00,PR01,PR02,PR03,PR04,PR05,PR06,PR07,PR08,PR09,PR0A,PR0B,PR0C,PR0D,PR0E,PR0F,PR10,PR11,PR12,PR13,PR14,PR15,PR16,PR17,PR18,PR19,PR1A,PR1B,PR1C,PR1D,PR1E,PR1F
      x = x+1
      goto Start
    
    PR00:
    RETURN
    PR01:
    RETURN
    PR02:
    RETURN
    PR03:
    RETURN
    PR04:
    RETURN
    PR05:
    RETURN
    PR06:
    RETURN
    PR07:
    RETURN
    PR08:
    RETURN
    PR09:
    RETURN
    PR0A:
    RETURN
    PR0B:
    RETURN
    PR0C:
    RETURN
    PR0D:
    RETURN
    PR0E:
    RETURN
    PR0F:
    RETURN
    PR10:
    RETURN
    PR11:
    RETURN
    PR12:
    RETURN
    PR13:
    RETURN
    PR14:
    RETURN
    PR15:
    RETURN
    PR16:
    RETURN
    PR17:
    RETURN
    PR18:
    RETURN
    PR19:
    RETURN
    PR1A:
    RETURN
    PR1B:
    RETURN
    PR1C:
    RETURN
    PR1D:
    RETURN
    PR1E:
    RETURN
    PR1F:
    RETURN
    
    
  • jmgjmg Posts: 15,173
    edited 2015-04-16 15:24
    t does not matter what procedures are targeted, or what the control variable is, about 90% of the ON GOSUB statements do not word. There is only one ON GOTO Statement, and it actually does seem to work..

    You say some of the time they do work ? - you may like to try multiple expanding test cases, as that sounds like some threshold effect ?
    What does the ASM look like, on the ones that fail ?
    How compact is the ASM on the ones that work ?

    How does GOTO differ in code generation - if that always works, you could workaround using that until the other is fixed ?
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 15:28
    jmg wrote: »
    You say some of the time they do work ? - you may like to try multiple expanding test cases, as that sounds like some threshold effect ?
    What does the ASM look like, on the ones that fail ?
    How compact is the ASM on the ones that work ?

    How does GOTO differ in code generation - if that always works, you could workaround using that until the other is fixed ?
    As I just stated above, you are correct, it is only the ones with between 20 and 40 targets that fail, and looking at the assembly it looks like they should work with out any trouble.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 18:54
    I am still going to do the PropBASIC version, though it is on hold for a while. At present I just want something that is easy for all to understand and is working quickly, so I am going to be using PropGCC for the initial release.

    I need to do some thinking about what the PropBASIC problem is anyway.
Sign In or Register to comment.