While I have been using CCS (mostly PCH) for a while now, I never took the time to learn how to do it properly. The time has finally come. And what better place to learn than this forum. I am currently struggling with the following:

(1)
Is this (post by PCM Programmer) still the preferred way of adding source files? So not using MPLABX' directory tree in the project Explorer for anything other than the main source file and then using #include for all other source files?

(2)
About source and header files structure and organization... How and where to put what then? To be more concrete, if I have a main.c and main.h, I typically include the device header (e.g., 16F1829.h) into main.h. Then let's assume I have a module_A.c and corresponding module_A.h, which together implement a certain system functionality. With the approach proposed in the linked post above I get a "#DEVICE required before this line" error. Easily fixed by moving the device header out of main.h and into main.c or also including it in module_A.h. But do I then have to move everything, which is shared between main and module_A into a separate file and include it in main.c?

(3)
And then to even further complicate things, how to make proper use of the static keyword as an access specifier? If I use above described approach and get it to work, I cannot declare some functions as static in module_A and not have them accessible in main.c. In other words, any function I declare and define as static in Module_A is also accessible in main.c, despite one of the known usages of the keyword static being: "A static function -- a function declared as static at the top level of a source file (outside any class definitions) -- is only visible throughout that file ("file scope", also known as "internal linkage")."

Here, gribas points out that "The 'static' keyword isolates global variables from different compilation units." Perhaps that's the key. How then to make module_A a compilation unit? Does making proper use of the static keyword truly have to lead to use of multi-compilation units (something I think is briefly described here on page 10)?

I've looked into the #MODULE directive a bit to try and use it instead of or in combination with the static keyword but was not successful. If this is the only way to limit scope of my functions I would be grateful if someone could provide an example of how this is done.

Thank you in advance for any light you can shed on these matters.

RF_Developer

Joined: 07 Feb 2011Posts: 839

Posted: Tue Jan 30, 2018 9:56 am

This is my, admittedly limited, understanding of the situation: the CCS C tool chain does not support multiple compilation units in the MPLAB IDEs.

CCS C was originally, and for a long time single unit only. More recently, CCS projects can have multiple compilation units, but only with the CCS IDE, and even then they present some issues and consequently are rarely used. The nature and scale of most PIC projects is that single unit compilation, using multiple included source files is satisfactory. As there is no multiple compilation units, there is strictly speaking no need for header files at all, they are there primarily to support multiple unit compilation, but old habits die hard...

The interface into MPLAB is, by its very nature, limited, and you cannot expect full functionality from the CCS C compilers in a non-CCS environment. Again, old habits die hard, and seasoned MPLAB users will want, not totally unreasonably, to use their preferred IDE. One thing that the MPLAB/CCS C combo does not support is multiple compilation units. In that environment its strictly single unit only, as is still commonly found and generally preferred in the CCS IDE. Personally I always use the CCS IDE and find MPLAB clunky and inefficient, but that's just another old habit.

So, yes, as far as I am aware you must only add the main source to your MPLAB project and include all other source files from it. If you add other source files to MPLAB they will not compile, nor will the project as a whole.

As to organisation, that's a question of personal preference. You can put all declarations in headers just as you would do with MCUs, but you cannot control visibility, except by the order of inclusion. It is one big file, one compilation unit, end of story. No object files, no libraries, no linking to speak of. Static won't help. If it's encapsulation you're after, use C++ or some other language designed to provide it.

Porting code written for other compilers can present some organizational issues, especially if you are very familiar with the MPLAB paradigm.

temtronic

Joined: 01 Jul 2010Posts: 6462Location: Greensville,Ontario

Posted: Tue Jan 30, 2018 11:14 am

OK, I'm another 'dinosaur'..my 1st PCM was version 2.534 and to me PICs have ONE source not htis new fangle mulitple compilation units stuff.

...
device header
includes for fuses
includes for pinouts
includes for drivers
main
...

I now have an include file for fuses. These days PICs have more fuses than instructions, so the file contains every fuse. As I'm a lousy typist(dead finger doesn't help), once the file is created it's easy to include it. Far less typing involved. Also visually less space in the program.
The include for the pinouts is handy, again less typing for me and a visual record of what pin does what. Stuff like HW UART and I2C are often used so it makes sense to 'preconfigure' accordingly. There are basic 'templates' as well as 'project specific' files as required.

I have a 'base' program for say the 18F46K22. Flashes an LED. From that, I'll copy the source,saveas 'programname_v2' and edit that. Compile/test. Then copy v2, save as v3, compile/test. Yes I end up with a LOT of files on the HD BUT I can always go back to ANY previous version. Once the project is done, then I delete all but the last 3 or 4 versions.

Everyone has their style of coding, these are just some things that help me.
Jay

Ttelmah

Joined: 11 Mar 2010Posts: 13983

Posted: Tue Jan 30, 2018 11:35 am

MPLAB is perfectly happy to have the other source files put into the 'include files' tab.

The 'downside' of multiple compilation units, is that it reduces the overall efficiency of optimsation. With the single pass compile, the compiler can save RAM between sections of the code, and re-use it's own libraries.
The pluses are potentially a slight time saving (though in fact the compilation times often turn out worse), and the ability to load 'complete' modules, that have been tested independently.
There also seem at times to be slight 'issues' with using MCU's, and it does involve extra work. I've used it in some projects but always found myself going back to the single pass mode. Given just how fast the compiler is, it is honestly easier.

xMerlin

Joined: 30 Jan 2018Posts: 5

File inclusion into MPLABX project and use of static keyword

Posted: Tue Jan 30, 2018 1:19 pm

Thank you everyone!

If I understood you all properly then this is what I got out of this discussion so far:

(A)
While CCSC does support multiple compilation units, they are rarely needed (after all, if my understanding is correct, CCS only added the feature relatively recently), bring few benefits and are known to create extra work and problems. Additionally, support for MCUs is better in CCS’ native IDE than in MPLABX.

(B)
It is more typical to use a single compilation unit, in which case one must add all source files as includes into the main source file. And in MPLABX, only the main source file should be listed under “Source Files” in project explorer.

(C)
Static keyword has no effect as an access specifier in CCS C compiler, if not using multiple compilation units. In other words, since using a single compilation unit basically just makes everything one big file before compilation, one can not use the static keyword to limit a function’s or variable’s visibility to one physical file (assuming a project is made of more than one .c and -h files).

(D)
As for code organization, it’s of course a matter of personal preference. If anyone is willing, I would be happy to hear more personal practices like the ones Jay (temtronic) shared – thank you Jay! Do you use a lot of extern’s, globals, do you have the habit of fragmenting code into multiple source files based on functionality, do you do a lot of fragmenting when it comes to header files and in what way etc.

Thanks again for all the answers. And for the speed with which they were given. This is turning out to be a great forum so far, even though I’ve just made one post.

temtronic

Joined: 01 Jul 2010Posts: 6462Location: Greensville,Ontario

Posted: Tue Jan 30, 2018 4:08 pm

re: D::
I tend to think of a PIC as a single computer running a single program. I still have quartz windowed 16C71s here that need 15 minutes to erase, so, yeah I'm a fossil like them....
Peripherals like RTC,KPD,KBD,LCD will have their own drivers and get 'loaded' as include files. Since I use USB<>TTL modules I don't need USB support. That saves a lot of code space and headaches.
I've standardized on the 18F46K22. While overkill for most projects it does have 2 HW UARTs, 2 I2C,lots of memory and 40 pins ! I also use 4x20 LCDs now and have a 'bodge' to allow 5V LCDs (cheap) to run with 3V PICs.
Most external peripherals these days are 3 V devices, something you always need to remember. The 46K22 is happy to run full speed at 3V.

Jay

Ttelmah

Joined: 11 Mar 2010Posts: 13983

Posted: Wed Jan 31, 2018 1:46 am

Yes. It's also important to remember you don't have any 'OS' behind the scenes. The code you write is everything.

However as a 'contrary example', one place I've use MCU's very successfully, was in a system where I had a large protected bootloader, including some bulky/complex I/O libraries. These were built so that the 'main' code, could share these libraries by using MCU's.

asmallri

Joined: 12 Aug 2004Posts: 1560Location: Perth, Australia

Re: File inclusion into MPLABX project and use of static key

Posted: Tue Feb 13, 2018 6:10 pm

Quote:

.... Additionally, support for MCUs is better in CCS’ native IDE than in MPLABX.

Some other thoughts. I have the "full CCS package for windows" all compilers, debuggers etc despite this, I much prefer the Microchip MPLAB interface to the CCS-IDE because it (at the time) supported the full range of Microchip controllers including the PIC32 family.

Two significant changes came about, Microchip dropped MPLAB IDE for the completely brain dead and utterly useless MPLAB-X IDE. This gave Microchip a platform that could be easily supported by them across multiple development environments (windows, MAC, Linux) but simultaneously make the IDE brain dead and development more difficult for their customers. The next major change was the use of "Harmony Libraries for the PIC32 family" intended to simplify the development of applications for the PIC32 and eventually other PIC processor families however the number of processor and family specific #define directives made it a nightmare to make changes to the library, debug code and life-cycle management of the code.

So, when should you use MPLAB-X instead of CCS IDE listed in order or priority?
1. If you are developing for the PIC32
2. Never_________________Regards, Andrew

I generally use the mplabx IDE in two scenarios:
1. I am merging two designs into one new one
2. maintenance of an already developed project which requires referencing another project

The support for multiple projects is really useful for me in both areas and the interface for browsing both projects is clean.

That said, 90-95% of my development happens in the CCS IDE as it has many more quick and easy features (1 click ASM and SYM listings, 1 click FUSES lists, 1 click interrupt lists) and it doesn't have the slowness or display issues of MPLABX.

When I anticipate using MPLABX along side PCWHD, I setup my directory structure and MPLABX project in such a way that all I need to do to remove any trace of the MPLABX part is to delete a single directory, leaving the CCS needed stuff intact.