Tool News
 
 
 

Tool News

Products Info
Downloads
Tools FAQs
MAEC TOOL NEWS: MAECT-M3T-CC32R-021201D

A Note on Cross-Tool Kit
M3T-CC32R V4.00 Release 1

Please take note of the following problem in using cross-tool kit M3T-CC32R V.4.00 Release 1 for the M32R family of MCUs:
  • On accessing an area declared to be volatile more than once


  1. Version Concerned
    M3T-CC32R V.4.00 Release 1

  2. Description
    When a member of a structure qualified as volatile or an area that is qualified as volatile and pointed to by a pointer is accessed more than once, the volatile type qualifier may become ineffective.
    2.1 Conditions
    This problem may occur if the following four conditions are satisfied:
    (1)An optimizing option covering -O4's function is used (any of the following options is selected: -O4, -O5, -O6, -O7, -Otime only, or -Ospace only) at compilation.
    (2)Any of the following is accessed:
    (a)Any member of a structure that satisfies the following two conditions:
    (i) It is a member of a structure except its first member and is qualified as volatile.
    (ii) The whole structure described in (i) is not qualified as volatile.
    (b)An area of type volatile pointed to by such a pointer with an offset as (*ptr+1).
    (c)An area of type volatile pointed to by such an array of pointers as ptr[0].
    Note that this condition is met only when the variable ptr is declared to be a pointer; not an array.
    (3)Any of the member and areas described in (2) is accessed more than once within the same function.
    (4)None of the following operations is performed during more than one access in (3) above:
    (a) writing to any member or area in (2)
    (b) writing to any area using a pointer
    (c) calling any function

    2.2 Examples
    [1. Source file sample1.c]
    ------------------------------------------------------------------------
    typedef struct {
        int a;
        volatile int b;                   /* Condition (2)-(a)-(i) */
    } DATA1;
    DATA1 data1;                          /* Condition (2)-(a)-(ii) */
    
    void
    foo1(void)
    {
        int tmp;
        tmp = data1.b;                    /* Conditions (3) and (4) */
        if (tmp) {
            while (data1.b != 2)          /* Conditions (3) and (4) */
                ;
        } else {
            while (data1.b != 5)          /* Conditions(3) and (4) */
                ;
        }
    }
    ------------------------------------------------------------------------
    
    [2. Source file sample2.c]
    ------------------------------------------------------------------------
    volatile int data2[100];
    volatile int *pdata2 = data2;         /* Condition (2)-(c) */
    
    int
    foo2(void)
    {
        int tmp;
    
        tmp = pdata2[1];            /* Conditions (2)-(c), (3), and (4) */
        if (tmp) {
            tmp = pdata2[1];        /* Conditions (2)-(c), (3), and (4) */
        }
        return tmp;
    }
    ------------------------------------------------------------------------
      
    [Examples of typing commands in M3T-CC32R (a % sign denotes a prompt):]
    ------------------------------------------------------------------------
    % cc32R -c -O4 sample1.c            ; Condition (1)
    % cc32R -c -O4 sample2.c            ; Condition (1)
    ------------------------------------------------------------------------
    When the above source files are compiled, data1.b in sample1.c and pdata2[1] in sample2.c are read out only once at the first time, and the reads-out at the second time and later are replaced by the first read-out. Such an operation is incorrect since the volatile qualifier is effective.

  3. Workaround
    This problem can be circumvented in any of the following three methods:
    (1) Access each area concerned using a pointer that can point to areas of type volatile.
    [Example 1.1: Modification of sample1.c]
    ------------------------------------------------------------------------
    typedef struct {
        int a;
        volatile int b;
    } DATA1;
    DATA1 data1;
    
    void
    foo1(void)
    {
        int tmp;
        volatile int *ptr = &data1.b; /* Provide a pointer to data1.b */
    
        tmp = *ptr;                   /* Replace data1.b by *ptr */
        if (tmp) {
            while (*ptr)              /* Replace data1.b by *ptr */
                ;
        } else {
            while (*ptr)              /* Replace data1.b by *ptr */
                ;
        }
    }
    ------------------------------------------------------------------------
    
    [Example 1.2: Modification of sample2.c]
    ------------------------------------------------------------------------
    volatile int data2[100];
    volatile int *pdata2 = data2;
    
    int
    foo2(void)
    {
        int tmp;
        volatile int *ptr = &pdata2[1]; /* Provide a pointer to pdata2[1] */
    
        tmp = *ptr;                     /* Replace pdata[2] by *ptr */
        if (tmp) {
            tmp = *ptr;                 /* Replace pdata[2] by *ptr */
        }
        return tmp;
    }
    ------------------------------------------------------------------------
    (2) Suppress optimization in the -O4 level.
    Optimization covering the -O4 option will be performed when optimizing option -04, -O5, -O6, -O7, -Otime only or -Ospace only has been selected. If you want to use -Otime or -Ospace, select any of these options, -O0, -O1, -O2, and -O3, at the same time.

    (3) Place an assignment statement using a dummy pointer.
    [Example 3.1: Modification of sample1.c]
    ------------------------------------------------------------------------
    typedef struct {
        int a;
        volatile int b;
    } DATA1;
    DATA1 data1;
    
    int dummy, *dummyaddr = &dummy;       /* A rewritable area */
    
    void
    foo1(void)
    {
        int tmp;
        int *dummyptr = dummyaddr;        /* Provide a pointer */
    
        tmp = data1.b;
        *dummyptr = 0;           /* Place an assignment using a pointer*/
        if (tmp) {
            while (data1.b)
                ;
        } else {
            while (data1.b)
                ;
        }
    }
    ------------------------------------------------------------------------
    
    [Example 3.2: Modification of sample2.c]
    ------------------------------------------------------------------------
    volatile int data2[100];
    volatile int *pdata2 = data2;
    
    int dummy, *dummyaddr = &dummy;       /* A rewritable area */
    
    int
    foo2(void)
    {
        int tmp;
        int *dummyptr = dummyaddr;        /* Provide a pointer */
    
        tmp = pdata2[1];
        *dummyptr = 0;           /* Place an assignment using a pointer */
        if (tmp) {
            tmp = pdata2[1];
        }
        return tmp;
    }
    ------------------------------------------------------------------------
  4. Schedule of Fixing the Problem
    We plan to fix this problem in our next release of the product.




© 2008. Renesas Technology Corp., All rights reserved. Privacy | Legal