CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Multiple Compilation Problem?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
TAMA25



Joined: 04 Dec 2022
Posts: 5

View user's profile Send private message

Multiple Compilation Problem?
PostPosted: Sun Dec 04, 2022 9:02 pm     Reply with quote

Compiler: PCWH 5.110
Device: PIC18F57Q84
Use PICKIT4 and No debugger.

I am testing multiple file compilations because I need them for work.

I found that it did not work properly (LEDs did not light up) with LINK, so I compiled it in C without LINK and found that it works.
I also found that it works even if I stop including string.h and stdlib.h.

Comparing the list with the problematic state, the code in the main function is quite different and I think this is the cause of the problem.
The problem seems to occur when I pass main.o with string.h and stdlib.h included to LINKER.
Why does this happen?

(Translated by Deepl. Sorry if some parts are hard to read.)

[ main.c ]
----------
#include <18F57Q84.h>

#device ADC=12
#fuses NOWDT,NOPROTECT,NOLVP
#use delay(clock=64000000, crystal=16000000)

#byte PORTA = 0x04CE
#byte PORTB = 0x04CF
#byte PORTC = 0x04D0
#byte PORTD = 0x04D1
#byte PORTE = 0x04D2
#byte PORTF = 0x04D3
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#use fast_io(F)

//#include <math.h>
//#include <stdlib.h>
#include <string.h>

void setup()
{
setup_oscillator(OSC_EXTOSC_PLL | OSC_CLK_DIV_BY_1 | OSC_PLL_ENABLED);
set_tris_a(0x30); // RA4,RA5 -input
set_tris_b(0x1f); // RB0-RB3 -input RB4 - CAN RX
set_tris_c(0x00);
set_tris_d(0xfd); // RD2-RD7 -input RD0 - SCI0 RX
set_tris_e(0x01); // RE0 -input
set_tris_f(0xf0); // RF4-RF7 -input
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
PORTF = 0;
}

void main( void ){
setup();
while(1) {
PORTC = PORTB;
}
}
----------

[ build.bat ]( make project.hex and main.hex )
----------
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +LN +STDOUT +EXPORT main.c
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +EA +STDOUT -EW +PE +LN LINK="project.hex=main.o"
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +LN +STDOUT main.c
----------

[ main.lst ](include string.h) -> work fine
----------
.................... void main( void ){
000A8: CLRF 4F8
000AA: BCF 4D6.5
000AC: BSF 507.7
000AE: CLRF xB0
000B0: CLRF xAF
000B2: CLRF xB3
000B4: CLRF xB1
000B6: MOVLW 20
000B8: MOVWF xAD
000BA: MOVLB 4
000BC: CLRF x00
000BE: CLRF x08
000C0: CLRF x10
000C2: CLRF x18
000C4: CLRF x20
000C6: CLRF x28
000C8: MOVLB 0
000CA: CLRF x71
000CC: CLRF x72
000CE: CLRF x73
000D0: CLRF x70
000D2: CLRF x75
000D4: CLRF x76
000D6: CLRF x77
000D8: CLRF x74
000DA: CLRF 51B
000DC: CLRF 51C
....................
.................... setup();
000DE: BRA 006E
....................
.................... while(1) {
.................... PORTC = PORTB;
000E0: MOVFF 4CF,4D0
000E4: BRA 00E0
.................... }
.................... }
000E6: SLEEP
----------

[ project.lst ](include string.h) -> Didnot work
----------
.................... void main( void ){
000A8: CLRF 4F8
000AA: BCF 4D6.5
000AC: BSF 507.7
000AE: CLRF xB0
000B0: CLRF xAF
000B2: CLRF xB3
000B4: CLRF xB1
000B6: MOVLW 20
000B8: MOVWF xAD
000BA: BRA 00C6
000BC: DATA 08,40
000BE: DATA 70,00
000C0: DATA 02,05
000C2: DATA 1B,00
000C4: DATA 00,00
000C6: MOVLW 00
000C8: MOVWF 4F8
000CA: MOVLW 00
000CC: MOVWF 4F7
000CE: MOVLW BC
000D0: MOVWF 4F6
000D2: TBLRD*+
000D4: MOVF 4F5,W
000D6: MOVWF 500
000D8: XORLW 00
000DA: BZ 0102
000DC: TBLRD*+
000DE: MOVF 4F5,W
000E0: MOVWF 501
000E2: BTFSC 4E8.7
000E4: BRA 00F0
000E6: ANDLW 3F
000E8: MOVWF 4EA
000EA: TBLRD*+
000EC: MOVFF 4F5,4E9
000F0: BTFSC 501.6
000F2: TBLRD*+
000F4: BTFSS 501.6
000F6: TBLRD*+
000F8: MOVFF 4F5,4EE
000FC: DCFSNZ 500,F
000FE: BRA 00D2
00100: BRA 00F4
00102: CLRF 4F8
....................
.................... setup();
00104: BRA 006E
....................
.................... while(1) {
.................... PORTC = PORTB;
00106: MOVFF 4CF,4D0
0010A: BRA 0106
.................... }
.................... }
....................
0010C: SLEEP
----------
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Dec 05, 2022 1:43 am     Reply with quote

Learn to use the code buttons...

The include files are not 'passed'.
What is passed in the MCU, is only the functions it is told to export. Nothing
else.
If a second file wants to use stdlib.h and string.h, then these have to be
included in _it's_ compilation.
Look at the example.
This shows how to export the functions from each section, and then how to
import these into a final master compilation.

The example is mcu.zip in the examples directory. Expand this and look
at how it is done.

Note importantly that _each_ part of the project has to include the 'master'
clock and fuse settings, and also any include files. #INCLUDE's like
stdlib and string, are _not_ exported in the built .o file.

You currently don't have anything putting the stuff together. Even though
you only have a single section, it still needs to have a final linking to
actually work.
TAMA25



Joined: 04 Dec 2022
Posts: 5

View user's profile Send private message

PostPosted: Mon Dec 05, 2022 3:45 am     Reply with quote

Thanks, mr.Ttelmah.

I'll be careful to use the code button.

Ttelmah wrote:
The example is mcu.zip in the examples directory. Expand this and look at how it is done.


I have checked the contents of mcu.zip and the CCS site description (http://www.ccsinfo.com/faq.php?page=multi_comp_units), and the first project I started writing had master clock, fuse, and settings in "project.h" and included them all source files. settings in "project.h" and included them all c-files. However, that did not work, so I created a test code with a minimal configuration of just main.c.
(I did this to verify the minimal configuration, although it is not necessary to use LINK since it is only in main.c. There is no indication that using LINK in a single o-file will cause problems.)

When I actually compiled the main.c shown above and checked the list file, I found that the implementation code for the functions included in string.h had been expanded to the main.c include location.
However, since the functions in string.h are not used in main.c and there is no other c file to integrate, no assembly code related to string.h is output in the list file. I believe this is correct.

However, only the assembly code at the beginning of the main function has increased as shown in the list file above, and the operation is not working properly.


I have additionally tried.

1. actually calling the strcmp function in main.c with the possibility that it is the code for resource initialization of the function in string.h

Result: the strcmp code developed in main.c is valid assembly code in the list file.
However, main.hex works, but project.hex does not.

2. #include the contents up to "string.h" into project.h and include it.

Result: No change.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Dec 05, 2022 7:21 am     Reply with quote

The point is you seem to be trying to build a single file project. Key in
MCU, is 'Multiple'. I don't think the linker supports building just one element.
You need to have multiple units, and link these together. I just tried a
copy of your project, but put setup, into a separate setup.c with a
setup.h. I then told the linker to link main.o, and setup.o
It merrily compiled (with string.h included), and linked, and in the
MPLAB sim, the resulting program ran.
TAMA25



Joined: 04 Dec 2022
Posts: 5

View user's profile Send private message

PostPosted: Mon Dec 05, 2022 8:53 pm     Reply with quote

In the course of multi-file testing, I discovered something.

project.h
Code:
#include <18F57Q84.h>

#device ADC=12
#fuses NOWDT,NOPROTECT,NOLVP
#use delay(clock=64000000, crystal=16000000)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#use fast_io(F)

#byte PORTA = 0x04CE
#byte PORTB = 0x04CF
#byte PORTC = 0x04D0
#byte PORTD = 0x04D1
#byte PORTE = 0x04D2
#byte PORTF = 0x04D3


setup.h
Code:
void setup();



setup.c
Code:
#include "project.h"
#include "setup.h"

void setup()
{
   setup_oscillator(OSC_EXTOSC_PLL | OSC_CLK_DIV_BY_1 | OSC_PLL_ENABLED);
   set_tris_a(0x30); // RA4,RA5 -input
   set_tris_b(0x1f); // RB0-RB3 -input RB4 - CAN RX
   set_tris_c(0x00);
   set_tris_d(0xfd); // RD2-RD7 -input RD0 - SCI0 RX
   set_tris_e(0x01); // RE0     -input
   set_tris_f(0xf0); // RF4-RF7 -input
   PORTA = 0;
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;
   PORTE = 0;
   PORTF = 0;
}


main.c

Code:
#include "project.h"
#include "setup.h"
void main( void ){

   setup();
   
   while(1) {
      PORTC = PORTB;
   }
}


When I compiled and linked this normally, it didn't work.

build.bat (not working)
Code:
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +LN +STDOUT +EXPORT setup.c
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +LN +STDOUT +EXPORT main.c
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +EA +STDOUT -EW +PE +LN LINK="project.hex=setup.o,main.o"


However, it worked when I turned off the optimization to try it out. (+Y0)

build.bat (work fine)
Code:
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +Y0 +LN +STDOUT +EXPORT setup.c
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +Y0 +LN +STDOUT +EXPORT main.c
"C:\Program Files (x86)\PICC\CCSC.exe" +FH +EA +STDOUT -EW +PE +LN LINK="project.hex=setup.o,main.o"


The following is a comparison of the listing files for the main function portion.

not working.
Code:
.................... void main( void ){
0003E:  CLRF   4F8
00040:  BCF    4D6.5
00042:  CLRF   xB0
00044:  CLRF   xAF
00046:  CLRF   xB3
00048:  CLRF   xB1
0004A:  MOVLW  20
0004C:  MOVWF  xAD
0004E:  BRA    0056
00050:  DATA 08,40
00052:  DATA 70,00
00054:  DATA 00,00
00056:  MOVLW  00
00058:  MOVWF  4F8
0005A:  MOVLW  00
0005C:  MOVWF  4F7
0005E:  MOVLW  50
00060:  MOVWF  4F6
00062:  TBLRD*+
00064:  MOVF   4F5,W
00066:  MOVWF  500
00068:  XORLW  00
0006A:  BZ    0092
0006C:  TBLRD*+
0006E:  MOVF   4F5,W
00070:  MOVWF  501
00072:  BTFSC  4E8.7
00074:  BRA    0080
00076:  ANDLW  3F
00078:  MOVWF  4EA
0007A:  TBLRD*+
0007C:  MOVFF  4F5,4E9
00080:  BTFSC  501.6
00082:  TBLRD*+
00084:  BTFSS  501.6
00086:  TBLRD*+
00088:  MOVFF  4F5,4EE
0008C:  DCFSNZ 500,F
0008E:  BRA    0062
00090:  BRA    0084
00092:  CLRF   4F8
....................
....................    setup();
00094:  BRA    0004
....................    
....................    while(1) {
....................       PORTC = PORTB;
00096:  MOVFF  4CF,4D0
0009A:  BRA    0096
....................    }
.................... }
....................
0009C:  SLEEP


works fine.
Code:
.................... void main( void ){
0003E:  CLRF   4F8
00040:  BCF    4D6.5
00042:  CLRF   xB0
00044:  CLRF   xAF
00046:  CLRF   xB3
00048:  CLRF   xB1
0004A:  MOVLW  20
0004C:  MOVWF  xAD
0004E:  MOVLW  00
00050:  MOVLB  3
00052:  MOVWF  xF8
00054:  MOVLW  00
00056:  MOVLB  4
00058:  MOVWF  x00
0005A:  MOVLW  00
0005C:  MOVWF  x08
0005E:  MOVLW  00
00060:  MOVWF  x10
00062:  MOVLW  00
00064:  MOVWF  x18
00066:  MOVLW  00
00068:  MOVWF  x20
0006A:  MOVLW  00
0006C:  MOVWF  x28
0006E:  MOVLB  0
00070:  CLRF   x71
00072:  CLRF   x72
00074:  CLRF   x73
00076:  CLRF   x70
00078:  CLRF   x75
0007A:  CLRF   x76
0007C:  CLRF   x77
0007E:  CLRF   x74
....................
....................    setup();
00080:  GOTO   0004
....................    
....................    while(1) {
....................       PORTC = PORTB;
00084:  MOVFF  4CF,4D0
00088:  GOTO   0084
....................    }
.................... }
....................
0008C:  SLEEP


When optimization is turned off, TBLRD and other instructions are missing, and the code is similar to that compiled from a C file alone.
(I thought it would have worked if I had not included string.h, but I could have been mistaken.)

Some models seem to have errata with the TBLRD instruction, but I do not know the cause, as it may simply be a compiler problem.
I tried to run it with MPLAB simulator, but I am not familiar with PIC itself and it did not go well.

I am not sure if the problem has been solved or not, but I would like to proceed with the verification without optimization for the time being.
Thank you for your help.
TAMA25



Joined: 04 Dec 2022
Posts: 5

View user's profile Send private message

PostPosted: Tue Dec 06, 2022 2:59 am     Reply with quote

This is the result of the verification by combining a total of 6 o-files, although it is still short of the desired scale.

Up to optimization level 8 (+Y8), TBLRD does not appear in the assembly code at the head of main() and seems to work.
When +Y9 is specified or not specified, TBLRD appears and it does not work.

It's a mystery.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Dec 06, 2022 6:12 am     Reply with quote

There was a problem with one particular maths operation and optimisation
with 5.105 (in the 'known issues' section of the forum). Your compiler should
have this fixed. However it is likely that something specific about your code
is triggering something similar.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Dec 06, 2022 8:10 am     Reply with quote

OK.
That is repeatable, and does it even with the latest compiler.
You need to report this to CCS, since it is obviously an issue on this
chip at least (on a much older chip it doesn't seem to be doing this), when
using MCU's.
Send them these examples and hopefully they will have a fix soon.
Meantime run with the optimisation turned down.
TAMA25



Joined: 04 Dec 2022
Posts: 5

View user's profile Send private message

PostPosted: Wed Dec 07, 2022 7:14 pm     Reply with quote

Thank you for the advice.

I just tried it with the latest version of the compiler (5.113),
and it outputs the same assembly code as 5.110,
and the result of running it is the same.

I have reported this to CCS.
I will post again if there is progress.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Thu Dec 08, 2022 2:52 am     Reply with quote

As I said "and does it even with the latest compiler".

Understand that MCU's with CCS, are really a bad idea. CCS was built as
a single pass compiler. Never designed to support linking. Working single
pass allows better optimisation, so most people never get involved with
trying to use MCU's. CCS added the capability a while ago, but for me it
has never worked 100%. Given how fast the compiler actually works,
compiling as a single entity, this is really the approach to use.
Now your phrasing at the start suggests that you have some specific need
for using MCU's. Difficult to really work out what this might be?.
Hopefully CCS will fix this issue for you, but do expect MCU's to still
have problems. They really are not the way to work with the CCS compiler.
BrianF



Joined: 12 Dec 2020
Posts: 10

View user's profile Send private message

PostPosted: Fri Feb 24, 2023 8:59 am     Reply with quote

Ttelmah wrote:

Understand that MCU's with CCS, are really a bad idea...They really are not the way to work with the CCS compiler.


That's an interesting observation.

I've been considering CCS for the last year or so as I really like the environment BUT not being able to reliably use multiple C files may well be a show stopper.

I've just looked at the commercial project I'm currently working on and it's 12 C files and 46,000 lines. My coding style is fairly relaxed so that's probably around 15,000 lines of code. I really can't see that working in a single file. OK, it will work but it'll not be fun to code.
gaugeguy



Joined: 05 Apr 2011
Posts: 286

View user's profile Send private message

PostPosted: Fri Feb 24, 2023 9:43 am     Reply with quote

Having multiple C files is quite normal and is not the same as MCU
newguy



Joined: 24 Jun 2004
Posts: 1899

View user's profile Send private message

PostPosted: Fri Feb 24, 2023 10:28 am     Reply with quote

BrianF wrote:
I've been considering CCS for the last year or so as I really like the environment BUT not being able to reliably use multiple C files may well be a show stopper.

I've just looked at the commercial project I'm currently working on and it's 12 C files and 46,000 lines. My coding style is fairly relaxed so that's probably around 15,000 lines of code. I really can't see that working in a single file. OK, it will work but it'll not be fun to code.


It's just a mindset. I cut my teeth using what is standard compiler - linker multiple object file style, then I migrated to CCS. I must admit that in the beginning, the "one big file" style proved to be a frustrating challenge. However, I've since come up with my own coding style which, when followed, doesn't present any obstacles to that approach.

The project I'm currently working on has 16 different files and many thousands of lines of code. In the past I've developed CCS projects comprising as many as 30+ files (can't remember the exact amount, but was somewhere around 32-34 if memory serves).

My standard approach is to go with a more-or-less standard CCS package which consists of the main project file.c and main project file.h. The header file includes the processor.h file, the fuses, pin select stuff, #use whatever stuff, and key things like #use fast_io.

The main project.c file is usually no more than 30 or so lines long. At the top I #include the project declarations.h, then follows the main function of the project. First 3 function calls are, in order: init processor, init globals, and finally init interrupts. Then into the program's while (TRUE) superloop. Inside that loop are typically 4 - 12 or so function calls.

The project declarations.h file carries all declarations (variables, structs, functions and #defines), or includes other header files where the division is appropriate. I place my function declarations near the end of this file, and right at the bottom I include the other .c files.

...Works for me, and I've found that CCS newbies can quite easily follow the flow.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Feb 24, 2023 11:15 am     Reply with quote

Dead right.
Your approach is pretty much what every one of the experienced users does.
Perhaps a file with the CPU setup, fuses & peripherals, then one with
global variables, then all the library includes, and then the files for each
section of the program (comms, memory, storage, different types of I/O,
etc. etc..). I often have a 'comments' file, included near the top, with details
of problems found with particular chips, and versions, with notes of what
changed. Also says what compiler was used. Makes coming 'back' to code
in many years time, vastly easier. Current project uses 3*DsPIC's, and the
code for each has perhaps 20 files. Compiles to just over 500KB of code
in total. One is handling a particular sensor, with a lot of nasty maths
(has to use logs and powers in the calculation of the polynomial to correct
the sensor). Second one handles the graphic display, and the main one
handles the user interface, storage, I/O, etc. etc..
jeremiah



Joined: 20 Jul 2010
Posts: 1314

View user's profile Send private message

PostPosted: Fri Feb 24, 2023 11:33 am     Reply with quote

BrianF wrote:
Ttelmah wrote:

Understand that MCU's with CCS, are really a bad idea...They really are not the way to work with the CCS compiler.


That's an interesting observation.

I've been considering CCS for the last year or so as I really like the environment BUT not being able to reliably use multiple C files may well be a show stopper.

I've just looked at the commercial project I'm currently working on and it's 12 C files and 46,000 lines. My coding style is fairly relaxed so that's probably around 15,000 lines of code. I really can't see that working in a single file. OK, it will work but it'll not be fun to code.


You don't literally put all the code in a single file, you just need to #include the other C files at the bottom of your main C file. It's technically single file compilation but you still use multiple C files. It just doesn't separately compile each C file this way.

Code:

#include <your_pic.h>
#fuses ...
#use delay(...)

#include "file1.h"
#include "file2.h"

void main void(){
   ...
}

#include "file1.c"
#include "file2.c"
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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