Shop OBEX P1 Docs P2 Docs Learn Events
Flexprop C standard output/printf: how to redirect it from the serial port to the object? — Parallax Forums

Flexprop C standard output/printf: how to redirect it from the serial port to the object?

As in the question.

Normal standard output for printf is a serial terminal. How to redirect this to the external object? What methods/functions have to be written in the object and how to tell the compiler to use them?

Comments

  • The built in FILE struct in FlexC has a "putcf" function pointer that specifies how to output a character (and similarly a "getcf" function for reading a character). You can replace this with your own. If you do this, make sure to #undef printf (because normally printf is defined to __builtin_printf, which has some internal optimizations which bypass the putcf function). So for example:

    #include <stdio.h>
    // do not use the built-in printf optimizations
    #undef printf
    
    // low level functions built in to the kernel
    extern int _tx(int c);
    extern int _rx(void);
    
    // our replacement transmit function
    int my_tx(int c)
    {
        if (c >= 'a' && c <= 'z')
            _tx(c + 1);
        else
            _tx(c);
        return 1;
    }
    
    int main()
    {
        // replace stdout put function
        stdout->putcf = my_tx;
        // now use it
        printf("hello\n");
        printf("HELLO\n");
        return 0;
    }
    

    All of this is undocumented and may change in future versions of FlexC.

  • pik33pik33 Posts: 2,366
    edited 2021-03-23 17:17

    This example generated a strange warning

    In line stdout->putcf = my_tx

    testprop.c:22: warning: incompatible pointer types in assignment: expected pointer to function returning int but got pointer to function returning int


    Now I have a material to start experiment with. :)

  • pik33pik33 Posts: 2,366
    edited 2021-03-23 18:05

    Success! :)

    Now the warning is:

    warning: incompatible pointer types in assignment: expected pointer to function returning int but got pointer to function returning any unknown type

    The Spin function header looks like this:

    pub putchar(achar): r | c

    #include <stdio.h>
    // do not use the built-in printf optimizations
    #undef printf
    #undef putchar 
    
    struct __using("hn008.spin2") v; // video driver
    
    int main()
    {
        stdout->putcf = v.putchar;
        int cog=v.start(256);
    
        printf("hello\n");
        printf("HELLO\n");
        return 0;
    }
    

  • pik33pik33 Posts: 2,366

    And now there is a challenge: to compile a flexprop compiler (not IDE, compiler and maybe loader) for Ultibo. If I manage to do it, my Pi Zero+P2Eval contraption can become a self programming modern OS-less retromachine system.

    I don't know yet if it is possible.

    I managed to do this with xmp module player and mad mp3 decoder, so I have some experience how to do this.

  • Sorry about the warning: the my_tx function should have been declared as:

    int my_tx(int c, FILE *x)
    

    but since the second parameter is ignored anyway it doesn't matter. The warning message was a bit garbled though, it should mention the parameters as well as the return type.

  • The flexprop compiler is found at https://github.com/totalspectrum/spin2cpp, and builds in pretty much any Unix-like environment (including Windows). I expect the Ultibo libraries are probably complete enough to build it, there's nothing special in the run time (it does need bison or byacc to build, but not at run time -- if those are a problem you could cross-compile on a Linux system).

    The loader is at https://github.com/totalspectrum/loadp2.

  • pik33pik33 Posts: 2,366

    I have to crosscompile on a Linux system, as Ultibo is a crosscompiler environment. It is written in Pascal but It provides libc and libm for precompiled C code and a mechanism to link this precompiled C code to the main Pascal unit, which works as a something like .h file for the C code.

    The workflow looks like this: compile C code using gcc on Raspbian, try to link it to the Ultibo program, check the linker errors, remove dependencies by rewriting or deleting if not critical, repeat until no more linker error, try to run.

    The end result looks like this: https://github.com/pik33/ultibo_retro_gui/blob/master/mp3.pas.

Sign In or Register to comment.