Shop OBEX P1 Docs P2 Docs Learn Events
propeller-load save to SD card - Page 2 — Parallax Forums

propeller-load save to SD card

2

Comments

  • pwm_start uses PropGCC's "cogstart()" function. In PropGCC 2408, the documentation reads as follows:
    /**
     * @brief Start a new propeller LMM function/thread in another COG.
     *
     * @details This function starts a new LMM VM kernel in a new COG with
     * func as the start function. The stack size must be big enough to hold
     * the struct _thread_state_t, the initial stack frame, and other stack
     * frames used by called functions.
     *
     * @details This function can be used instead of _start_cog_thread.
     *
     * @param func LMM start function
     * @param par Value of par parameter usually an address
     * @param stack Address of user defined stack space.
     * @param stacksize Size of user defined stack space.
     * @returns COG ID allocated by the function or -1 on failure.
     */
    int cogstart(void (*func)(void *), void *par, void *stack, size_t stacksize);
    

    LMM... hmmm... sounds like a high probability that cogstart isn't compatible with XMMC modes.
  • DavidZemon wrote: »
    pwm_start uses PropGCC's "cogstart()" function. In PropGCC 2408, the documentation reads as follows:
    /**
     * @brief Start a new propeller LMM function/thread in another COG.
     *
     * @details This function starts a new LMM VM kernel in a new COG with
     * func as the start function. The stack size must be big enough to hold
     * the struct _thread_state_t, the initial stack frame, and other stack
     * frames used by called functions.
     *
     * @details This function can be used instead of _start_cog_thread.
     *
     * @param func LMM start function
     * @param par Value of par parameter usually an address
     * @param stack Address of user defined stack space.
     * @param stacksize Size of user defined stack space.
     * @returns COG ID allocated by the function or -1 on failure.
     */
    int cogstart(void (*func)(void *), void *par, void *stack, size_t stacksize);
    

    LMM... hmmm... sounds like a high probability that cogstart isn't compatible with XMMC modes.
    That was true of the old version of PropGCC but it is supposed to work with the newer version. However, cogstart will start another XMMC COG which requires its own cache. Allocating space for that cache may have overflowed hub memory.

  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-02-15 16:40
    Switching to a recent build from TeamCity yields the same result :/
  • Something isn't right here. The definition for pwm_start:
    int pwm_start(unsigned int cycleMicroseconds)
    {
      //us = CLKFREQ/1000000;
      tCycle = cycleMicroseconds * st_usTicks;
      pwcog = cogstart(pw, NULL, pwstack, sizeof(pwstack)) + 1;  
      return pwcog;
    }
    

    My code
    #include "simpletools.h"
    #include <PropWare/printer/printer.h>
    
    int main(void) {
    
        pwOut << "Hello, world!\n";
    
        int Led_Intensity = 0;
        int return_cog = pwm_start(1000);
        pwOut << "Current cog    " << cogid() << '\n';
        pwOut << "Running in cog " << return_cog << '\n';
    
        return 0;
    }
    

    And the output (in xmmc)
    [ Entering terminal mode. Type ESC or Control-C to exit. ]
    Hello, world!
    Current cog    0
    Running in cog 0
    

    Where as with lmm I get
    [ Entering terminal mode. Type ESC or Control-C to exit. ]
    Hello, world!
    Current cog    0
    Running in cog 2
    

    So, your guess that it isn't starting up the second cog sounds very accurate. But why it isn't starting... I'm lost on that one.
  • DavidZemon wrote: »
    Switching to a recent build from TeamCity yields the same result :/
    How big a stack did you provide? The cache gets allocated out of the stack space so you need a lot more than for LMM or CMM programs. There is a constant, EXTRA_STACK_BYTES, in propeller.h that helps set the cache amount. Add that number to whatever you think you actually need for the stack.
  • Ah, it's hardcoded as the following in pwm.c
    static unsigned int pwstack[(160 + (50 * 4)) / 4];
    

    I've copied all of the functions and variables from that file into the test harness, so my code is now
    #include "simpletools.h"
    #include <PropWare/printer/printer.h>
    
    void         pw(void *par);
    unsigned int pwstack[((160 + (50 * 4)) / 4) + EXTRA_STACK_LONGS];
    
    volatile unsigned int g_tCycle, g_ticksA, g_ticksB, g_ctra, g_ctrb;
    
    int g_pwcog = 0;
    
    int custom_pwm_start(unsigned int cycleMicroseconds) {
        g_tCycle = cycleMicroseconds * st_usTicks;
        g_pwcog  = cogstart(pw, NULL, pwstack, sizeof(pwstack)) + 1;
        return g_pwcog;
    }
    
    void custom_pwm_set(int pin, int channel, int _tHigh) {
        if (!channel) {
            g_ctra   = NCO_PWM_1;
            g_ctra |= pin;
            g_ticksA = _tHigh * st_usTicks;
        }
        else {
            g_ctrb   = NCO_PWM_1;
            g_ctrb |= pin;
            g_ticksB = _tHigh * st_usTicks;
        }
    }
    
    void custom_pwm_stop(void) {
        if (g_pwcog) cogstop(g_pwcog - 1);
        g_pwcog = 0;
    }
    
    void pw(void *par) {
        FRQA            = 1;
        FRQB            = 1;
        int          pin;
        unsigned int dt = g_tCycle;
        unsigned int t  = CNT;
        while (1) {
            waitcnt(t += dt);
            if (g_ctra != CTRA) {
                if (g_ctra != 0) {
                    pin = CTRA & 0b111111;
                    DIRA &= ~(1 << pin);
                }
                CTRA = g_ctra;
                pin = CTRA & 0b111111;
                DIRA |= (1 << pin);
            }
            if (g_ctrb != CTRB) {
                if (g_ctrb != 0) {
                    pin = CTRB & 0b111111;
                    DIRB &= ~(1 << pin);
                }
                CTRB = g_ctrb;
                pin = CTRB & 0b111111;
                DIRA |= (1 << pin);
            }
            PHSA = -g_ticksA;
            PHSB = -g_ticksB;
        }
    }
    
    int main(void) {
    
        pwOut << "Hello, world!\n";
    
        int Led_Intensity = 0;
        int return_cog    = custom_pwm_start(1000);
        pwOut << "Current cog    " << cogid() << '\n';
        pwOut << "Running in cog " << return_cog << '\n';
    
        while (1)                                    // Endless loop
        {
    
            while (Led_Intensity < 1000) {
                custom_pwm_set(26, 1, Led_Intensity);
                Led_Intensity++;
                pause(1);
            }
    
    
            while (Led_Intensity > 0) {
                custom_pwm_set(26, 1, Led_Intensity);
                Led_Intensity--;
                pause(1);
            }
    
        }
    }
    

    And it works. What is very surprising though is that it takes a solid 30 seconds (ish) for the light to start flashing! I haven't timed it or anything, it just feels that long. I actually came back here to say the cog was starting (the terminal immediately printed the expected output after the program started) but no light flashed. Then in the middle of typing that, the light started flashing!

    So.. it work.s It just takes a loongggggggg time to start the second cog I guess?

    And @AS, the real take away here is that the pwm functions in the Simple library are not compatible with XMM modes. I will file a bug report with them for you, but in the meantime you can re-define those functions as I did above and you should be good to go. And by the way, I got these definitions from pwm.c here.
  • Probably gets delayed because CNT wraps around or something like that. Remember, XMMC is a lot slower than LMM or even CMM.
  • David Betz wrote: »
    Probably gets delayed because CNT wraps around or something like that. Remember, XMMC is a lot slower than LMM or even CMM.

    Spot on. Changing the invocation of custom_pwm_start from
    int return_cog    = custom_pwm_start(1000);
    

    to
    int return_cog    = custom_pwm_start(10000);
    

    fixes it.
  • ASAS Posts: 149
    David Zemon,

    This is great!

    But at the moment, I miss something. :(

    I can´t run the code, you post, in the [xmmc] mode, that I call the "Hello_Cogs". I have the same situation than before "Starting program" and after freeze.

    It works well in the [lmm] mode, like you said, the same result.

    It could be the file "activityboard.cfg"? or something else?

  • ASAS Posts: 149
    edited 2016-02-15 21:12
    David Zemon,
    One more question:
    I understand that is necessary more stack to the "xmmc", you add it:
    unsigned int pwstack[((160 + (50 * 4)) / 4) + EXTRA_STACK_LONGS];
    

    but I got this error that 'EXTRA_STACK_LONGS' was not declared in this scope. I understand that this could be very basic but I don´t understand how you did! It´s for add a integer value for more stack, ok. For this example. How much? EXTRA_STACK_LONGS=50??

    Thanks
  • AS wrote: »
    David Zemon,
    One more question:
    I understand that is necessary more stack to the "xmmc", you add it:
    unsigned int pwstack[((160 + (50 * 4)) / 4) + EXTRA_STACK_LONGS];
    

    but I got this error that 'EXTRA_STACK_LONGS' was not declared in this scope. I understand that this could be very basic but I don´t understand how you did! It´s for add a integer value for more stack, ok. For this example. How much? EXTRA_STACK_LONGS=50??

    Thanks

    I'm afraid David's solution only works with the most recent version of PropGCC, not the version that comes with the current release of SimpleIDE.
  • @AS,

    I'm not sure the right combination of tools exists to make this happen. I have the following PropGCC builds on my system:

    2408
    Very recent GCC4 build from TeamCity
    Very recent GCC6 build from TeamCity
    Version distributed with Ubuntu SimpleIDE package

    The first three do not work because sd-cache was disabled, as David Betz explained elsewhere. The version in SimpleIDE fails to compile with
    [ 50%] Building CXX object CMakeFiles/Scratch-exe.dir/main.cpp.obj
    /home/david/reusable/Documents/Programming/PropellerProjects/Scratch/main.cpp:5:47: error: 'EXTRA_STACK_LONGS' was not declared in this scope
    /home/david/reusable/Documents/Programming/PropellerProjects/Scratch/main.cpp:5:64: error: array bound is not an integer constant before ']' token
    /home/david/reusable/Documents/Programming/PropellerProjects/Scratch/main.cpp: In function 'int custom_pwm_start(unsigned int)':
    /home/david/reusable/Documents/Programming/PropellerProjects/Scratch/main.cpp:13:33: error: 'pwstack' was not declared in this scope
    CMakeFiles/Scratch-exe.dir/build.make:62: recipe for target 'CMakeFiles/Scratch-exe.dir/main.cpp.obj' failed
    

    With that in mind, and the fact that David Betz has explained how using an SD card as cache is really not a good idea, I would encourage you to take a few steps back and maybe post (in a new thread) the code you're trying and failing to compile with CMM mode. Maybe there's a way we can help you get it to fit in CMM mode.

    When I compile the eFFL examples with CMM mode, I have lots of free space left:
    Scanning dependencies of target arduino_simple_sample-exe
    [ 92%] Building CXX object examples/CMakeFiles/arduino_simple_sample-exe.dir/arduino_simple_sample/arduino_simple_sample.cpp.obj
    [ 93%] Linking C executable arduino_simple_sample.elf.elf
    [ 93%] Built target arduino_simple_sample-exe
    Scanning dependencies of target arduino_simple_sample
    Code size  = 15940
    Total size = 16244
    [ 93%] Built target arduino_simple_sample
    Scanning dependencies of target general_advanced_sample-exe
    [ 95%] Building CXX object examples/CMakeFiles/general_advanced_sample-exe.dir/general_advanced_sample/general_advanced_sample.cpp.obj
    [ 96%] Linking C executable general_advanced_sample.elf.elf
    [ 96%] Built target general_advanced_sample-exe
    Scanning dependencies of target general_advanced_sample
    Code size  = 17396
    Total size = 17628
    [ 96%] Built target general_advanced_sample
    Scanning dependencies of target general_simple_sample-exe
    [ 98%] Building CXX object examples/CMakeFiles/general_simple_sample-exe.dir/general_simple_sample/general_simple_sample.cpp.obj
    [100%] Linking C executable general_simple_sample.elf.elf
    [100%] Built target general_simple_sample-exe
    Scanning dependencies of target general_simple_sample
    Code size  = 15640
    Total size = 15872
    [100%] Built target general_simple_sample
    
  • I agree with David. If your program will fit using the CMM memory model, you should use that. It will outperform XMM.
  • ASAS Posts: 149
    I don´t understand why but "pwOut" is not working here, no errors or warnings but in [xmmc] it freezes after the "Starting Program", in [lmm] is working good.

    Only works with "printf":
    #include "simpletools.h"
    
    int main(void) {
    
        printf("Hello, world!\n");
    
        int return_cog = pwm_start(1000);
    
        printf("Curent Cog:");
        printf("%d\n",cogid());
    
        printf("Running in cog:");
        printf("%d\n",return_cog );
    
        return 0;
    }
    

    in [lmm] mode:
    $ /opt/parallax/bin/propeller-load -b activityboard Hello_Cogs.elf -r -t
    ...
    Hello, world!
    Curent Cog:0
    Running in cog:2
    

    in [xmmc] mode:
    $ /opt/parallax/bin/propeller-load -b activityboard -z Hello_Cogs.elf -r -t
    ...
    Hello, world!
    Curent Cog:2
    Running in cog:0
    

    The other example with th LED_PWM, in the [lmm] everything works good with "pwOut" in [xmmc] it freezes after the "Starting Program". With "printf" everything works good in [lmm] in [xmmc] the two while cycles are working I see the numbers in the terminal with:
    printf("%d\n",Led_Intensity);
    
    is interesting to see the diferent velocities.
    but the led always off!!!

    How could I install the last GCC?

    I got some issues with [cmm] but I never had any problem with space with the Fuzzy libraries, I need see it again for sure.

    Thanks!

  • ASAS Posts: 149
    I will install these instructions (https://github.com/dbetz/propeller-gcc).
    I will give news.

    Thanks
  • AS wrote: »
    I will install these instructions (https://github.com/dbetz/propeller-gcc).
    I will give news.

    Thanks

    Note that those instructions are for cross-compiling PropGCC for the Pi, not a native compile from the Pi. Try this (warning: I'm at work now so I can't actually test these commands to verify they're correct)
    cd /opt
    sudo bash
    wget http://david.zemon.name:8111/repository/download/PropGCC5_Gcc4rpi/.lastSuccessful/propellergcc-alpha_v1_9_0-gcc4-rpi.tar.gz?guest=1 -O propellergcc-alpha_v1_9_0-gcc4-rpi.tar.gz
    mv parallax parallax.simpleide
    tar -xf propellergcc-alpha_v1_9_0-gcc4-rpi.tar.gz
    mv parallax parallax.gcc4
    ln -s parallax.gcc4 parallax
    

    That will hopefully get you up and running with the latest Raspberry Pi build
  • ASAS Posts: 149
    edited 2016-02-16 19:06
    I done exacly what you post.

    At this moment I can´t run with a error in [xmmc] mode! :P

    I think the issue is not in the compilation but in the propeller-load, because I try some files already compilated before and I got a similar error:
    $  /opt/parallax/bin/propeller-load -b activityboard -z Hello_Cogs.elf -r -t
    Propeller Version 1 on /dev/ttyUSB0
    Loading the serial helper to hub memory
    10392 bytes sent
    Verifying RAM ... OK
    Loading 'Hello_Cogs.pex' to SD card
    9136 bytes sent
    error: load failed
    

    I think I go format the SD card and start again :P
    maybe you have a better solution, when you have some time give me a sugestion.

    Thanks
  • This is the problem David mentioned earlier. This newer version of PropGCC does not support using the SD card as cache (-z flag).
  • DavidZemon wrote: »
    This is the problem David mentioned earlier. This newer version of PropGCC does not support using the SD card as cache (-z flag).
    Ugh. Is this really a problem? I realize there should be a better error message than "load failed" but do you really have a desire to use the SD card as external memory for XMM? As I mentioned, it's likely to be even slower than other XMM configurations. The SD cache support could be resurrected if people really want to use it though.

  • David Betz wrote: »
    DavidZemon wrote: »
    This is the problem David mentioned earlier. This newer version of PropGCC does not support using the SD card as cache (-z flag).
    Ugh. Is this really a problem? I realize there should be a better error message than "load failed" but do you really have a desire to use the SD card as external memory for XMM? As I mentioned, it's likely to be even slower than other XMM configurations. The SD cache support could be resurrected if people really want to use it though.

    I can't speak to AS's needs, but I have no need. I only asked for my own purposes because I want to make sure that PropWare supports each feature that PropGCC and propeller-load support.
  • ASAS Posts: 149
    At this moment I hope that [cmm] mode is enough.

    Only a question:
    The SPI flash chip, how it can be used? is not similar to the SD card?
  • AS wrote: »
    At this moment I hope that [cmm] mode is enough.

    Only a question:
    The SPI flash chip, how it can be used? is not similar to the SD card?

    SPI flash chips are similar in the sense that they are flash memory and can be used to store your program, but the really important difference is that SPI flash chips allow reading a single byte of memory. This is actually not possible with an SD card. If you want to read any one byte from an SD card, you must read the entire 512 byte "block" or "sector" that the byte resides in.

    This makes perfect sense for something like an SD card, where you usually read/write files that are multiple megabytes or even gigabytes in size... but not so much when caching program code :)

    Of course, the other important difference is form factor. I'm not sure about you, but my computer doesn't have an 8-pin DIP socket on the front for an SPI flash chip :P
  • ASAS Posts: 149
    Interesting! thank you to explain better.

    My question is: the procedure to use a SPI flash chips is not similar to the SD cards?
    with the flag "-z" in the "propeller-load"?

    How we can make a USB conect to a 8-pin DIP socket? :P

    After the last installation of PropGCC, I have some errors, but at this moment I can do Fuzzy control with the PROPELLER!! Great thing!! In my opinion it´s one of the great tools to control machines. And I don´t know how, but, for a simple program, it work in [lmm] mode but in the limit, I think that soon I will need the [cmm] mode.

    Thanks a lot!
  • AS wrote: »
    Interesting! thank you to explain better.

    My question is: the procedure to use a SPI flash chips is not similar to the SD cards?
    with the flag "-z" in the "propeller-load"?

    I believe so. I don't have an SPI flash chip - only SPI SRAM that comes with the Propeller DNA board... other David will have to help with this one. Also, the source code for propeller-load has a PDF manual in it, which is very helpful.
    How we can make a USB conect to a 8-pin DIP socket? :P

    Probably similar to this:
    adapter_chain.jpg
  • AS wrote: »
    Interesting! thank you to explain better.

    My question is: the procedure to use a SPI flash chips is not similar to the SD cards?
    with the flag "-z" in the "propeller-load"?

    How we can make a USB conect to a 8-pin DIP socket? :P

    After the last installation of PropGCC, I have some errors, but at this moment I can do Fuzzy control with the PROPELLER!! Great thing!! In my opinion it´s one of the great tools to control machines. And I don´t know how, but, for a simple program, it work in [lmm] mode but in the limit, I think that soon I will need the [cmm] mode.

    Thanks a lot!
    Why do you want a USB connection to an 8-pin DIP socket? If you have a SPI flash chip, you don't need to use -z with propeller-load. Just select the right board type and use propeller-load as normal. The board configuration file that is selected by the board type argument provides information about what pins the SPI flash chip is connected to.

  • ASAS Posts: 149
    Great solutions!

    In [cmm] it needs less space that with Arduino this is great. And it´s very fast, need to test more.

    I think that the SD using as cache, is not a solution to Propeller with these SPI flash chip.
    But to change the program in the EEPROM can be interesting, but for that I don´t need using as flash. I know that in ".spin" it´s easy to change the program in the EEPROM from a file in the SD card, I´m not sure how it is done in C.

    Thanks a lot your help!

  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-02-16 22:32
    AS wrote: »
    But to change the program in the EEPROM can be interesting

    I'm not sure what you mean by this. Are you trying to modify the code itself - such that you have self-modifying code - or are you just trying to store data in EEPROM so that you can retrieve the value of a variable after it powers down?

    If you are trying to store data, that is quite easy. Check out this example using PropWare objects or this example using the Simple library.
  • ASAS Posts: 149
    edited 2016-02-17 01:20
    Store data in the EEPROM is very useful for sure, more than what I speak about, I think.

    I just thought that can be useful change the code in the EEPROM with the .elf files from the SD card to change the mode or something like that.
    (http://learn.parallax.com/node/370)
  • AS wrote: »
    Store data in the EEPROM is very useful for sure, more than what I speak about, I think.

    I just thought that can be useful change the code in the EEPROM with the .elf files from the SD card to change the mode or something like that.
    (http://learn.parallax.com/node/370)

    Ohhhh that... :/ I'm afraid I do not know how to do that. As cool of a feature as it is... I actually haven't seen anyone bring it up with regards to PropGCC.
  • DavidZemon wrote: »
    AS wrote: »
    Store data in the EEPROM is very useful for sure, more than what I speak about, I think.

    I just thought that can be useful change the code in the EEPROM with the .elf files from the SD card to change the mode or something like that.
    (http://learn.parallax.com/node/370)

    Ohhhh that... :/ I'm afraid I do not know how to do that. As cool of a feature as it is... I actually haven't seen anyone bring it up with regards to PropGCC.
    I imagine you can probably do it in the same way they do in Spin if you're using LMM or CMM with PropGCC. Just use propeller-load -s to generate Spin-style .binary files from your .elf file and use the Spin code to launch the files off an SD card. Of course, it would be nice to be able to write the launcher itself in C but that isn't necessary if your goal is to be able to launch C programs stored on an SD card.

Sign In or Register to comment.