 |
|
 |
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
- Version Concerned
M3T-CC32R V.4.00 Release 1
- 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.
- 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;
}
------------------------------------------------------------------------
- Schedule of Fixing the Problem
We plan to fix this problem in our next release of the product.
|
 |