Shop OBEX P1 Docs P2 Docs Learn Events
FlexProp: a complete programming system for P2 (and P1) - Page 20 — Parallax Forums

FlexProp: a complete programming system for P2 (and P1)

1171820222355

Comments

  • So I've been out of the P2 loop for a few months working on other projects, and I come back and see this?

    Dude. Awesome. Seriously. This is awesome.

  • RaymanRayman Posts: 14,721
    edited 2021-06-20 15:24

    There seems to be some condition where FlexProp (in C) starts echoing back any serial characters sent to P2 back to PC.

    If you start PST after loading a program, sometimes it echoes back everything you type and sometimes it doesn't.
    Seems to depend on what is in the code, but can't find the trigger...

    I'm trying to figure out how to turn this off, but can't figure it out.
    Any ideas?

    Update: Ok, I think it starts happening when it gets to a "gets()" line... Is that expected behavior?

    Update2: Don't seem to have this issue using Spin2 with Prop Tool, so I don't think it needs to be this way...

  • RaymanRayman Posts: 14,721

    Here is a minimum code to produce the behavior above:

    #include "stdio.h"
    
    int main()
    {
    
        char s[255];
        gets(s);
    
    }
    

    Run this, close the loadp2 terminal and then open PST. Anything you type gets repeated back...

  • gets() reads data from the serial port. It echos the data back so you can see what you are typing. This is expected behavior.

  • RaymanRayman Posts: 14,721

    Ok, thanks. I think I'm seeing on the web that the echo is usually the default and there are platform dependent ways to turn it off.

    The problem is that I want to read a command in from serial port and then reply with a response.
    But, with gets(), it seems I reply with the command and then the response...
    Maybe I can deal with that, but it's not ideal.

    Does getch() also echo? Is there any way to turn the echo off?

    Guess I might have to use a separate serial driver if not...

  • RaymanRayman Posts: 14,721
    edited 2021-06-21 07:28

    After thinking about this, decided to use modified version of jm_fullduplexserial.spin2 from OBEX to avoid the echo.
    Will probably need for serial to have a buffer using a cog at some point anyway.
    Just removed all the string formatting code from it as can do that in C.

  • You can use _rxraw() to read a character without any echo.

  • I've uploaded flexprop5.5.1.zip to github. This version has quite a few bug fixes and improvements, so it's definitely worth upgrading. For the adventurous, the compiler now includes @Wuerfel_21 's P1 bytecode backend. This isn't built in to the GUI yet as it is still incomplete, but it's available with the flexspin command line option --interp=rom. The bytecode support is still under active development. Many Spin programs can be compiled with this option, but complicated BASIC and C programs may get mysterious compile time failures.

    Changes in 5.5.1 include:

    - Added a warning for ignored second parameter to `org`
    - Added -Os option; similar to -O1, but favors smaller size.
    - Added #warning directive to C preprocessor
    - Fixed Spin startup function (should be first PUB function, not first function)
    - Fixed evaluation of @ inside CONSTANT
    - Fixed assembly of PTRA++[0] and PTRA++[16]
    - Fixed some spurious warnings about uninitialized variables
    - Fixed an optimization error for BYTE[] and WORD[]
    - Fixed incorrect unary assignment operator behavior in Spin
    - Fixed ~x and ~~x at top level in Spin1
    - Fixed SIGNX= and ZEROX= in Spin2
    - Fixed compilation of MOUNT if there is no OPEN (not a useful case, but still)
    - Improved COG memory usage
    - Improved conversion of longmove() in Spin to handle labels
    - Made objects come after all variables in Spin
    - Merged colorized error message changes from Wuerfel21.
    - Optimized PRINT CHR$(x) in BASIC
    - ALPHA: new bytecode backend from Wuerfel21, accessed by --interp=rom.
    
  • yetiyeti Posts: 818
    edited 2021-06-21 15:05
    - ALPHA: new bytecode backend from Wuerfel21, accessed by --interp=rom.
    

    ... C and BASIC with Spin's code density.

    Great stuff!     \o/
    Definitely!

  • Many Spin programs can be compiled with this option

    I'd like to boast that it will likely compile pretty much any Spin program, but not necessarily correctly.

    C and BASIC with Spin's code density.

    Not quite. But there's some tricks to it:
    - Bytecode doesn't deal with global variables well (because they basically get allocated in DAT space, where no short addressing is available (and even if, the object header comes first)
    - Avoid unsigned int and unsigned types in general, the interpreter only provides signed operations, so unsigned ops have to be emulated with larger sequences. However, an unsigned operation can be converted into a signed one automatically if the arguments are provably smaller than INT_MAX (either by inferring the type of the expression to be a small unsigned type or by detecting certain masking sequences, such as x&0xFF), so it's not as bad for unsigned short and char

  • RaymanRayman Posts: 14,721

    @ersmith said:
    gets() reads data from the serial port. It echos the data back so you can see what you are typing. This is expected behavior.

    This echo appears to have a carriage return injected... Did FlexProp do this?
    Trying to figure out where it came from...

  • @Rayman said:

    @ersmith said:
    gets() reads data from the serial port. It echos the data back so you can see what you are typing. This is expected behavior.

    This echo appears to have a carriage return injected... Did FlexProp do this?
    Trying to figure out where it came from...

    From the general documentation:

    Normally input (e.g. from a C getchar()) is echoed back to the screen, and carriage return (ASCII 13) is converted to line feed (ASCII 10). Both of these behaviors may be changed via the _setrxtxflags(mode) function. The bits in mode control terminal behavior: if mode & 1 is true, then characters are echoed, and if mode & 2 is true then carriage return (CR) is converted to line feed (LF) on input, and line feed is converted to CR + LF on output.

    The current state of the flags may be retrieved via _getrxtxflags().

  • RaymanRayman Posts: 14,721

    Thanks! If I'm reading this right, seems we can turn off the echo. I've worked around this, but good to know.

  • @ersmith A question about how FlexBASIC handles subroutines called by multiple cogs: Assume the following code:

    SUB Blinky()
        do
            pintoggle(CPUID())
            pauseMS(100)
        loop
    END SUB
    

    If tell multiple cogs to run this sub using CPU, how does FlexBASIC handle the contention between many cogs calling PAUSEMS()? Is there a separate copy of PAUSEMS() for each cog (so no contention issue possible), or is there going to be a contention problem with multiple cogs trying to access a single copy of PAUSEMS() at once?

    I've found a new bug (I think) in Flex 5.5.1 and I think it involves this issue but cant seem to isolate it. Any light you could shed on how the compiler handles this would help.

  • Given the propellers clock register a shared wait would be a surprising implementation choice. And the code seems to indicate that: pausems is defined in terms of _waitms, See here:

    https://github.com/totalspectrum/spin2cpp/blob/b0b4880299e442efa9f867561c7aebfda7fe7291/frontends/common.c#L244

    And that’s just waiting clocks on the core:

    https://github.com/totalspectrum/spin2cpp/blob/f640d037324b5030aad9b43190b6900988d7956d/sys/common.spin#L221

    So IMHO the wait itself is not under contention.

  • @JRoark : deets is correct, each COG has its own timer so there is no contention on pauseMS (it pretty much translates into a "waitct" instruction).

  • JRoarkJRoark Posts: 1,215
    edited 2021-06-22 21:28

    Deets: what you say makes perfect sense. I bet you’re right.

    Edit: Indeed you are! Eric just posted as I posted this.

    Now lets take a user-created function instead. Call it Blah(). I assume that Blah() exists in memory as a single function, and any sharing needs to use a lock system to make sure no two cogs try to access it at once?

  • @JRoark said:
    Deets: what you say makes perfect sense. I bet you’re right.

    Now lets take a user-created function instead. Call it Blah(). I assume that Blah() exists in memory as a single function, and any sharing needs to use a lock system to make sure no two cogs try to access it at once?

    Functions themselves may be called by any number of COGS. But the memory resources the functions use (shared or global variables) do need to be protected by a lock or mutex or something to avoid contention.

  • @ersmith said:
    Functions themselves may be called by any number of COGS. But the memory resources the functions use (shared or global variables) do need to be protected by a lock or mutex or something to avoid contention.

    Bingo. Thanks for the clarification, Eric.

  • I've posted flexprop 5.5.2 to github (and Patreon). This is a continuation of the 5.5.x series and basically just has bug fixes in the compiler:

    - Added cpustop for BASIC
    - Allow relative branches between COG and LUT RAM
    - Cleaned up exec() and CHAIN to clear RAM before starting the new program
    - Fixed an optimizer bug where reads/writes could be incorrectly re-ordered
    - Fixed a bug in *s parsing in sscanf()
    - Fixed a bug which could cause duplicate struct definitions in C
    - Fixed an error parsing += in BASIC array operations
    

    I'm working on a 6.0.0 release, which will have bytecode interpreter support for both P1 and P2, but that's going more slowly than I had hoped so it may still be a while. Source code for it is checked in to github if you want to follow along, and periodically I post beta version binaries to Patreon.

  • @ersmith said:
    I've posted flexprop 5.5.2 to github (and Patreon). This is a continuation of the 5.5.x series and basically just has bug fixes in the compiler:

    - Added cpustop for BASIC
    - Allow relative branches between COG and LUT RAM
    - Cleaned up exec() and CHAIN to clear RAM before starting the new program
    - Fixed an optimizer bug where reads/writes could be incorrectly re-ordered
    - Fixed a bug in *s parsing in sscanf()
    - Fixed a bug which could cause duplicate struct definitions in C
    - Fixed an error parsing += in BASIC array operations
    

    I'm working on a 6.0.0 release, which will have bytecode interpreter support for both P1 and P2, but that's going more slowly than I had hoped so it may still be a while. Source code for it is checked in to github if you want to follow along, and periodically I post beta version binaries to Patreon.

    Oh, already started work on P2 bytecode?

  • @Wuerfel_21 said:

    @ersmith said:
    I'm working on a 6.0.0 release, which will have bytecode interpreter support for both P1 and P2, but that's going more slowly than I had hoped so it may still be a while. Source code for it is checked in to github if you want to follow along, and periodically I post beta version binaries to Patreon.

    Oh, already started work on P2 bytecode?

    Not exactly... I'm working on something I call "nucode" in which the interpreter is generated at compile time. I have no idea whether it will work out or not, but I hope it will allow customization of the bytecode so as to minimize the size of the interpreter and code. The branch it's being developed on is "test/nucode", and it doesn't do anything at all yet.

    A more traditional P2 bytecode (using Chip's interpreter) would be interesting too, but would be a different project.

  • Oh, that sounds really interesting.

  • Tried the latest on my linux box, got the following error.

    Ray

    cc  -o flexprop.bin src/flexprop_native.c -I/usr/include/tcl8.6 -ltk8.6 -ltcl8.6 -lfontconfig -lXft -lXss -lXext -lX11 -lz -ldl -lpthread -lm
    src/flexprop_native.c:23:10: fatal error: tk.h: No such file or directory
     #include "tk.h"
              ^~~~~~
    compilation terminated.
    make: *** [Makefile:124: flexprop.bin] Error 1
    pi@gbbrix1:~/src/flexprop $ 
    
    
  • @Rsadeika said:
    Tried the latest on my linux box, got the following error.

    Ray

    cc  -o flexprop.bin src/flexprop_native.c -I/usr/include/tcl8.6 -ltk8.6 -ltcl8.6 -lfontconfig -lXft -lXss -lXext -lX11 -lz -ldl -lpthread -lm
    src/flexprop_native.c:23:10: fatal error: tk.h: No such file or directory
     #include "tk.h"
              ^~~~~~
    compilation terminated.
    make: *** [Makefile:124: flexprop.bin] Error 1
    pi@gbbrix1:~/src/flexprop $ 
    
    

    The instructions in README.md have changed slightly. You'll need to install the tk8.6-dev package.

  • @ersmith said:

    @Wuerfel_21 said:

    @ersmith said:
    I'm working on a 6.0.0 release, which will have bytecode interpreter support for both P1 and P2, but that's going more slowly than I had hoped so it may still be a while. Source code for it is checked in to github if you want to follow along, and periodically I post beta version binaries to Patreon.

    Oh, already started work on P2 bytecode?

    Not exactly... I'm working on something I call "nucode" in which the interpreter is generated at compile time. I have no idea whether it will work out or not, but I hope it will allow customization of the bytecode so as to minimize the size of the interpreter and code. The branch it's being developed on is "test/nucode", and it doesn't do anything at all yet.

    A more traditional P2 bytecode (using Chip's interpreter) would be interesting too, but would be a different project.

    Also, if the interpreter needs to be customized, will that finally entail an automated SKIP pattern generation feature?

  • @Wuerfel_21 said:
    Also, if the interpreter needs to be customized, will that finally entail an automated SKIP pattern generation feature?

    Probably not. I'm not sure if the "interpreter" will be an interpreter at all. It may end up being a JIT compiler like the one in my RISC-V emulator, so that inner loops can run at a speed approximating PASM.

  • iseriesiseries Posts: 1,492
    edited 2021-07-27 15:23

    I am using the BOSCH driver from bocsh for the BME280 environmental unit which has these defines in it:

    #if !defined(UINT8_C) && !defined(INT8_C)
    #define INT8_C(x)    S8_C(x)
    #define UINT8_C(x)   U8_C(x)
    #endif
    
    #if !defined(UINT16_C) && !defined(INT16_C)
    #define INT16_C(x)   S16_C(x)
    #define UINT16_C(x)  U16_C(x)
    #endif
    
    #if !defined(INT32_C) && !defined(UINT32_C)
    #define INT32_C(x)   S32_C(x)
    #define UINT32_C(x)  U32_C(x)
    #endif
    
    #if !defined(INT64_C) && !defined(UINT64_C)
    #define INT64_C(x)   S64_C(x)
    #define UINT64_C(x)  U64_C(x)
    #endif
    

    and the real defines for registers and arrays looks like this:

    /**\name Register Address */
    #define BME280_CHIP_ID_ADDR                       UINT8_C(0xD0)
    #define BME280_RESET_ADDR                         UINT8_C(0xE0)
    #define BME280_TEMP_PRESS_CALIB_DATA_ADDR         UINT8_C(0x88)
    #define BME280_HUMIDITY_CALIB_DATA_ADDR           UINT8_C(0xE1)
    #define BME280_PWR_CTRL_ADDR                      UINT8_C(0xF4)
    #define BME280_CTRL_HUM_ADDR                      UINT8_C(0xF2)
    #define BME280_CTRL_MEAS_ADDR                     UINT8_C(0xF4)
    #define BME280_CONFIG_ADDR                        UINT8_C(0xF5)
    #define BME280_DATA_ADDR                          UINT8_C(0xF7)
    
    /**\name API success code */
    #define BME280_OK                                 INT8_C(0)
    

    I ended up adding these defines to the stdint.h file:

        /* 7.18.4.1 macros for minimum-width integer constants */
    #define INT8_C(x)   (x)
    #define INT16_C(x)  (x)
    #define INT32_C(x)  (x)
    
    #define UINT8_C(x)  (x ## u)
    #define UINT16_C(x) (x ## u)
    #define UINT32_C(x) (x ## u)
    

    I don't know if you have better ones than these but it fixes the compile issues with sizes.
    I was thinking you could add these defs to your code.

    Mike

  • @iseries : Thanks for the suggestion, Mike. I'll add those.

  • Hello,
    to make FlexBasic even more awesome it would be nice to have more options in the select case statement.
    e.g
    Case 1,5,436
    Case 10 To 20, 30, 40 To 50
    Case "S","T","U"
    or an integer jumptable like in freebasic
    Select Case As Const integer_expression
    to make fast jumps would also be a nice addition

    Cheers!

Sign In or Register to comment.