Shop OBEX P1 Docs P2 Docs Learn Events
PropCS - a small project — Parallax Forums

PropCS - a small project

RsadeikaRsadeika Posts: 3,822
edited 2012-04-23 14:30 in Propeller 1
Below is a small project, I combined Dave Hine's filetest.c, and an RTC example provided by jazzed into a program called PropCS.

I am running this on a C3 board with the board setting of "C3F-SDXMMC", and a memory model of "XMMC". This should be run using the 'Run Console' method. For an explanation of the available commands, use, as an example 'manecho' which gives a brief explanation for the 'echo' command. If you type 'help' it will list the available commands.

I wanted to test out using the uSD card as an extended program space. Since the program itself is fairly small the program response time is very good, which surprised me.

I would appreciate it if everybody would run this program to see what bugs they run into, or other problems with the program.

Have at it.
Ray

<edit1> 4/12/2012 ***WARNING*** This version of PropCS is a Proof Of Concept (POC) version. For the non-regulars here, this was created to check and see if program space on a uSD/SD card does in fact work. So, far it works for me, and I am using the C3 board at the moment.
<eoe1>
«1

Comments

  • denominatordenominator Posts: 242
    edited 2012-04-11 11:16
    Ray,

    If you're running from the SD cache and you're using the SD card, you should change your call to mount(). Specifically, in your PropCS_SD.h, you should comment out the "#define C3_CARD" on line 413 and add a "#define SD_IS_USING_SD_CACHE_DRIVER" before line 454.

    I know it runs properly the way you have it now, but you actually have two exact copies of the SD driver in memory running on two separate cogs. After the change, all SD access (both for library file access and for retrieving cache misses) will be done through a single copy of the driver in a single cog.

    - Ted
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-11 11:33
    I still have a somewhat functioning GG board, what changes would I have to make to be able to run this program, on that board. The board uses 0,1,2,3 pins for the uSD card reader, I think I can get that setup correctly, but I am not sure about 'SDXMMC' part. The next thing I will be trying this program on is the QSboard, once I get the info for that setup.

    The one thing I did notice with the new uSD driver, problems with the different uSD cards went away. In fact I had an uSD card that just would not work correctly with the old driver, now without doing any kind of changes to that card, I plugged it in, and the new driver recognized it immediately.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2012-04-11 11:49
    Rsadeika wrote: »
    The one thing I did notice with the new uSD driver, problems with the different uSD cards went away. In fact I had an uSD card that just would not work correctly with the old driver, now without doing any kind of changes to that card, I plugged it in, and the new driver recognized it immediately.

    Ray

    Score! :) Thanks for reporting that.
    And thanks to Ted (denominator) for doing the SD card work.

    I'll post the instructions for using your GG board in a bit.
  • denominatordenominator Posts: 242
    edited 2012-04-11 12:17
    jazzed wrote: »
    And thanks to Ted (denominator) for doing the SD card work.

    The real thanks go to the authors of FSRW, Jonathan Dummer and Tomas Rokicki, for figuring out what to do - I liberally used their work as a guide.
  • jazzedjazzed Posts: 11,803
    edited 2012-04-11 12:39
    Rsadeika wrote: »
    I still have a somewhat functioning GG board, what changes would I have to make to be able to run this program, on that board. The board uses 0,1,2,3 pins for the uSD card reader, I think I can get that setup correctly, but I am not sure about 'SDXMMC' part. The next thing I will be trying this program on is the QSboard, once I get the info for that setup.

    Ray, in SimpleIDE ....
    1. Make your c:\propgcc\propeller-load\ppusb.cfg look like below.
    2. Reload board types by clicking the jigsaw puzzle piece.
    3. Choose board type PPUSB-SDXMMC
    4. Compile with XMMC mode
    5. Press play.
    # [ppusb]
    # IDE:SDXMMC
        clkfreq: 80000000
        clkmode: XTAL1+PLL16X
        baudrate: 115200
        rxpin: 31
        txpin: 30
        cache-driver: eeprom_cache.dat
        cache-size: 8K
        cache-param1: 0
        cache-param2: 0
        eeprom-first: TRUE
        sd-driver: sd_driver.dat
        sdspi-do: 0
        sdspi-clk: 1
        sdspi-di: 2
        sdspi-cs: 3
    

    @Ted,

    I appreciate Jonathan's, Tom's, and Kye's work too.
    But you're the one who had the time to consider all the issues and do the work for us!
    So cheers to you!

    BTW, I'll have to send your care package next week. I'm overwhelmed this week.
  • pinedustpinedust Posts: 19
    edited 2012-04-11 17:06
    jazzed wrote: »
    Ray, in SimpleIDE ....
    1. Make your c:\propgcc\propeller-load\ppusb.cfg look like below.
    2. Reload board types by clicking the jigsaw puzzle piece.
    3. Choose board type PPUSB-SDXMMC
    4. Compile with XMMC mode
    5. Press play.
    # [ppusb]
    # IDE:SDXMMC
        clkfreq: 80000000
        clkmode: XTAL1+PLL16X
        baudrate: 115200
        rxpin: 31
        txpin: 30
        cache-driver: eeprom_cache.dat
        cache-size: 8K
        cache-param1: 0
        cache-param2: 0
        eeprom-first: TRUE
        sd-driver: sd_driver.dat
        sdspi-do: 0
        sdspi-clk: 1
        sdspi-di: 2
        sdspi-cs: 3
    

    I got kind of excited when I read this and had to try it with my GG PPUSB board.

    What do I need to do to get it to successfully load on my Ubuntu box? I repeatedly get the same result...
    Project Directory: /home/jkraj/propgcc_projects/filetest/
    
    propeller-elf-gcc -o a.out -Os -mxmmc -fno-exceptions filetest.c -s
    propeller-elf-objdump -h a.out
    propeller-load -x a.out
    Done. Build Succeeded!
    
    propeller-load -b PPUSB -p /dev/ttyUSB0 -r -z a.out
    Propeller Version 1 on /dev/ttyUSB0
    Loading the serial helper to hub memory
    9432 bytes sent
    Verifying RAM ... OK
    Loading 'a.pex' to SD card
      37116 bytes remaining             error: load failed
    Timeout waiting for ACK/NAK
    error: SendPacket DATA failed
    
  • Luis DigitalLuis Digital Posts: 371
    edited 2012-04-11 18:31
    Hello Ray,

    The bug is when the program tries to use the SD card. Do you have a card installed?
  • denominatordenominator Posts: 242
    edited 2012-04-11 19:43
    pinedust wrote: »
    What do I need to do to get it to successfully load on my Ubuntu box? I repeatedly get the same result...
    Project Directory: /home/jkraj/propgcc_projects/filetest/
    
    propeller-elf-gcc -o a.out -Os -mxmmc -fno-exceptions filetest.c -s
    propeller-elf-objdump -h a.out
    propeller-load -x a.out
    Done. Build Succeeded!
    
    propeller-load -b PPUSB -p /dev/ttyUSB0 -r -z a.out
    Propeller Version 1 on /dev/ttyUSB0
    Loading the serial helper to hub memory
    9432 bytes sent
    Verifying RAM ... OK
    Loading 'a.pex' to SD card
      37116 bytes remaining             error: load failed
    Timeout waiting for ACK/NAK
    error: SendPacket DATA failed
    

    The error you're seeing occurs when the serial helper program cannot access the SD card. The checklist:

    1) Make sure that ppusb.cfg (in the propeller-load subdirectory of your PropGCC) has the appropriate contents (sdspi-do, -clk, -di, -cs are set to 0, 1, 2, 3 respectively)
    2) Make sure that you're using the latest version of PropGCC and/or SimpleIDE
    3) Make sure you have a SD card fully engaged in the reader/adapter

    If that all fails, then the next things to try are:

    - A different SD card
    - Run the c3files/lmm demo (make sure first you change the mount() routine in src/filetest.c appropriately) and see what happens.
  • jazzedjazzed Posts: 11,803
    edited 2012-04-11 23:15
    @pinedust,

    The 0-6-3 debian-64 package and subsequent 0-6-4 SimpleIDE update that you downloaded should work.

    Does your SD card work with fsrw or kye's SD code?
    The SD card must be formatted as "FAT type" that is FAT16 for 2G or FAT32 for 4G+ cards.

    You might consider reformatting the SD Card. However it seems like connection is bad in this case.
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 02:09
    Hello Ray,

    The bug is when the program tries to use the SD card. Do you have a card installed?

    I take it that you used the 'ls' command to check and see if there is anything on the card? If you are seeing './: I/O error' then you might want to check the version of SimpleIDE that you are using. Other than that, you might have to provide more detail as to what is occurring.

    Ray
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 02:17
    So, has anybody got PropCS to work on there C3 board?

    For a version revision, I think I will be removing the automatic 'mount', and make that a command, so you can 'mount' an uSD/SD card at any time. With that in mind it would be nice to have an 'unmount' command. Also something to consider, a 'format' command.

    WISH LIST
    'unmount' command
    'format' command

    Ray
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 04:48
    I updated ppusb.cfg with the new info for a GG PPUSB board, and added an #ifdef ppusb-sdxmmc code to the PropCS_SD.h file. When I run PropCS I get 'Load and mount SD: Mount error: 3'. Not sure what is causing that. I used the propboe code as an example.

    As for
    "#define C3_CARD" on line 413 and add a "#define SD_IS_USING_SD_CACHE_DRIVER" before line 454.

    my revisions caused errors, so I am not sure how that should be done.


    Ray

    /* PropCS_SD.h */
    
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FileDriver;
    
    _Driver *driverlist[] = {
        &_SimpleSerialDriver,
        &_FileDriver,
        NULL
    };
    
    FILE *stdinfile;
    FILE *stdoutfile;
    
    char *FindChar(char *ptr, int val);
    
    void Cd(int argc, char **argv)
    {
        if (argc < 2) return;
    
        if (chdir(argv[1]))
            perror(argv[1]);
    }
    
    void Pwd(int argc, char **argv)
    {
        uint8_t buffer[64];
        char *ptr = getcwd(buffer, 64);
        if (!ptr)
            perror(0);
        else
            fprintf(stdoutfile, "%s\n", ptr);
    }
    
    void Mkdir(int argc, char **argv)
    {
        int i;
    
        for (i = 1; i < argc; i++)
        {
            if (mkdir(argv[i], 0))
                perror(argv[i]);
        }
    }
    
    void Rmdir(int argc, char **argv)
    {
        int i;
    
        for (i = 1; i < argc; i++)
        {
            if (rmdir(argv[i]))
                perror(argv[i]);
        }
    }
    
    /* This routine implements the file cat function */
    void Cat(int argc, char **argv)
    {
        int i;
        int num;
        void *infile;
        uint8_t buffer[40];
    
        for (i = 0; i < argc; i++)
        {
            if (i == 0)
            {
                if (argc == 1 || stdinfile != stdin)
                    infile = stdinfile;
                else
                    continue;
            }
            else
            {
                infile = fopen(argv[i], "r");
                if (infile == 0)
                {
                    perror(argv[i]);
                    continue;
                }
            }
            if (infile == stdin)
            {
                while (gets(buffer))
                {
                    if (buffer[0] == 4) break;
                    fprintf(stdoutfile, "%s\n", buffer);
                }
            }
            else
            {
                while ((num = fread(buffer, 1, 40, infile)))
                    fwrite(buffer, 1, num, stdoutfile);
            }
            if (i)
                fclose(infile);
        }
        fflush(stdout);
    }
    
    /* This routine deletes the files specified by the command line arguments */
    void Remove(int argc, char **argv)
    {
        int i;
    
        for (i = 1; i < argc; i++)
        {
            if (remove(argv[i]))
                perror(argv[i]);
        }
    }
    
    /* This routine echos the command line arguments */
    void Echo(int argc, char **argv)
    {
        int i;
        for (i = 1; i < argc; i++)
        {
            if (i != argc - 1)
                fprintf(stdoutfile, "%s ", argv[i]);
            else
                fprintf(stdoutfile, "%s\n", argv[i]);
        }
    }
    
    /* This routine lists the root directory or any subdirectories specified
       in the command line arguments.  If the "-l" option is specified, it
       will print the file attributes and size.  Otherwise, it will just
       print the file names.  */
    void List(int argc, char **argv)
    {
        int i, j;
        char *ptr;
        char fname[13];
        int32_t count = 0;
        uint32_t filesize;
        uint32_t longflag = 0;
        char *path;
        char drwx[5];
        int column;
        int prevlen;
        DIR *dirp;
        struct dirent *entry;
    
        // Check flags
        for (j = 1; j < argc; j++)
        {
            if (argv[j][0] == '-')
            {
                if (!strcmp(argv[j], "-l"))
                    longflag = 1;
                else
                    printf("Unknown option \"%s\"\n", argv[j]);
            }
            else
                count++;
        }
    
        // List directories
        for (j = 1; j < argc || count == 0; j++)
        {
            if (count == 0)
            {
                count--;
                path = "./";
            }
            else if (argv[j][0] == '-')
                continue;
            else
                path = argv[j];
    
            if (count >= 2)
                fprintf(stdoutfile, "\n%s:\n", path);
    
            dirp = opendir(path);
    
            if (!dirp)
            {
                perror(path);
                continue;
            }
    
            column = 0;
            prevlen = 14;
            while (entry = readdir(dirp))
            {
                if (entry->name[0] == '.') continue;
                ptr = fname;
                for (i = 0; i < 8; i++)
                {
                    if (entry->name[i] == ' ') break;
                    *ptr++ = tolower(entry->name[i]);
                }
                if (entry->name[8] != ' ')
                {
                    *ptr++ = '.';
                    for (i = 8; i < 11; i++)
                    {
                        if (entry->name[i] == ' ') break;
                        *ptr++ = tolower(entry->name[i]);
                    }
                }
                *ptr = 0;
                filesize = entry->filesize_3;
                filesize = (filesize << 8) | entry->filesize_2;
                filesize = (filesize << 8) | entry->filesize_1;
                filesize = (filesize << 8) | entry->filesize_0;
                strcpy(drwx, "-rw-");
                if (entry->attr & ATTR_READ_ONLY)
                    drwx[2] = '-';
                if (entry->attr & ATTR_ARCHIVE)
                    drwx[3] = 'x';
                if (entry->attr & ATTR_DIRECTORY)
                {
                    drwx[0] = 'd';
                    drwx[3] = 'x';
                }
                if (longflag)
                    fprintf(stdoutfile, "%s %8d %s\n", drwx, filesize, fname);
                else if (++column == 5)
                {
                    for (i = prevlen; i < 14; i++) fprintf(stdoutfile, " ");
                    fprintf(stdoutfile, "%s\n", fname);
                    column = 0;
                    prevlen = 14;
                }
                else
                {
                    for (i = prevlen; i < 14; i++) fprintf(stdoutfile, " ");
                    prevlen = strlen(fname);
                    fprintf(stdoutfile, "%s", fname);
                }
            }
            closedir(dirp);
            if (!longflag && column)
                fprintf(stdoutfile, "\n");
        }
    }
    
    
    
    /* This routine returns a pointer to the first character that doesn't
       match val. */
    char *SkipChar(char *ptr, int val)
    {
        while (*ptr)
        {
            if (*ptr != val) break;
            ptr++;
        }
        return ptr;
    }
    
    /* This routine returns a pointer to the first character that matches val. */
    char *FindChar(char *ptr, int val)
    {
        while (*ptr)
        {
            if (*ptr == val) break;
            ptr++;
        }
        return ptr;
    }
    
    
    /* This routine extracts tokens from a string that are separated by one or
       more spaces.  It returns the number of tokens found. */
    int tokenize(char *ptr, char *tokens[])
    {
        int num = 0;
    
        while (*ptr)
        {
            ptr = SkipChar(ptr, ' ');
            if (*ptr == 0) break;
            if (ptr[0] == '>')
            {
                ptr++;
                if (ptr[0] == '>')
                {
                    tokens[num++] = ">>";
                    ptr++;
                }
                else
                    tokens[num++] = ">";
                continue;
            }
            if (ptr[0] == '<')
            {
                ptr++;
                tokens[num++] = "<";
                continue;
            }
            tokens[num++] = ptr;
            ptr = FindChar(ptr, ' ');
            if (*ptr) *ptr++ = 0;
        }
        return num;
    }
    
    
    /* This routine searches the list of tokens for the redirection operators
       and opens the files for input, output or append depending on the 
       operator. */
    int CheckRedirection(char **tokens, int num)
    {
        int i, j;
    
        for (i = 0; i < num-1; i++)
        {
            if (!strcmp(tokens[i], ">"))
            {
                stdoutfile = fopen(tokens[i+1], "w");
                if (!stdoutfile)
                {
                    perror(tokens[i+1]);
                    stdoutfile = stdout;
                    return 0;
                }
            }
            else if (!strcmp(tokens[i], ">>"))
            {
                stdoutfile = fopen(tokens[i+1], "a");
                if (!stdoutfile)
                {
                    perror(tokens[i+1]);
                    stdoutfile = stdout;
                    return 0;
                }
            }
            else if (!strcmp(tokens[i], "<"))
            {
                stdinfile = fopen(tokens[i+1], "r");
                if (!stdinfile)
                {
                    perror(tokens[i+1]);
                    stdinfile = stdin;
                    return 0;
                }
            }
            else
                continue;
            for (j = i + 2; j < num; j++) tokens[j-2] = tokens[j];
            i--;
            num -= 2;
        }
        return num;
    }
    
    
    /* This routine closes files that were open for redirection */
    void CloseRedirection()
    {
        if (stdinfile != stdin)
        {
            fclose(stdinfile);
            stdinfile = stdin;
        }
        if (stdoutfile != stdout)
        {
            fclose(stdoutfile);
            stdoutfile = stdout;
        }
    }
    
    void mount()
    {
        printf("Load and mount SD: ");
        _SD_Params* mountParams = (_SD_Params*)-1;
    
    // Important: This code assumes you're using a C3 card.
    // If you're using different hardware, make sure you
    // change the following initialization to match your card!
    
    #ifdef SPINNERET_CARD
        static _SD_Params params =
        {
            AttachmentType: _SDA_SingleSPI,
            pins:
            {
                SingleSPI:
                {
                    MISO: 16,   // The pin attached to the SD card's MISO or DO output
                    CLK:  21,   // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 20,   // The pin attached to the SD card's MOSI or DI input
                    CS:   19    // The pin attached to the SD card's CS input
                }
            }
        };
        mountParams = &params;
    #endif
    #ifdef PROP_BOE /* Board of Education */
        static _SD_Params params =
        {
            AttachmentType: _SDA_SingleSPI,
            pins:
            {
                SingleSPI:
                {
                    MISO: 22,   // The pin attached to the SD card's MISO or DO output
                    CLK:  23,   // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 24,   // The pin attached to the SD card's MOSI or DI input
                    CS:   25    // The pin attached to the SD card's CS input
                }
            }
        };
        mountParams = &params;
    #endif
    
    #ifdef PPUSB-SDXMMC
        static _SD_Params params =
        {
            AttachmentType: _SDA_SingleSPI,
            pins:
            {
                SingleSPI:
                {
                    MISO: 0,   // The pin attached to the SD card's MISO or DO output
                    CLK:  1,   // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 2,   // The pin attached to the SD card's MOSI or DI input
                    CS:   3    // The pin attached to the SD card's CS input
                }
            }
        };
        mountParams = &params;
    #endif
    
    
    #define C3_CARD
    #ifdef C3_CARD
    
        static _SD_Params params =
        {
            AttachmentType: _SDA_SerialDeMUX,
            pins:
            {
                SerialDeMUX:
                {
                    MISO: 10,    // The pin attached to the SD card's MISO or DO output
                    CLK:  11,    // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 9,     // The pin attached to the SD card's MOSI or DI input
                    CLR:  25,    // The pin attached to the counter's reset/clear pin
                    INC:  8,     // The pin attached to the counter's clock/count pin
                    ADDR: 5,     // The SD card's demux address (the counter's count)
                }
            }
        };
        mountParams = &params;
    #endif
    //#define SD_IS_USING_SD_CACHE_DIVER
    
    #ifdef PARALLEL_SPI /* This is a hypothetical example - modify to suit your needs */
        static _SD_Params params =
        {
            AttachmentType: _SDA_ParallelDeMUX,
            pins:
            {
                ParallelDeMUX:
                {
                    MISO: 4,    // The pin attached to the SD card's MISO or DO output
                    CLK:  5,    // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 6,    // The pin attached to the SD card's MOSI or DI input
                    CS:   0,    // The pin attached to the counter's reset/clear pin
                    SEL:  0x04, // The pin mask to set when selecting the SD card's deMUX address
                    MSK:  0x0E  // The pin mask for all pins attached to the deMUX address
                }
            }
        };
        mountParams = &params;
    #endif
    
    #if defined(__PROPELLER_XMMC__) && defined(SD_IS_USING_SD_CACHE_DRIVER)
        // Pass NULL as the params. In this case, we'll use the SD Cache driver.
        // Beware: This only works if you're running your program
        // cached off of the SD card (i.e. propeller-load -z).
        mountParams = 0;
    #endif
    
        if (mountParams == (_SD_Params*)-1)
        {
            printf("You must specify the SD paramters in the filetest.c\n");
            exit(1);
        }
    
        uint32_t mountErr = dfs_mount(mountParams);
        if (mountErr)
        {
            printf("Mount error: %d\n", mountErr);
            exit(1);
        }
    
        printf("done.\n\n");
    }
    
    void ManCat()
    {
        printf("cat - opens and displays contents of a file.\n");
        printf(" cat test1.txt\n"); 
    }
    
    void ManRm()
    {
        printf("rm - removes (erases) a file.\n");
        printf(" rm test1.txt\n");
    }
    
    void ManLs()
    {
        printf("ls - list files and directories.\n");
        printf("ls -l - list files with size and attributes.\n");
    }
    
    void ManLL()
    {
        printf("ll - list files with size and attributes.\n");
    }
    
    void ManEcho()
    {
        printf("echo - echos the command line arguments.\n");
        printf(" echo This is a line of text. Will display 'This is a line of text.'\n");
        printf(" echo This is a line of text. >> test1.txt\n");
        printf(" Will create the test1.txt file with 'This is a line of text' in the file.\n");
    }
    
    void ManCD()
    {
        printf("cd - change directory.\n");
        printf(" cd .. - change to root directory.\n");
    }
    
    void ManMkdir()
    {
        printf("mkdir - create a directory.\n");
        printf(" mkdir test - creates directory 'test'.\n");
    }
    
    void ManRmdir()
    {
        printf("rmdir - remove a directory.\n");
        printf(" rmdir test - removes the directory 'test'.\n");
    }
    
    void ManMisc()
    {
        printf("File redirection - '<, >, <<, >>'\n");
    }
    
    
  • jazzedjazzed Posts: 11,803
    edited 2012-04-12 06:59
    Hi Ray,

    Just one thing.

    Your #ifdef PPUSB-SDXMMC should not contain "-".
    Using "-" makes an error for me. For example:
    propboe.c:8:10: warning: extra tokens at end of #ifdef directive [enabled by default]

    Use "_" instead. I.E. #ifdef PPUSB_SDXMMC


    I'm travelling today, so I may not be around the forums much.
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 07:31
    I just tried your suggestion, and it did not make it any better, does not work as expected. I think there might be an inconsistency in the mount() or SD file code as it pertains to accessing the uSD card reader on the GG PPUSB board. I did not try a propboe board, since I do not have one.

    I also noticed for the 'cat' command, if you type in 'cat' and hit return, it locks up the program. It needs a 'cat' command with a parameter. I did not try the 'echo' command yet, but it might have the same problem.

    Ray
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 08:04
    The 'echo' command is OK, I changed the i=0 to i=1, in the first for loop, that took care of the problem. This could use some better command error trapping.

    Ray
    /* This routine implements the file cat function */
    void Cat(int argc, char **argv)
    {
        int i;
        int num;
        void *infile;
        uint8_t buffer[40];
    
    //    for (i = 0; i < argc; i++)
        for (i=1; i < argc; i++)
        {
            if (i == 0)
            {
                if (argc == 1 || stdinfile != stdin)
                    infile = stdinfile;
                else
                    continue;
            }
            else
            {
                infile = fopen(argv[i], "r");
                if (infile == 0)
                {
                    perror(argv[i]);
                    continue;
                }
            }
            if (infile == stdin)
            {
                while (gets(buffer))
                {
                    if (buffer[0] == 4) break;
                    fprintf(stdoutfile, "%s\n", buffer);
                }
            }
            else
            {
                while ((num = fread(buffer, 1, 40, infile)))
                    fwrite(buffer, 1, num, stdoutfile);
            }
            if (i)
                fclose(infile);
        }
        fflush(stdout);
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2012-04-12 08:22
    Hi Ray, Nice work on this program!

    Your original #ifdef was a syntax error, and not a functional problem.

    I've loaded and run your program with board type PPUSB-SDXMMC using SimpleIDE and the steps mentioned in the post to pinedust.
    My C3 is buried in a box - sorry I can't test it. I changed the #ifdef to #ifdef PPUSB

    I added your Cat(...) to my file, and it seems to work fine.

    Can I suggest making the .h files to be .c files?
    They do contain implementation, and that's traditionally in a .C file.
    I do however recognize that people put functions in .h files in C++.

    Hope you don't mind that I'm attaching a version that puts all implementation in .C files.

    Note that the .C files are listed in the project manager.
    Also note I put -D PPUSB in the compiler options field - change it to -D C3_CARD for your board.
    Load and mount SD: done.
    
    
    This is the PropCS program!
    Type help for 'Commands' list.
    >ls
    autorun.pex
    >help
    Commands are 'help, time, settime, ls, cat, rm, ll, echo, cd, pwd, mkdir, rmdir  '
    Manual pages 'mantime, mansettime, manls, mancat, manrm, manll, manecho,
    mancd, manpwd, manmkdir, manrmdir, manmisc
    >mancat
    cat - opens and displays contents of a file.
     cat test1.txt
    >manecho
    echo - echos the command line arguments.
     echo This is a line of text. Will display 'This is a line of text.'
     echo This is a line of text. >> test1.txt
     Will create the test1.txt file with 'This is a line of text' in the file.
    >echo "hello, world!\n" > hello.txt
    >cat hello.txt
    "hello, world!\n"
    >
    
    624 x 517 - 120K
  • denominatordenominator Posts: 242
    edited 2012-04-12 09:33
    Rsadeika wrote: »
    So, has anybody got PropCS to work on there C3 board?

    Ray,

    I have used your source on my C3, and it works fine. Both with your original source, and the updated source with #define SD_IS_USING_SD_CACHE_DRIVER (shown below) - remember that SD_IS_USING_SD_CACHE_DRIVER only works in SDCMMC mode (e.g. your board is set to C3F-SDXMMC):
    /* PropCS_SD.h */
    
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FileDriver;
    
    _Driver *driverlist[] = {
        &_SimpleSerialDriver,
        &_FileDriver,
        NULL
    };
    
    FILE *stdinfile;
    FILE *stdoutfile;
    
    char *FindChar(char *ptr, int val);
    
    void Cd(int argc, char **argv)
    {
        if (argc < 2) return;
    
        if (chdir(argv[1]))
            perror(argv[1]);
    }
    
    void Pwd(int argc, char **argv)
    {
        uint8_t buffer[64];
        char *ptr = getcwd(buffer, 64);
        if (!ptr)
            perror(0);
        else
            fprintf(stdoutfile, "%s\n", ptr);
    }
    
    void Mkdir(int argc, char **argv)
    {
        int i;
    
        for (i = 1; i < argc; i++)
        {
            if (mkdir(argv[i], 0))
                perror(argv[i]);
        }
    }
    
    void Rmdir(int argc, char **argv)
    {
        int i;
    
        for (i = 1; i < argc; i++)
        {
            if (rmdir(argv[i]))
                perror(argv[i]);
        }
    }
    
    /* This routine implements the file cat function */
    void Cat(int argc, char **argv)
    {
        int i;
        int num;
        void *infile;
        uint8_t buffer[40];
    
        for (i = 0; i < argc; i++)
        {
            if (i == 0)
            {
                if (argc == 1 || stdinfile != stdin)
                    infile = stdinfile;
                else
                    continue;
            }
            else
            {
                infile = fopen(argv[i], "r");
                if (infile == 0)
                {
                    perror(argv[i]);
                    continue;
                }
            }
            if (infile == stdin)
            {
                while (gets(buffer))
                {
                    if (buffer[0] == 4) break;
                    fprintf(stdoutfile, "%s\n", buffer);
                }
            }
            else
            {
                while ((num = fread(buffer, 1, 40, infile)))
                    fwrite(buffer, 1, num, stdoutfile);
            }
            if (i)
                fclose(infile);
        }
        fflush(stdout);
    }
    
    /* This routine deletes the files specified by the command line arguments */
    void Remove(int argc, char **argv)
    {
        int i;
    
        for (i = 1; i < argc; i++)
        {
            if (remove(argv[i]))
                perror(argv[i]);
        }
    }
    
    /* This routine echos the command line arguments */
    void Echo(int argc, char **argv)
    {
        int i;
        for (i = 1; i < argc; i++)
        {
            if (i != argc - 1)
                fprintf(stdoutfile, "%s ", argv[i]);
            else
                fprintf(stdoutfile, "%s\n", argv[i]);
        }
    }
    
    /* This routine lists the root directory or any subdirectories specified
       in the command line arguments.  If the "-l" option is specified, it
       will print the file attributes and size.  Otherwise, it will just
       print the file names.  */
    void List(int argc, char **argv)
    {
        int i, j;
        char *ptr;
        char fname[13];
        int32_t count = 0;
        uint32_t filesize;
        uint32_t longflag = 0;
        char *path;
        char drwx[5];
        int column;
        int prevlen;
        DIR *dirp;
        struct dirent *entry;
    
        // Check flags
        for (j = 1; j < argc; j++)
        {
            if (argv[j][0] == '-')
            {
                if (!strcmp(argv[j], "-l"))
                    longflag = 1;
                else
                    printf("Unknown option \"%s\"\n", argv[j]);
            }
            else
                count++;
        }
    
        // List directories
        for (j = 1; j < argc || count == 0; j++)
        {
            if (count == 0)
            {
                count--;
                path = "./";
            }
            else if (argv[j][0] == '-')
                continue;
            else
                path = argv[j];
    
            if (count >= 2)
                fprintf(stdoutfile, "\n%s:\n", path);
    
            dirp = opendir(path);
    
            if (!dirp)
            {
                perror(path);
                continue;
            }
    
            column = 0;
            prevlen = 14;
            while (entry = readdir(dirp))
            {
                if (entry->name[0] == '.') continue;
                ptr = fname;
                for (i = 0; i < 8; i++)
                {
                    if (entry->name[i] == ' ') break;
                    *ptr++ = tolower(entry->name[i]);
                }
                if (entry->name[8] != ' ')
                {
                    *ptr++ = '.';
                    for (i = 8; i < 11; i++)
                    {
                        if (entry->name[i] == ' ') break;
                        *ptr++ = tolower(entry->name[i]);
                    }
                }
                *ptr = 0;
                filesize = entry->filesize_3;
                filesize = (filesize << 8) | entry->filesize_2;
                filesize = (filesize << 8) | entry->filesize_1;
                filesize = (filesize << 8) | entry->filesize_0;
                strcpy(drwx, "-rw-");
                if (entry->attr & ATTR_READ_ONLY)
                    drwx[2] = '-';
                if (entry->attr & ATTR_ARCHIVE)
                    drwx[3] = 'x';
                if (entry->attr & ATTR_DIRECTORY)
                {
                    drwx[0] = 'd';
                    drwx[3] = 'x';
                }
                if (longflag)
                    fprintf(stdoutfile, "%s %8d %s\n", drwx, filesize, fname);
                else if (++column == 5)
                {
                    for (i = prevlen; i < 14; i++) fprintf(stdoutfile, " ");
                    fprintf(stdoutfile, "%s\n", fname);
                    column = 0;
                    prevlen = 14;
                }
                else
                {
                    for (i = prevlen; i < 14; i++) fprintf(stdoutfile, " ");
                    prevlen = strlen(fname);
                    fprintf(stdoutfile, "%s", fname);
                }
            }
            closedir(dirp);
            if (!longflag && column)
                fprintf(stdoutfile, "\n");
        }
    }
    
    
    
    /* This routine returns a pointer to the first character that doesn't
       match val. */
    char *SkipChar(char *ptr, int val)
    {
        while (*ptr)
        {
            if (*ptr != val) break;
            ptr++;
        }
        return ptr;
    }
    
    /* This routine returns a pointer to the first character that matches val. */
    char *FindChar(char *ptr, int val)
    {
        while (*ptr)
        {
            if (*ptr == val) break;
            ptr++;
        }
        return ptr;
    }
    
    
    /* This routine extracts tokens from a string that are separated by one or
       more spaces.  It returns the number of tokens found. */
    int tokenize(char *ptr, char *tokens[])
    {
        int num = 0;
    
        while (*ptr)
        {
            ptr = SkipChar(ptr, ' ');
            if (*ptr == 0) break;
            if (ptr[0] == '>')
            {
                ptr++;
                if (ptr[0] == '>')
                {
                    tokens[num++] = ">>";
                    ptr++;
                }
                else
                    tokens[num++] = ">";
                continue;
            }
            if (ptr[0] == '<')
            {
                ptr++;
                tokens[num++] = "<";
                continue;
            }
            tokens[num++] = ptr;
            ptr = FindChar(ptr, ' ');
            if (*ptr) *ptr++ = 0;
        }
        return num;
    }
    
    
    /* This routine searches the list of tokens for the redirection operators
       and opens the files for input, output or append depending on the 
       operator. */
    int CheckRedirection(char **tokens, int num)
    {
        int i, j;
    
        for (i = 0; i < num-1; i++)
        {
            if (!strcmp(tokens[i], ">"))
            {
                stdoutfile = fopen(tokens[i+1], "w");
                if (!stdoutfile)
                {
                    perror(tokens[i+1]);
                    stdoutfile = stdout;
                    return 0;
                }
            }
            else if (!strcmp(tokens[i], ">>"))
            {
                stdoutfile = fopen(tokens[i+1], "a");
                if (!stdoutfile)
                {
                    perror(tokens[i+1]);
                    stdoutfile = stdout;
                    return 0;
                }
            }
            else if (!strcmp(tokens[i], "<"))
            {
                stdinfile = fopen(tokens[i+1], "r");
                if (!stdinfile)
                {
                    perror(tokens[i+1]);
                    stdinfile = stdin;
                    return 0;
                }
            }
            else
                continue;
            for (j = i + 2; j < num; j++) tokens[j-2] = tokens[j];
            i--;
            num -= 2;
        }
        return num;
    }
    
    
    /* This routine closes files that were open for redirection */
    void CloseRedirection()
    {
        if (stdinfile != stdin)
        {
            fclose(stdinfile);
            stdinfile = stdin;
        }
        if (stdoutfile != stdout)
        {
            fclose(stdoutfile);
            stdoutfile = stdout;
        }
    }
    
    void mount()
    {
        printf("Load and mount SD: ");
        _SD_Params* mountParams = (_SD_Params*)-1;
    
    // Important: This code assumes you're using a C3 card.
    // If you're using different hardware, make sure you
    // change the following initialization to match your card!
    
    #ifdef SPINNERET_CARD
        static _SD_Params params =
        {
            AttachmentType: _SDA_SingleSPI,
            pins:
            {
                SingleSPI:
                {
                    MISO: 16,   // The pin attached to the SD card's MISO or DO output
                    CLK:  21,   // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 20,   // The pin attached to the SD card's MOSI or DI input
                    CS:   19    // The pin attached to the SD card's CS input
                }
            }
        };
        mountParams = &params;
    #endif
    
    #ifdef PROP_BOE /* Board of Education */
        static _SD_Params params =
        {
            AttachmentType: _SDA_SingleSPI,
            pins:
            {
                SingleSPI:
                {
                    MISO: 22,   // The pin attached to the SD card's MISO or DO output
                    CLK:  23,   // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 24,   // The pin attached to the SD card's MOSI or DI input
                    CS:   25    // The pin attached to the SD card's CS input
                }
            }
        };
        mountParams = &params;
    #endif
    
    //#define C3_CARD
    #ifdef C3_CARD
        static _SD_Params params =
        {
            AttachmentType: _SDA_SerialDeMUX,
            pins:
            {
                SerialDeMUX:
                {
                    MISO: 10,    // The pin attached to the SD card's MISO or DO output
                    CLK:  11,    // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 9,     // The pin attached to the SD card's MOSI or DI input
                    CLR:  25,    // The pin attached to the counter's reset/clear pin
                    INC:  8,     // The pin attached to the counter's clock/count pin
                    ADDR: 5,     // The SD card's demux address (the counter's count)
                }
            }
        };
        mountParams = &params;
    #endif
    
    #ifdef PARALLEL_SPI /* This is a hypothetical example - modify to suit your needs */
        static _SD_Params params =
        {
            AttachmentType: _SDA_ParallelDeMUX,
            pins:
            {
                ParallelDeMUX:
                {
                    MISO: 4,    // The pin attached to the SD card's MISO or DO output
                    CLK:  5,    // The pin attached to the SD card's CLK or SCLK input
                    MOSI: 6,    // The pin attached to the SD card's MOSI or DI input
                    CS:   0,    // The pin attached to the counter's reset/clear pin
                    SEL:  0x04, // The pin mask to set when selecting the SD card's deMUX address
                    MSK:  0x0E  // The pin mask for all pins attached to the deMUX address
                }
            }
        };
        mountParams = &params;
    #endif
    
    #define SD_IS_USING_SD_CACHE_DRIVER
    #if defined(__PROPELLER_XMMC__) && defined(SD_IS_USING_SD_CACHE_DRIVER)
        // Pass NULL as the params. In this case, we'll use the SD Cache driver.
        // Beware: This only works if you're running your program
        // cached off of the SD card (i.e. propeller-load -z).
        mountParams = 0;
    #endif
    
        if (mountParams == (_SD_Params*)-1)
        {
            printf("You must specify the SD paramters in the filetest.c\n");
            exit(1);
        }
    
        uint32_t mountErr = dfs_mount(mountParams);
        if (mountErr)
        {
            printf("Mount error: %d\n", mountErr);
            exit(1);
        }
    
        printf("done.\n\n");
    }
    
    void ManCat()
    {
        printf("cat - opens and displays contents of a file.\n");
        printf(" cat test1.txt\n"); 
    }
    
    void ManRm()
    {
        printf("rm - removes (erases) a file.\n");
        printf(" rm test1.txt\n");
    }
    
    void ManLs()
    {
        printf("ls - list files and directories.\n");
        printf("ls -l - list files with size and attributes.\n");
    }
    
    void ManLL()
    {
        printf("ll - list files with size and attributes.\n");
    }
    
    void ManEcho()
    {
        printf("echo - echos the command line arguments.\n");
        printf(" echo This is a line of text. Will display 'This is a line of text.'\n");
        printf(" echo This is a line of text. >> test1.txt\n");
        printf(" Will create the test1.txt file with 'This is a line of text' in the file.\n");
    }
    
    void ManCD()
    {
        printf("cd - change directory.\n");
        printf(" cd .. - change to root directory.\n");
    }
    
    void ManMkdir()
    {
        printf("mkdir - create a directory.\n");
        printf(" mkdir test - creates directory 'test'.\n");
    }
    
    void ManRmdir()
    {
        printf("rmdir - remove a directory.\n");
        printf(" rmdir test - removes the directory 'test'.\n");
    }
    
    void ManMisc()
    {
        printf("File redirection - '<, >, <<, >>'\n");
    }
    

    Regarding unmount and format: The c3files demo fits into the LMM memory space, but just barely. When I made the recent changes to the SD driver, I wasn't supposed to break that. Getting everything to work with SDHC and getting the directory code to conform to standards ate away almost all the breathing room. There may be no room for unmount in LMM. Therefore, this feature may not appear until we can reconcile the size of the code with the need to support LMM in the c3files test. I'll look into it though.

    Format is a bit more involved, definitely won't fit in LMM, but I agree that it is definitely something to think about.

    - Ted
  • denominatordenominator Posts: 242
    edited 2012-04-12 09:42
    Rsadeika wrote: »
    I just tried your suggestion, and it did not make it any better, does not work as expected. I think there might be an inconsistency in the mount() or SD file code as it pertains to accessing the uSD card reader on the GG PPUSB board. I did not try a propboe board, since I do not have one.

    I also noticed for the 'cat' command, if you type in 'cat' and hit return, it locks up the program. It needs a 'cat' command with a parameter. I did not try the 'echo' command yet, but it might have the same problem.

    Ray

    Ray,

    These commands act like UNIX commands. For example, if you type "cat" without any arguments, it just reads from the terminal and echos it back until it hits EOF (i.e. you type <Ctrl>-D).

    This is meant to allow you to copy files or create new ones, for example:

    >cat foo > bar
    >cat > bar
    Hello this is a test
    <Ctrl>-D
    >

    The stock echo in your test worked fine for me; notice the use of cat to view the file:

    >echo foo
    foo
    > echo foo > foo.foo
    > cat foo
    foo
    >

    Again, this all worked fine with the code you previously posted (and with the #define SD_IS_USING_SD_CACHE_DRIVER, because I ran this compiled with the XMMC Memory Model and with the C3F-SDXMMC board config).

    - Ted
  • denominatordenominator Posts: 242
    edited 2012-04-12 09:51
    Rsadeika wrote: »
    The 'echo' command is OK, I changed the i=0 to i=1, in the first for loop, that took care of the problem. This could use some better command error trapping.

    Ray

    Notice the "if (i == 0)" statement in the for loop; that block handles the case of "cat" with no arguments. If you use the original code, this works:

    >cat
    Hello
    Hello
    <Ctrl>-D
    >

    With your changes it no longer works. Not that it matters much, because using "cat" to just echo what you type is mostly a curiosity. But I mention this just so you know that the test's author didn't have a bug - he purposefully made the command act like UNIX's cat.

    - Ted
  • pinedustpinedust Posts: 19
    edited 2012-04-12 11:12
    jazzed wrote: »
    @pinedust,

    The 0-6-3 debian-64 package and subsequent 0-6-4 SimpleIDE update that you downloaded should work.

    Does your SD card work with fsrw or kye's SD code?
    The SD card must be formatted as "FAT type" that is FAT16 for 2G or FAT32 for 4G+ cards.

    You might consider reformatting the SD Card. However it seems like connection is bad in this case.
    Everything is now working... mostly. I am not sure what is happening, but sometimes the SD card (cheap Kingston 2GB) gets locked, hung, or something? I have to remove it and put it back in to clear it and get things working again.

    Not a problem unless I have my board in a case.
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 11:47
    Everything is now working... mostly. I am not sure what is happening, but sometimes the SD card (cheap Kingston 2GB) gets locked, hung, or something? I have to remove it and put it back in to clear it and get things working again.

    I just got my GG PPUSB board up and running, I noticed the same thing, as you describe, was happening to me. The uSD card that I used was working perfectly on the C3 board. I am starting to suspect that maybe it is the card reader on the GG board that is the problem. I am using a Microcenter uSD card, that is on the cheap side.

    Ray
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-12 12:21
    I changed back the revision I made to the 'cat' command, as Ted explained it, now I know what it is supposed to do. I added the explanation to the ManCat() file.

    For my ManMisc() file I need a good explanation for how the redirection works. I tried 'echo This is >> test1.txt', it created a test1.txt file and inserted 'This is', but so did the use of just '>', what is the difference? Now I am wondering if you use something like test1.txt << echo this is', would you get the same results?

    Also I noticed there is a 'pwd' command, not sure what this is. If it is a way of producing a password, interesting, but how would that work?

    Ray
  • denominatordenominator Posts: 242
    edited 2012-04-12 12:42
    Rsadeika wrote: »
    I changed back the revision I made to the 'cat' command, as Ted explained it, now I know what it is supposed to do. I added the explanation to the ManCat() file.

    For my ManMisc() file I need a good explanation for how the redirection works. I tried 'echo This is >> test1.txt', it created a test1.txt file and inserted 'This is', but so did the use of just '>', what is the difference? Now I am wondering if you use something like test1.txt << echo this is', would you get the same results?

    Also I noticed there is a 'pwd' command, not sure what this is. If it is a way of producing a password, interesting, but how would that work?

    Ray

    pwd = print working directory
    > says direct the output into the file, deleting the old file if it exists
    >> says direct the output into the file, appending to any previous file that may exist.

    So:

    >echo foo > bar
    >cat bar
    foo
    >echo foo > bar
    >cat bar
    foo
    >echo foo >> bar
    >cat bar
    foo
    foo
    >echo foo > bar
    >cat bar
    foo
    >
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-04-12 15:26
    Ray.

    filetest.c was developed to test out the file driver in PropGCC. I used the "software tool" approach, where I wrote simple functions that could be combined together to do some basic testing. The software tools along with the basic redirection operators provide a flexible and compact program that could fit in 32K in the LMM mode. I like what you've done with PropCS. It's looking good. As Steve suggested, you might want to name your *.h files to *.c to conform with normal C practice. Of course, it works fine the way you have it also. BTW, there is no << redirection operator. There is only <, > and >>.

    If you have access to a Linux machine or a Windows machine with Cygwin you might try out the commands to see how they work there. If you don't have access to either one you could download Spinix and try it our on a Prop. I've added quite a few Linux-like features to it.

    Dave
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-14 06:20
    Below is another version of PropCS, which has a problem that I can not figure out. I am trying to add a PPUSB in the mount() function, using SimpleIDE, when I compile I get an error: redefinition of 'params'. This 'params' seems to appear in the other board definitions, but only becomes a problem when I add the PPUSB code.

    I also tried to move the printf.c code into PropCS_uni.c, having the notion that if I use an '#ifdef __PROPELLER_LMM__' for control , I would not have to remember to have printf.c added to compile when using LMM mode. The problem here is, that when I compile, it comes up with a not enough memory error. The question I have is, why does it not come up with a memory error when it is compiled with the PropCS_Uni.c and printf.c?

    Ray
  • denominatordenominator Posts: 242
    edited 2012-04-14 06:58
    Rsadeika wrote: »
    Below is another version of PropCS, which has a problem that I can not figure out. I am trying to add a PPUSB in the mount() function, using SimpleIDE, when I compile I get an error: redefinition of 'params'. This 'params' seems to appear in the other board definitions, but only becomes a problem when I add the PPUSB code.

    Ray,

    This error occurred because you have two blocks that say #ifdef PPUSB: one at line 395, and one at line 476. And, you also have a #define C3_CARD at line 455. Therefore, you are triply-defining params!

    The solution is to change "#ifdef PPUSB //PARALLEL_SPI" on line 476 back to "#ifdef PARALLEL_SPI", remove the #define at line 455 (or comment it out), and fix the #ifdef PPUSB block at line 395 to be appropriate for the board you're working with.
    Rsadeika wrote: »
    I also tried to move the printf.c code into PropCS_uni.c, having the notion that if I use an '#ifdef __PROPELLER_LMM__' for control , I would not have to remember to have printf.c added to compile when using LMM mode. The problem here is, that when I compile, it comes up with a not enough memory error. The question I have is, why does it not come up with a memory error when it is compiled with the PropCS_Uni.c and printf.c?

    You most likely get the "not enough memory" error because your #ifdef isn't correct, the C compiler isn't seeing your code, and therefore is linking in the standard printf(), which is much bigger than the code in printf.c.

    Try this... put the following code at line 20 of your PropCS_Uni.c:
    #ifdef __PROPELLER_LMM__
    #include "printf.c"
    #endif
    

    If you compile, all is well. Then, change #ifdef __PROPELLER_LMM__ in some subtle way, for example, change LMM to MMM, or delete one of the underscore characters. You'll get the memory error.

    The reason is "#ifdef" says "if defined". Nothing makes sure the symbol is in the symbol table - if it's not defined, that block of code is just ignored.

    When debugging #ifdef problems, it is often useful to look at the preprocessor's output. If you include --save-temps (note the two dashes at the start) in your command line, you should see a PropCS_Uni.i file in your project directory. You can then look to see what the preprocessor did, and can fix any problems you find.

    - Ted
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-14 12:02
    I just tried the 'Send file to target SD card:' , which compiled, and made an autorun.pex file which I specified to be put on the SD card. When I hit the reset button, nothing happened, I was expecting a program to start and run. I tried the 'Burn' option which in fact worked, when I did a reset, it started up a program. So, I am not sure if I missed a step when I did 'Send file to target SD card:', or what?

    Now that I have this relatively large program that I can start off of an SD card, what do I have to do to be able to have it run on a personal terminal screen? I think the last time I tried using pins 31,30 for accessing a personal terminal screen, it was running into problems. Has this been taken care of, or there never was a problem to begin with?

    The other thing that I am thinking about is running small programs that would be located on the SD card, which I would call from within a program. For instance, in my PropCS program I would have a command 'GetIt', the actual command code would be on the SD card, and would be accessed from within PropCS? Am I expecting to much?

    Ray
  • denominatordenominator Posts: 242
    edited 2012-04-14 12:19
    Rsadeika wrote: »
    I just tried the 'Send file to target SD card:' , which compiled, and made an autorun.pex file which I specified to be put on the SD card. When I hit the reset button, nothing happened, I was expecting a program to start and run. I tried the 'Burn' option which in fact worked, when I did a reset, it started up a program. So, I am not sure if I missed a step when I did 'Send file to target SD card:', or what?

    Ray,

    You didn't make a mistake. In order to run your program from the SD card, you need a program called the SD Cache Loader. When you send to SD card, the loader sends a program into Propeller RAM via the Propeller's built-in boot loader. That program is called the Serial Helper. The loader and the Serial Helper then communicate; the loader sends up your program for placement on the SD card, and the Serial Helper does the actual writing. Then, the loader resets the Propeller and sends yet a new program up in the Propeller RAM (again via the Propeller's built-in boot loader) - this program is called the SD Cache Loader. The loader then tells that program to run.

    The SD Cache Loader looks at the SD card, finds AUTORUN.PEX, caches the sector map for the entire program, loads the XMMC kernel and the SD Cache Driver, and then hands over control to the kernel. At this point, your program is running, but nothing was written to the EEPROM!

    When you select "Burn", the loader in its last step, send the SD Cache Loader to the Propeller, sends it to both RAM and EEPROM. That way when you reset the Propeller, the SD Cache Loader lives again and can refind your AUTORUN.PEX and re-run it.

    Interestingly, if you take the SD card out at this point, insert it into a PC, change AUTORUN.PEX to a different program, reinsert it into your Prop board and reset it, then the new program would run. For the same reason, if you use Simple IDE to "Send file to target SD card" with a new program, then hit reset, your new program will run. This is because the magic SD Cache Loader is already in your Propeller's EEPROM.

    - Ted
  • denominatordenominator Posts: 242
    edited 2012-04-14 12:30
    Rsadeika wrote: »
    Now that I have this relatively large program that I can start off of an SD card, what do I have to do to be able to have it run on a personal terminal screen? I think the last time I tried using pins 31,30 for accessing a personal terminal screen, it was running into problems. Has this been taken care of, or there never was a problem to begin with?

    The other thing that I am thinking about is running small programs that would be located on the SD card, which I would call from within a program. For instance, in my PropCS program I would have a command 'GetIt', the actual command code would be on the SD card, and would be accessed from within PropCS? Am I expecting to much?

    Ray

    Ray,

    I'm not sure what you mean when you refer to "accessing a personal terminal screen".

    As far as loading programs using PropGCC, AFAIK, nobody has done this. However, it sounds like you are re-creating Dave Hein's Spinix (http://forums.parallax.com/showthread.php?123795-spinix) in C. His Spin code would be a great guide for this task, but beware the memory usage for Spin and PropGCC differ, so there are probably a few landmines you'll want to navigate around.

    - Ted
  • RsadeikaRsadeika Posts: 3,822
    edited 2012-04-14 14:41

    I'm not sure what you mean when you refer to "accessing a personal terminal screen".

    As far as loading programs using PropGCC, AFAIK, nobody has done this. However, it sounds like you are re-creating Dave Hein's Spinix (http://forums.parallax.com/showthread.php?123795-spinix) in C. His Spin code would be a great guide for this task, but beware the memory usage for Spin and PropGCC differ, so there are probably a few landmines you'll want to navigate around.

    - Ted

    Actually, I have not looked at Dave Hine's Spinix program, I want to keep an open mind about how I will be coding my small project. I am not sure about what you mean about "memory usage" differences.

    In the early days of PropGCC usage, I had a heck of a time trying to use pins 31,30 to communicate with a terminal program that is not the PropGCC terminal/SimpleIDE terminal. What I am thinking is, I have the C3 start up with PropCS, and on my computer I start a terminal program which is connected to the C3 with whatever port is available. In other words, communicating with the C3 without the use of SimpleIDE.

    When the PropCS is running in stand alone, it would be nice to be able to start up programs that are on the SD card, just to see if something like that can be done. I personally do not think that it can be done, but I thought I would present the idea. That way you could keep the PropCS code as small as possible, and still have the capability to expand the 'commands' list.

    The other idea that I had was trying to implement the UNIX '&' (background task?), so that means using pthreads, that is why I want to keep the PropCS code as small as possible. I am also staying away from thinking in terms of PropCS as a kernel, or an OS, just thinking that PropCS is some tight code that can run some specific commands.

    Ray
Sign In or Register to comment.