View previous topic :: View next topic |
Author |
Message |
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
Arrays of Booleans |
Posted: Thu Mar 21, 2013 2:59 am |
|
|
Hi friends,
In CCS C Compiler Reference Manual February 2011 I read page 43 (Basic ans Special Types) :
Arrays of bits (INT1=Boolean) in RAM are now supported. Pointers to bits are not permitted.
I have the following struct :
Code: | struct SFLS_Type
{
int length;
int defaut[32];
//boolean defaut[32]; // NOONNNNNN Surtout pas !
int Led_Verte[32];
//boolean Led_Verte[32];
int Led_Rouge[32];
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS; |
When I use int defaut[32] and modify the value of one of its members it works well
When I use boolean defaut[32] it changes the value of length, which is before
Question 1 : is it really supported ?
Question 2 Why modifying one bit of the first byte of defaut (which has 4 bytes I think) modify the value of byte length which I think is before defaut and not after it ?
Don't let me with this trouble.
Thanks to all |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Thu Mar 21, 2013 3:12 am |
|
|
What version compiler are you running?. What chip?
4.xxx?.
It was supported quite well for a while, then went wrong, with problems when you performed operations on the values, especially on chips like the PIC24's - sounds like what you are seeing, but most of these have been fixed on the latest release.
Best Wishes |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Thu Mar 21, 2013 3:53 am |
|
|
My PCH version is 4.119
My PIC is PIC18F2520
I thought that :
Byte 0 = length
Byte 1 = boolean defaut [0 to 7]
Byte 2 = boolean defaut [8 to 15]
Byte 3 = boolean defaut [16 to 23]
Byte 4 = boolean defaut [24 to 31]
Byte 5 = boolean Led_Verte [0 to 7]
etc ...
Last edited by Jean FOUGERON on Fri Mar 22, 2013 3:25 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Thu Mar 21, 2013 6:41 am |
|
|
No, compiler versions are always X.XXX.
If you mean 4.014, then this was a beta compiler (at best), and hasn't got a hope. Also almost certainly implies it is a rip off version. |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Fri Mar 22, 2013 1:02 am |
|
|
Sorry, 4.119 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Fri Mar 22, 2013 2:57 am |
|
|
OK. If the compiler is doing a calculation 'wrong', then the result can be anything!". I'd guess the boolean array is not correctly offsetting itself in the structure, and thinks it is starting a byte earlier.
Haven't got .119, but tried .118, and it definately gets things wrong here.
Generally, the compiler has always had problems with 'things inside things', incorrectly offsetting things like structures inside structures.
Tried some fiddling, and if you put the arrays as the first items in the structure, it handles the first one correctly, but then gets the second one wrong. Still does the same if you 'overload' the arrays with a union into int32 types as well.
It cannot handle an array of bits that starts at anything other than the first bit of a data structure.
This is still wrong in the current compiler, so report it.
Basically it handles the arrays fine, but not inside a structure... :(
Best Wishes |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
bit arrays in structs |
Posted: Sun Mar 24, 2013 8:12 am |
|
|
Just add some further evidence. I was about the post the following code which seems to fail for the same reason. i.e. If a bit array is used in a struct there can be problems. In my case simply putting an int into the struct before the bit array confuses the compiler. If I comment out my "int dummy" the program works correctly. Also if I pass my struct to my function using reference instead of pointer then it also works.
The difference is in my case is that I am using PCM v4.133. However the code was ported from PCH v4.133 using PIC18F27J53 where it worked correctly !!!
I would interested to know if this works in the latest release
This is my code :
Code: | #include <16f886.h>
#fuses INTRC_IO
#fuses NOWDT
#fuses PUT
#fuses MCLR
#fuses NOPROTECT
#fuses NOCPD
#fuses BROWNOUT_SW
#fuses NOLVP
#fuses BORV40
#use delay(clock=8000000)
#use rs232(baud=9600, UART1, errors)
#define OUTPUTS 36
typedef struct {
int dummy ; // Comment this and it works !!
int1 led[OUTPUTS];
} path ;
void PrintBa(int1 ba[], int sz)
{
int i ;
for(i = 0 ; i < sz ; i++) {
if((int8)ba[i]&1) {
putc('X') ;
} else {
putc('.') ;
}
}
printf("\r\n") ;
}
void SetPathOutputs(path *p)
{
int i ;
// Set the static bits
for(i = 0 ; i < OUTPUTS ; i++) {
if(i >= 0 && i < 5) {
p->led[i] = 1 ;
} else {
p->led[i] = 0 ;
}
}
}
void SetPathOutputs2(path &p)
{
int i ;
// Set the static bits
for(i = 0 ; i < OUTPUTS ; i++) {
if(i >= 0 && i < 5) {
p.led[i] = 1 ;
} else {
p.led[i] = 0 ;
}
}
}
void main()
{
path p ;
int i ;
setup_oscillator(OSC_8MHZ) ;
printf("\r\nStart\r\n") ;
// Default the outputs
for(i = 0 ; i < OUTPUTS ; i++)
p.led[i] = 0 ;
// This does'nt work
SetPathOutputs(&p) ;
PrintBa(&p.led, OUTPUTS) ;
// This does work
SetPathOutputs2(p) ;
PrintBa(&p.led, OUTPUTS) ;
for(;;) ;
}
|
The output :
Code: | Start
....................................
XXXXX...............................
|
|
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Sun Mar 24, 2013 11:45 am |
|
|
Just for completion's sake, try the pointer version using (*p).led[i] instead of p->led[i].
Just curious to see if all pointer based methods fail. |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
|
Posted: Mon Mar 25, 2013 3:07 am |
|
|
Well its no different if I replace with this :
Code: | void SetPathOutputs(path *p)
{
int i ;
// Set the static bits
for(i = 0 ; i < OUTPUTS ; i++) {
if(i >= 0 && i < 5) {
// p->led[i] = 1 ;
(*p).led[i] = 1 ;
} else {
// p->led[i] = 0 ;
(*p).led[i] = 0 ;
}
}
} |
ie. I still see this output :
Code: | Start
....................................
XXXXX...............................
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Mon Mar 25, 2013 3:24 am |
|
|
Yes, it is the actual 'core' address calculation that is done wrong. It doesn't handle offsetting one Boolean array above another. It does work OK, with a single array on it's own, or as the first item in a structure, but put a second in the same structure, and it immediately goes wrong....
The only place you can put a Boolean array in a structure is as the first element. Anywhere else, and things go wrong.
Best Wishes |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Mon Mar 25, 2013 3:53 am |
|
|
So if I relace
Code: | struct SFLS_Type
{
int length;
int defaut[32];
//boolean defaut[32]; // NOONNNNNN Surtout pas !
int Led_Verte[32];
//boolean Led_Verte[32];
int Led_Rouge[32];
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS; |
with
Code: | struct SFLS_Type
{
int defaut[32];
//boolean defaut[32]; // NOONNNNNN Surtout pas !
int Led_Verte[32];
//boolean Led_Verte[32];
int length;
int Led_Rouge[32];
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS; |
It could work |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Mon Mar 25, 2013 3:54 am |
|
|
So if I relace
Code: | struct SFLS_Type
{
int length;
int defaut[32];
int Led_Verte[32];
int Led_Rouge[32];
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS; |
with
Code: | struct SFLS_Type
{
boolean defaut[32];
boolean Led_Verte[32];
int length;
int Led_Rouge[32];
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS; |
It could work ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Mon Mar 25, 2013 4:09 am |
|
|
No.
The first array will work fine, but not the second.
If you combined them into one 64 element array, and just use your own 'offset' to access the second lot of data, then it'll work.
Worth realising you can do it by cheating massively:
Code: |
struct SFLS_Type
{
int32 Defaut;
int32 Led_Verte;
int length;
int Led_Rouge[32];
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS;
//and just use the bit_set, bit_clear, and bit_test operations, like:
#define led_status(LED_number) bit_test(Led_Verte,LED_number)
//So "if(Led_Verte[23]==TRUE)" becomes "if(led_status(23)==TRUE)"
|
A bodge, but it works.
Best Wishes |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Mon Mar 25, 2013 9:48 am |
|
|
Yes. Played again, and combined 3*32bit arrays into one array, as:
Code: |
//Apologies for bodging the names...
#define GREEN (32)
#define DEFAUT (0)
#define RED (64)
struct SFLS_Type
{
int1 all[96];
int length;
boolean Alarm;
boolean MA, MI, HI;
boolean Local;
Boolean Changed;
} SFLS;
//Then tested with
SFLS.Changed=SFLS.Local=TRUE;
SFLS.MA=SFLS.MI=SFLS.HI=FALSE;
for (count=0;count<32;count++) {
SFLS.all[count+RED]=TRUE;
SFLS.all[count+GREEN]=FALSE;
SFLS.all[count+DEFAUT]=TRUE;
}
for (count=0;count<32;count++) {
SFLS.all[count+RED]=FALSE;
SFLS.all[count+GREEN]=TRUE;
SFLS.all[count+DEFAUT]=FALSE;
}
SFLS.Changed=SFLS.Local=FALSE;
SFLS.MA=SFLS.MI=SFLS.HI=TRUE;
|
and every bit set/cleared, was the correct one.
So a single array at the start of the structure works OK.
Best Wishes |
|
|
|