General Category > Discussion - Software

Vinculum II Toolchain (VinC) Issues Porting Code

(1/2) > >>

KTrenholm:
Hey all,

I'm working on a project to turn the VNC2 into essentially a bootloader host for a Cypress PSoC5LP.  The idea being to connect a USB flash drive to the system, read the firmware file, and bootload the MCU via the UART.

This would in theory not be too much trouble, as Cypress actually provides the C (I think GCC) code for a bootloader host for use in this exact kind of situation.  I figured porting the bootloader host wouldn't be too tall of an order.  However I am running into problems with VinC throwing some unexpected syntax errors.

First thing I noticed what was that the toolchain appears to have no stdint.h?  Since all the bootloader host code is written with standard types like uint8_t/uint16_t/uint32_t I just needed a few typedefs.  I included my own header file to provide the needed types and replaced the includes of stdint.h with my own little "int.h":


--- Code: ---#ifndef _INT_H_
#define _INT_H_

typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;

#endif

--- End code ---

No problems so far, I get a few warnings for mismatched widths/signs on certain calls but I can resolve those easily enough.
The real weirdness starts with the C1000 errors I'm getting:
..\cybootloaderutils\cybtldr_api.c line 401: (error) C1000 syntax error, unexpected TYPE_NAME
..\cybootloaderutils\cybtldr_api.c line 423: (error) C1000 syntax error, unexpected TYPE_NAME
..\cybootloaderutils\cybtldr_api.c line 456: (error) C1000 syntax error, unexpected TYPE_NAME


I'm not sure where these are cropping up from.  Here's the function with the call that causes the first C1000 error:

--- Code: ---int CyBtldr_ProgramRow_v1(uint32_t address, uint8_t* buf, uint16_t size)
{
    const int TRANSFER_HEADER_SIZE = 15;

    uint8_t inBuf[MAX_COMMAND_SIZE];
    uint8_t outBuf[MAX_COMMAND_SIZE];
    uint32_t inSize;
    uint32_t outSize;
    uint16_t offset = 0;
    uint16_t subBufSize;
    uint8_t status = CYRET_SUCCESS;
    int err = CYRET_SUCCESS;

    uint32_t chksum = CyBtldr_ComputeChecksum32bit(buf, size);

    if (CYRET_SUCCESS == err)
        err = SendData(buf, size, &offset, (uint16_t)(g_comm->MaxTransferSize - TRANSFER_HEADER_SIZE), inBuf, outBuf);

    if (CYRET_SUCCESS == err)
    {
        subBufSize = (uint16_t)(size - offset);

        err = CyBtldr_CreateProgramDataCmd(address, chksum, &buf[offset], subBufSize, inBuf, &inSize, &outSize);    //401 - C1000 syntax error: unexpected TYPE NAME
        if (CYRET_SUCCESS == err)
            err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
        if (CYRET_SUCCESS == err)
            err = CyBtldr_ParseDefaultCmdResult(outBuf, outSize, &status);
        if (CYRET_SUCCESS != status)
            err = status | CYRET_ERR_BTLDR_MASK;
    }

    return err;
}

--- End code ---

The code for the function in question is here:

--- Code: ---int CyBtldr_CreateProgramDataCmd(uint32_t address, uint32_t chksum, uint8_t* buf, uint16_t size, uint8_t* cmdBuf, uint32_t* cmdSize, uint32_t* resSize)
{
    const uint16_t COMMAND_DATA_SIZE = 8;
    uint16_t i;
    *resSize = BASE_CMD_SIZE;
    *cmdSize = BASE_CMD_SIZE + COMMAND_DATA_SIZE + size;

    fillData32(cmdBuf + 4, address);
    fillData32(cmdBuf + 8, chksum);
    for (i = 0; i < size; i++)
        cmdBuf[i + 4 + COMMAND_DATA_SIZE] = buf[i];
    return  CreateCmd(cmdBuf, *cmdSize, CMD_PROGRAM_DATA);
}

--- End code ---


I'm kind of at a loss as to where an unexpected TYPE_NAME could be coming up.  If it was an issue with my typedefs, I'd think this error would be cropping up in many more places.

Here are the other places this error is thrown:

--- Code: ---int CyBtldr_EraseRow_v1(uint32_t address)
{
    uint8_t inBuf[MAX_COMMAND_SIZE];
    uint8_t outBuf[MAX_COMMAND_SIZE];
    uint32_t inSize = 0;
    uint32_t outSize = 0;
    uint8_t status = CYRET_SUCCESS;
    int err = CYRET_SUCCESS;

    if (CYRET_SUCCESS == err)
        err = CyBtldr_CreateEraseDataCmd(address, inBuf, &inSize, &outSize);    //423 - C1000 syntax error: unexpected TYPE NAME
    if (CYRET_SUCCESS == err)
        err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
    if (CYRET_SUCCESS == err)
        err = CyBtldr_ParseEraseRowCmdResult(outBuf, outSize, &status);
    if (CYRET_SUCCESS != status)
        err = status | CYRET_ERR_BTLDR_MASK;

    return err;
}


int CyBtldr_VerifyRow_v1(uint32_t address, uint8_t* buf, uint16_t size)
{
    const int TRANSFER_HEADER_SIZE = 15;

    uint8_t inBuf[MAX_COMMAND_SIZE];
    uint8_t outBuf[MAX_COMMAND_SIZE];
    uint32_t inSize;
    uint32_t outSize;
    uint16_t offset = 0;
    uint16_t subBufSize;
    uint8_t status = CYRET_SUCCESS;
    int err = CYRET_SUCCESS;

    uint32_t chksum = CyBtldr_ComputeChecksum32bit(buf, size);

    if (CYRET_SUCCESS == err)
        err = SendData(buf, size, &offset, (uint16_t)(g_comm->MaxTransferSize - TRANSFER_HEADER_SIZE), inBuf, outBuf);

    if (CYRET_SUCCESS == err)
    {
        subBufSize = (uint16_t)(size - offset);

        err = CyBtldr_CreateVerifyDataCmd(address, chksum, &buf[offset], subBufSize, inBuf, &inSize, &outSize);    //456 - C1000 syntax error: unexpected TYPE NAME
        if (CYRET_SUCCESS == err)
            err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
        if (CYRET_SUCCESS == err)
            err = CyBtldr_ParseDefaultCmdResult(outBuf, outSize, &status);
        if (CYRET_SUCCESS != status)
            err = status | CYRET_ERR_BTLDR_MASK;
    }

    return err;
}

--- End code ---

Might anyone have an idea as to why this specific error is being thrown (or how to resolve it)?

FTDI Community:
Hello,

Please try renaming the variable from "address" to anything else.


--- Code: ---typedef signed char                           int8_t;

int t2(int8_t address)
{
    return  0;
}

int t1()
{
                int8_t paramt1;

                t2(paramt1);    //401 - C1406
               
                return 0;
}
--- End code ---

Both of these work:

int t2(int8_t badress)

int t2(int8_t baddress)

Best Regards,
FTDI Community

KTrenholm:
Indeed, changed "address" to "addr" and it cleared it right up.  I would expect the editor in the IDE to color it like a type if it was reserved by the toolchain in some way.  Time to do a whole lot of find/replace, as you can imagine for a bootloader, the name address is everywhere.

I don't know if I would have ever considered the name "address" being the problem!
Thanks for the tip!

(P.S. There is no mention of "address" being a reserved word/type in AN151 - Vinculum-II User's Guide, at least not that I could find.  Worth noting this does not seem to be documented anywhere)

I also found something else weird.  VinC will not compile this CRC32 table:

--- Code: ---
    enum {
        g0 = 0x82F63B78,
        g1 = (g0 >> 1) & 0x7fffffff,
        g2 = (g0 >> 2) & 0x3fffffff,
        g3 = (g0 >> 3) & 0x1fffffff,
    };

    static const uint32_t table[16] =
    {
        0,                  (uint32_t)g3,           (uint32_t)g2,           (uint32_t)(g2^g3),
        (uint32_t)g1,       (uint32_t)(g1^g3),      (uint32_t)(g1^g2),      (uint32_t)(g1^g2^g3),
        (uint32_t)g0,       (uint32_t)(g0^g3),      (uint32_t)(g0^g2),      (uint32_t)(g0^g2^g3),
        (uint32_t)(g0^g1),  (uint32_t)(g0^g1^g3),   (uint32_t)(g0^g1^g2),   (uint32_t)(g0^g1^g2^g3),
    };

--- End code ---

This throws (error) C2001 expression not constant for every element in that table that isn't 0 or g0.  All elements in the table should be calculable at compile-time (ARM-GCC and MSVC++ have no problems).  At the end of the day I can calculate these all out in another compiler or even just through a programmers calculator and put the constants into my VNC2 project.  Still, kind of a pain.

EDIT: found this in the Toolchain ReadMe, sounds like what I was running into:

--- Quote ---Restrictions:
- Floating point not supported.
- Structs and unions may not be passed to or returned from a function. Pointers to structs and unions are allowed.
- Vacuous declarations of structures and unions is not supported.
- Structure and union assignments not supported.
- Anonymous aggregates, unnamed members in unions, are not supported.
- Compound literals expressions are not supported.
- Modulus operations treat signed values as unsigned values. Do not use with negative values.
--- End quote ---
I'd imagine those table entries are "Compound literal expressions"?

KTrenholm:
So here's a question regarding the stdio library.  I need to use fgets() which is noted in stdio.h as "To Be Added".  So let's put one in.  The fgets() implementation I'm using makes use of fgetc(), which is implemented in stdio.  However I can't find a reference for the EOF return value?  I need to check for EOF on the fgetc() call.  I know normally (in most implementations at least?) EOF == -1, but I'm not about to take that as gospel just because that's how it works in GCC, as the C standard says it can be implementation defined.  Would anyone be able to confirm what fgetc() returns when the end of file is encountered?  Is the FAT_EOF enum what I should be using?
[EDIT] I was able to rather than use the return value of fgetc() with any kind of EOF value use the feof() function to determine end of file and it seems to work

Oh, and a new bit of fun, I had to also put an implementation of strcspn() in, and the compiler does not much care for assigning pointers in the declaration:

--- Code: ---static size_t strcspn(const char * s1, const char * s2){
    char *s = s1;    //Error C2808 illegal use of pointer
    char *c;

    while (*s1)
    {
        for (c = s2; *c; c++)
{
    if (*s1 == *c)
        break;
}

        if (*c)
    break;
s1++;
    }

    return s1 - s;

}

--- End code ---

moving the assignment after the declaration clears it up:

--- Code: ---static size_t strcspn(const char * s1, const char * s2){
    char *s;   
    char *c;

    *s = s1;    //No Errors Thrown!

    while (*s1)
    {
        for (c = s2; *c; c++)
        {
            if (*s1 == *c)
    break;
        }

        if (*c)
    break;
        s1++;
    }

    return s1 - s;

}

--- End code ---

FTDI Community:
Unfortunately the compiler doesn't do all constant initialisation which you might expect on other compilers.

If the values are expressed as constants without typecasting then it will compile.

   
--- Code: ---enum {
        g0 = 0x82F63B78,
        g1 = (g0 >> 1) & 0x7fffffff,
        g2 = (g0 >> 2) & 0x3fffffff,
        g3 = (g0 >> 3) & 0x1fffffff,
    };
                               
    static const int table[16] =
    {
        0,                  g3,           g2,          (g2^g3),
     g1,       (g1^g3),      (g1^g2),      (g1^g2^g3),
        g0,       (g0^g3),      (g0^g2),      (g0^g2^g3),
        (g0^g1),  (g0^g1^g3),   (g0^g1^g2),   (g0^g1^g2^g3),
   };
--- End code ---

I’ve not checked the values in the code though. They are precompiled (in decimal) to the following values according to the ASM output file:

0, 274646895, 549293790, 820201905, 1098587580, 1361435347, 1640403810, 1905808397, -2097792136, -1834419177, -1572096602, -1307217207, -1014159676, -741088853, -483350502, -210866315

Best Regards,
FTDI Community

Navigation

[0] Message Index

[#] Next page

Go to full version