|
|
View previous topic :: View next topic |
Author |
Message |
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
const bit array problem |
Posted: Fri Mar 08, 2013 12:54 pm |
|
|
My assumption is that this should produce a string of "X.X.X.X.".
Code: |
void test()
{
const int1 klm[] = {1,0,1,0,1,0,1,0} ;
int i ;
for(i = 0 ; i < 8 ; i++) {
if(klm[i]) {
usb_cdc_putc('X') ;
} else {
usb_cdc_putc('.') ;
}
}
printf(usb_cdc_putc, "\r\n") ;
}
|
However I actualy get "XXXXXXXX"
Is there any reason I can't have a const bit array ?
The code works corretly if i change "int1 klm" to be "int8 klm"
The PIC is 18F27J53 and CCS PCH C Compiler, Version 4.133 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Fri Mar 08, 2013 1:33 pm |
|
|
There is a problem with int1 variables not automatically 'casting' in certain cases.
Now the behaviour of certain things changed with later compilers. Historically the test:
if(klm[i])
Translated as "if klm[i] does not equal zero". With an int1 you'd expect this to comfortably translate as true/false. However the ANSI test changed the meaning, and it now evaluates as "if klm[1] and 1 does not equal zero". Again you'd expect this to work, but in fact the int1 type mishandles this. If you explicitly cast the int1 to int8, it'll then work.
This has been reported to CCS, and they claim it will be fixed in the next release.
As a comment, you do realise how much code space this will use?. If you have several thousand bits needing storage, then worth doing, but for small arrays, the int8 code will be a lot smaller.
Best Wishes |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
|
Posted: Sat Mar 09, 2013 3:29 am |
|
|
I tried both casting and copying int1 to int8 and result the same. ie both of these don't work :
Code: |
void test()
{
const int1 klm[] = {1,0,1,0,1,0,1,0} ;
int i ;
for(i = 0 ; i < 8 ; i++) {
if((int8)klm[i]) {
usb_cdc_putc('X') ;
} else {
usb_cdc_putc('.') ;
}
}
printf(usb_cdc_putc, "\r\n") ;
}
|
Code: |
void test()
{
const int1 klm[] = {1,0,1,0,1,0,1,0} ;
int i ;
int8 x ;
for(i = 0 ; i < 8 ; i++) {
x = klm[i] ;
if(x) {
usb_cdc_putc('X') ;
} else {
usb_cdc_putc('.') ;
}
}
printf(usb_cdc_putc, "\r\n") ;
}
|
So given I am using V4.133 which is from about June 2012, and its not been fixed in the last half dozen or more updates, is it ever likely to be fixed now V5 is around the next corner
Its not then end of the world for my app as I am just using the 18F27J53 to develop some code on and then port it to a 16F886 (the ultimate target has used the ICD pins as outputs). I was using const bit array as substitue for not having EEPROM on the dev part. When the app gets ported to the 886 the bit arrays will be access from RAM after a copy from EEPROM. So it should all work there.
I did also tried changing "const" to "rom" but program got hugh and crashed somewhere in the wild blue yonder. So I quickly changed it back to const. |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
|
Posted: Sat Mar 09, 2013 3:54 am |
|
|
Ok I tried another test :
Code: | void test2()
{
const int1 klm[] = {1,0,1,0,1,0,1,0} ;
int1 cp[] = {1,0,1,0,1,0,1,0} ;
int i ;
int8 x ;
for(i = 0 ; i < 8 ; i++) {
x = klm[i] ;
printf(usb_cdc_putc, "%02x ", x) ;
}
printf(usb_cdc_putc, "\r\n") ;
for(i = 0 ; i < 8 ; i++) {
x = cp[i] ;
printf(usb_cdc_putc, "%02x ", x) ;
}
printf(usb_cdc_putc, "\r\n") ;
}
|
Result :
01 01 01 01 01 01 01 01
55 2a 95 4a a5 52 a9 54
So the const bit array can't work, code allways gives same result for each element of the array. For the RAM bit array bit 0 is as expected. ie if use x = cp[i] & 0x01 then should see 01 00 01 00 01 00 01 00. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Mar 09, 2013 5:02 am |
|
|
No, your are still having the same problem.
You have to force the actual test to be done on an int8, and use the correct logic. Currently all you are doing is effectively converting the result of the test to int8 The test is 'implicit' before you get as far as the cast.
So you need:
if((int8)klm[i]!=0)
It does work.
Best Wishes |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
|
Posted: Sat Mar 09, 2013 7:16 am |
|
|
Dear Ttelmah
Thanks for the explicit code but, Nope ! Still don't work that way either, unless I am being dense. When you say it works, have you tested it ? If so which version gave the correct result ?
I changed code as you suggested to be :
Code: | void test()
{
const int1 klm[] = {1,0,1,0,1,0,1,0} ;
int i ;
for(i = 0 ; i < 8 ; i++) {
if((int8)klm[i]!=0) {
usb_cdc_putc('X') ;
} else {
usb_cdc_putc('.') ;
}
}
printf(usb_cdc_putc, "\r\n") ;
}
|
Result is still XXXXXXXX
Here is the relavant list so you can compare to your output :
Code: | CCS PCH C Compiler, Version 4.133, 61227 09-Mar-13 13:02
.................... void test()
.................... {
.................... const int1 klm[] = {1,0,1,0,1,0,1,0} ;
.................... int i ;
....................
.................... for(i = 0 ; i < 8 ; i++) {
01306: MOVLB 1
01308: CLRF xC3
0130A: MOVF xC3,W
0130C: SUBLW 07
0130E: BNC 1360
.................... if((int8)klm[i]!=0) {
01310: CLRF xC5
01312: MOVFF 1C3,1C4
01316: MOVFF 1C3,00
0131A: RRCF 00,F
0131C: RRCF 00,F
0131E: RRCF 00,F
01320: MOVLW 1F
01322: ANDWF 00,F
01324: MOVF 00,W
01326: MOVLB 0
01328: CALL 0262
0132C: MOVWF 01
0132E: MOVLW 07
01330: ANDWF 00,F
01332: BCF FD8.0
01334: RLCF 01,F
01336: INCF 00,F
01338: BCF FD8.0
0133A: RRCF 01,F
0133C: DECFSZ 00,F
0133E: BRA 1338
01340: BTFSS 01.0
01342: BRA 1350
.................... usb_cdc_putc('X') ;
01344: MOVLW 58
01346: MOVLB 1
01348: MOVWF xC4
0134A: MOVLB 0
0134C: RCALL 12F2
.................... } else {
0134E: BRA 135A
.................... usb_cdc_putc('.') ;
01350: MOVLW 2E
01352: MOVLB 1
01354: MOVWF xC4
01356: MOVLB 0
01358: RCALL 12F2
.................... }
.................... }
0135A: MOVLB 1
0135C: INCF xC3,F
0135E: BRA 130A
.................... printf(usb_cdc_putc, "\r\n") ;
01360: MOVLW 0D
01362: MOVWF xC4
01364: MOVLB 0
01366: RCALL 12F2
01368: MOVLW 0A
0136A: MOVLB 1
0136C: MOVWF xC4
0136E: MOVLB 0
01370: RCALL 12F2
.................... }
01372: GOTO 1552 (RETURN) |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Mar 09, 2013 8:50 am |
|
|
I'd guess the problem is 4.133 then.
The nearest I have is 4.137, and on this it works. It also works on a couple of older versions, but wouldn't work on 4.118.
There are two separate 'issues' older compilers had problems with int1 arrays in general. It was a 'feature' that appeared around the late 4.0xx area, worked, then didn't, then worked again. Possible that 4.133 was one of the ones where it didn't....
The second issue is that on the latest few releases there are this peculiar type casting issue with some operations. It behaves as if the int1, is 'half way' to an int8. Certain operations seem to treat it as an int1, but others treat it as an int8, and in some cases maths is applied to the int8 'container', not to the required bit. This causes some major oddities like the result sometimes being different if you test:
Code: |
int8 test_val=1;
int1 bit1=0,bit=1;
if (test_val==bit)
//gives different results to:
if (bit==test_val)
|
In the former case, it sees that 'test_val' is an int8, decodes 'bit' and propagates this into a byte and tests. In the second, it compares the bytes and decides they are different.....
I've sent a 'suite' of demo test codes to CCS, covering about a dozen operations where variations on this oddity appears, and several weeks ago, they said they would be fixed. Perhaps this is one reason why 4.141 is so slow coming.....
Yes, I did test it in 4.137, and on this it merrily generates X.X.X.X.
Best Wishes |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
|
Posted: Sat Mar 09, 2013 9:05 am |
|
|
Dear Ttelmah
Thanks for testing this, atleast I know know its a compiler bug. However even paying for another maintenance update is not going to fully solve it for me. Makes sense to hold onto my money until I see a compiler update with load of bit array fixes. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Mar 09, 2013 9:39 am |
|
|
As a comment, you don't have the array access code there.
To see this, you need to 'rem' out the #nolist at the top of the processor include file. The call to 262, is the actual code to access the array element. The code divides to address required by 8 (the RRCF instructions), and then calls this function to read program memory. It then tests the bit in the returned value.
Best Wishes |
|
|
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
|
Posted: Sat Mar 09, 2013 10:53 am |
|
|
Dear Ttelmah
See list output below :
FYI, I also found to test for Non Zero in RAM bit arrays I need to use "if((int8)xyz[i]&1)"
Code: | .................... void test()
.................... {
.................... const int1 klm[] = {1,0,1,0,1,0,1,0} ;
.................... int i ;
....................
.................... for(i = 0 ; i < 8 ; i++) {
*
0190E: MOVLB 1
01910: CLRF xAA
01912: MOVF xAA,W
01914: SUBLW 07
01916: BNC 1968
.................... if((int8)klm[i]!=0) {
01918: CLRF xAC
0191A: MOVFF 1AA,1AB
0191E: MOVFF 1AA,00
01922: RRCF 00,F
01924: RRCF 00,F
01926: RRCF 00,F
01928: MOVLW 1F
0192A: ANDWF 00,F
0192C: MOVF 00,W
0192E: MOVLB 0
01930: CALL 02AA
01934: MOVWF 01
01936: MOVLW 07
01938: ANDWF 00,F
0193A: BCF FD8.0
0193C: RLCF 01,F
0193E: INCF 00,F
01940: BCF FD8.0
01942: RRCF 01,F
01944: DECFSZ 00,F
01946: BRA 1940
01948: BTFSS 01.0
0194A: BRA 1958
.................... usb_cdc_putc('X') ;
0194C: MOVLW 58
0194E: MOVLB 1
01950: MOVWF xC6
01952: MOVLB 0
01954: RCALL 1356
.................... } else {
01956: BRA 1962
.................... usb_cdc_putc('.') ;
01958: MOVLW 2E
0195A: MOVLB 1
0195C: MOVWF xC6
0195E: MOVLB 0
01960: RCALL 1356
.................... }
.................... }
01962: MOVLB 1
01964: INCF xAA,F
01966: BRA 1912
|
Code: |
002AA: CLRF FF7
002AC: ADDLW BE
002AE: MOVWF FF6
002B0: MOVLW 02
002B2: ADDWFC FF7,F
002B4: MOVLW 00
002B6: MOVWF FF8
002B8: TBLRD*+
002BA: MOVF FF5,W
002BC: RETURN 0
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 09, 2013 3:35 pm |
|
|
Ttelmah wrote: | Perhaps this is one reason why 4.141 is so slow coming..... | Did you notice v4.141 was released March 6? Quote: | Recent changes include:
4.141 Various chip specific built in functions fixes have been made
4.141 A problem on some chips with strings in #rom is fixed
4.141 A PIC24 problem with some bit arrays is fixed | Strange that bit array problems are mentioned for the PIC24 only, but we have seen before that the release notes are far from complete. As Ttelmah seems to have a complete test suite he can confirm the problems to be solved or not. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Mar 09, 2013 3:40 pm |
|
|
I wouldn't say 'complete', but 'medium comprehensive'....
I hadn't noticed it. I had looked a few days ago. Normally if you have a ticket 'lodged' they tell you. I'll do some gentle trying when I get a chance. The real question (as always), is what else goes wrong?.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 09, 2013 4:19 pm |
|
|
Instead of checking the website on a regular interval I've registered myself to be notified when a new compiler update is available (bottom right of the page is an option "Get email notifications for new versions"). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Mar 12, 2013 1:54 am |
|
|
I can confirm that 4.141, does correctly handle this. Now going to test some of the more complex problems I found.
It appears to be handling all the problems I had found.
Only problem is that as FvM has already pointed out, they may have broken some other bits.....
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|