Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

0 Neutral

About BrownFrog

  • Rank

Contact Methods

  • Website URL
  • ICQ

Profile Information

  • Location
    Canberra, Australia
  1. Using IDE version: 6.70 Compiler: BoostC for PIC18 Compiler version: 6.70 Target device: PIC18F25J10 OS: Windows XP SP2 The += statement at the end of this code segment compiles incorrectly: #include <system.h> typedef struct _SOCKET_INFO { unsigned char smState; unsigned char TxBuffer; unsigned int TxCount; unsigned int RxCount; unsigned long SND_SEQ; unsigned SND_ACK; } SOCKET_INFO; SOCKET_INFO TCB[4]; void main(void) { SOCKET_INFO *ps; ps = &TCB[1]; // This statement compiles incorrectly ps->SND_SEQ += (unsigned long)ps->TxCount; } The assembler produced is: ps->SND_SEQ += (unsigned long)ps->TxCount; 000C 5032 MOVF main_1_ps+D'1', W 000E 6EEA MOVWF FSR0H 0010 5031 MOVF main_1_ps, W 0012 6EE9 MOVWF FSR0L 0014 0E06 MOVLW 0x06 0016 26E9 ADDWF FSR0L, F 0018 50EF MOVF INDF0, W 001A 6E37 MOVWF CompTempVar494 001C 50EC MOVF PREINC0, W 001E 6E38 MOVWF CompTempVar494+D'1' 0020 50EC MOVF PREINC0, W 0022 6E39 MOVWF CompTempVar494+D'2' 0024 50EC MOVF PREINC0, W 0026 6E3A MOVWF CompTempVar494+D'3' 0028 5032 MOVF main_1_ps+D'1', W 002A 6EEA MOVWF FSR0H 002C 5031 MOVF main_1_ps, W 002E 6EE9 MOVWF FSR0L 0030 0E02 MOVLW 0x02 0032 26E9 ADDWF FSR0L, F 0034 50EE MOVF POSTINC0, W 0036 6E33 MOVWF CompTempVar492 0038 50EF MOVF INDF0, W 003A 6E34 MOVWF CompTempVar492+D'1' 003C 6A35 CLRF CompTempVar492+D'2' 003E 6A36 CLRF CompTempVar492+D'3' 0040 5033 MOVF CompTempVar492, W 0042 2637 ADDWF CompTempVar494, F 0044 5034 MOVF CompTempVar492+D'1', W 0046 2238 ADDWFC CompTempVar494+D'1', F 0048 5035 MOVF CompTempVar492+D'2', W 004A 2239 ADDWFC CompTempVar494+D'2', F 004C 5036 MOVF CompTempVar492+D'3', W 004E 223A ADDWFC CompTempVar494+D'3', F 0050 5037 MOVF CompTempVar494, W 0052 06E9 DECF FSR0L, F 0054 06E9 DECF FSR0L, F 0056 06E9 DECF FSR0L, F 0058 6EEF MOVWF INDF0 005A 5038 MOVF CompTempVar494+D'1', W 005C 6EEC MOVWF PREINC0 005E 5039 MOVF CompTempVar494+D'2', W 0060 6EEC MOVWF PREINC0 0062 503A MOVF CompTempVar494+D'3', W 0064 6EEC MOVWF PREINC0 Note that TxCount is at offset 2 in the structure and SND_SEQ is at offset 6. The assembler code first loads the SND_SEQ member into CompTempVar494 then the TxCount member into CompTempVar492, correctly promoting the 16 bit int to a 32 bit long by clearing the two upper bytes. The 32 bit addition goes into CompTempVar494 and then this is written to the wrong location: the compiler is behaving as if the last location read was the destination of the +=, which it is not. Furthermore, because FSR0 has been incremented only once reading the 2 byte value TxCount, the adjustment of the FSR0 pointer back by 3 bytes means that the 32 bit result is written starting two bytes before the TxCount member, so the two char members smState and TxBuffer are clobbered as well as TxCount. Writing the += as an explict ps->SND_SEQ = ps->SND_SEQ + ps->TxCount produces code that looks correct. The += statement also seems to work if there is no promotion involved eg if we use ps->RxCount in place of ps->SND_SEQ (assembler does addition in-place). Cheers John
  2. OK, here is my third bug report on BoostC related to nested structures found in Microchip's TCP/IP code. The following code generates incorrect accesses to elements within the 'packet' object. #include <system.h> typedef unsigned char BYTE; typedef unsigned long DWORD; typedef union _IP_ADDR { BYTE v[4]; DWORD Val; } IP_ADDR; typedef struct _MAC_ADDR { BYTE v[6]; } MAC_ADDR; typedef struct _NODE_INFO { MAC_ADDR MACAddr; IP_ADDR IPAddr; } NODE_INFO; typedef struct _ARP_PACKET { MAC_ADDR TargetMACAddr; IP_ADDR TargetIPAddr; MAC_ADDR SenderMACAddr; IP_ADDR SenderIPAddr; } ARP_PACKET; void main(void) { ARP_PACKET packet; NODE_INFO *remote; /* This member copy ... */ remote->IPAddr = packet.SenderIPAddr; /* should do the same as the following but it uses the wrong offsets in packet. */ remote->IPAddr.v[0] = packet.SenderIPAddr.v[0]; remote->IPAddr.v[1] = packet.SenderIPAddr.v[1]; remote->IPAddr.v[2] = packet.SenderIPAddr.v[2]; remote->IPAddr.v[3] = packet.SenderIPAddr.v[3]; } The code the compiler produces as shown in the Code view window: /* This member copy ... */ remote->IPAddr = packet.SenderIPAddr; 0003 1383 BCF STATUS,IRP 0004 1283 BCF STATUS, RP0 0005 1303 BCF STATUS, RP1 0006 1835 BTFSC main_1_remote+D'1',0 0007 1783 BSF STATUS,IRP 0008 0834 MOVF main_1_remote, W 0009 0084 MOVWF FSR 000A 3006 MOVLW 0x06 000B 0784 ADDWF FSR, F 000C 0820 MOVF main_1_packet, W 000D 0080 MOVWF INDF 000E 0A84 INCF FSR, F 000F 0821 MOVF main_1_packet+D'1', W 0010 0080 MOVWF INDF 0011 0A84 INCF FSR, F 0012 0822 MOVF main_1_packet+D'2', W 0013 0080 MOVWF INDF 0014 0A84 INCF FSR, F 0015 0823 MOVF main_1_packet+D'3', W 0016 0080 MOVWF INDF /* should do the same as the following but it uses the wrong offsets in packet. */ remote->IPAddr.v[0] = packet.SenderIPAddr.v[0]; 0017 1383 BCF STATUS,IRP 0018 1835 BTFSC main_1_remote+D'1',0 0019 1783 BSF STATUS,IRP 001A 0834 MOVF main_1_remote, W 001B 0084 MOVWF FSR 001C 3006 MOVLW 0x06 001D 0784 ADDWF FSR, F 001E 0830 MOVF main_1_packet+D'16', W 001F 0080 MOVWF INDF remote->IPAddr.v[1] = packet.SenderIPAddr.v[1]; 0020 1383 BCF STATUS,IRP 0021 1835 BTFSC main_1_remote+D'1',0 0022 1783 BSF STATUS,IRP 0023 0834 MOVF main_1_remote, W 0024 0084 MOVWF FSR 0025 3006 MOVLW 0x06 0026 0784 ADDWF FSR, F 0027 0A84 INCF FSR, F 0028 0831 MOVF main_1_packet+D'17', W 0029 0080 MOVWF INDF remote->IPAddr.v[2] = packet.SenderIPAddr.v[2]; 002A 1383 BCF STATUS,IRP 002B 1835 BTFSC main_1_remote+D'1',0 002C 1783 BSF STATUS,IRP 002D 0834 MOVF main_1_remote, W 002E 0084 MOVWF FSR 002F 3006 MOVLW 0x06 0030 0784 ADDWF FSR, F 0031 3002 MOVLW 0x02 0032 0784 ADDWF FSR, F 0033 0832 MOVF main_1_packet+D'18', W 0034 0080 MOVWF INDF remote->IPAddr.v[3] = packet.SenderIPAddr.v[3]; 0035 1383 BCF STATUS,IRP 0036 1835 BTFSC main_1_remote+D'1',0 0037 1783 BSF STATUS,IRP 0038 0834 MOVF main_1_remote, W 0039 0084 MOVWF FSR 003A 3006 MOVLW 0x06 003B 0784 ADDWF FSR, F 003C 3003 MOVLW 0x03 003D 0784 ADDWF FSR, F 003E 0833 MOVF main_1_packet+D'19', W 003F 0080 MOVWF INDF Note that the code copying the 32 bit value as a single item accesses addresses 0 through 3 in the packet structure, while the explicit copying code accesses addresses 16 through 19 (the correct addresses). A pity really, because the 32 bit copy produces much better assembler! IDE version: 6.70 Compiler: BoostC Compiler version: 6.70 Target device: PIC18F25J10 OS: WinXP SP2 All the best John
  3. The following code crashes boostc.pic18 in versions 6.60 and 6.70: #include <system.h> #undef BYTE typedef unsigned char BYTE; // 8-bit typedef struct _MAC_ADDR { BYTE v[6]; } MAC_ADDR; typedef struct _NODE_INFO { MAC_ADDR MACAddr; } NODE_INFO; typedef enum _TCP_STATE { TCP_INVALID } TCP_STATE; typedef struct _SOCKET_INFO { TCP_STATE smState; NODE_INFO remote; } SOCKET_INFO; SOCKET_INFO test; void CrashMe(void) { SOCKET_INFO *ps; NODE_INFO *remote; ps = &test; remote = &ps->remote; return; } (This is a much-abridged fragment from Microchip TCP/IP stack - some of the struct nesting looks unnecessary because I've removed members not needed to trigger the crash). The compiler crashes, popping up an error window reporting "Error: Access violation at 0x004a93a9 (tried to write 0x00000064), program terminated", and the IDE Build window reports an exit code of -1073741819. The offending statement is the access to ps->remote - with that line commented out the code compiles fine. Swapping the order of the members inside the SOCKET_INFO struct removes the problem (although I've not tested the full code with this change). IDE version: 6.70 Compiler: BoostC Compiler version: 6.60, 6.70 Target device: PIC18F25J10 OS: WinXP SP2 Comments: The crash occurs when boostc.pic18 is invoked from the command line too. Cheers John
  4. I am pretty sure the ANSI C specification for preprocessor directives requires them to be lower case. I haven't been able to find a definitive statement that they are, but all examples and specifications show them as lower case, eg http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html Your uppercase version #IF is an unrecognised preprocessor directive, just like #BLAH would be, so the error message of "Illegal directive" seems correct. Maybe expanding the message to "Illegal preprocessor directive" would be marginally more descriptive, but I don't think there is anything wrong here. It is a common convention for the macros defined to be in uppercase (like BOOSTC - except it shoud be _BOOSTC), but not the directives themselves. Cheers John
  5. I think I've seen worse And I think I'm getting an understanding of the way the programmer thinks, and it is making sense to me now. I agree it could have been constructed more neatly. I'm making good progress, got DHCP and ARP working, now debugging ICMP ping before I move onto TCP sockets. My biggest worry is that once it is all working there will not be enough code space left for the application I have in mind. And I really could have done without compiler bugs (I've since found another that I'll report shortly), but SourceBoost is doing the job. I am planning on releasing the modified code once I have it under control, but I'm not sure what forum it should go to - any suggestions? Cheers John
  6. I've been trying to compile the Microchip TCP/IP stack for an Olimex PIC_MINI_WEB device, and after many syntax alterations to suit BoostC all the source files compile OK but I struck this error at link time: failure Error:Linking externs failed, mismatch of data types for variable:'AppConfig' I've traced the problem to a nested struct/union/struct (WORD_VAL). Here is code that triggers the problem: ----- test1.h ----- #include <system.h> typedef unsigned char BYTE; typedef unsigned short WORD; typedef union _WORD_VAL { WORD Val; struct { BYTE LSB; BYTE MSB; } byte; BYTE v[2]; } WORD_VAL; typedef struct _APP_CONFIG { WORD_VAL SerialNumber; BYTE Flags; } APP_CONFIG; #define bIsDHCPEnabled 0b00000001 void DoTest(void); ----- test1.c ----- #include "test1.h" APP_CONFIG AppConfig; void main(void) { DoTest(); } ----- test2.c ----- #include "test1.h" extern APP_CONFIG AppConfig; void DoTest(void) { if ( AppConfig.Flags & bIsDHCPEnabled ) { AppConfig.SerialNumber.Val = 0; } } Playing with the struct showed: - If SerialNumber is defined as WORD instead of WORD_VAL, and the .Val reference in test2. removed, the problem goes away. - If the struct { } byte; part of the WORD_VAL struct is removed the problem goes away. - Changing the names of elements of struct {} byte, eg LSB to lsbyte and byte to s_byte did not remove the problem. My workaround will be to remove the inner struct {} byte and change code to use the v array. I'm using : IDE version: 6.70 Compiler: BoostC for PIC18 Compiler version: 6.70 Target device: PIC18F25J10 OS: Windows XP SP2 As an aside, are there any tools available for inspecting BoostC object files? It would have been helpful when tracking this down to be able to see which of the object files had a type for AppConfig that was different to the others; and interesting to see what was different! Cheers John
  • Create New...