MPLAB C Compiler for PIC18 MCUs is available as either a Standard Evaluation Edition or a full version. This Read Me file is the same in both.
For 60 days, the Standard Evaluation Edition of MPLAB C Compiler for PIC18 MCUs will function as the full version. After 60 days, the MPLAB C Compiler for PIC18 MCUs Standard Evaluation Edition differs from the full version in the following ways:
To purchase a full version of the MPLAB C Compiler for PIC18 MCUs, please contact your local distributor or visit http://www.microchip.com/c18.
Due to the elimination of the COD Format from MPASM ouput, and the use of COFF format instead, new flags have been added to COFF files that are generated by C18 v3.30 and MPASM v5.30. These flags are only recognized by MPLINK v4.30 and above. MPLINK v4.30 and above continue to recognized the old COFF files, however, earlier version of MPLINK may not recognized new COFF files.
This note is only applicable to programs with the following characteristics:
In the previous versions of the linker scripts (with the vectors region), no code or data was being placed between the High/Low-priority interrupt vectors. Consequently, with the arrival of a High-priority interrupt, the execution of the program would (erroneously) fall into the low-priority ISR. With the removal of the vectors region from the linker scripts, other data or code may be placed at the addresses between the High and Low priority interrupt vectors. This results in a non-deterministic behavior, upon the arrival of a high priority interrupt for these programs.
The changes to fix SSR 22612 in MPLAB C18 v3.06 affect programs
written without consideration of C language specifications
regarding the syntactic use of const
,
volatile
, rom
, ram
,
near
, and far
qualifiers for user
defined types using typedef
. An error or a warning
will be generated if the compiler detects such problems in code.
For example in the following code:
typedef char * cPtr_t; cPtr_t rom rompc; rom char romc; void f(void) { rompc = &romc; }
rompc
should be [rom pointer to ram char]
so MPLAB C18 v3.06 and later produce a warning indicating there is a
qualifier mismatch in assignment. Please note that this program
compiles with no warning in MPLAB C Compiler for PIC18 MCUs prior to
this fix because in
those versions, rompc
was incorrectly qualified as
[ram pointer to rom char]
. Since romc
was
in rom there was no mismatch in type and qualification for this
assignment in earlier versions of MPLAB C Compiler for PIC18 MCUs.
The qualifiers rom
, ram
,
near
, and far
are specific to MPLAB C
Compiler for PIC18 MCUs.
While different from const
and volatile
from a semantic point of view, they are parsed in the same syntactic
context, hence the above example is applicable to all qualifiers. (For
more information on the syntax of using qualifiers please refer to your
C programming language reference manual. For a description of
rom
, ram
, near
, and
far
qualifiers please refer to the "Storage Qualifiers"
section of the MPLAB C18 C Compiler User's Guide.)
Due to a change in COFF file format, MPLAB C18 v3.00 and later will not be compatible with versions of MPLINK Linker prior to v4.00 or versions of the MPLAB IDE prior to v7.21.
MPLAB C18 v3.00 and later will have backward compatibility to earlier versions at the source level only. Any existing object files or libraries compiled with earlier versions of the tools will not link using new versions of the tools. They will need to be recompiled from source.
If the user attempts to use this release with object files or libraries compiled with earlier versions of MPLAB C18, MPLINK Linker, and MPASM Assembler, the error message that will be received will be similar to:
Error - Coff file format for 'C:\mcc18\lib/c018i.o' is out of date.
If the user attempts to use an old version of MPLINK Linker to link object files or libraries compiled with this release, the error message that will be received will be similar to:
Error - Coff file format for 'C:\mcc18\lib/c018i.o' does not appear
to be a valid COFF file.
PIC18C242 PIC18C252 PIC18C442 PIC18C452 PIC18C601 PIC18C658 PIC18C801 PIC18C858 PIC18F1220 PIC18F1230 PIC18F1320 PIC18F1330 PIC18F13K22 PIC18F13K50 PIC18F14K22 PIC18F14K22LIN+ PIC18F14K50 PIC18F2220 PIC18F2221 PIC18F2320 PIC18F2321 PIC18F2331 PIC18F23K20 PIC18F23K22 PIC18F2410 PIC18F242 PIC18F2420 PIC18F2423 PIC18F2431 PIC18F2439 PIC18F2450 PIC18F2455 PIC18F2458 PIC18F248 PIC18F2480 PIC18F24J10 PIC18F24J11 PIC18F24J50 PIC18F24K20 PIC18F24K22 PIC18F2510 PIC18F2515 PIC18F252 PIC18F2520 PIC18F2523 PIC18F2525 PIC18F2539 PIC18F2550 PIC18F2553 PIC18F258 PIC18F2580 PIC18F2585 PIC18F25J10 PIC18F25J11 PIC18F25J50 PIC18F25K20 PIC18F25K22 PIC18F25K80 PIC18F2610 PIC18F2620 PIC18F2680 PIC18F2682 PIC18F2685 PIC18F26J11 PIC18F26J13 PIC18F26J50 PIC18F26J53 PIC18F26K20 PIC18F26K22 PIC18F26K80 PIC18F27J13 PIC18F27J53 PIC18F4220 PIC18F4221 PIC18F4320 PIC18F4321 PIC18F4331 PIC18F43K20 PIC18F43K22 PIC18F4410 PIC18F442 PIC18F4420 PIC18F4423 PIC18F4431 PIC18F4439 PIC18F4450 PIC18F4455 PIC18F4458 PIC18F448 PIC18F4480 PIC18F44J10 PIC18F44J11 PIC18F44J50 PIC18F44K20 PIC18F44K22 PIC18F4510 PIC18F4515 PIC18F452 PIC18F4520 PIC18F4523 PIC18F4525 PIC18F4539 PIC18F4550 PIC18F4553 PIC18F458 PIC18F4580 PIC18F4585 PIC18F45J10 PIC18F45J11 PIC18F45J50 PIC18F45K20 PIC18F45K22 PIC18F45K80 PIC18F4610 PIC18F4620 PIC18F4680 PIC18F4682 PIC18F4685 PIC18F46J11 PIC18F46J13 PIC18F46J50 PIC18F46J53 PIC18F46K20 PIC18F46K22 PIC18F46K80 PIC18F47J13 PIC18F47J53 PIC18F6310 PIC18F6390 PIC18F6393 PIC18F63J11 PIC18F63J90 PIC18F6410 PIC18F6490 PIC18F6493 PIC18F64J11 PIC18F64J90 PIC18F6520 PIC18F6525 PIC18F6527 PIC18F6585 PIC18F65J10 PIC18F65J11 PIC18F65J15 PIC18F65J50 PIC18F65J90 PIC18F65K22 PIC18F65K80 PIC18F65K90 PIC18F6620 PIC18F6621 PIC18F6622 PIC18F6627 PIC18F6628 PIC18F6680 PIC18F66J10 PIC18F66J11 PIC18F66J15 PIC18F66J16 PIC18F66J50 PIC18F66J55 PIC18F66J60 PIC18F66J65 PIC18F66J90 PIC18F66J93 PIC18F66J94*+ PIC18F66K22 PIC18F66K80 PIC18F66K90 PIC18F6720 PIC18F6722 PIC18F6723 PIC18F67J10 PIC18F67J11 PIC18F67J50 PIC18F67J60 PIC18F67J90 PIC18F67J93 PIC18F67J94*+ PIC18F67K22 PIC18F67K90 PIC18F8310 PIC18F8390 PIC18F8393 PIC18F83J11 PIC18F83J90 PIC18F8410 PIC18F8490 PIC18F8493 PIC18F84J11 PIC18F84J90 PIC18F8520 PIC18F8525 PIC18F8527 PIC18F8585 PIC18F85J10 PIC18F85J11 PIC18F85J15 PIC18F85J50 PIC18F85J90 PIC18F85K22 PIC18F85K90 PIC18F8620 PIC18F8621 PIC18F8622 PIC18F8627 PIC18F8628 PIC18F8680 PIC18F86J10 PIC18F86J11 PIC18F86J15 PIC18F86J16 PIC18F86J50 PIC18F86J55 PIC18F86J60 PIC18F86J65 PIC18F86J72 PIC18F86J90 PIC18F86J93 PIC18F86J94*+ PIC18F86K22 PIC18F86K90 PIC18F8720 PIC18F8722 PIC18F8723 PIC18F87J10 PIC18F87J11 PIC18F87J50 PIC18F87J60 PIC18F87J72 PIC18F87J90 PIC18F87J93 PIC18F87J94*+ PIC18F87K22 PIC18F87K90 PIC18F96J60 PIC18F96J65 PIC18F96J94*+ PIC18F97J60 PIC18F97J94*+ PIC18LF13K22 PIC18LF13K50 PIC18LF14K22 PIC18LF14K50 PIC18LF23K22 PIC18LF24J10 PIC18LF24J11 PIC18LF24J50 PIC18LF24K22 PIC18LF25J10 PIC18LF25J11 PIC18LF25J50 PIC18LF25K22 PIC18LF25K80 PIC18LF26J11 PIC18LF26J13 PIC18LF26J50 PIC18LF26J53 PIC18LF26K22 PIC18LF26K80 PIC18LF27J13 PIC18LF27J53 PIC18LF43K22 PIC18LF44J10 PIC18LF44J11 PIC18LF44J50 PIC18LF44K22 PIC18LF45J10 PIC18LF45J11 PIC18LF45J50 PIC18LF45K22 PIC18LF45K80 PIC18LF46J11 PIC18LF46J13 PIC18LF46J50 PIC18LF46J53 PIC18LF46K22 PIC18LF45K80 PIC18LF47J13 PIC18LF47J53 PIC18LF65K80 PIC18LF66K80 PICMCV20USB
*Note: Early adopter support has been added for these devices since last release
+Note: These devices DO NOT have peripheral library support.
THE PARTS LISTED ABOVE MAY NOT ALL BE COMMERCIALLY AVAILABLE.
The following files are associated with this release and can be found in the <install_dir>\doc directory.:
Documentation (in pdf format) is available from our web site: http://www.microchip.com/c18 however:
MPLAB C Compiler for PIC18 MCUs requires the use of MPLINK Linker; MPLAB C18 v3.00 or later will require MPLINK Linker v4.00 or later. The latest version of MPLINK Linker is included with the installation.
To verify correct installation of MPLAB C Compiler for PIC18 MCUs, execute the batch file <install_dir>\example\an696\buildit.bat. If the compiler system has been installed correctly, the file 18motor.out will be created.
When installing MPLAB C Compiler for PIC18 MCUs, the setup program offers the user the ability to change several environment settings. The following options are provided:
Environment Variables:
MPLAB IDE Configuration:
The options below only appear if the user has a version of MPLAB IDE
installed.
If MPLAB C18 is uninstalled, these changes to the IDE configuration
will not be rolled back.
If you have previously installed a Student, Demo, or Lite version of MPLAB C18 and you wish to upgrade your current installation, simply purchase and install the full Standard version - it will overwrite the other version. So, no license key is required.
See the document "MPLAB C18 C Compiler Getting Started Guide" for a step-by-step tutorial on using MPLAB C Compiler for PIC18 MCUs with the MPLAB IDE.
The current documentation is available from our web site, http://www.microchip.com/c18
NOTE: MPLAB C18 v3.00 and later will not be compatible with versions of the MPLAB IDE prior to v7.21.
The following are some of the known issues with MPLAB C18 v3.21. The first list presented, SSR SUMMARY, is a brief summary of each SSR, System Service Request, for ease of reference. For more details on an SSR, see that SSR in the list SSR DETAILS which follows.
signed char x; unsigned char y; ... x /= y;with:
signed char x; unsigned char y; ... x = x / y;-- The compound assignment remainder operator may return incorrect results when the right operand is greater than 8 bits in size. The workaround is to replace
unsigned char x; unsigned short y; ... x %= y;with:
unsigned char x; unsigned short y; ... x = x % y;
struct { void (*f) (static int x); } S; void main (void) { S.f (1); }
void main (void) { typedef int X; { struct Y { int X; }; (X)3; /* this should refer to the typedef name, * not the structure member */ } }The textually intervening declaration of 'X' as a structure member causes the typedef declaration of 'X' to be lost.
signed char x; x = 0x80; x >>= 7; /* 'x' should be -1, but is 1 instead */The integer promotions are not performed on 'x'.
rom short long x; void main (void) { short long y; x = 1025; y = x %= 2; /* 'x' correctly receives 1, but 'y' does not */ ...
unsigned long x[4]; void main (void) { ((void (*)(void))x)( ); }
Error - could not find definition of symbol '_foo:101' ...Such would be the error message if the function in question is called 'foo'.
const rom char x; char *p; void main (void) { p = &x; ... }A diagnostic should be generated. The effect of referencing through 'p' following the assignment is indeterminate.
struct s { int x; } S; void main (void) { struct s; /* this introduces a new type, hiding the previous */ struct s *Sp = &S; /* this is an incompatible assignment */ Sp->x++; /* invalid access of an incomplete type */ ...The inner declaration of 'struct s' introduces a new (incomplete) type, which is different than the first 'struct s'. However, the above program compiles quietly. The structure tag is not redefined.
char *s = "hello world";Any references through 's' will result in indeterminate behavior.
struct foo { int a; }; struct foo { char b; }; struct foo F;compiles quietly without error. The variable 'F' takes on the type of the second declaration.
struct s { unsigned long x; char y; } S, T; void main (void) { char b; unsigned long z; ... z = (b ? S : T).x; ...generates such an error. The workaround is to use an 'if' statement instead of the conditional operator.
volatile unsigned char uc_test; uc_test = 80; uc_test *= 0.7; /* Expected: 56, Actual: 0*/A workaround to this is to write the last statement as:
uc_test = uc_test * 0.7;
typedef unsigned short long foo; typedef unsigned char foo; typedef unsigned short foo; typedef unsigned int foo; typedef unsigned long foo; typedef double foo; typedef long double foo; typedef struct { ... } foo; typedef union foo { ... } foo;It should cause the compiler to emit errors such as:
test.c:3: error: conflicting types for `foo' test.c:2: error: previous declaration of `foo'
#pragma romdata constscn=0x2000 rom const unsigned char var; #pragma romdata rom const unsigned char *varptr = &var + 0x8000;The above code gives the following relocation entries:
Relocation: r_vaddr=0x00000000, r_symndx=2, r_offset=-32768, r_type=4 Relocation: r_vaddr=0x00000001, r_symndx=2, r_offset=-32768, r_type=3 Relocation: r_vaddr=0x00000002, r_symndx=2, r_offset=-32768, r_type=21Note that the r_offset field reflects an offset of -32k instead of +32k.
void foo( void ) { varptr = &var; varptr += 0x8000; }
void foo(const rom far char * FullPath, char *Path, char *FileName) { char *NameStart; char *s; if ((NameStart > FullPath + 1) && (*(Path - 1) == '\\')) return; }results in:
Fatal [100] - internal - unable to reduce treeThe problem is caused by comparing the address of a pointer located on the stack (i.e. ram) with one located in rom. This is not a valid comparison and should result in an error.
typedef struct { int b; } typeB; const typeB objB; void fB_type( ) { objB.b = 1; }does not generate an error.
struct { unsigned char aaa; volatile unsigned char bbb; } flags;the volatile qualifier on the second member of the struct 'flags' is ignored.
struct { unsigned char aaa; volatile unsigned char bbb; } volatile flags;
struct { unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b4:1; } Test; char Signal (void) { while(1); return 1; } volatile unsigned char testval; void main (void) { Test.b1 = 1; Test.b2 = 1; Test.b3 = 1; Test.b4 = 1; testval = Test.b1 + Test.b2 + Test.b3; /* Expected false, Actual true */ if (Test.b1 + Test.b2 + Test.b3 == 1) /* line 26 */ Signal(); /* Expected false, Actual false */ if (Test.b1 + Test.b2 + Test.b3 == 2) Signal(); /* Expected false, Actual false */ if (!(Test.b1 + Test.b2 + Test.b3 - 1)) Signal(); while(1); }the first 'if' statement incorrectly evaluates to TRUE. The related generated code is
mcc18 -s test.c -O- ... 43( 26): movlb high( Test ) 44( 26): movf Test, 0, 1 45( 26): andlw 1 46( 26): addwf __tmp_0, 0, 0 47( 26): addwf __tmp_0 + 1, 0, 0 48( 26): bz 1 // <--- Why compare with zero? 49( 26): rcall Signal, 0The workaround for this SSR is to cast the left hand side of the comparison to (unsigned char) as following
if ((unsigned char) Test.b1 + Test.b2 + Test.b3 == 1) /* line 26 */ signal()
BUILDING EXTENDED MODE LIBRARIES Building startup modules... Installing startup modules... Building library modules... ...math module... ...standard C library module... C:\MCC18\src\extended\stdclib\vfprintf.c:268:Warning [2066] type qualifier mismatch in assignment ...delay module... Installing library...The code shows
/* Change this to near (or omit altogether) if building small memory model * versions of the libraries */ #define MEM_MODEL near /** @name strlenpgm * The {\bf strlenpgm} function performs a {\bf strlen} where {\bf s} * points to program memory. * @param s pointer to object in program memory */ sizerom_t strlenpgm (auto const MEM_MODEL rom char *s);vfprintf.c
int vfprintf (auto FILE *handle, auto const rom char *f, auto va_list ap) { unsigned char c; int count = 0; for (c = *f; c; c = *++f) { if (c == '%') { unsigned char flags = 0; unsigned char width = 0; unsigned char precision = 0; unsigned char have_precision = 0; unsigned char size = 0; unsigned char space_cnt; unsigned char cval; unsigned long larg; far rom char *romstring; /* ... Removed code ... */ case 'S': if (size == _FMT_SHLONG) romstring = va_arg (ap, rom far char *); else romstring = (far rom char*)va_arg (ap, rom near char *); n = strlenpgm (romstring); /* line 268 */Passing a far pointer to a function expecting a near pointer should be ok, but our library should really build without warnings.
char* pdromU8; const char cdromU8; void funct (void) { pdromU8 = &cdromU8; /* Expect warning */ }the compiler should emit a qualifier-mismatch warning because the 'const' is lost.
int add( int a, int b ) { int c; c = a + b; return c; }Compiled with:
mcc18 test.c -scoThen placed in an archive containing only this file:
mplib -c test.lib test.oMPLIB librarian is unable to list the files in the archive.
mplib -t test.libGives the error:
Error - Coff file 'test.o' could not read string table. Error - Could not build member 'test.o' in library file 'test.lib'.Trying to use such an archive with MPLINK Linker also gives an error saying it could not read the string table.
#include <p18f452.h> void assignlocals( void ) { auto char a, b; _asm // correctly assigns TMR0L to variable 'a' movlw a movff TMR0L, PLUSW2 // DOES NOT correctly assign TMR0L to variable 'b' movff TMR0L, b _endasm }The compiler should give an error (or at least a warning) on the use of variable 'b' in a direct mode addressing instruction, but it instead generates code as if the offset were an absolute address.
void main (void) { int x; f (arg1, arg2, arg3); // macro call ... x++; // breakpoint may not function correctly here ...A breakpoint set on a line following such a macro call may not work correctly. MPLAB IDE may state that such a breakpoint cannot be set.
void main (void) { int x; f (arg1,\ arg2,\ arg3); ... x++;
#define STR(a) NXSTR(a) #define NXSTR(a) #a void foo (void) { // Apply "merging" operator #define CAT(a, b) NXCAT(a, b) #define NXCAT(a, b) a ## b // The two tokens '1.' and 'E9' should be merged into a single token // before the stringization operator is applied. STR(CAT (1., E9)); }Preprocesses to:
"CAT (1., E9)" ;but it should produce:
"1.E9" ;
#define x (4 + y) #define y (2 * x) void main (void) { y; }causes the preprocessor to run indefinitely.
#pragma romdata CONFIG _CONFIG_DECL (_OSCS_OFF_1H & _OSC_HSPLL_1H, // comments _PWRT_ON_2L & _BOR_OFF_2L & _BORV_42_2L, // comments 0, _CCP2MUX_OFF_3H, ...Another example:
#include <p18f8720.h> #pragma romdata CONFIG _CONFIG_DECL (_CONFIG1H_DEFAULT, _CONFIG2L_DEFAULT, _CONFIG2H_DEFAULT, _CONFIG3L_DEFAULT, _CONFIG3H_DEFAULT, _CONFIG4L_DEFAULT, _CONFIG5L_DEFAULT, _CONFIG5H_DEFAULT, _CONFIG6L_DEFAULT, _CONFIG6H_DEFAULT, _CONFIG7L_DEFAULT, _CONFIG7H_DEFAULT //12 ); #pragma romdataThe workaround is to not have comments inside a macro call.
#define FOSC 1800 #error "FOSC is 1800"Preprocessor command line:
cpp18 preproc-1.cPreprocessor output:
#line 1 "preproc-1.c" #line 2 "preproc-1.c" preproc-1.c:2: "1800 is 1800"
... /* no #if here */ #elif defined (_FOO_) #endif
#if defined(x) int y = x;But this does not:
#define x 2 #if defined(x) int y = x;Both should give syntax errors since the #endif is missing.
#ifdef foo #if 12/foo #endif #endif ...Will generate a divide by zero error from the preprocessor, but should not since the expression shouldn't be evaluated.
#define _BAR_ #if defined(_FOO_) #error "_FOO_ defined" #elsif defined(_BAR_) #error "_BAR_ defined" #else #error "Neither defined" #endifwill print "Neither defined" since "#elsif" is not a valid preprocessor directive. Although it should be "#elif" no error or warning is given about the typo.
#define symbol #if symbol /* end of file */causes the preprocessor to crash.
void main(void) { #define f g #define g f f(1); }causes the preprocessor to hang for a long time, then give an error similar to:
Preprocessor Error : out of dynamic memory in yy_scan_buffer
float a, c; char b[] = ".15625"; void main ( ) { a = atof (b); c = .15625; }The representation of 'c' is 0x7c200000 and 'a' is 0x7c1fffff.
Microchip gratefully acknowledges the contributions of the following to the development of MPLAB C Compiler for PIC18 MCUs.
Daniel Madill, Quanser Consulting --
December 2000, Optimizations to fixed point divide library routines.