Академический Документы
Профессиональный Документы
Культура Документы
• Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the
intended manner and under normal conditions.
• There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our
knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip’s Data
Sheets. Most likely, the person doing so is engaged in theft of intellectual property.
• Microchip is willing to work with the customer who is concerned about the integrity of their code.
• Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not
mean that we are guaranteeing the product as “unbreakable.”
Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our
products. Attempts to break Microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts
allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act.
Table of Contents
Preface ........................................................................................................................... 5
Chapter 1. Compiler Overview
1.1 Introduction ................................................................................................... 11
1.2 Compiler Description and Documentation .................................................... 11
1.3 Device Description ....................................................................................... 12
Chapter 2. How To’s
2.1 Introduction ................................................................................................... 13
2.2 Installing and Activating the Compiler .......................................................... 13
2.3 Invoking the Compiler ................................................................................... 15
2.4 Writing Source Code .................................................................................... 17
2.5 Getting My Application to Do What I Want ................................................... 28
2.6 Understanding the Compilation Process ...................................................... 33
2.7 Fixing Code That Does Not Work ................................................................. 41
Chapter 3. XC8-CC Command-line Driver
3.1 Introduction ................................................................................................... 45
3.2 Invoking the Compiler ................................................................................... 46
3.3 The Compilation Sequence .......................................................................... 48
3.4 Runtime Files ............................................................................................... 51
3.5 Compiler Output ........................................................................................... 52
3.6 Compiler Messages ...................................................................................... 53
3.7 Option Descriptions ...................................................................................... 56
Chapter 4. C Language Features
4.1 Introduction ................................................................................................... 83
4.2 C Standard Compliance ............................................................................... 83
4.3 Device-Related Features .............................................................................. 86
4.4 Supported Data Types and Variables .......................................................... 95
4.5 Memory Allocation and Access .................................................................. 112
4.6 Operators and Statements ......................................................................... 120
4.7 Register Usage ........................................................................................... 122
4.8 Functions .................................................................................................... 123
4.9 Interrupts .................................................................................................... 131
4.10 Main, Runtime Startup and Reset ............................................................ 142
4.11 Libraries .................................................................................................... 146
4.12 Mixing C and Assembly Code .................................................................. 148
4.13 Optimizations ............................................................................................ 157
4.14 Preprocessing .......................................................................................... 159
4.15 Linking Programs ..................................................................................... 170
Preface
NOTICE TO CUSTOMERS
All documentation becomes dated, and this manual is no exception. Microchip tools and
documentation are constantly evolving to meet customer needs, so some actual dialogs
and/or tool descriptions can differ from those in this document. Please refer to our web site
(www.microchip.com) to obtain the latest documentation available.
Documents are identified with a “DS” number. This number is located on the bottom of each
page, in front of the page number. The numbering convention for the DS number is
“DSXXXXXA”, where “XXXXX” is the document number and “A” is the revision level of the
document.
For the most up-to-date information on development tools, see the MPLAB® IDE online help.
Select the Help menu, and then Topics to open a list of available online help files.
INTRODUCTION
This chapter contains general information that will be useful to know before using the
MPLAB® XC8 C Compiler User’s Guide for PIC® MCU. Items discussed in this chapter
include:
• Document Layout
• Conventions Used in this Guide
• Recommended Reading
• The Microchip Web Site
• Development Systems Customer Change Notification Service
• Customer Support
• Document Revision History
DOCUMENT LAYOUT
The MPLAB XC8 C Compiler User’s Guide for PIC is organized as follows:
• Chapter 1. Compiler Overview
• Chapter 2. How To’s
• Chapter 3. XC8-CC Command-line Driver
• Chapter 4. C Language Features
• Chapter 5. Macro Assembler
• Chapter 6. Linker
• Chapter 7. Utilities
• Appendix A. Library Functions
• Appendix B. Error and Warning Messages
• Appendix C. Implementation-Defined Behavior
• Glossary
• Index
DOCUMENTATION CONVENTIONS
Description Represents Examples
Arial font:
Italic characters Referenced books MPLAB® IDE User’s Guide
Emphasized text ...is the only compiler...
Initial caps A window the Output window
A dialog the Settings dialog
A menu selection select Enable Programmer
Quotes A field name in a window or “Save project before build”
dialog
Underlined, italic text with A menu path File>Save
right angle bracket
Bold characters A dialog button Click OK
A tab Click the Power tab
N‘Rnnnn A number in verilog format, 4‘b0010, 2‘hF1
where N is the total number of
digits, R is the radix and n is a
digit.
Text in angle brackets < > A key on the keyboard Press <Enter>, <F1>
Courier New font:
Plain Courier New Sample source code #define START
Filenames autoexec.bat
File paths c:\mcc18\h
Keywords _asm, _endasm, static
Command-line options -Opa+, -Opa-
Bit values 0, 1
Constants 0xFF, ‘A’
Italic Courier New A variable argument file.o, where file can be
any valid filename
Square brackets [ ] Optional arguments mcc18 [options] file
[options]
Curly brackets and pipe Choice of mutually exclusive errorlevel {0|1}
character: { | } arguments; an OR selection
Ellipses... Replaces repeated text var_name [,
var_name...]
Represents code supplied by void main (void)
user { ...
}
RECOMMENDED READING
This user’s guide describes how to use MPLAB XC8 C Compiler. Other useful docu-
ments are listed below. The following Microchip documents are available and
recommended as supplemental reference resources.
Readme for MPLAB XC8 C Compiler
For the latest information on using MPLAB XC8 C Compiler, read MPLAB® XC8 C
Compiler Release Notes (an HTML file) in the Docs subdirectory of the compiler’s
installation directory. The release notes contain update information and known issues
that cannot be included in this user’s guide.
Readme Files
For the latest information on using other tools, read the tool-specific Readme files in
the Readmes subdirectory of the MPLAB IDE installation directory. The Readme files
contain update information and known issues that cannot be included in this user’s
guide.
CUSTOMER SUPPORT
Users of Microchip products can receive assistance through several channels:
• Distributor or Representative
• Local Sales Office
• Field Application Engineer (FAE)
• Technical Support
Customers should contact their distributor, representative or field application engineer
(FAE) for support. Local sales offices are also available to help customers. A listing of
sales offices and locations is included in the back of this document.
Technical support is available through the web site at:
http://www.microchip.com/support
Note: Features described as being part of MPLAB XC8 in this document assume
that you are using a Microchip PIC device and are building for the C99 C
standard. These features may differ if you choose to instead compile for a
Microchip AVR device or for the C90 standard.
The compiler is available for several popular operating systems, including Professional
editions of Microsoft® Windows® 7 (32/64 bit), Windows® 8 (64 bit), and Windows® 10
(64 bit); Ubuntu 16.04 (32/64 bit); Fedora 23 (64 bit) or Mac OS X 10.12 (64 bit).
The compiler is available in three operating modes: Free, Standard2 or PRO. The Stan-
dard and PRO operating modes are licensed modes and require a serial number to
enable them. Free mode is available for unlicensed customers. The basic compiler
operation, supported devices and available memory are identical across all modes.
The modes only differ in the level of optimization employed by the compiler.
1.2.1 Conventions
Throughout this manual, the term “compiler” is used. It can refer to all, or a subset of,
the collection of applications that comprise the MPLAB XC8 C Compiler. When it is not
important to identify which application performed an action, it will be attributed to “the
compiler”.
In a similar manner, “compiler” is often used to refer to the command-line driver;
although specifically, the driver for the MPLAB XC8 C Compiler package is named
xc8-cc. The driver and its options are discussed in Section 3.7 “Option Descriptions.”
Accordingly, “compiler options” commonly refers to command-line driver options.
In a similar fashion, “compilation” refers to all or a selection of steps involved in
generating an executable binary image from source code.
2.2.3 Can I Install More Than One Version of the Same Compiler?
Yes, the compilers and installation process has been designed to allow you to have
more than one version of the same compiler installed, and you can easily move
between the versions by changing options in MPLAB X IDE; see Section 2.3.4 “How
Can I Select Which Compiler I Want to Build With?”
Compilers should be installed into a directory whose name is related to the compiler
version. This is reflected in the default directory specified by the installer. For example,
the 1.44 and 1.45 MPLAB XC8 compilers would typically be placed in separate
directories.
C:\Program Files\Microchip\xc8\v1.44\
C:\Program Files\Microchip\xc8\v1.45\
2.3.6 How Do I Know What Compiler Options Are Available and What
They Do?
A list of all compiler options can be obtained by using the --help option on the com-
mand line (see Section 3.7.2.7 “help”).
Alternatively, all options are listed in Section 3.7 “Option Descriptions” of this user’s
guide.
i = l;
Here, a long type is being assigned to an int type and the assignment will truncate
the value in l. The compiler will automatically perform a type conversion from the type
of the expression on the right of the assignment operator (long) to the type of the value
on the left of the operator (int).This is called an implicit type conversion. The compiler
typically produces a warning concerning the potential loss of data by the truncation.
A cast to type int is not required and should not be used in the above example if a
long to int conversion was intended. The compiler knows the types of both operands
and performs the conversion accordingly. If you did use a cast, there is the potential for
mistakes if the code is later changed. For example, if you had:
i = (int)l;
the code works the same way; but if in the future, the type of i is changed to a long,
for example, then you must remember to adjust the cast, or remove it, otherwise the
contents of l will continue to be truncated by the assignment, which cannot be correct.
Most importantly, the warning issued by the compiler will not be produced if the cast is
in place.
fl = i/j;
In this case, integer division is performed, then the rounded integer result is converted
to a float format. So if i contained 7 and j contained 2, the division yields 3 and this
is implicitly converted to a float type (3.0) and then assigned to fl. If you wanted the
division to be performed in a float format, then a cast is necessary:
fl = (float)i/j;
(Casting either i or j forces the compiler to encode a floating-point division.) The
result assigned to fl now is 3.5.
An explicit cast can suppress warnings that might otherwise have been produced. This
can also be the source of many problems. The more warnings the compiler produces,
the better chance you have of finding potential bugs in your code.
2.4.4 Variables
This sections examines questions that relate to the definition and usage of variables
and types within a program.
• Why Are My Floating-point Results Not Quite What I Am Expecting?
• How Can I Access Individual Bits of a Variable?
See also the following linked information in other sections.
• How Do I Share Data Between Interrupt and Main-line Code?
• How Do I Position Variables at an Address I Nominate?
• How Do I Place Variables in Program Memory?
• How Do I Place Variables in the PIC18 Device’s External Program Memory?
• How Can I Rotate a Variable?
• How Do I Utilize/Allocate the RAM Banks on My Device?
• How Do I Utilize the Linear Memory on Enhanced Mid-range PIC Devices?
• How Do I Find Out Where Variables and Functions Have Been Positioned?
2.4.5 Functions
This section examines questions that relate to functions.
• What is the Optimum Size For Functions?
• How Do I Stop An Unused Function Being Removed?
• How Do I Make a Function Inline?
See also the following linked information in other sections.
• How Can I Tell How Big a Function Is?
• How Do I Position Functions at an Address I Nominate?
• How Do I Know Which Resources Are Being Used by Each Function?
• How Do I Find Out Where Variables and Functions Have Been Positioned?
• How Do I Use Interrupts in C?
2.4.6 Interrupts
Interrupt and interrupt service routine questions are discussed in this section.
How Do I Use Interrupts in C?
See also the following linked information in other sections.
• How Can I Make My Interrupt Routine Faster?
• How Do I Share Data Between Interrupt and Main-line Code?
1. This specifier was originally named in-line but was changed to avoid confusion.
2.6.1 What’s the Difference Between the Free, Standard and PRO
Modes?
These modes (see Section 1.2 “Compiler Description and Documentation”) mainly dif-
fer in the optimizations that are performed when compiling. Compilers operating in Free
(formerly called Lite) and Standard mode can compile for all the same devices as sup-
ported by the Pro mode. The code compiled in Free and Standard mode can use all the
available memory for the selected device. What will be different is the size and speed
of the generated compiler output. Free mode output will be much less efficient when
compared to that produced in Standard mode, which in turn will be less efficient than
that produce when in Pro mode.
All these modes use the OCG compiler framework, so the entire C program is compiled
in one step and the source code does not need many non-standard extensions.
2.6.15 How Do I Find Out Where Variables and Functions Have Been
Positioned?
You can determine where variables and functions have been positioned from either the
assembly list file (see Section 5.4 “Assembly List Files”), or the map file (see
Section 6.4 “Map Files”). Only symbols associated with objects with static storage
duration are shown in the map file; all symbols (including those with automatic storage
duration) are listed in the assembly list file, but only for the code represented by that
list file. Each assembly module has its own list file.
There is a mapping between C identifiers and the symbols used in assembly code,
which are the symbols shown in both of these files (see Section 4.12.3.1 “Equivalent
Assembly Symbols”). The symbol associated with a variable is assigned the address
of the lowest byte of the variable; for functions it is the address of the first instruction
generated for that function.
2.6.21 How Do I Know Which Stack Model the Compiler Has Assigned
to a Function?
Look in the function information section in the assembly list file (see
Section 5.4.3 “Function Information”). The last line of this block will indicate whether
the function uses a reentrant or non-reentrant model.
psect config
org 0x0
dw 0xFFBF
2.7.9 What Can Cause Corrupted Variables and Code Failure When
Using Interrupts?
This is usually caused by having variables used by both interrupt and main-line code.
If the compiler optimizes access to a variable or access is interrupted by an interrupt
routine, then corruption can occur. See Section 2.5.6 “How Do I Share Data Between
Interrupt and Main-line Code?” for more information.
There are no compiler restrictions imposed on the names of source files, but be aware
of case, name-length, and other restrictions that are imposed by your operating sys-
tem.
Avoid using the same base name for assembly and C source files, even if they are
located in different directories, and avoid having source files with the same basename
as the MPLAB X IDE project name.
C source .i .p1 .s
files
.c code
cod
preprocessor
preproc
cessorr parser
pars
ser assembler
assem
mbler
gener
rator
generator
debug
.i file
preprocessed crom
cromwell
m .elf
C source
files
linker objtohex
objto hex
hexmate
hexm .hex
.o .o .hex
hex file
relocatable absolute hex file
object file object file
It is recommended that only the hexmate (hexmate) and librarian (xc8-ar) internal
applications be executed directly. Their command-line options are described in Chapter
7. Utilities.
Note: Throughout this manual, the term project name will refer to either the name
of the project created in the IDE, or the base name (file name without
extension) of the first C source file specified on the command line.
The default output file types can be explicitly controlled by the -gcoff and
-gdwarf-3 options, which generate a COFF and ELF file format as output, respec-
tively (described in Section 3.7.5.2 “g: Produce debugging information”).The
ELF/DWARF file is used by debuggers to obtain debugging information about the proj-
ect and allows for more accurate debugging compared to the COFF format. The IDE
will typically request the compiler to produce an ELF file.
The default names of temporary files use the same base name as the source file from
which they were derived. For example, the source file input.c will create a p-code file
called input.p1.
If these options are used in a DOS batch file, two percent characters will need to be
used to specify the placeholders, as DOS interprets a single percent character as an
argument and will not pass this on to the compiler. For example:
SET HTC_ERR_FORMAT="file %%f: line %%l"
Note: Disabling error or warning messages in no way fixes the condition that
triggered the message. Always use extreme caution when exercising these
options.
The __near qualifier is affected by this option. On PIC18 devices, this option affects
the __far qualifier; and for other 8-bit devices, the __bank(x) qualifier. By default,
these qualifiers are ignored; i.e., they are accepted without error, but have no effect.
Using this option allows these qualifiers to be interpreted differently by the compiler.
For example, when using the option -maddrqual=request, the compiler will try to
honor any non-standard qualifiers, but silently ignore them if they cannot be met.
3.7.1.2 CHECKSUM
The -mchecksum=specs option will calculate a hash value (for example checksum or
CRC) over the address range specified and stores the result at the indicated destina-
tion address. The general form of this option is as follows.
-mchecksum=start-end@destination[,specifications]
The following specifications are appended as a comma-separated list to this option.
The start, end and destination attributes are, by default, hexadecimal constants.
The addresses defining the input range are typically made multiples of the algorithm
width. If this is not the case, zero bytes will pad any missing input word locations.
If an accompanying --fill option (Section 3.7.11.8 “fill”) has not been specified,
unused locations within the specified address range will be automatically filled with
0xFFF for baseline devices, 0x3FFF for mid-range devices, or 0xFFFF for PIC18
devices. This is to remove any unknown values from the calculations and ensure the
accuracy of the result.
For example:
-mchecksum=800-fff@20,width=1,algorithm=2
The hash calculations are performed by the HEXMATE application. The information in
this driver option is passed to the HEXMATE application when it is executed.
3.7.1.3 CODEOFFSET
The -mcodeoffset=offset option shifts the reset and interrupt vector locations up
in memory by the specified offset, and prevents code and data from using memory up
to this offset address. This operation is commonly required when writing bootloaders.
The address is assumed to be a hexadecimal constant. A leading 0x, or a trailing h
hexadecimal specifier can be used but is not necessary.
For example, the option -mcodeoffset=600 will move the reset vector from address
0 to 0x600; and move the interrupt vector from address 4 to 0x604, in the case of
mid-range PIC devices, or to the addresses 0x608 and 0x618 for PIC18 devices. No
code or data will be placed at the addresses 0 thru 0x5FF.
As the reset and interrupt vector locations are at fixed addresses in the PIC device, it
is the programmer’s responsibility to provide code that can redirect control from the
actual vector locations to the reset and interrupt routines in there offset location.
This option differs from the -mreserve option in that it will also move the code asso-
ciated with the reset and interrupt vectors (see Section 3.7.1.17 “reserve”).
3.7.1.4 CONFIG
The -mconfig option can be used to have the compiler program default values for
those configuration bits that have not been specified in the code using the config
pragma. This option can only be used when programming PIC18 devices. The alter-
nate form of this option is -mdefault-config-bits.
The default operation is to not program unspecified bits, and this can be made explicit
using the option -mno-config (-mno-default-config-bits).
3.7.1.6 DEBUGGER
The --mdebugger=type option is intended for use for compatibility with development
tools that can act as a debugger. xc8-cc supports several debuggers and these are
defined in Table 3-10.
For example:
xc8-cc -mcpu=16F877AA -mdebugger=icd3 main.c
will ensure that none of the source code is allocated resourced that would be used by
the debug executive for an MPLAB ICD 3.
Failing to select the appropriate debugger can lead to runtime failure.
If the debugging features of the development tool are not to be used (for example, if the
MPLAB ICD 3 is only being used as a programmer), then the debugger option can be
set to none, because memory resources are not being used by the tool.
MPLAB X IDE will automatically apply this option for debug builds once you have
indicated the hardware tool in the Project Preferences.
3.7.1.7 DFP
The -mdfp=path option specifies an alternate the path to use for the device family
pack. This option is required if you have installed new device family packs on your host
machine.
3.7.1.8 DOWNLOAD
The -mdownload option conditions the Intel HEX for use by bootloader. The
-mdownload-hex option is equivalent in effect.
When used, this option will pad data records in the Intel HEX file to 16-byte lengths and
will align them on 16-byte boundaries. The compiler-generated startup code will not
assume that certain registers hold their reset values.
The default operation is to not modify the HEX file, and this can be made explicit using
the option -mno-download. (-mno-download-hex)
For example, the option -memi=bytewrite will select the 8-bit byte-write mode.
The selected mode will affect the code generated when writing to the external data
interface. In word write mode, dummy reads and writes can be added to ensure that an
even number of bytes are always written. In byte-select or byte-write modes, dummy
reads and writes are not generated and can result in more efficient code.
Note that this option does not pre-configure the device for the selected mode. Your
device data sheet will indicate the settings required in your code.
3.7.1.10 ERRATA
The -merrata=type option allows specification of software workarounds to docu-
mented silicon errata issues. A default set of errata apply to each device, but this set
can be adjusted by using this option and the arguments presented in Table 3-12.
3.7.1.11 IVT
The -mivt=address option selects the interrupt vector table that will be used at the
beginning of program execution for those PIC18 devices that implement interrupt vec-
tor tables.
The address argument specified is written to the IVTBASE register during startup, for
example, -mivt=0x200 will select the interrupt vector table whose base address is at
200h. This table would need to have been populated with vectors by the interrupt rou-
tine definitions in your source code (see Section 4.9.1 “Writing an Interrupt Service
Routine”). The default operation is to leave the vector table at address 0x8 and this can
be made explicit using the option -mno-ivt.
3.7.1.12 MAXICHIP
The -mmaxichip option tells the compiler to build for a hypothetical device with the
same physical core and peripherals as the selected device, but with the maximum
allowable memory resources permitted by the device family. You might use this option
if your program does not fit in your intended target device and you wish to get an indi-
cation of the code or data size reductions needed to be able to program that device.
The compiler will normally terminate compilation if the selected device runs out of pro-
gram memory, data memory, or EEPROM. When using this option, the program mem-
ory of PIC18 and mid-range devices will be maximized to extend from address 0 to
either the bottom of external memory or the maximum address permitted by the PC reg-
ister, whichever is lower. The program memory of baseline parts is maximized from
address 0 to the lower address of the Configuration Words.
The number of data memory banks is expanded to the maximum number of selectable
banks as defined by the BSR register (for PIC18 devices), RP bits in the STATUS reg-
ister (for mid-range devices), or the bank select bits in the FSR register (for baseline
devices). The amount of RAM in each additional bank is equal to the size of the largest
contiguous memory area within the physically implemented banks.
EEPROM is only maximized if the device implements this memory. If present,
EEPROM is maximized to a size dictated by the number of bits in the EEADR register.
If required, check the map file (see Section 6.4 “Map Files”) to see the size and
arrangement of the memory available when using this option with your device.
Note: When using the -mmaxichip option, you are not compiling for a real
device. The generated code may not load or execute in simulators or the
selected device. This option will not allow you to fit extra code into a device.
3.7.1.14 OSCCAL
The -mosccal option can be used to calibrate the oscillator for some PIC10/12/16
devices.
When using this option, the compiler will generate code which will calibrate the oscilla-
tor using the calibration constant preprogrammed in the device. The option
-mno-osccal will omit the code that performs this initialization from the runtime
startup code.
3.7.1.15 OSCVAL
The -moscval=value option allows you to specify the value that will be used to cali-
brate the oscillator for some PIC10/12/16 devices.
The calibration value is usually preprogrammed into your device; however this option
allows you to specify an alternate value, or the original value if has been erased from
the device. The option -moscval=55 would ensure that the value 55h is loaded to the
oscillator calibration register at startup (see Section 4.3.11 “Oscillator Calibration Con-
stants”).
3.7.1.16 RAM
The -mram=ranges option is used to adjust the data memory that is specified for the
target device. Without this option, all the on-chip RAM implemented by the device is
available, thus this option only needs be used if there are special memory require-
ments. Specifying additional memory that is not in the target device might result in a
successful compilation, but can lead to code failures at runtime.
For example, to specify an additional range of memory to that already present on-chip,
use:
-mram=default,+100-1ff
This will add the range from 100h to 1ffh to the on-chip memory. To only use an external
range and ignore any on-chip memory, use:
-mram=0-ff
This option can also be used to reserve memory ranges already defined as on-chip
memory in the chipinfo file. To do this, supply a range prefixed with a minus character,
-, for example:
-mram=default,-100-103
will use all the defined on-chip memory, but not use the addresses in the range from
100h to 103h for allocation of RAM objects.
This option will adjust the memory ranges used by linker classes (see
Section 6.2.1 “-Aclass =low-high,...”) . Any objects contained in a psect that do not use
the classes affected by this option might be linked outside the memory specified by this
option.
This option is also used to specify RAM for far objects on PIC18 devices. These
objects are stored in the PIC18 extended memory. Any additional memory specified
with this option whose address is above the on-chip program memory is assumed to
be extended memory implemented as RAM.
For example, to indicate that RAM has been implemented in the extended memory
space at addresses 0x20000 to 0x20fff, use the following option.
-mram=default,+20000-20fff
3.7.1.18 RESETBITS
The -mresetbits option allows you to have the content of the status register pre-
served by the runtime startup code for PIC10/12/16 devices (described in
Section 4.10.2.4 “STATUS Register Preservation”). The -m[no-]save-resetbits
option is equivalent in effect.
When this option is in effect, the saved registers can be accessed in your program. The
compiler can detect references to the saved STATUS register symbols an will automat-
ically enable this option.
3.7.1.19 ROM
The -mrom=ranges option is used to change the default program memory that is
specified for the target device. Without this option, all the on-chip program memory
implemented by the device is available, thus this option only needs be used if there are
special memory requirements. Specifying additional memory that is not in the target
device might result in a successful compilation, but can lead to code failures at runtime.
For example, to specify an additional range of memory to that on-chip, use:
-mrom=default,+100-2ff
This will add the range from 100h to 2ffh to the on-chip memory. To only use an external
range and ignore any on-chip memory, use:
-mrom=100-2ff
This option can also be used to reserve memory ranges already defined as on-chip
memory in the chip configuration file. To do this supply a range prefixed with a minus
character, -, for example:
-mrom=default,-100-1ff
will use all the defined on-chip memory, but not use the addresses in the range from
100h to 1ffh for allocation of ROM objects.
This option will adjust the memory ranges used by linker classes (see
Section 6.2.1 “-Aclass =low-high,...”) . Any code or objects contained in a psect that do
not use the classes affected by this option might be linked outside the memory speci-
fied by this option.
Note that some psects must be linked above a threshold address, most notably some
psects that hold const-qualified data. Using this option to remove the upper memory
ranges can make it impossible to place these psects.
3.7.1.20 SHROUD
The -mshroud option should be used in situations where either intermediate or library
files are built from confidential source code and are to be distributed.
3.7.1.21 STACK
The -mstack=model[:size] option allows selection of the stack model to be used
by a program’s stack-based variables.
The data stacks available are called a compiled stack and a software stack (described
in Section 4.3.4.2 “Data Stacks”). The stack models that can be used with this option
are described in Table 3-13.
The software (or reentrant) or hybrid models have no effect on projects target-
ing baseline and mid-range devices, as they do not support a software stack. In addi-
tion, interrupt functions must use the compiled stack, but functions they call may use
the software stack.
The hybrid model (-mstack=hybrid) will let the compiler choose how to encode each
function based on how it is called. A function is compiled to use the software stack if it
is called reentrantly in the program; otherwise, it will use a compiled stack. This model
allows for reentrancy, when required, but takes advantage of the efficiency of the com-
piled stack for the majority of the program’s functions.
Any of these option settings can be overridden for individual functions by using function
specifiers (described in Section 4.8.1.3 “Reentrant and nonreentrant Specifiers”).
Note: Use the software (reentrant) setting with caution. The maximum run-
time size of the software stack is not accurately known at compile time, so
the compiler cannot predict an overflow, which could corrupt objects or reg-
isters. When all functions are forced to use the software stack, the stack
size will increase substantially.
In addition to the stack model, this option can be used to specify the maximum size of
memory reserved by the compiler for the software stack. This option configuration only
affects the software stack; there are no controls for the size of the compiled stack.
Distinct memory areas are allocated for the software stack that is used by main-line
code and each interrupt function, but this is transparent at the program level. The com-
piler automatically manages the allocation of memory to each stack. If your program
does not define any interrupt functions, all the available memory is made available to
the software stack used by main-line code.
You can manually specify the maximum space allocated for each area of the stack by
following the stack type with a colon-separated list of decimal values, each value being
the maximum size, in bytes, of the memory to be reserved. The sizes specified corre-
spond to the main-line code, the lowest priority interrupt through the highest priority
interrupt. (PIC18 devices have two separate interrupts; other devices have only one.)
Alternatively, you can explicitly state that you have no size preference by using a size
of auto. For PIC18 devices, the following example:
3.7.1.22 STACKCALL
The -mstackcall option allows the compiler to use a table look-up method of calling
functions.
Once the hardware function return address stack (Section 4.3.4.1 “Function Return
Address Stack”) has been filled, no further function nesting can take place without cor-
rupting function return values. If this option is enabled, the compiler will revert to using
a look-up table method of calling functions once the stack is full (see
Section 4.8.8 “Calling Functions”).
3.7.1.23 SUMMARY
The -msummary=type option selects the type of information that is included in the
summary that is displayed after compilation. By default, or if the mem type is selected,
a memory summary is shown. This shows the total memory usage for all memory
spaces.
A psect summary can be shown by enabling the psect type. This shows individual
psects after they have been grouped by the linker and the memory ranges they cover.
Table 4-20 shows what summary types are available. The output printed when compil-
ing normally corresponds to the mem setting.
If produced, the XML files contain information about memory spaces on the selected
device, consisting of the space’s name, addressable unit, size, amount used and
amount free.
3.7.2.7 HELP
The --help option displays information on the xc8-cc compiler options, then the
driver will terminate.
3.7.2.8 PRINT-DEVICES
The --mprint-devices option displays a list of devices the compiler supports. The
names listed are those chips that are defined in the chipinfo file and which can be used
with the -mcpu option. Compiler execution will terminate after this list has been printed.
3.7.2.9 VERSION
The --version option prints compiler version information then exits.
3.7.3.1 ANSI
The -ansi option is equivalent to -std=c90, and controls the C standard used.
3.7.3.2 SIGNED-CHAR/UNSIGNED-CHAR
The -fsigned-char and -funsigned-char options enforce the signedness of a
plain char type.
By default, the plain char type is equivalent to unsigned char. These options spec-
ify the exact type that will be used by the compiler. Use the -funsigned-char or
-fno-signed-char option to force a plain char to be unsigned, and the
-fsigned-char or -fno-unsigned-char option to force a plain char to be signed.
Consider explicitly stating the signedness of char objects when they are defined,
rather than relying on the type assigned to a plain char type by the compiler.
3.7.3.3 EXT
The -mext=extension option controls the language extension used during compila-
tion and those extensions allowed are shown in Table 4-13.
Enabling the cci extension requests the compiler to check all source code and com-
piler options for compliance with the Common C Interface (CCI). Code that complies
with this interface can be more easily ported across all MPLAB XC compilers. Code or
options that do not conform to the CCI will be flagged by compiler warnings.
3.7.3.4 STD
The -std=standard option specifies the C standard to which the compiler assumes
source code will conform. Allowable standards and devices are shown in Table 3-19.
Note that a different compiler front end will be used for these two standards, thus you
might see a change in compiler behavior when swapping between standards. Float-
ing-point sizes of 24-bits are not permitted with building for C99 compliance (see
Section 4.4.4 “Floating-Point Data Types”).
3.7.4.1 MAX-ERRORS
The -fmax-errors=n option sets the maximum number of errors each compiler
application (excluding Clang), as well as the driver, will display before execution is ter-
minated.
By default, up to 20 error messages will be displayed by each application before the
application terminates. The option -fmax-errors=10, for example, would ensure the
applications terminate after only 10 errors.
See Section 3.6 “Compiler Messages” for full details of the messaging system
employed by xc8-cc.
3.7.4.2 WARN
The -mwarn=level option is used to set the compiler warning level threshold. Allow-
able warning levels range from -9 to 9. The warning level determines how pedantic the
compiler is about dubious type conversions and constructs. Each compiler warning has
a designated warning level; the higher the warning level, the more important the warn-
ing message. If the warning message’s warning level exceeds the set threshold, the
warning is printed by the compiler. The default warning level threshold is 0 and will
allow all normal warning messages.
Use this option with care as some warning messages indicate code that is likely to fail
during execution, or compromise portability. The warnings from the Clang front end are
not controlled by this option.
Section 3.6 “Compiler Messages”has full information on the compiler’s messaging sys-
tem.
3.7.4.4 PEDANTIC
The -Wpedantic option is used to enable strict ANSI C conformance of all special,
non-standard keywords when building C89/90 conforming programs.
If this option is used, non-standard keywords must include two leading underscore
characters (for example, __persistent) so as to strictly conform to the C standard.
3.7.5.1 INSTRUMENT-FUNCTIONS
The -finstrument-functions option embeds diagnostic code into the output to
allow for function profiling with the appropriate hardware. See Section 4.3.13 “Function
profiling” for more information.
The compiler supports the use of this option with the optimizers enabled, making it pos-
sible to debug optimized code; however, the shortcuts taken by optimized code may
occasionally produce surprising results, such as variables that do not exist and flow
control that changes unexpectedly.
3.7.5.3 SAVE-TEMPS
The -save-temps option instructs the compiler to keep temporary files after compila-
tion has finished.
3.7.6.5 ASMFILE
The -fasmfile option enables assembler optimizations on hand-written assembly
source files. By default assembly source is not optimized.
3.7.6.6 LOCAL
The -flocal option limits the extent to which some optimizations are applied to the
program.
This option will use omniscient code generation (OCG) optimizations with libraries or
individual program modules but have the scope of those optimizations restricted to
code within those libraries or modules. Normally optimizations in one module can be
affected by code in other modules or libraries, and there are situations where you want
to prevent this from occurring. The output of source compiled with this setting enabled
with typically be larger but will change little from build to build, even if other project code
that does not use this setting is modified. Such changes in the output might be unde-
sirable if you have validated code that is to be distributed and used in many different
applications.
All the source code specified with a build command that uses local optimizations con-
stitutes one group and you can create as many groups as required by building source
code with separate build commands. Any code built without local optimizations
becomes part of the default (unrestricted) group. The standard libraries that are sup-
plied with the compiler are built with local optimizations disabled and are always part of
this default group.
Enabling local optimizations restricts the scope of many optimizations, but does not
necessarily disable the optimizations themselves. Optimizations can still be performed
within each group, but those optimizations will not be made if they depend on code that
is contained in another group. For example, abstraction of common code sequences
will not be made if the sequences are contained in different groups, but would be made
if the sequences are from the same group. Since a group can be limited to just a few
modules of source code (which you can build into a library in the usual way if you pre-
fer), this still allows you to fully optimize the bulk of a project.
By default this option is disabled. It can be enabled when building for enhanced
mid-range and PIC18 devices and an error message will be emitted if the optimization
is selected with an incompatible device.
When code is built with local optimizations, all variables defined in that group are allo-
cated to banked memory unless they are qualified with near. Bank selection instruc-
tions are often output when they might normally have been emitted. Page selection
instructions before and after function calls are always output, constant propagation is
disabled, floating-point type sizes are fixed at 32 bits for both float and double
types (and this will be enforced for the entire program) and pointer sizes can be fixed
based on their definition (see Section 4.4.6.2 “Pointer-Target Qualifiers”). Some
assembly optimizations are also restricted, such as procedural abstraction, routine
inlining, psect merging, and peephole optimizations.
3.7.8.1 XPARSER
The -Xparser option option passes its option argument directly to the parser. For exam-
ple, -Xparser -v runs the parser in verbose mode. The options -Xp1 and -Xclang are
alternate forms of this option.
3.7.11.2 SERIAL
The -mserial=options option allows a hexadecimal code to be stored at a particu-
lar address in program memory. A typical task for this option might be to position a
serial number in program memory.
The byte-width of data to store is determined by the byte-width of the hexcode param-
eter in the option. For example, to store a one-byte value, 0, at program memory
address 1000h, use -mserial=00@1000. To store the same value as a four byte
quantity use -mserial=00000000@1000.
This option is functionally identical to the corresponding HEXMATE option. For more
detailed information and advanced controls that can be used with this option (refer to
Section 7.3.1.20 “-SERIAL”).
The driver will also define a label at the location where the value was stored and can
be referenced from C code as _serial0. To enable access to this symbol, remember
to declare it, for example:
extern const int _serial0;
3.7.11.3 NODEFAULTLIBS
The -nodefaultlibs option will prevent the standard system libraries being linked
into the project. Only the libraries you specify are passed to the linker.
3.7.11.4 NOSTARTFILES
The -nostartfiles option will prevent the runtime startup modules from being
linked into the project.
3.7.11.5 NOSTDLIB
The -nostdlib option will prevent the standard system start-up files and libraries
being linked into the project. No start-up files and only the libraries you specify are
passed to the linker.
3.7.11.8 FILL
The --fill=options option allows you to fill unused memory with specified values
in a variety of ways.
3.7.13.3 NOSTDINC
The -nostdinc option prevents the standard system directories for header files being
searched by the preprocessor. Only the directories you have specified with -I options
(and the current directory, if appropriate) are searched.
3.7.14.1 SHORT-DOUBLE
The -fshort-double option controls the size of the double type.
By default, the compiler will choose the truncated IEEE754 24-bit format for double
types, or this can be explicitly requested by using this option. When using the
-fno-short-double form of the option, the double type can be changed to the full
32-bit IEEE754 format. The selection of this option must be consistent across all mod-
ules of the program and a 32-bit double size should be selected when you require C99
compliance.
3.7.14.2 SHORT-FLOAT
The -fshort-float option controls the size of the float type.
By default, the compiler will choose the truncated IEEE754 24-bit format for float
types, or this can be explicitly requested by using this option. When using the
-fno-short-float form of the option, the float type can be changed to the full
32-bit IEEE754 format. The selection of this option must be consistent across all mod-
ules of the program and a 32-bit float size should be selected when you require C99
compliance.
4.3.4 Stacks
Stacks are used for two different purposes by programs running on 8-bit PIC devices:
one stack is for storing function return addresses and one or two other stacks are used
for data allocation.
4.3.6 ID Locations
The 8-bit PIC devices have locations outside the addressable memory area that can be
used for storing program information, such as an ID number. The config pragma is
also used to place data into these locations by using a special register name. The
pragma is used as follows:
#pragma config IDLOCx = value
where x is the number (position) of the ID location, and value is the nibble or byte that
is to be positioned into that ID location. The value can only be specified in decimal or
in hexadecimal, the latter radix indicated by the usual 0x prefix. Values must never be
specified in binary (i.e., using the 0b prefix). If value is larger than the maximum value
allowable for each location on the target device, the value will be truncated and a warn-
ing message is issued. The size of each ID location varies from device to device. See
your device data sheet for more information. For example:
#pragma config IDLOC0 = 1
#pragma config IDLOC1 = 4
will attempt fill the first two ID locations with 1 and 4. One pragma can be used to pro-
gram several locations by separating each register-value pair with a comma. For
example, the above could also be specified as shown below.
#pragma config IDLOC0 = 1, IDLOC1 = 4
The config pragma does not produce executable code and so should ideally be placed
outside function definitions.
4.3.9 Multiplication
The PIC18 instruction set includes several 8-bit by 8-bit hardware multiple instructions,
and these are used by the compiler in many situations. Non-PIC18 targets always use
a library routine for multiplication operations.
There are three ways that 8x8-bit integer multiplication can be implemented by the
compiler:
Hardware Multiply These assembly instructions are the most efficient method of
Instructions multiplication, but they are only available on PIC18 devices.
(HMI)
A bitwise iteration Where dedicated multiplication instructions are not available,
(8loop) this implementation produces the smallest amount of code – a
loop cycles through the bit pattern in the operands and
constructs the result bit-by-bit.
The speed of this implementation varies and is dependent on
the operand values; however, this is typically the slowest
method of performing multiplication.
An unrolled This implementation performs a sequence of instructions that is
bitwise sequence identical to the bitwise iteration (above), but the loop is
(8seq) unrolled.
The generated code is larger, but execution is faster than the
loop version.
Multiplication of operands larger than 8 bits can be performed one of the following two
ways:
A bitwise iteration This is the same algorithm used by 8-bit multiplication (above)
(xloop) but the loop runs over all (x) bits of the operands.
Like its 8-bit counterpart, this implementation produces the
smallest amount of code but is typically the slowest method of
performing multiplication.
A bytewise This is a decomposition of the multiplication into a summation
decomposition of many 8-bit multiplications. The 8-bit multiplications can then
(bytdec) be performed using any of the methods described above.
This decomposition is advantageous for PIC18 devices, which
can then use hardware multiply instructions.
For other devices, this method is still fast, but the code size can
become impractical.
Table 4-2 shows the method chosen when space optimizations are enabled or when no
C-level optimizations are enabled.
The source code for the multiplication routines (documented with the algorithms
employed) is available in the pic/c99/sources directory, located in the compiler’s
installation directory. Look for files whose name has the form Umulx.c. where x is the
size of the operation in bits.
If your device and optimization settings dictate the use of a bitwise multiplication loop
you can sometimes arrange the multiplication operands in your C code to improve the
operation’s speed. Where possible, ensure that the left operand to the multiplication is
the smallest of the operands.
For example, in the code:
x = 10;
y = 200;
result = x * y; // first multiply
result = y * x; // second multiply
the variable result will be assigned the same value in both statements, but the first
multiplication expression will be performed faster than the second.
Note: The location that stores the calibration constant is never code protected
and will be lost if you reprogram the device. Thus, the calibration constant
must be saved before the device is erased. The constant must then be
reprogrammed at the same location along with the new program and data.
If you are using an in-circuit emulator (ICE), the location used by the cali-
bration retlw instruction cannot be programmed and subsequent calls to
__osccal_val() will not work. If you wish to test code that calls this func-
tion on an ICE, you must program a retlw instruction at the appropriate
location. Remember to remove this instruction when programming the
actual part so you do not destroy the calibration value.
Legacy projects can use the macro _READ_OSCCAL_DATA(), which maps to the
__osccal_val() function.
inpStatus = readUser();
if(inpStatus == 0) {
__TRACE(id);
recovery();
}
__LOG(id, inpStatus);
The __bit and __int24 types are non-standard types available in this implementa-
tion. The long long types are 64-bit C99 standard types when building for PIC18
devices, but this implementation limits their size to only 32 bits for projects conforming
to the C90 Standard or any project targeting any other device.
All integer values are represented in little endian format with the Least Significant Byte
(LSB) at the lower address.
If no signedness is specified in the type, then the type will be signed except for the
char and __bit types which are always unsigned. The concept of a signed bit is
meaningless.
Signed values are stored as a two’s complement integer value.
The range of values capable of being held by these types is summarized in Table A-7.
For both float and double values, the 24-bit format is the default. The options
-fshort-float and -fshort-double can also be used to specify this explicitly.
The 32-bit format is used for double values if -fno-short-double option is used
and for float values if -fno-short-float is used.
Variables can be declared using the float and double keywords, respectively, to
hold values of these types. Floating-point types are always signed and the unsigned
keyword is illegal when specifying a floating-point type. Types declared as long
double will use the same format as types declared as double. All floating-point
values are represented in little endian format with the LSB at the lower address.
The 32-bit floating-point type supports "relaxed" semantics when compared to the full
IEEE implementation, which means the following rules are observed.
Tiny (sub-normal) arguments to floating-point routines are interpreted as zeros. There
are no representable floating-point values possible between -1.17549435E-38 and
1.17549435E-38, except for 0.0. This range is called the denormal range. Sub-normal
results of routines are flushed to zero. There are no negative 0 results produced.
Not-a-number (NaN) arguments to routines are interpreted as infinities. NaN results are
never created in addition, subtraction, multiplication, or division routines where a NaN
would be normally expected—an infinity of the proper sign is created instead. The
square root of a negative number will return the “distinguished” NaN (default NaN used
for error return).
Infinities are legal arguments for all operations and behave as the largest representable
number with that sign. For example, +inf + -inf yields the value 0.
The format for both floating-point types is described in Table 4-5, where:
• Sign is the sign bit, which indicates if the number is positive or negative
• The Biased Exponent is 8 bits wide and is stored as excess 127 (i.e., an exponent
of 0 is stored as 127).
• Mantissa is the mantissa, which is to the right of the radix point. There is an
implied bit to the left of the radix point which is always 1 except for a zero value,
where the implied bit is zero. A zero value is indicated by a zero exponent.
IEEE 754 32-bit x xxxx xxxx xxx xxxx xxxx xxxx xxxx xxxx
modified IEEE 754 x xxxx xxxx xxx xxxx xxxx xxxx
24-bit
Here are some examples of the IEEE 754 32-bit formats shown in Table 4-6. Note that
the most significant bit (MSb) of the mantissa column (i.e., the bit to the left of the radix
point) is the implied bit, which is assumed to be 1 unless the exponent is zero.
Use the following process to manually calculate the 32-bit example in Table 4-6.
The sign bit is zero; the biased exponent is 251, so the exponent is 251-127=124. Take
the binary number to the right of the decimal point in the mantissa. Convert this to dec-
imal and divide it by 223 where 23 is the size of the mantissa, to give 0.302447676659.
Add 1 to this fraction. The floating-point number is then given by:
-10´2124´1.302447676659
which is approximately equal to:
2.77000e+37
Binary floating-point values are sometimes misunderstood. It is important to remember
that not every floating-point value can be represented by a finite sized floating-point
number. The size of the exponent in the number dictates the range of values that the
number can hold and the size of the mantissa relates to the spacing of each value that
can be represented exactly. Thus the 24-bit format allows for values with approximately
the same range of values representable by the 32-bit format, but the values that can be
exactly represented by this format are more widely spaced.
So, for example, if you are using a 24-bit wide floating-point type, it can exactly store
the value 95000.0. However, the next highest number it can represent is 95002.0 and
it is impossible to represent any value in between these two in such a type as it will be
rounded. This implies that C code which compares floating-point values might not
behave as expected.
For example:
volatile float myFloat;
myFloat = 95002.0;
if(myFloat == 95001.0) // value will be rounded
PORTA++; // this line will be executed!
in which the result of the if expression will be true, even though it appears the two val-
ues being compared are different.
Compare this to a 32-bit floating-point type, which has a higher precision. It also can
exactly store 95000.0 as a value. The next highest value which can be represented is
(approximately) 95000.00781.
Note: Accessing bit-fields larger than a single bit can be very inefficient. If code
size and execution speed are critical, consider using a char type or a char
structure member, instead. Be aware that some SFRs are defined as
bit-fields. Most are single bits, but some can be multi-bit objects.
Unnamed bit-fields can be declared to pad out unused space between active bits in
control registers. For example, if dummy is never referenced, the structure above could
have been declared as:
struct {
unsigned lo : 1;
unsigned : 6;
unsigned hi : 1;
} foo;
A structure with bit-fields can be initialized by supplying a comma-separated list of initial
values for each field. For example:
struct {
unsigned lo : 1;
unsigned mid : 6;
unsigned hi : 1;
} foo = {1, 8, 0};
Structures with unnamed bit-fields can be initialized. No initial value should be supplied
for the unnamed members, for example:
struct {
unsigned lo : 1;
unsigned : 6;
unsigned hi : 1;
} foo = {1, 0};
will initialize the members lo and hi correctly.
A bit-field that has a size of 0 is a special case. The Standard indicates that no further
bit-field is to be packed into the allocation unit in which the previous bit-field, if any, was
placed.
aaa.x = 99;
Here, the union is not named and its members are accessed as if they are part of the
structure.
Objects defined with anonymous structures or unions can only be initialized if you are
using the C99 Standard.
Note: Care must be taken when describing pointers. Is a “const pointer” a pointer
that points to const objects, or a pointer that is const itself? You can talk
about “pointers to const” and “const pointers” to help clarify the definition,
but such terms might not be universally understood.
Any integral constant will have a type of int, long int or long long int, so that
the type can hold the value without overflow. Constants specified in octal or hexadeci-
mal can also be assigned a type of unsigned int, unsigned long int or
unsigned long long int if their signed counterparts are too small to hold the
value.
The default types of constants can be changed by the addition of a suffix after the digits;
e.g., 23U, where U is the suffix. Table 4-8 shows the possible combination of suffixes
and the types that are considered when assigning a type. So, for example, if the suffix
l is specified and the value is a decimal constant, the compiler will assign the type
long int, if that type will hold the constant; otherwise, it will assigned long long
int. If the constant was specified as an octal or hexadecimal constant, then unsigned
types are also considered.
shifter = 20;
result = 1 << shifter; // oops!
The constant 1 (one) will be assigned an int type, hence the value 1 shifted left 20 bits
will yield the result 0, not 0x100000.
The following uses a suffix to change the type of the constant, hence ensure the shift
result has an unsigned long type.
result = 1UL << shifter;
When compiling for those devices that do not support the reentrant function model, all
functions are encoded to use the compiled stack, which are non-reentrant functions.
For the Enhanced Mid-range and PIC18 devices, by default the compiler will use the
non-reentrant model for all functions. The -mstack option (see
Section 3.7.1.21 “stack”) can be used to change the compiler’s default behavior when
assigning function models. Select the software argument with this option so that the
compiler will always choose the reentrant model (software stack) for each function. Set
this option to hybrid to allow the compiler to decide how each function should be
encoded. If the function is not reentrantly called, then it will be encoded to use the
non-reentrant model and the compiled stack. If the function appears in more than one
call graph (i.e., it is called from main-line and interrupt code), or it appears in a loop in
a call graph (i.e., it is called recursively), then the compiler will use the reentrant model.
The hybrid mode allows the program to use recursion but still take advantage of the
more efficient compiled stack.
Alternatively you can change the function model for individual functions by using func-
tion specifiers when you define the function. Use either the __compiled or
__nonreentrant specifier (identical meanings) to indicate that the specified function
must use the compiled stack, without affecting any other function. Alternatively, use
either the __software or __reentrant specifier to indicate a function must be
encoded to use the software stack.
The function specifiers have precedence over the -mstack option setting. If, for exam-
ple, the option -mstack=compiled has been used, but one function uses the
__software (or __reentrant) specifier, then the specified function will use the soft-
ware stack and all the remaining functions will use the compiled stack. These functions
specifiers also override any choice made by the compiler in hybrid mode.
1. What is referred to as a software stack in this user’s guide is the typical dynamic stack arrange-
ment employed by most computers. It is ordinary data memory accessed by some sort of push and
pop instructions, and a stack pointer register.
Note: Defining absolute objects can fragment memory and can make it impossi-
ble for the linker to position other objects. If absolute objects must be
defined, try to place them at either end of a memory bank so that the
remaining free memory is not fragmented into smaller chunks.
The compiler will mark storage for absolute objects as being used (if the address is
within general-purpose RAM), but does not make any checks for overlap of absolute
variables with other absolute variables. There is no harm in defining more than one
absolute variable to live at the same address if this is what you require. No warning will
be issued if the address of an absolute object lies outside the memory of the device or
outside the memory defined by the linker classes.
Absolute variables in RAM cannot be initialized when they are defined, and they are
not cleared by the runtime startup code. After defining absolute variables, assign them
an initial value at a suitable point in your main-line code, if required.
Objects should not be made absolute to force them into common (unbanked) memory.
Always use the __near qualifier for this purpose (see Section 4.4.9.4 “__Near Type
Qualifier”).
When defining absolute bit variables (see Section 4.4.2.1 “Bit Data Types and Vari-
ables”), the address specified must be a bit address. A bit address is obtained by mul-
tiplying the byte address by 8, then adding the bit offset within that bit. For example, to
place a bit variable called mode at bit position #2 at address 0x50, use the following:
bit mode __at(0x282);
When compiling for an Enhanced Mid-range PIC device, the address specified for
absolute objects can be either a conventional banked memory address or a linear
address. As the linear addresses start above the largest banked address, it is clear
which type of address has been specified. In the following example:
int input[100] __at(0x2000);
it is clear that input should placed at address 0x2000 in the linear address space,
which is address 0x20 in bank 0 RAM in the conventional banked address space.
4.6.2 Rotation
The C language does not specify a rotate operator; however, it does allow shifts. The
compiler will detect expressions that implement rotate operations using shift and logical
operators and compile them efficiently.
For the following code:
c = (c << 1) | (c >> 7);
if c is unsigned and non-volatile, the compiler will detect that the intended
operation is a rotate left of 1 bit and will encode the output using the PIC MCU rotate
instructions. A rotate left of 2 bits would be implemented with code like:
c = (c << 2) | (c >> 6);
This code optimization will also work for integral types larger than a char. If the opti-
mization cannot be applied, or this code is ported to another compiler, the rotate will be
implemented, but typically with shifts and a bitwise OR operation.
The xtemp registers are variables that the compiler treats as registers. These are
saved like any other register if they are used in interrupt code. The lltemp register is
only available on PIC18 devices.
The compiler will not be aware of changes to a register’s value when the register itself
is a C lvalue (assignment destination). For example, if the statement WREG = 0; was
encoded using the clrf instruction, the compiler would not consider this as modifying
the W register. Nor should these registers be changed directly by in-line assembly code,
as shown in the following example which modifies the ZERO bit in the STATUS register.
#include <xc.h>
void getInput(void)
{
#asm
bcf ZERO ; do not write using inline assembly code
#endasm
process(c);
}
If any of the applicable registers listed in the table are used by interrupt code, they will
be saved and restored when an interrupt occurs, either in hardware or software (see
Section 4.9.4 “Context Switching”).
4.8 FUNCTIONS
Functions are written in the usual way, in accordance with the C language. Implemen-
tation-specific features associated with functions are discussed in following sections.
Note: The names “argument” and “parameter” are often used interchangeably,
but typically an argument is the value that is passed to the function and a
parameter is the variable defined by the function to store the argument.
4.9 INTERRUPTS
The MPLAB XC8 compiler incorporates features allowing interrupts to be fully handled
from C code. Interrupt functions are often called Interrupt Service Routines, or ISRs.
The operation of interrupts is handled differently by the different device families. Most
Baseline devices do not implement interrupts at all; Mid-range devices have one vector
location which is linked to all interrupt sources; some PIC18 devices have two indepen-
dent interrupt vectors, one assigned to low-priority interrupt sources, the other to
high-priority sources; and, finally, some PIC18 devices implement a vectored interrupt
controller (VIC) module with support for one or more interrupt vector tables (IVTs),
which can be populated with the addresses of high- or low-priority interrupt functions.
The operation of the IVT on devices with a VIC module can be disabled by clearing the
MVECEN configuration bit. The device is then said to be operating in legacy mode, oper-
ating with dual priorities and dual vector locations. This bit is also used by the compiler
to determine how interrupt functions should be programmed. Although the vector table
is disabled in this mode, the vector locations are still relocatable. By default the vector
location will be 0x8 and 0x18, the same for regular PIC18 devices without the VIC mod-
ule.
The priority scheme implemented by PIC18 devices can also be disabled by clearing
the IPEN SFR bit. Such devices are then said to be operating in Mid-range compatibility
mode and utilize only one interrupt vector, located at address 0x8.
The following are the general steps you need to follow to use interrupts. More detail
about these steps is provided in the sections that follow.
For Enhanced Baseline devices with interrupts, Mid-range devices, or PIC18 devices
operating in Mid-range compatibility mode:
• Write one interrupt function to process all interrupt sources.
• At the appropriate point in your main-line code, unmask the interrupt sources
required by setting their interrupt enable bit in the corresponding SFR.
• At the appropriate point in your code, enable the global interrupt enable to allow
interrupts to be generated.
For PIC18 devices without the VIC module, or PIC18 devices operating in legacy
mode:
• Plan the priorities to be assigned to each interrupt source. If the device is operat-
ing in legacy mode, determine the number of sets of dual interrupt vectors you
require.
• Program the MVECEN configuration bit if appropriate.
• Write one interrupt function to process each priority being used. You can define at
most two interrupt functions, or two interrupt functions per vector set for devices
operating in legacy mode. Consider implementing both interrupt functions to han-
dle accidental triggering of unused interrupts, or use the -mundefints option to
provide a default action (see Section 3.7.1.24 “undefints”).
• Write code to assign the required priority to each interrupt source by writing the
appropriate bits in the SFRs.
• If the device is operating in legacy mode and if required, at the appropriate points
in your code, select the required set of dual vectors by writing to the IVTBASE
registers. Never write the IVTBASE registers if interrupts are enabled. The initial
vectors can also be selected by using the -mivt option (see
Section 3.7.1.11 “ivt”).
• At the appropriate point in your code, enable the interrupt sources required.
• At the appropriate point in your code, enable the global interrupt enable.
1. It is recommended that the parameter list be set to void if you want to ensure portability with
devices that do not have the VIC module.
2. It is recommended that the base address be left as the default if you want to ensure portability with
devices that do not have the VIC module.
1. These registers are memory locations allocated by the compiler, but are treated like registers for
code generation purposes. They are typically used when generating reentrant code.
Note: Never re-enable interrupts inside the interrupt function itself. Interrupts are
automatically re-enabled by hardware on execution of the retfie
instruction. Re-enabling interrupts inside an interrupt function can result in
code failure.
4.11 LIBRARIES
4.11.1 Standard Libraries
The C standard libraries contain a standardized collection of functions, such as string,
and math routines. These functions are listed in Appendix A. Library Functions.
The libraries also contain C routines that are implicitly called by programs to perform
tasks such as floating-point operations and integer division. These routines do not
directly correspond to a function call in the source code.
And finally, there are several library functions, such as functions relating to func-
tion-level profiling, mid-range EEPROM access, REALICE trace and log etc., that are
built with the program as required. These will not be found in any library file.
Note: The more assembly code a project contains, the more difficult and time con-
suming will be its maintenance. Assembly code might need revision if the
compiler is updated due to differences in the way the updated compiler may
work. These factors do not affect code written in C.
If assembly must be added, it is preferable to write this as a self-contained
routine in a separate assembly module, rather than in-lining it in C code.
void main(void) {
volatile unsigned char result;
void main(void)
{
var = 1;
asm(“bcf 0,3”);
asm(“BANKSEL _var”);
asm(“rlf (_var)&07fh”);
asm(“rlf (_var+1)&07fh”);
}
In-line assembly code is never optimized by the assembler optimizer.
When using in-line assembler code, it is extremely important that you do not interact
with compiler-generated code. The code generator cannot scan the assembler code for
register usage; so, it will remain unaware if registers are clobbered or used by the
assembly code. However, the compiler will reset all bank tracking once it encounters
in-line assembly, so any SFRs or bits within SFRs that specify the current bank do not
need to be preserved by in-line assembly.
The registers used by the compiler are explained in Section 4.7 “Register Usage”. If
you are in doubt as to which registers are being used in surrounding code, compile your
program with the -Wa,-a option (see Section 3.7.10 “Mapped Assembler Options”)
and examine the assembler code generated by the compiler. Remember that as the
rest of the program changes, the registers and code strategy used by the compiler will
change as well.
If a C function is called from main-line and interrupt code, it can be duplicated (see
Section 4.9.7 “Function Duplication”). Although a special prefix is used to ensure that
labels generated by the compiler are not duplicated, this does not apply to labels
defined in hand-written, in-line assembly code in C functions. Thus, you should not
define assembly labels for in-lined assembly if the containing function might be
duplicated.
PSECT text,class=CODE,local,delta=2
_setports:
movlw 0xAA
BANKSEL (PORTA)
movwf BANKMASK(PORTA)
BANKSEL (PORTB)
bsf RB1
PSECT text2,local,class=CODE,delta=2
GLOBAL _inc
_inc:
stack_auto x,2 ;an auto called 'x'; 2 bytes wide
stack_param foo,2 ;a parameter called 'foo'; 2 bytes wide
alloc_stack
;x = foo + 1;
moviw [foo_offset+0]FSR1
addlw low(01h)
movwf btemp+0
moviw [foo_offset+1]FSR1
movwf btemp+1
movlw high(01h)
addwfc btemp+1,f
movf btemp+0,w
movwi [x_offset+0]FSR1
movf btemp+1,w
movwi [x_offset+1]FSR1
;return x;
moviw [x_offset+0]FSR1
movwf btemp+0
moviw [x_offset+1]FSR1
movwf btemp+1
restore_stack
return
psect text1,class=CODE,space=0,reloc=2
GLOBAL _add
_add:
stack_auto tmp,2 ;an auto called 'tmp'; 2 bytes wide
stack_auto result,2 ;an auto called 'result'; 2 bytes wide
stack_param base,2 ;a parameter called 'base'; 2 bytes wide
stack_param index,2 ;a parameter called 'index'; 2 bytes wide
alloc_stack
;result = tmp + 1;
movlw tmp_offset
movf PLUSW1,w,c
addlw 1
movwf btemp+0,c
movlw tmp_offset+1
movff PLUSW1,btemp+1
movlw 0
addwfc btemp+1,f,c
movlw result_offset
movff btemp+0,PLUSW1
movlw result_offset+1
movff btemp+1,PLUSW1
;return result;
movlw result_offset
movff PLUSW1,btemp+0
movlw result_offset+1
movff PLUSW1,btemp+1
restore_stack
return
4.13 OPTIMIZATIONS
The optimizations in the MPLAB XC8 compiler can be broadly grouped into C-level
optimizations performed on the source code before conversion into assembly and
assembly-level optimizations performed on the assembly code generated by the
compiler.
The C-level optimizations are performed early during the code generation phase and
so have flow-on benefits: performing one optimization might mean that another can
then be applied. As these optimizations are applied before the debug information has
been produced, there is less impact on source-level debugging of programs.
Some of these optimizations are integral to the code generation process and so cannot
be disabled via an option. Suggestions as to how specific optimizations can be
defeated are given in the sections below.
If your compiler is unlicensed, some of the optimization levels are disabled (see
Section 3.7.6 “Options for Controlling Optimization”). Even if they are enabled, optimi-
zations can only be applied if very specific conditions are met. As a result, you might
see that some lines of code are optimized, but other similar lines are not.
The optimization level determines the available optimizations, which are listed in
Table 4-13.
4.14 PREPROCESSING
All C source files are preprocessed before compilation. The preprocessed file is
deleted after compilation, but you can examine this file by using the -E option (see
Section 3.7.2.2 “E: Preprocess Only”).
Assembler source files are preprocessed if the file uses a .S or .sx extension.
void main(void) {
unsigned char c;
#pragma warning disable 359
readp(&i);
#pragma warning enable 359
}
This same effect would be observed using the following code.
#pragma warning push
#pragma warning disable 359
readp(&i);
#pragma warning pop
Here, the state of the messaging system is saved by the warning push pragma.
Warning 359 is disabled, then after the source code which triggers the warning, the
state of the messaging system is retrieved by using the warning pop pragma.
Format 1 label:
Format 2 label: mnemonic operands ; comment
Format 3 name pseudo-op operands ; comment
Format 4 ; comment only
Format 5 empty line
5.2.3 Characters
The character set used is standard 7 bit ASCII. Alphabetic case is significant for
identifiers, but not mnemonics and reserved words. Tabs are equivalent to spaces.
5.2.3.1 DELIMITERS
All numbers and identifiers must be delimited by white space, non-alphanumeric
characters or the end of a line.
5.2.4 Comments
An assembly comment is initiated with a semicolon that is not part of a string or
character constant.
If the assembly file is first processed by the C preprocessor (see Section 3.2.3 “Input
File Types”), then the file can also contain C or C++ style comments using the standard
/* ... */ and // syntax.
5.2.5 Constants
5.2.5.1 NUMERIC CONSTANTS
The assembler performs all arithmetic with signed 32-bit precision.
The default radix for all numbers is 10. Other radices can be specified by a trailing base
specifier, as given in Table 5-2.
Hexadecimal numbers must have a leading digit (e.g., 0ffffh) to differentiate them
from identifiers. Hexadecimal digits are accepted in either upper or lower case.
Note that a binary constant must have an upper case B following it, as a lower case b
is used for temporary (numeric) label backward references.
In expressions, real numbers are accepted in the usual format, and are interpreted as
IEEE 32-bit format.
5.2.6 Identifiers
Assembly identifiers are user-defined symbols representing memory locations or num-
bers. A symbol can contain any number of characters drawn from the alphabetics,
numerics, and the special characters: dollar, $; question mark, ?; and underscore, _.
The first character of an identifier cannot be numeric. The case of alphabetics is signif-
icant, e.g., Fred is not the same symbol as fred. Some examples of identifiers are
shown here:
An_identifier
an_identifier
an_identifier1
$
?$_12345
An identifier cannot be one of the assembler directives, keywords, or psect flags.
An identifier that begins with at least one underscore character can be accessed from
C code. Care must be taken with such symbols that they do not interact with C code
identifiers. Identifiers that do not begin with an underscore can only be accessed from
the assembly domain. See Section 4.12.3.1 “Equivalent Assembly Symbols” for the
mapping between the C and assembly domains.
5.2.7 Expressions
The operands to instructions and directives are comprised of expressions. Expressions
can be made up of numbers, identifiers, strings and operators.
Operators can be unary (one operand, e.g., not) or binary (two operands, e.g., +). The
operators allowable in expressions are listed in Table 5-3.
The usual rules governing the syntax of expressions apply.
The operators listed can all be freely combined in both constant and relocatable
expressions. The linker permits relocation of complex expressions, so the results of
expressions involving relocatable identifiers cannot be resolved until link time.
5.2.9.2 END
The END directive is optional, but if present should be at the very end of the program.
It will terminate the assembly and not even blank lines should follow this directive.
If an expression is supplied as an argument, that expression will be used to define the
entry point of the program. This is stored in a start record in the object file produced by
the assembler. Whether this is of any use will depend on the linker.
The default runtime startup code that is defined by the compiler will contain an END
directive with a start address. As only one start address can be specified for each proj-
ect, you generally do not need to define this address – you can use the END directive
with no entry point in any file.
For example:
END start_label ;defines the entry point
or
END ;do not define entry point
5.2.9.3.2 Bit
The bit flag specifies that a psect holds objects that are 1 bit long. Such psects will
have a scale value of 8 to indicate that there are 8 addressable units to each byte of
storage and all addresses associated with this psect will be bit address, not byte
addresses. The scale value is indicated in the map file (see Section 6.4 “Map Files”).
5.2.9.3.3 Class
The class flag specifies a corresponding linker class name for this psect. A class is a
range of addresses in which psects can be placed.
Class names are used to allow local psects to be located at link time, since they cannot
always be referred to by their own name in a -P linker option (as would be the case if
there are more than one local psect with the same name).
Class names are also useful where psects need only be positioned anywhere within a
range of addresses rather than at a specific address. The association of a class with a
psect that you have defined typically means that you do not need to supply a custom
linker option to place it in memory.
See Section 6.2.1 “-Aclass =low-high,...” for information on how linker classes are
defined.
5.2.9.3.4 Delta
The delta flag defines the size of the addressable unit. In other words, the number of
data bytes that are associated with each address.
With PIC mid-range and baseline devices, the program memory space is word
addressable; so, psects in this space must use a delta of 2. That is to say, each address
in program memory requires 2 bytes of data in the HEX file to define their contents. So,
addresses in the HEX file will not match addresses in the program memory.
The data memory space on these devices is byte addressable; so, psects in this space
must use a delta of 1. This is the default delta value.
All memory spaces on PIC18 devices are byte addressable; so a delta of 1 (the default)
should be used for all psects on these devices.
The redefinition of a psect with conflicting delta values can lead to phase errors being
issued by the assembler.
5.2.9.3.5 Global
A psect defined as global will be combined with other global psects with the same
name at link time. Psects are grouped from all modules being linked.
Psects are considered global by default, unless the local flag is used.
5.2.9.3.6 Inline
This flag is deprecated. Consider, instead, using the optim psect flag.
The inline flag is used by the code generator to tell the assembler that the contents
of a psect can be inlined. If this operation is performed, the contents of the inline
psect will be copied and used to replace calls to the function defined in the psect.
5.2.9.3.8 Limit
The limit flag specifies a limit on the highest address to which a psect can extend. If
this limit is exceeded when it is positioned in memory, an error will be generated. This
is currently only available when building for PIC18 devices.
5.2.9.3.9 Local
A psect defined as local will not be combined with other local psects from other
modules at link time, even if there are others with the same name. Where there are two
local psects in the one module, they reference the same psect. A local psect
cannot have the same name as any global psect, even one in another module.
Psects which are local and which are not associated with a linker class (see
Section 5.2.9.3.3 “Class”) cannot be linked to an address using the -P linker option,
since there could be more than one psect with this name. Typically these psects define
a class flag and they are placed anywhere in that class range.
5.2.9.3.10 Merge
This flag is deprecated. Consider, instead, using the optim psect flag.
This flag can be assigned 0, 1, or not specified. When assigned 0, the psect will never
be merged by the assembly optimizer during optimizations. If assigned the value 1, the
psect can be merged if other psect attributes allow it and the optimizer can see an
advantage in doing so. If this flag is not specified, then merging will not take place.
Typically, merging is only performed on code-based psects (text psects).
5.2.9.3.11 Noexec
The noexec flag is used to indicate that the psect contains no executable code. This
information is only relevant for debugging purposes.
5.2.9.3.15 Reloc
The reloc flag allows the specification of a requirement for alignment of the psect on
a particular boundary. The boundary specification must be a power of two, for example
2, 8 or 0x40. For example, the flag reloc=100h would specify that this psect must
start on an address that is a multiple of 0x100 (e.g., 0x100, 0x400, or 0x500).
PIC18 instructions must be word aligned, so a reloc value of 2 must be used for any
PIC18 psect that contains executable code. All other sections, and all sections for all
other devices, can typically use the default reloc value of 1.
Devices that have a banked data space do not use different space values to identify
each bank. A full address that includes the bank number is used for objects in this
space. So, each location can be uniquely identified. For example, a device with a bank
size of 0x80 bytes will use address 0 to 0x7F to represent objects in bank 0, and then
addresses 0x80 to 0xFF to represent objects in bank 1, etc.
5.2.9.3.18 Split
This flag is deprecated. Consider, instead, using the optim psect flag.
This flag can be assigned 0, 1, or not specified. When assigned 0, the psect will never
be split by the assembly optimizer during optimizations. If assigned the value 1, the
psect can be split if other psect attributes allow it and the psect is too large to fit in avail-
able memory. If this flag is not specified, then the splitability of this psect is based on
whether the psect can be merged, see Section 5.2.9.3.10 “Merge”.
5.2.9.3.19 With
The with flag allows a psect to be placed in the same page with another psect. For
example the flag with=text will specify that this psect should be placed in the same
page as the text psect.
The term withtotal refers to the sum of the size of each psect that is placed “with” other
psects.
5.2.9.4 ORG
The ORG directive changes the value of the location counter within the current psect.
This means that the addresses set with ORG are relative to the base address of the
psect, which is not determined until link time.
Note: The much-abused ORG directive does not move the location counter to the
absolute address you specify. Only if the psect in which this directive is
placed is absolute and overlaid will the location counter be moved to the
specified address. To place objects at a particular address, place them in a
psect of their own and link this at the required address using the linkers -P
option (see Section 6.2.18 “-Pspec”). The ORG directive is not commonly
required in programs.
5.2.9.5 EQU
This pseudo-op defines a symbol and equates its value to an expression. For example
thomas EQU 123h
The identifier thomas will be given the value 123h. EQU is legal only when the symbol
has not previously been defined. See Section 5.2.9.7 “SET” for redefinition of values.
This directive performs a similar function to the preprocessor’s #define directive (see
Section 4.14.1 “Preprocessor Directives”).
5.2.9.6 EXTRN
This pseudo-op is similar to GLOBAL (see Section 5.2.9.1 “GLOBAL”), but can only be
used to link in with global symbols defined in other modules. An error will be triggered
if you use EXTRN with a symbol that is defined in the same module.
5.2.9.7 SET
This pseudo-op is equivalent to EQU (Section 5.2.9.5 “EQU”), except that allows a sym-
bol to be re-defined without error. For example:
thomas SET 0h
This directive performs a similar function to the preprocessor’s #define directive (see
Section 4.14.1 “Preprocessor Directives”).
5.2.9.8 DB
The DB directive is used to initialize storage as bytes. The argument is a comma-sep-
arated list of expressions, each of which will be assembled into one byte and
assembled into consecutive memory locations.
Examples:
alabel: DB ’X’,1,2,3,4,
If the size of an address unit in the program memory is 2 bytes, as it will be for baseline
and mid-range devices (see Section 5.2.9.3.4 “Delta”), the DB pseudo-op will initialize
a word with the upper byte set to zero. So, the above example will define bytes padded
to the following words.
0058 0001 0002 0003 0004
However, on PIC18 devices (PSECT directive’s delta flag should be 1), no padding
will occur and the following data will appear in the HEX file.
58 01 02 03 04
5.2.9.9 DW
The DW directive operates in a similar fashion to DB, except that it assembles
expressions into 16-bit words. Example:
5.2.9.10 DDW
The DDW directive operates in a similar fashion to DW, except that it assembles
expressions into double-width (32-bit) words. Example:
DDW ’d’, 12345678h, 0
5.2.9.11 DS
This directive reserves, but does not initialize, memory locations. The single argument
is the number of bytes to be reserved.
This directive is typically used to reserve memory location for RAM-based objects in
the data memory. If used in a psect linked into the program memory, it will move the
location counter, but not place anything in the HEX file output. Note that because the
size of an address unit in the program memory is 2 bytes (see
Section 5.2.9.3.4 “Delta”), the DS pseudo-op will actually reserve an entire word.
A variable is typically defined by using a label and then the DS directive to reserve
locations at the label location.
Examples:
alabel: DS 23 ;Reserve 23 bytes of memory
xlabel: DS 2+3 ;Reserve 5 bytes of memory
5.2.9.12 DABS
This directive allows one or more bytes of memory to be reserved at the specified
address. The general form of the directive is:
DABS memorySpace, address, bytes[ ,symbol]
where memorySpace is a number representing the memory space in which the reser-
vation will take place, address is the address at which the reservation will take place,
and bytes is the number of bytes that is to be reserved. The symbol is optional and
refers to the name of the object at the address.
Use of symbol in the directive will aid debugging. The symbol is automatically made
globally accessible and is equated to the address specified in the directive. So, for
example, the following directive uses a symbol:
DABS 1,0x100,4,foo
that is identical to the following directives:
GLOBAL foo
foo EQU 0x100
DABS 1,0x100,4
This directive differs to the DS directive in that it can be used to reserve memory at any
location, not just within the current psect. Indeed, these directives can be placed any-
where in the assembly code and do not contribute to the currently selected psect in any
way.
The memory space number is the same as the number specified with the space flag
option to psects (see Section 5.2.9.3.17 “Space”).
The code generator issues a DABS directive for every user-defined absolute C variable,
or for any variables that have been allocated an address by the code generator.
The linker reads this DABS-related information from object files and ensures that the
reserved addresses are not used for other memory placement.
5.2.9.15 LOCAL
The LOCAL directive allows unique labels to be defined for each expansion of a given
macro. Any symbols listed after the LOCAL directive will have a unique assembler
generated symbol substituted for them when the macro is expanded. For example:
down MACRO count
LOCAL more
more: decfsz count
goto more
ENDM
when expanded, will include a unique assembler generated label in place of more. For
example:
down foobar
expands to:
??0001 decfsz foobar
goto ??0001
If invoked a second time, the label more would expand to ??0002, and multiply defined
symbol errors will be averted.
5.2.9.17 REPT
The REPT directive temporarily defines an unnamed macro, then expands it a number
of times as determined by its argument.
For example:
REPT 3
addwf fred,w
ENDM
will expand to:
addwf fred,w
addwf fred,w
addwf fred,w
(see Section 5.2.9.18 “IRP and IRPC”).
5.2.9.19 BANKSEL
This directive can be used to generate code to select the bank of the operand. The
operand should be the symbol or address of an object that resides in the data memory
(see Section 5.2.1.2 “Bank and Page Selection”).
5.2.9.20 PAGESEL
This directive can be used to generate code to select the page of the address operand.
(see Section 5.2.1.2 “Bank and Page Selection”).
5.2.9.21 PROCESSOR
The output of the assembler can vary, depending on the target device. The device
name is typically set using the -mcpu option to the command-line driver xc8-cc (see
Section 3.7.1.5 “cpu”). However, it can also be set with this directive for example:
PROCESSOR 16F877
This directive will override any device selected by any command-line option.
5.2.9.22 SIGNAT
This directive is used to associate a 16-bit signature value with a label. At link time, the
linker checks that all signatures defined for a particular label are the same. The linker
will produce an error if they are not. The SIGNAT directive is used by MPLAB XC8 to
enforce link time checking of C function prototypes and calling conventions.
Use the SIGNAT directive if you want to write assembly language routines that are
called from C. For example:
SIGNAT _fred,8192
associates the signature value 8192 with the symbol _fred. If a different signature
value for _fred is present in any object file, the linker will report an error.
The easiest way to determine the correct signature value for a routine is to write a C
routine with the same prototype as the assembly routine and check the signature value
determined by the code generator. This will be shown in the assembly list file (see
Section 3.7.10 “Mapped Assembler Options” and Section 5.3 “Assembly-Level Optimi-
zations”).
5.2.10.3 COND
Any conditional code is included in the listing output. (see the NOCOND control in
Section 5.2.10.7 “NOCOND”).
5.2.10.4 EXPAND
When EXPAND is in effect, the code generated by macro expansions appears in the list-
ing output. (see the NOEXPAND control in Section 5.2.10.8 “NOEXPAND”).
5.2.10.6 LIST
If, previously, the listing was turned off using the NOLIST control, the LIST control
automatically turns listing on.
Alternatively, the LIST control can include options to control the assembly and the
listing. The options are listed in Table 5-9.
TABLE 5-9: LIST CONTROL OPTIONS
List Option Default Description
c= nnn 80 Set the page (i.e., column) width.
n= nnn 59 Set the page length.
t= ON|OFF OFF Truncate listing output lines. The default wraps lines.
p=< device > n/a Set the device type.
r=< radix > HEX Set the default radix to HEX, dec or oct.
x= ON|OFF OFF Turn macro expansion on or off.
5.2.10.7 NOCOND
Using this control will prevent conditional code from being included in the assembly list
file output (see the COND control in Section 5.2.10.3 “COND”).
5.2.10.8 NOEXPAND
The NOEXPAND control disables macro expansion in the assembly list file. The macro
call will be listed instead. See the EXPAND control in Section 5.2.10.4 “EXPAND”.
Assembly macros are discussed in Section 5.2.9.14 “MACRO and ENDM”.
5.2.10.9 NOLIST
This control turns the listing output off from a precise point forward (see the LIST con-
trol in Section 5.2.10.6 “LIST”).
5.2.10.11 SPACE
The SPACE control places a number of blank lines in the listing output, as specified by
its parameter.
5.2.10.12 SUBTITLE
The SUBTITLE control defines a subtitle to appear at the top of every listing page, but
under the title. The string should be enclosed in single or double quotes (see the TITLE
control in Section 5.2.10.13 “TITLE”).
5.2.10.13 TITLE
This control keyword defines a title to appear at the top of every listing page. The string
should be enclosed in single or double quotes (see the SUBTITLE control in
Section 5.2.10.12 “SUBTITLE”).
---------------------------------------------------------------------------------
(Depth) Function Calls Base Space Used Autos Params Refs
---------------------------------------------------------------------------------
(0) _main 12 12 0 34134
43 BANK0 5 5 0
0 BANK1 7 7 0
_aOut
_initSPI
---------------------------------------------------------------------------------
(1) _aOut 2 0 2 68
2 BANK0 2 0 2
_SPI
_GetDACValue (ARG)
---------------------------------------------------------------------------------
(1) _initSPI 0 0 0 0
---------------------------------------------------------------------------------
(2) _SPI 2 2 0 23
0 BANK0 2 2 0
...
_main (ROOT)
_initSPI
_aOut
_SPI
_GetDACValue
___ftadd
___ftpack
___ftmul (ARG)
...
Indentation is used to indicate the call depth. In the diagram, you can see that main()
calls aOut(), which in turn calls GetDACValue(), which in turn calls the library
function __ftadd(), etc. If a star (*) appears next to the function’s name, this implies
that the function has been called indirectly via a pointer.
6.2 OPERATION
A command to the linker takes the following form:
hlink [options] files
The options are zero or more linker options, each of which modifies the behavior of
the linker in some way. The files is one or more object files and zero or more library
files (.a extension).
6.2.2 -Cpsect=class
This option allows a psect to be associated with a specific class. Normally, this is not
required on the command line because psect classes are specified in object files (see
Section 5.2.9.3.3 “Class”).
6.2.3 -Dclass=delta
This option allows the delta value for psects that are members of the specified class to
be defined. The delta value should be a number. It represents the number of bytes per
addressable unit of objects within the psects. Most psects do not need this option as
they are defined with a delta value (see Section 5.2.9.3.4 “Delta”).
6.2.4 -Dsymfile
Use this option to produce an old-style symbol file. An old-style symbol file is an ASCII
file, where each line has the link address of the symbol followed by the symbol name.
6.2.5 -Eerrfile
Error messages from the linker are written to the standard error stream. Under DOS,
there is no convenient way to redirect this to a file (the compiler drivers will redirect
standard errors, if standard output is redirected). This option makes the linker write all
error messages to the specified file instead of the screen, which is the default standard
error destination.
6.2.6 -F
Normally the linker will produce an object file that contains both program code and data
bytes, and symbol information. Sometimes you want to produce a symbol-only object
file that can be used again in a subsequent linker run to supply symbol values. The -F
option suppresses data and code bytes from the output file, leaving only the symbol
records.
This option can be used when part of one project (i.e., a separate build) is to be shared
with another, as might be the case with a bootloader and application. The files for one
project are compiled using this linker option to produce a symbol-only object file. That
file is then linked with the files for the other project.
6.2.7 -Gspec
When linking programs using segmented, or bank-switched psects, there are two ways
the linker can assign segment addresses, or selectors, to each segment. A segment is
defined as a contiguous group of psects where each psect in sequence has both its link
and load addresses concatenated with the previous psect in the group. The segment
address or selector for the segment is the value derived when a segment type
relocation is processed by the linker.
By default the segment selector is generated by dividing the base load address of the
segment by the relocation quantum of the segment, which is based on the reloc= flag
value given to psects at the assembler level (see Section 5.2.9.3.15 “Reloc”). The -G
option allows an alternate method for calculating the segment selector. The argument
to -G is a string similar to:
A /10h-4h
where A represents the load address of the segment and / represents division. This
means “Take the load address of the psect, divide by 10 HEX, then subtract 4.” This
form can be modified by substituting N for A, * for / (to represent multiplication) and
adding, rather than subtracting, a constant. The token N is replaced by the ordinal
number of the segment, which is allocated by the linker. For example:
N*8+4
means “take the segment number, multiply by 8, then add 4.” The result is the segment
selector. This particular example would allocate segment selectors in the sequence 4,
12, 20, ... for the number of segments defined.
The selector of each psect is shown in the map file (see Section 6.4.2.2 “Psect
Information Listed by Module”).
6.2.8 -Hsymfile
This option instructs the linker to generate a symbol file. The optional argument
symfile specifies the name of the file to receive the data. The default file name is
l.sym.
6.2.9 -H+symfile
This option will instruct the linker to generate an enhanced symbol file, which provides,
in addition to the standard symbol file, class names associated with each symbol and
a segments section which lists each class name and the range of memory it occupies.
This format is recommended if the code is to be run in conjunction with a debugger. The
optional argument symfile specifies a file to receive the symbol file. The default file
name is l.sym.
6.2.10 -I
Usually, failure to resolve a reference to an undefined symbol is a fatal error. Using this
option causes undefined symbols to be treated as warnings, instead.
6.2.11 -Jerrcount
The linker will stop processing object files after a certain number of errors (other than
warnings). The default number is 10, but the -J option allows this to be altered.
6.2.12 -K
This option should not be used. It is for older compilers that use a compiled stack. In
those cases, the linker tries to overlay function auto and parameter blocks to reduce
the total amount of RAM required. For debugging purposes, that feature can be dis-
abled with this option. However, doing so will increase the data memory requirements.
This option has no effect when compiled stack allocation is performed by the code gen-
erator. This is the case for OCG (PRO-Standard-Free mode) compilers, and this option
should not be used.
6.2.13 -L
When the linker produces an output file it does not usually preserve any relocation
information, since the file is now absolute. In some circumstances a further “relocation”
of the program is done at load time. The -L option generates, in the output file, one null
relocation record for each relocation record in the input.
6.2.14 -LM
Similar to the above option, this preserves relocation records in the output file, but only
segment relocations.
6.2.15 -Mmapfile
This option causes the linker to generate a link map in the named file, or on the stan-
dard output, if the file name is omitted. The format of the map file is illustrated in
Section 6.4 “Map Files”.
6.2.17 -Ooutfile
This option allows specification of an output file name for the object file.
6.2.18 -Pspec
Psects are linked together and assigned addresses based on information supplied to
the linker via -P options. The argument to the -P option consists of comma-separated
sequences with the form:
-Ppsect=linkaddr+min/loadaddr+min,psect=linkaddr/loadaddr,...
All values can be omitted, in which case a default will apply, depending on previous val-
ues. The link address of a psect is the address at which it can be accessed at runtime.
The load address is the address at which the psect starts within the output file (HEX or
binary file etc.), but it is rarely used by 8-bit PIC devices. The addresses specified can
be numerical addresses, the names of other psects, classes, or special tokens.
Examples of the basic and most common forms of this option are:
-Ptext10=02000h
which places (links) the starting address of psect text10 at address 0x2000;
-PmyData=AUXRAM
which places the psect myData anywhere in the range of addresses specified by the
linker class AUXRAM (which would need to be defined using the -A option, see
Section 6.2.1 “-Aclass =low-high,...”), and
-PstartCode=0200h,endCode
which places endCode immediately after the end of startCode, which will start at
address 0x200.
The additional variants of this option are rarely needed; but, are described below.
If a link or load address cannot be allowed to fall below a minimum value, the +min,
suffix indicates the minimum address.
If the link address is a negative number, the psect is linked in reverse order with the top
of the psect appearing at the specified address minus one. Psects following a negative
address will be placed before the first psect in memory.
If the load address is omitted entirely, it defaults to the link address. If the slash / char-
acter is supplied with no address following, the load address will concatenate with the
load address of the previous psect. For example, after processing the option:
-Ptext=0,data=0/,bss
the text psect will have a link and load address of 0; data will have a link address of
0 and a load address following that of text. The bss psect will concatenate with data
in terms of both link and load addresses.
A load address specified as a dot character, “.” tells the linker to set the load address
to be the same as the link address.
The final link and load address of psects are shown in the map file (see
Section 6.4.2.2 “Psect Information Listed by Module”).
6.2.19 -Qprocessor
This option allows a device type to be specified. This is purely for information placed in
the map file. The argument to this option is a string describing the device. There are no
behavioral changes attributable to the device type.
6.2.20 -S
This option prevents symbol information relating from being included in the symbol file
produced by the linker. Segment information is still included.
6.2.22 -Usymbol
This option will enter the specified symbol into the linker’s symbol table as an undefined
symbol. This is useful for linking entirely from libraries, or for linking a module from a
library where the ordering has been arranged so that by default a later module will be
linked.
6.2.23 -Vavmap
To produce an Avocet format symbol file, the linker needs to be given a map file to allow
it to map psect names to Avocet memory identifiers. The avmap file will normally be
supplied with the compiler, or created automatically by the compiler driver as required.
6.2.24 -Wnum
The -W option can be used to set the warning level, in the range -9 to 9, or the width of
the map file, for values of num >= 10.
-W9 will suppress all warning messages. -W0 is the default. Setting the warning level
to -9 (-W-9) will give the most comprehensive warning messages.
6.2.25 -X
Local symbols can be suppressed from a symbol file with this option. Global symbols
will always appear in the symbol file.
6.2.26 -Z
Some local symbols are compiler generated and not of interest in debugging. This
option will suppress from the symbol file all local symbols that have the form of a single
alphabetic character, followed by a digit string. The set of letters that can start a trivial
symbol is currently “klfLSu“. The -Z option will strip any local symbols starting with
one of these letters, and followed by a digit string.
6.4.1 Generation
If compilation is being performed via MPLAB X IDE, a map file is generated by default.
If you are using the driver from the command line, use the -Wl,-Map option to request
that the map file be produced (see Section 3.7.12 “Mapped Linker Options”). Map files
have the extension .map.
Map files are produced by the linker. If the compilation process is stopped before the
linker is executed, then no map file is produced. The linker produces a map file, even
if it encounters errors. The file, then, helps you track down the cause of the errors. How-
ever, if the linker ultimately reports too many errors, the linker did not run to com-
pletion, the map file was not created. You can use the -fmax-errors option (see
Section 3.7.4.1 “max-errors”) on the command line to increase the number of errors
encountered before the linker exits.
6.4.2 Contents
The sections in the map file, in order of appearance, are as follows.
• the compiler name and version number
• a copy of the command line used to invoke the linker
• the version number of the object code in the first file linked
• the machine type
• a psect summary sorted by the psect’s parent object file
• a psect summary sorted by the psect’s CLASS
• a segment summary
• unused address ranges summary
• the symbol table
• information summary for each function
• information summary for each module
Portions of an example map file, along with explanatory text, are shown in the following
sections.
The Linker command line shows all the command-line options and files that were
passed to the linker for the last build. Remember, these are linker options, not
command-line driver options.
The linker options are necessarily complex. Fortunately, they rarely need adjusting
from their default settings. They are formed by the command-line driver, xc8-cc,
based on the selected target device and the specified driver options. You can often con-
firm that driver options were valid by looking at the linker options in the map file. For
example, if you ask the driver to reserve an area of memory, you should see a change
in the linker options used.
If the default linker options must be changed, this can be done indirectly through the
driver using the driver -Wl option (see Section 3.7.12 “Mapped Linker Options”). If you
use this option, always confirm the change appears correctly in the map file.
7.2 LIBRARIAN
The librarian program, xc8-ar, has the function of combining several intermediate files
into a single file, known as a library or archive file. Libraries are easier to manage and
might consume less disk space that the individual files.
The librarian can build all library types needed by the compiler and can detect the for-
mat of existing libraries.
7.2.1.1 EXAMPLES
Here are some examples of usage of the librarian. The following command:
xc8-ar -r myPicLib.a ctime.p1 init.p1
creates a library called myPicLib.a that contains the modules ctime.p1 and
init.p1
The following command deletes the object module a.p1 from the library lcd.a:
xc8-ar -d lcd.a a.p1
7.3 HEXMATE
The hexmate utility is a program designed to manipulate Intel HEX files. hexmate is a
post-link stage utility that is automatically invoked by the compiler driver, and that
provides the facility to:
• Calculate and store variable-length hash values
• Fill unused memory locations with known data sequences
• Merge multiple Intel HEX files into one output file
• Convert INHX32 files to other INHX formats (e.g., INHX8M)
• Detect specific or partial opcode sequences within a HEX file
• Find/replace specific or partial opcode sequences
• Provide a map of addresses used in a HEX file
• Change or fix the length of data records in a HEX file
• Validate checksums within Intel HEX files.
Typical applications for hexmate might include:
• Merging a bootloader or debug module into a main application at build time
• Calculating a checksum or CRC value over a range of program memory and
storing its value in program memory or EEPROM
• Filling unused memory locations with an instruction to send the PC to a known
location if it gets lost
• Storage of a serial number at a fixed address
• Storage of a string (e.g., time stamp) at a fixed address
• Store initial values at a particular memory address (e.g., initialize EEPROM)
• Detecting usage of a buggy/restricted instruction
• Adjusting HEX file to meet requirements of particular bootloaders
If you are using the driver, xc8, to compile your project (or the IDE), a log file is
produced by default. It will have the project’s name and the extension .hxl.
The input parameters to hexmate are now discussed in detail. The format or assumed
radix of values associated with options are described with each option. Note that any
address fields specified in these options are to be entered as byte addresses, unless
specified otherwise in the -ADDRESSING option.
7.3.1.2 + PREFIX
When the + operator precedes an argument or input file, the data obtained from that
source will be forced into the output file and will overwrite another other data existing
at that address range. For example:
+input.HEX +-STRING@1000=”My string”
Ordinarily, hexmate will issue an error if two sources try to store differing data at the
same location. Using the + operator informs hexmate that if more than one data source
tries to store data to the same address, the one specified with a + prefix will take priority.
7.3.1.3 --EDF
This option must be used to have warning and hexmate error messages correctly dis-
played. The argument should be the full path to the message file to use when executing
hexmate. The message files are located in the MPLAB XC8 compiler’s pic/dat direc-
tory (e.g., the English language file is called en_msgs.txt).
7.3.1.4 --EMAX
This option sets the maximum number of errors hexmate will display before execution
is terminated, e.g., --EMAX=25. By default, up to 20 error messages will be displayed.
7.3.1.5 --MSGDISABLE
This option allows error, warning or advisory messages to be disabled during execution
of hexmate.
The option is passed a comma-separated list of message numbers that are to be dis-
abled. Any error message numbers in this list are ignored unless they are followed by
an :off argument. If the message list is specified as 0, then all warnings are disabled.
(See Section 3.6 “Compiler Messages” for more information on the messaging
system.)
7.3.1.7 --VER
This option will ask hexmate to print version and build information and then quit.
7.3.1.8 -ADDRESSING
By default, all address arguments in hexmate options expect that values will be entered
as byte addresses. In some device architectures, the native addressing format can be
something other than byte addressing. In these cases, it would be much simpler to be
able to enter address-components in the device’s native format. To facilitate this, the
-ADDRESSING option is used.
This option takes one parameter that configures the number of bytes contained per
address location. If, for example, a device’s program memory naturally used a 16-bit (2
byte) word-addressing format, the option -ADDRESSING=2 will configure hexmate to
interpret all command line address fields as word addresses. The affect of this setting
is global and all hexmate options will now interpret addresses according to this setting.
This option will allow specification of addressing modes from one byte per address to
four bytes per address.
7.3.1.9 -BREAK
This option takes a comma-separated list of addresses. If any of these addresses are
encountered in the HEX file, the current data record will conclude and a new data
record will recommence from the nominated address. This can be useful to use new
data records to force a distinction between functionally different areas of program
space. Some HEX file readers depend on this.
7.3.1.10 -CK
The -CK option is for calculating a hash value. The usage of this option is:
-CK=start-end@dest [+offset][wWidth][tCode][gAlgorithm][pPolynomial]
where:
• start and end specify the address range over which the hash will be calculated.
If these addresses are not a multiple of the algorithm width, the value zero will be
padded into the relevant input word locations that are missing.
• dest is the address where the hash result will be stored. This value cannot be
within the range of calculation.
• offset is an optional initial value to be used in the calculations.
• Width is optional and specifies the byte-width of the result. Results can be calcu-
lated for byte-widths of 1 to 4 bytes. If a positive width is requested, the result will
be stored in big-endian byte order. A negative width will cause the result to be
stored in little-endian byte order. If the width is left unspecified, the result will be 2
bytes wide and stored in little-endian byte order. This width argument is not used if
you have selected any Fletcher algorithm.
• Code is a hexadecimal code that will trail each byte in the result. This can allow
each byte of the hash result to be embedded within an instruction.
• Algorithm is an integer to select which hexmate hash algorithm to use to calcu-
late the result. A list of selectable algorithms is provided in Table 7-3. If
unspecified, the default algorithm used is 8-bit checksum addition (1).
• Polynomial is a hexadecimal value which is the polynomial to be used if you
have selected a CRC algorithm.
See Section 7.3.2 “Hash Functions” for more details about the algorithms that are used
to calculate checksums.
7.3.1.13 -FIND...,DELETE
If the DELETE form of the -FIND option is used, any matching sequences will be
removed. This function should be used with extreme caution and is not normally
recommended for removal of executable code.
7.3.1.14 -FIND...,REPLACE
If the REPLACE form of the -FIND option is used, any matching sequences will be
replaced, or partially replaced, with new codes. The usage for this sub-option is:
-FIND...,REPLACE=Code [mMask]
where:
• Code is a little endian hexadecimal code to replace the sequences that match the
-FIND criteria.
• Mask is an optional bit mask to specify which bits within Code will replace the
code sequence that has been matched. This can be useful if, for example, it is
only necessary to modify 4 bits within a 16-bit instruction. The remaining 12 bits
can masked and left unchanged.
7.3.1.16 -HELP
Using -HELP will list all hexmate options. Entering another hexmate option as a param-
eter of -HELP will show a detailed help message for the given option. For example:
-HELP=string
will show additional help for the -STRING hexmate option.
7.3.1.17 -LOGFILE
The -LOGFILE option saves HEX file statistics to the named file. For example:
-LOGFILE=output.hxl
will analyze the HEX file that hexmate is generating, and save a report to a file named
output.hxl.
7.3.1.19 -OFILE
The generated Intel HEX output will be created in this file. For example:
-Oprogram.hex
will save the resultant output to program.hex. The output file can take the same name
as one of its input files; but, by doing so, it will replace the input file entirely.
7.3.1.20 -SERIAL
This option will store a particular HEX value sequence at a fixed address. The usage
of this option is:
-SERIAL=Code [+/-Increment]@Address [+/-Interval][rRepetitions]
where:
• Code is a hexadecimal sequence to store. The first byte specified is stored at the
lowest address.
• Increment is optional and allows the value of Code to change by this value with
each repetition (if requested).
• Address is the location to store this code, or the first repetition thereof.
• Interval is optional and specifies the address shift per repetition of this code.
• Repetitions is optional and specifies the number of times to repeat this code.
All numerical arguments are assumed to be hexadecimal values, except for the
Repetitions argument, which is decimal value by default.
For example:
-SERIAL=000001@EFFE
will store HEX code 00001h to address EFFEh.
Another example:
-SERIAL=0000+2@1000+10r5
will store 5 codes, beginning with value 0000 at address 1000h. Subsequent codes
will appear at address intervals of +10h and the code value will change in increments
of +2h.
7.3.1.21 -SIZE
Using the -SIZE option will report the number of bytes of data within the resultant HEX
image to standard output. The size will also be recorded in the log file if one has been
requested.
7.3.1.23 -STRPACK
This option performs the same function as -STRING, but with two important differ-
ences. First, only the lower seven bits from each character are stored. Pairs of 7-bit
characters are then concatenated and stored as a 14-bit word rather than in separate
bytes. This is known as string packing. This is usually only useful for devices where pro-
gram space is addressed as 14-bit words (PIC10/12/16 devices). The second
difference is that -STRING’s t specifier is not applicable with the -STRPACK option.
chksum = offset;
while(n--) {
chksum += *data;
data++;
}
return chksum;
}
The readType and resultType type definitions should be adjusted to suit the data
read/sum width and checksum result width, respectively. When using MPLAB XC8 and
for a size of 1, use a char type; for a size of 4, use a long type, etc., or consider using
the exact-width types provided by <stdint.h>. If you never use an offset, that param-
eter can be removed and chksum assigned 0 before the loop.
Here is how this function might be used when, for example, a 2-byte-wide checksum is
to be calculated from the addition of 1-byte-wide values over the address range 0x100
to 0x7fd, starting with an offset of 0x20. The checksum is to be stored at 0x7fe and 0x7ff
in little endian format. The following option is specified when building the project. (In
MPLAB X IDE, only enter the information to the right of the first = in the Checksum field
in the Additional options Option category in the XC8 Linker category.)
-mchecksum=100-7fd@7fe,offset=20,algorithm=1,width=-2
Into your project, add the following code snippet, which calls ck_add, above, and
compare the runtime checksum with that stored by hexmate at compile time.
extern const readType ck_range[0x6fe/sizeof(readType)] @ 0x100;
extern const resultType hexmate @ 0x7fe;
resultType result;
chksum = offset;
while(n--) {
chksum -= *data;
data++;
}
return chksum;
}
Here is how this function might be used when, for example, a 4-byte-wide checksum is
to be calculated from the addition of 2-byte-wide values over the address range 0x0 to
0x7fd, starting with an offset of 0x0. The checksum is to be stored at 0x7fe and 0x7ff in
little endian format. The following option is specified when building the project. (In
MPLAB X IDE, only enter the information to the right of the first = in the Checksum field
in the Additional options Option category in the XC8 Linker category.)
-mchecksum=0-7fd@7fe,offset=0,algorithm=-2,width=-4
Into your project add the following code snippet, which calls ck_sub, above, and
compare the runtime checksum with that stored by hexmate at compile time.
extern const readType ck_range[0x7fe/sizeof(readType)] @ 0x0;
extern const resultType hexmate @ 0x7fe;
resultType result;
while (n) {
tlen = n > 20 ? 20 : n;
n -= tlen;
do {
sumB += sum += *data++;
} while (--tlen);
sum = (sum & 0xff) + (sum >> 8);
sumB = (sumB & 0xff) + (sumB >> 8);
}
sum = (sum & 0xff) + (sum >> 8);
sumB = (sumB & 0xff) + (sumB >> 8);
while (n) {
tlen = n > 359 ? 359 : n;
n -= tlen;
do {
sumB += sum += *data++;
} while (--tlen);
sum = (sum & 0xffff) + (sum >> 16);
sumB = (sumB & 0xffff) + (sumB >> 16);
}
sum = (sum & 0xffff) + (sum >> 16);
sumB = (sumB & 0xffff) + (sumB >> 16);
resultType
crc(const unsigned char * data, unsigned n, resultType remainder) {
unsigned pos;
unsigned char bitp;
return remainder;
}
The resultType type definition should be adjusted to suit the result width. When
using MPLAB XC8 and for a size of 1, use a char type; for a size of 4, use a long type,
etc., or consider using the exact-width types provided by <stdint.h>.
Here is how this function might be used when, for example, a 2-byte-wide CRC hash
value is to be calculated values over the address range 0x0 to 0xFF, starting with an
initial value of 0xFFFF. The result is to be stored at 0x100 and 0x101 in little endian
format. The following option is specified when building the project. (In MPLAB X IDE,
only enter the information to the right of the first = in the Checksum field in the Addi-
tional options Option category in the XC8 Linker category.)
-mchecksum=0-FF@100,offset=0xFFFF,algorithm=5,width=-2,polynomial=0x1021
reflectWidth
reflect(reflectWidth data, unsigned char nBits)
{
reflectWidth reflection = 0;
reflectWidth reflectMask = (reflectWidth)1 << nBits - 1;
unsigned char bitp;
return reflection;
}
return remainder;
}
resultType
crc_reflected_poly(const unsigned char * data, unsigned n, resultType
remainder) {
unsigned pos;
unsigned char bitp;
resultType rpoly;
return remainder;
}
Here is how this function might be used when, for example, a 2-byte-wide reflected
CRC result is to be calculated over the address range 0x0 to 0xFF, starting with an ini-
tial value of 0xFFFF. The result is to be stored at 0x100 and 0x101 in little endian for-
mat. The following option is specified when building the project. (Note the algorithm
selected is negative 5 in this case.)
-mchecksum=0-FF@100,offset=0xFFFF,algorithm=-5,width=-2,polynomial=0x1021
In your project, call crc(), as shown previously.
EEPROM_READ
Synopsis
#include <xc.h>
int
main (void)
{
unsigned char serNo;
serNo = eeprom_read(0x20);
}
EEPROM_WRITE
Synopsis
#include <xc.h>
int
main (void)
{
eeprom_write(0x20, 0x55);
}
EEPROM_READ (MACRO)
Synopsis
#include <xc.h>
EEPROM_READ(address);
Description
This macro is available for all Mid-range devices that implement EEPROM.
Unlike the function version, this macro does not wait for any concurrent writes to
EEPROM to conclude before performing the required operation.
Example
#include <xc.h>
int
main (void)
{
unsigned char serNo;
EEPROM_WRITE (MACRO)
Synopsis
#include <xc.h>
EEPROM_WRITE(address, value);
Description
This macro is available for all Mid-range devices that implement EEPROM.
This macro tests and waits for any concurrent writes to EEPROM to conclude before
performing the required operation. The function will initiate the write to EEPROM and
this process will still be taking place when the function returns. The new data written to
EEPROM will become valid at a later time. See your device data sheet for exact infor-
mation about EEPROM on your target device.
Example
#include <xc.h>
int
main (void)
{
EEPROM_WRITE(0x20, 0x55);
}
__BUILTIN_SOFTWARE_BREAKPOINT
Synopsis
#include <xc.h>
void __builtin_software_breakpoint(void);
Description
This builtin unconditionally inserts code into the program output which triggers a
software breakpoint when the code is executed using a debugger.
The software breakpoint code is only generated for mid-range and PIC18 devices.
Baseline devices do not support software breakpoints in this way, and the builtin will be
ignored if used with these devices.
Example
#include <xc.h>
int
main (void)
{
__builtin_software_breakpoint(); // stop here to begin
...
__CONDITIONAL_SOFTWARE_BREAKPOINT
Synopsis
#include <assert.h>
__conditional_software_breakpoint(expression)
Description
This macro implements a light-weight embedded version of the standard C assert()
macro, and is used in the same way.
When executed, the expression argument is evaluated. If the argument is false the
macro attempts to halt program execution; the macro performs no action if the argu-
ment is true.
The macro is removed from the program output if the manifest constant NDEBUG is
defined. In addition, it is included only for debug builds (i.e., when the __DEBUG macro
is defined). Thus, it does not consume device resources for production builds.
If the target device does not support the ability to halt via a software breakpoint, use of
this macro will trigger a compiler error.
Example
#include <assert.h>
__DEBUG_BREAK
Synopsis
#include <xc.h>
void __debug_break(void);
Description
This macro conditionally inserts code into the program output which triggers a software
breakpoint when the code is executed using a debugger. The code is only generated
for debug builds (see Section 2.3.7 “What is Different About an MPLAB X IDE Debug
Build?”) and is omitted for production builds (i.e., when the __DEBUG macro is defined).
The software breakpoint code is only generated for mid-range and PIC18 devices.
Baseline devices do not support software breakpoints in this way, and the macro will
be ignored if used with these devices.
Example
#include <xc.h>
int
main (void)
{
__debug_break(); // stop here to begin
...
See also
__builtin_software_breakpoint()
__EEPROM_DATA
Synopsis
#include <xc.h>
__EEPROM_DATA(a,b,c,d,e,f,g,h)
Description
This macro is used to store initial values in the device’s EEPROM registers at the time
of programming.
The macro must be given blocks of 8 bytes to write each time it is called, and can be
called repeatedly to store multiple blocks.
__EEPROM_DATA() will begin writing to EEPROM address zero, and auto-increments
the address written to by 8 each time it is used.
Example
#include <xc.h>
__EEPROM_DATA(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07)
__EEPROM_DATA(0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F)
void
main (void)
{
}
__FPNORMALIZE
Synopsis
#include <xc.h>
void
main (void)
{
double input_fp;
__OSCCAL_VAL
Synopsis
#include <xc.h>
void
main (void)
{
unsigned char c;
c = __osccal_val();
}
_DELAY() , _DELAYWDT
Synopsis
#include <xc.h>
void
main (void)
{
control |= 0x80;
_delay(10); // delay for 10 cycles
control &= 0x7F;
}
_DELAY3()
Synopsis
#include <xc.h>
void
main (void)
{
control |= 0x80;
_delay3(10); // delay for 30 cycles
control &= 0x7F;
}
ASSERT
Synopsis
#include <assert.h>
void
ptrfunc (struct xyz * tp)
{
assert(tp != 0);
}
CLRWDT
Synopsis
#include <xc.h>
CLRWDT();
Description
This macro is used to clear the device’s internal watchdog timer.
Example
#include <xc.h>
void
main (void)
{
WDTCON=1;
/* enable the WDT */
CLRWDT();
}
DI, EI
Synopsis
#include <xc.h>
void ei (void)
void di (void)
Description
The di() and ei() routines disable and re-enable interrupts respectively. These are
implemented as macros. The example shows the use of ei() and di() around access
to a long variable that is modified during an interrupt. If this was not done, it would be
possible to return an incorrect value, if the interrupt occurred between accesses to
successive words of the count value.
The ei() macro should never be called in an interrupt function.
Example
#include <xc.h>
void
__interrupt(high_priority) tick (void)
{
count++;
}
void
getticks (void)
{
di();
val = count;
ei();
}
EVAL_POLY
Synopsis
#include <math.h>
void
main (void)
{
double x, y;
double d[3] = {1.1, 3.5, 2.7};
x = 2.2;
y = eval_poly(x, d, 2);
printf(“The polynomial evaluated at %f is %f\n”, x, y);
}
Return Value
A double value, being the polynomial evaluated at x.
abs(), labs()
GET_CAL_DATA
Synopsis
#include <xc.h>
void
main (void)
{
double x;
unsigned char y;
NOP
Synopsis
#include <xc.h>
NOP();
Description
Execute NOP instruction here. This is often useful to fine tune delays or create a handle
for breakpoints. The NOP instruction is sometimes required during some sensitive
sequences in hardware.
Example
#include <xc.h>
void
crude_delay(void) {
RA1 = 0;
NOP();
RA1 = 1;
}
}
PUTCH
Synopsis
#include <conio.h>
void
main (void)
{
char * cp;
cp = x;
while(*x)
putch(*x++);
putch(’\n’);
}
READTIMERx
Synopsis
#include <xc.h>
unsigned short READTIMERx (void);
Description
The READTIMERx() macro returns the value held by the TMRx register, where x is one
of the digits 0, 1 or 3.
Example
#include <xc>
void
main (void)
{
while(READTIMER0() != 0xFF)
continue;
SLEEP();
}
See Also
WRITETIMERx()
Return Value
The value held by the TMRx register.
Note
This macro can only be used with PIC18 devices.
RESET
Synopsis
#include <xc.h>
RESET();
Description
Execute a RESET instruction here. This will trigger a software device Reset.
Example
#include <xc.h>
void
main(void)
{
init();
while( ! (fail_code = getStatus())) {
process();
}
if(fail_code > 2) // something’s serious wrong
RESET(); // reset the whole device
// otherwise try restart code from main()
}
SLEEP
Synopsis
#include <xc.h>
SLEEP();
Description
This macro is used to put the device into a low-power standby mode.
Example
#include <xc.h>
extern void init(void);
void
main (void)
{
init(); /* enable peripherals/interrupts */
while(1)
SLEEP(); /* save power while nothing happening */
}
WRITETIMERx
Synopsis
#include <xc.h>
void WRITETIMERx (int n);
Description
The WRITETIMERx() macro writes the 16-bit argument, n, to both bytes of the TMRx
register, where x is one of the digits 0, 1 or 3.
Example
#include <xc.h>
void
main (void)
{
WRITETIMER1(0x4A);
while(1)
continue;
}
Note
This macro can only be used with PIC18 devices.
MESSAGES 1-249
(110) too many file arguments; usage: cpp [input [output]] (Preprocessor)
CPP should be invoked with at most two file arguments. Contact Microchip Technical
Support if the preprocessor is being executed by a compiler driver.
(116) end of file within preprocessor macro argument from line * (Preprocessor)
A macro argument has not been terminated. This probably means the closing paren-
thesis has been omitted from a macro invocation. The line number given is the line
where the macro argument started, for example:
#define FUNC(a, b) func(a+b)
FUNC(5, 6; /* oops -- where is the closing bracket? */
(140) can’t open * file "*": * (Driver, Preprocessor, Code Generator, Assembler)
The command file specified could not be opened for reading. Confirm the spelling and
path of the file specified on the command line, for example:
xc8 @communds
should that be:
xc8 @commands
(165) #include filename "*" does not match actual name (check upper/lower case)
(Preprocessor)
In Windows versions this means the file to be included actually exists and is spelled the
same way as the #include filename; however, the case of each does not exactly
match. For example, specifying #include "code.c" will include Code.c, if it is
found. In Linux versions this warning could occur if the file wasn’t found.
(167) too many values specified with -S option; "*" unused Preprocessor)
There were too many values supplied to the -S preprocessor option. See message 166.
MESSAGES 250-499
(327) long long int argument required in printf-style format string (Parser)
A long long argument is required for this format specifier. Check the number and
order of format specifiers and corresponding arguments, for example:
printf("%llx", 2); // possibly you meant: printf("%llx", 2LL);
Note that MPLAB XC8 does not provide direct support for a long long integer type.
void main(void)
{
/* at this point, a prototype for set() has already been seen */
set(10L, 6);
}
(454) link and load address can’t both be set to "." in -P option (Linker)
The link and load address of a psect have both been specified with a dot character.
Only one of these addresses can be specified in this manner, for example:
-Pmypsect=1000h/.
-Pmypsect=./1000h
Both of these options are valid and equivalent. However, the following usage is
ambiguous:
-Pmypsect=./.
What is the link or load address of this psect?
(472) non-reentrant function "*" appears in multiple call graphs: rooted at "*" and "*"
(Linker)
This function can be called from both main-line code and interrupt code. Use the
reentrant keyword, if this compiler supports it, or recode to avoid using local vari-
ables or parameters, or duplicate the function, for example:
void interrupt my_isr(void)
{
scan(6); /* scan is called from an interrupt function */
}
void process(int a)
{
scan(a); /* scan is also called from main-line code */
}
(476) fixup overflow referencing * * (location 0x* (0x*+*), size *, value 0x*) (Linker)
The linker was asked to relocate (fixup) an item that would not fit back into the space
after relocation. See the following error message (1356) for more information.
(477) fixup overflow in expression (location 0x* (0x*+*), size *, value 0x*) (Linker)
The linker was asked to relocate (fixup) an item that would not fit back into the space
after relocation. See the following error message (1356) for more information.
(478) * range check failed (location 0x* (0x*+*), value 0x* > limit 0x*) (Linker)
This is an internal compiler error. Contact Microchip Technical Support with details.
(491) can’t find 0x* words for psect "*" in segment "*" (Linker)
One of the main tasks the linker performs is positioning the blocks (or psects) of code
and data that is generated from the program into the memory available for the target
device. This error indicates that the linker was unable to find an area of free memory
large enough to accommodate one of the psects. The error message indicates the
name of the psect that the linker was attempting to position and the segment name
which is typically the name of a class which is defined with a linker -A option.
MESSAGES 500-749
(525) too many address (memory) spaces; space (*) ignored (Linker)
The limit to the number of address spaces (specified with the PSECT assembler
directive) is currently 16.
(526) psect "*" not specified in -P option (first appears in "*") (Linker)
This psect was not specified in a -P or -A option to the linker. It has been linked at the
end of the program, which is probably not where you wanted it.
(593) can’t find 0x* words (0x* withtotal) for psect "*" in segment "*" (Linker)
See message (491).
(629) bad storage class "*" in SDB file "*" line * column * (Cromwell)
This is an internal compiler error. Contact Microchip Technical Support with details.
(630) invalid syntax for prefix list in SDB file "*" (Cromwell)
This is an internal compiler error. Contact Microchip Technical Support with details.
(631) syntax error at token "*" in SDB file "*" line * column * (Cromwell)
This is an internal compiler error. Contact Microchip Technical Support with details.
(668) prefix list did not match any SDB types (Cromwell)
This is an internal compiler error. Contact Microchip Technical Support with details.
(669) prefix list matched more than one SDB type (Cromwell)
This is an internal compiler error. Contact Microchip Technical Support with details.
(682) this architecture is not supported by the PICC™ Lite compiler (Code Generator)
A target device other than baseline, mid-range or highend was specified. This compiler
only supports devices from these architecture families.
(683) bank 1 variables are not supported by the PICC Lite compiler (Code Generator)
A variable with an absolute address located in bank 1 was detected. This compiler does
not support code generation of variables in this bank.
(684) bank 2 and 3 variables are not supported by the PICC Lite compiler
(Code Generator)
A variable with an absolute address located in bank 2 or 3 was detected. This compiler
does not support code generation of variables in these banks.
(691) interrupt functions not implemented for 12 bit PIC MCU (Code Generator)
The 12-bit range of PIC MCU processors do not support interrupts.
(692) more than one interrupt level is associated with the interrupt function "*"
(Code Generator)
Only one interrupt level can be associated with an interrupt function. Check to
ensure that only one interrupt_level pragma has been used with the function
specified. This pragma can be used more than once on main-line functions that are
called from interrupt functions. For example:
#pragma interrupt_level 0
#pragma interrupt_level 1 /* oops -- which is it to be: 0 or 1? */
void interrupt isr(void)
{
(693) 0 (default) or 1 are the only acceptable interrupt levels for this function
(Code Generator)
The only possible interrupt levels are 0 or 1. Check to ensure that all
interrupt_level pragmas use these levels.
#pragma interrupt_level 2 /* oops -- only 0 or 1 */
void interrupt isr(void)
{
/* isr code goes here */
}
(746) object "*" qualified const but not initialized (Code Generator)
An object has been qualified as const, but there is no initial value supplied at the defi-
nition. As this object cannot be written by the C program, this can imply the initial value
was accidentally omitted.
(748) variable "*" possibly used before being assigned a value (Code Generator)
This variable has possibly been used before it was assigned a value. Because it is an
auto variable, this will result in it having an unpredictable value, for example:
void main(void)
{
int a;
if(a) /* oops -- ’a’ has never been assigned a value */
process();
}
MESSAGES 750-999
(758) constant conditional branch: possible use of "=" instead of "==" (Code Generator)
There is an expression inside an if or other conditional construct, where a constant is
being assigned to a variable. This can mean you have inadvertently used an assign-
ment = instead of a compare ==, for example:
int a, b;
/* this can never be false;
always perform the true statement */
if(a = 4)
b = 6;
will assign the value 4 to a, then , as the value of the assignment is always true, the
comparison can be omitted and the assignment to b always made. Did you mean:
/* this can never be false;
always perform the true statement */
if(a == 4)
b = 6;
which checks to see if a is equal to 4.
(777) can’t allocate space for opnd structure within object "*" (offs: *) (Assembler)
The assembler has run out of memory.
(825) too many RAMBANK lines in chipinfo file for "*" (Assembler)
The chipinfo file contains a device section with too many RAMBANK fields. Reduce the
number of values.
(827) too many COMMON lines in chipinfo file for "*" (Assembler)
There are too many lines specifying common (access bank) memory in the chip
configuration file.
(848) label defined in this module has also been declared EXTRN (Assembler)
The definition for an assembly label, and an EXTRN declaration for the same symbol,
appear in the same module. Use GLOBAL instead of EXTRN if you want this symbol to
be accessible from other modules.
(857) use of both local and global psect flags is illegal with same psect (Linker)
A local psect cannot have the same name as a global psect, for example:
psect text,class=CODE ; the text psect is implicitly global
MOVE r0, r1
; elsewhere:
psect text,local,class=CODE
MOVE r2, r4
The global flag is the default for a psect if its scope is not explicitly stated.
(864) argument to "size" psect flag must specify a positive constant (Assembler)
The parameter to the PSECT assembler directive’s size option must be a positive con-
stant number, for example:
PSECT text,class=CODE,size=-200 ; a negative size?
(866) argument to "reloc" psect flag must specify a positive constant (Assembler)
The parameter to the PSECT assembler directive’s reloc option must be a positive
constant number, for example:
psect test,class=CODE,reloc=-4 ; the reloc must be positive
(868) argument to "delta" psect flag must specify a positive constant (Assembler)
The parameter to the PSECT assembler directive’s DELTA option must be a positive
constant number, for example:
PSECT text,class=CODE,delta=-2 ; negative delta value doesn’t make
sense
(870) argument to "pad" psect flag must specify a positive constant (Assembler)
The parameter to the PSECT assembler directive’s ’PAD’ option must be a non-zero
positive integer.
(871) argument to "space" psect flag must specify a positive constant (Assembler)
The parameter to the PSECT assembler directive’s space option must be a positive
constant number, for example:
PSECT text,class=CODE,space=-1 ; space values start at zero
(880) invalid number of parameters. Use "* –HELP" for help (Driver)
Improper command-line usage of the of the compiler’s driver.
(884) please ensure you have write permissions to the configuration file (Driver)
The compiler was not successfully setup using the --setup driver option because the
driver was unable to access the XML configuration file. Ensure that you have write per-
mission to this file. The driver will search the following configuration files in order:
• the file specified by the environment variable XC_XML
• the file /etc/xc.xml if the directory ’/etc ’ is writable and there is no .xc.xml
file in your home directory
• the file .xc.xml file in your home directory
If none of the files can be located, then the above error will occur.
(895) can’t request and specify options in the one command (Driver)
The usage of the driver options --getoption and --setoption is mutually
exclusive.
(899) can’t open option file "*" for application "*": * (Driver)
An option file specified by a --getoption or --setoption driver option could not
be opened. If you are using the --setoption option, ensure that the name of the file
is spelled correctly and that it exists. If you are using the --getoption option ensure
that this file can be created at the given location or that it is not in use by any other
application.
(902) no chip name specified; use "* –CHIPINFO" to see available chip names (Driver)
The driver was invoked without selecting what chip to build for. Running the driver with
the –CHIPINFO option will display a list of all chips that could be selected to build for.
(907) unknown memory space tag "*" in "*" option specification (Driver)
A parameter to this memory option was a string but did not match any valid tags. Refer
to the section of this manual that describes this option to see what tags (if any) are valid
for this device.
(913) "*" option can cause compiler errors in some standard header files (Driver)
Using this option will invalidate some of the qualifiers used in the standard header files,
resulting in errors. This issue and its solution are detailed in the section of this manual
that specifically discusses this option.
(915) no room for arguments (Preprocessor, Parser, Code Generator, Linker, Objtohex)
The code generator could not allocate any more memory.
(951) start of fill range must be less than end of range (Hexmate)
The -FILL option has been given a range where the start is greater than the end. The
parameters can be incomplete or entered in the wrong order.
(965) -STRPACK option not yet implemented; option will be ignored (Hexmate)
This option currently is not available and will be ignored.
(972) only modifiers "h" and "l" valid with this format (Parser)
Only modifiers h (short ) and l (long ) are legal with this printf format specifier.
(994) some command-line options are disabled and compilation is delayed (Driver)
The compiler is operating in demo mode. Some command-line options are disabled,
the compilation speed will be slower.
(995) some command-line options are disabled; code size is limited to 16kB, compilation
is delayed (Driver)
The compiler is operating in demo mode. Some command-line options are disabled;
the compilation speed will be slower, and the maximum allowed code size is limited to
16 KB.
MESSAGES 1000-1249
(1016) missing argument* to "*" specification in chipinfo file "*" at line * (Driver)
This value of this attribute is blank in the chip configuration file.
(1017) extraneous argument* to "*" specification in chipinfo file "*" at line * (Driver)
There are too many attributes for the listed specification in the chip configuration file.
(1018) illegal number of "*" specification* (* found; * expected) in chipinfo file "*" at line *
(Driver)
This attribute was expected to appear a certain number of times; but, it did not appear
for this chip.
(1021) syntax error reading "*" value in chipinfo file "*" at line * (Driver)
The chip configuration file incorrectly defines the specified value for this device. If you
are modifying this file yourself, take care and refer to the comments at the beginning of
this file for a description on what type of values are expected here.
(1022) syntax error reading "*" range in chipinfo file "*" at line * (Driver)
The chip configuration file incorrectly defines the specified range for this device. If you
are modifying this file yourself, take care and refer to the comments at the beginning of
this file for a description on what type of values are expected here.
(1032) use –HELP=<option> for usage of these command line options (Hexmate)
More detailed information is available for a specific option by passing that option to the
HELP option.
(1088) function pointer "*" is used but never assigned a value (Code Generator)
A function call involving a function pointer was made, but the pointer was never
assigned a target address, for example:
void (*fp)(int);
fp(23); /* oops -- what function does fp point to? */
(1098) conflicting declarations for variable "*" (*:*) (Parser, Code Generator)
Differing type information has been detected in the declarations for a variable, or
between a declaration and the definition of a variable, for example:
extern long int test;
int test; /* oops -- which is right? int or long int ? */
(1178) the "*" option has been removed and has no effect (Driver)
This option no longer exists in this version of the compiler and has been ignored. Use
the compiler’s –help option or refer to the manual to find a replacement option.
(1179) interrupt level for function "*" cannot exceed * (Code Generator)
The interrupt level for the function specified is too high. Each interrupt function is
assigned a unique interrupt level. This level is considered when analyzing the call
graph and reentrantly called functions. If using the interrupt_level pragma, check
the value specified.
(1190) FAE license only - not for use in commercial applications (Driver)
Indicates that this compiler has been activated with an FAE license. This license does
not permit the product to be used for the development of commercial applications.
(1205) using the configuration file *; you can override this with the environment variable
HTC_XML (Driver)
This is the compiler configuration file selected during compiler setup. This can be
changed via the HTC_XML environment variable. This file is used to determine where
the compiler has been installed.
(1207) some of the command line options you are using are now obsolete (Driver)
Some of the command line options passed to the driver have now been discontinued
in this version of the compiler; however, during a grace period these old options will still
be processed by the driver.
(1208) use –help option or refer to the user manual for option details (Driver)
An obsolete option was detected. Use –help or refer to the manual to find a replace-
ment option that will not result in this advisory message.
(1210) Visit the Microchip website (www.microchip.com) for a possible upgrade (Driver)
Visit our website to see if an upgrade is available to address the issue(s) listed in the
previous compiler message. Navigate to the MPLAB XC8 C Compiler page and look
for a version upgrade downloadable file. If your version is current, contact Microchip
Technical Support for further information.
(1248) symbol (*) encountered with undefined type size (Code Generator)
The code generator was asked to position a variable, but the size of the variable is not
known. This is an internal compiler error. Contact Microchip Technical Support with
details.
MESSAGES 1250-1499
(1250) could not find space (* byte*) for variable * (Code Generator)
The code generator could not find space in the banked RAM for the variable specified.
(1254) could not find space (* byte*) for data block (Code Generator)
The code generator could not find space in RAM for the data psect that holds initialized
variables.
(1257) local variable "*" is used but never given a value (Code Generator)
An auto variable has been defined and used in an expression, but it has not been
assigned a value in the C code before its first use. Auto variables are not cleared on
startup and their initial value is undefined. For example:
void main(void) {
double src, out;
out = sin(src); /* oops -- what value was in src? */
(1258) possible stack overflow when calling function "*" (Code Generator)
The call tree analysis by the code generator indicates that the hardware stack can over-
flow. This should be treated as a guide only. Interrupts, the assembler optimizer and the
program structure can affect the stack usage. The stack usage is based on the C pro-
gram and does not include any call tree derived from assembly code.
(1284) malformed mapfile while generating summary: CLASS expected but not found
(Driver)
The map file being read to produce a memory summary is malformed. Either the file
has been edited or corrupted, or this is a compiler error – contact Microchip Technical
Support with details.
(1286) malformed mapfile while generating summary: no link address at position * (Driver)
The map file being read to produce a memory summary is malformed. Either the file
has been edited or corrupted, or this is a compiler error – contact Microchip Technical
Support with details.
(1289) line range limit exceeded, possibly affecting ability to debug code (Cromwell)
A C statement has produced assembly code output whose length exceeds a preset
limit. This means that debug information produced by CROMWELL may not be accurate.
This warning does not indicate any potential code failure.
(1293) couldn’t find type for "*" in DWARF debugging information entry (Cromwell)
The type of symbol could not be determined from the SDB file passed to CROMWELL.
Either the file has been edited or corrupted, or this is a compiler error – contact
Microchip Technical Support with details.
(1294) there is only one day left until this license expires (Driver)
The compiler is running as a demo and will be unable to run in PRO mode after the
evaluation license has expired in less than one day’s time. After expiration, the compiler
can be operated in Free mode indefinitely, but will produce a larger output binary.
(1295) there are * days left until this license will expire (Driver)
The compiler is running as a demo and will be unable to run in PRO mode after the
evaluation license has expired in the indicated time. After expiration, the compiler can
be operated in Free mode indefinitely, but will produce a larger output binary.
(1300) maximum number of program classes reached; some classes may be excluded
from debugging information (Cromwell)
CROMWELL is passed a list of class names on the command line. If the number of class
names passed in is too large, not all will be used and there is the possibility that debug-
ging information will be inaccurate.
(1302) could not find valid ELF output extension for this device (Cromwell)
The extension could not be for the target device family.
(1310) specified speed (*Hz) exceeds max operating frequency (*Hz); defaulting to *Hz
(Driver)
The frequency specified to the perform suboption to --RUNTIME option is too large
for the selected device.
--RUNTIME=default,speed:0xffffffff
Oops, that value is too large.
(1311) missing configuration setting for config word *; using default (Driver)
The configuration settings for the indicated word have not be supplied in the source
code and a default value will be used.
(1312) conflicting runtime perform sub-option and configuration word settings; assuming
*Hz (Driver)
The configuration settings and the value specified with the perform suboption of the
--RUNTIME options conflict and a default frequency has been selected.
(1329) can only modify RAM type interrupt vectors (Code Generator)
The SETVECTOR() macro has been used to attempt to change the interrupt vector
table, but this table is in ROM and cannot be changed at runtime.
(1330) instruction set architecture qualifiers are only applicable to functions or function
pointers (Code Generator)
An instruction set qualifier has been used with something that does not represent exe-
cutable code.
mips16e int input; /* oops -- you cannot qualify a variable with an
instruction set type */
(1332) invalid qualifier (*) and type combination on "*" (Code Generator)
Some qualified variables must have a specific type or size. A combination has been
detected that is not allowed.
volatile cp0 int mycpvar @ __REGADDR(7,0); /* oops --
you must use unsigned types with the cp0 qualifier */
(1343) hexfile data at address 0x* (0x*) overwritten with 0x* (Objtohex)
The indicated address is about to be overwritten by additional data. This would indicate
more than one section of code contributing to the same address.
(1346) can’t find 0x* words for psect "*" in segment "*" (largest unused contiguous range
0x%lX) (Linker)
See also message (491). The new form of message also indicates the largest free
block that the linker could find. Unless there is a single space large enough to accom-
modate the psect, the linker will issue this message. Often when there is banking or
paging involved the largest free space is much smaller than the total amount of space
remaining,
(1347) can’t find 0x* words (0x* withtotal) for psect "*" in segment "*" (largest unused
contiguous range 0x%lX) (Linker)
See also message (593). The new form of message also indicates the largest free
block that the linker could find. Unless there is a single space large enough to accom-
modate the psect, the linker will issue this message. Often when there is banking or
paging involved the largest free space is much smaller than the total amount of space
remaining,
(1350) pointer operands to "-" must reference the same array (Code Generator)
If two addresses are subtracted, the addresses must be of the same object to be ANSI
compliant.
int * ip;
int fred, buf[20];
ip = &buf[0] - &fred; /* oops --
second operand must be an address of a "buf" element */
(1356) fixup overflow referencing * * (0x*) into * byte* at 0x*/0x* -> 0x* (*** */0x*) (Linker)
’Fixup’ is the process conducted by the linker of replacing symbolic references to oper-
ands with an absolute value. This takes place after positioning the psects (program
sections or blocks) into the available memory. ‘Fixup overflow’ is when a symbol’s value
is too large to fit within the assembler instruction. For example, if an assembler instruc-
tion has an 8-bit field to hold an address and the linker determines that the symbol used
to represent this address has the value 0x110, then clearly this value cannot be
encoded into the instruction.
Fixup errors are often caused by hand-written assembly code. Common mistakes that
trigger these errors include failing to mask a full, banked data address in file register
instructions, or failing to mask the destination address in jump or call instructions. If this
error is triggered by assembly code generated from C source, then it is often that con-
structs like switch() statements have generated a block of assembly too large for jump
instructions to span. Adjusting the default linker options can also causes such errors.
To identify these errors, follow these steps.
• Perform a debug build (in MPLAB X IDE select Debug > Discrete Debugger
Operation > Build for Debugging; alternatively, on the command line use the
-D__DEBUG option)
• Open the relevant assembler list file (ensure the MPLAB X IDE project properties
has XC8 Compiler > Preprocessing and Messaging > Generate the ASM listing
file enabled; alternatively, on the command line, use the --ASMLIST option)
• Find the instruction at the address quoted in the error message
Consider the following error message.
main.c: 4: (1356)(linker) fixup overflow referencing psect bssBANK1
(0x100) into 1 byte at 0x7FF0/0x1 -> 0x7FF0 (main.obj 23/0x0)
The file being linked was main.obj. This tells you the assembly list file in which you
should be looking is main.lst. The location of the instruction at fault is 0x7FF0. (You
can also tell from this message that the instruction is expecting a 1 byte quantity—this
size is rounded to the nearest byte—but the value was determined to be 0x100.)
In the assembly list file, search for the address specified in the error message.
61 007FF0 6F00 movwf _foobar,b ;#
and to confirm, look for the symbol referenced in the assembler instruction at this
address in the symbol table at the bottom of the same file.
Symbol Table Tue Oct 28 11:06:37 2014
_foobar 0100
(1357) fixup overflow storing 0x* in * byte* at 0x*/0x* -> 0x* (*** */0x*) (Linker)
See message (1356).
(1371) float type can’t be bigger than double type; double has been changed to * bits
(Driver)
Use of the --float and --double options has result in the size of the double type
being smaller than that of the float type. This is not permitted by the C Standard. The
double type size has been increased to be that indicated.
(1375) multiple interrupt functions (* and *) defined for device with only one interrupt
vector (Code Generator)
The named functions have both been qualified interrupt, but the target device only sup-
ports one interrupt vector and hence one interrupt function.
interrupt void isr_lo(void) {
// ...
}
interrupt void isr_hi(void) { // oops, cannot define two ISRs
// ...
}
(1376) initial value (*) too large for bitfield width (*) (Code Generator)
A structure with bit-fields has been defined an initialized with values. The value indi-
cated it too large to fit in the corresponding bit-field width.
struct {
unsigned flag :1;
unsigned mode :3;
} foobar = { 1, 100 }; // oops, 100 is too large for a 3 bit object
(1386) unable to determine the semantics of the configuration setting "*" for register "*"
(Parser, Code Generator)
The numerical value supplied to a configuration bit setting has no direct association
setting specified in the data sheet. The compiler will attempt to honor your request, but
check your device data sheet.
#pragma config OSC=11
// oops -- there is no direct association for that value on an 18F2520
// either use OSC=3 or OSC=RC
(1389) attempt to reprogram configuration * "*" with * (is *) (Parser, Code Generator)
A Configuration bit that was already programmed has been programmed again with a
conflicting setting to the original.
#pragma config WDT=ON
#pragma config WDT=OFF // oops -- watchdog on or off?
(1391) constant object size of * exceeds the maximum of * for this chip (Code Generator)
The const object defined is too large for the target device.
const int array[200] = { ... }; // oops -- not on a Baseline part!
(1392) function "*" is called indirectly from both mainline and interrupt code
(Code Generator)
A function has been called by main-line (non-interrupt) and interrupt code. If this warn-
ing is issued, it highlights that such code currently violates a compiler limitation for the
selected device.
(1394) attempting to create memory range ( * - * ) larger than page size * (Driver)
The compiler driver has detected that the memory settings include a program memory
“page” that is larger than the page size for the device. This would mostly likely be the
case if the --ROM option is used to change the default memory settings. Consult your
device data sheet to determine the page size of the device you are using and to ensure
that any contiguous memory range you specify using the --ROM option has a boundary
that corresponds to the device page boundaries.
--ROM=100-1fff
The above might need to be paged. If the page size is 800h, the above could specified
as
--ROM=100-7ff,800-fff,1000-17ff,1800-1fff
(1395) notable code sequence candidate suitable for compiler validation suite detected (*)
(Code Generator)
The compiler has in-built checks that can determine if combinations of internal code
templates have been encountered. Where unique combinations are uncovered when
compiling code, this message is issued. This message is not an error or warning and
its presence does not indicate possible code failure, but if you are willing to participate,
the code you are compiling can be sent to Support to assist with the compiler testing
process.
(1396) "*" positioned in the * memory region (0x* - 0x*) reserved by the compiler
(Code Generator)
Some memory regions are reserved for use by the compiler. These regions are not nor-
mally used to allocate variables defined in your code. However, by making variables
absolute, it is possible to place variables in these regions and avoid errors that would
normally be issued by the linker. (Absolute variables can be placed at any location,
even on top of other objects.) This warning from the code generator indicates that an
absolute has been detected that will be located at memory that the compiler will be
reserving. You must locate the absolute variable at a different location. This message
will commonly be issued when placing variables in the common memory space.
char shared @ 0x7; // oops, this memory is required by the compiler
(1397) unable to implement non-stack call to "*"; possible hardware stack overflow
(Code Generator)
The compiler must encode a C function call without using a call assembly instruction
and the hardware stack (i.e., use a lookup table), but is unable to. A call instruction
might be required if the function is called indirectly via a pointer, but if the hardware
stack is already full, an additional call will cause a stack overflow.
(1401) eeprom qualified variables can’t be accessed from both interrupt and mainline
code (Code Generator)
All eeprom variables are accessed via routines that are not reentrant. Code might fail
if an attempt is made to access eeprom-qualified variables from interrupt and main-line
code. Avoid accessing eeprom variables in interrupt functions.
(1402) a pointer to eeprom can’t also point to other data types (Code Generator)
A pointer cannot have targets in both the EEPROM space and ordinary data space.
(1410) can’t assign the result of an invalid function pointer (Code Generator)
The compiler will allow some functions to be called via a constant cast to be a function
pointer, but not all. The address specified is not valid for this device.
foobar += ((int (*)(int))0x0)(77);
// oops -- you cannot call a function with a NULL pointer
(1413) pointer comparisons involving address of "*", positioned at address 0x0, may be
invalid (Code Generator)
An absolute object placed at address 0 has had its address taken. By definition, this is
a NULL pointer and code which checks for NULL (i.e., checks to see if the address is
valid) can fail.
int foobar @ 0x00;
int * ip;
void
main(void)
{
ip = &foobar; // oops -- 0 is not a valid address
(1418) Attempt to read "control" qualified object which is Write-Only (Code Generator)
An attempt was made to read a write-only register.
state = OPTION; // oops -- you cannot read this register
(1419) using the configuration file *; you can override this with the environment variable
XC_XML (Driver)
This is the compiler configuration file that is selected during compiler setup. This can
be changed via the XC_XML environment variable. This file is used to determine where
the compiler has been installed. See message 1205.
(1425) __pack qualifier only applies to structures and structure members (Parser)
The qualifier you have specified only makes sense when used with structures or
structure members. It will be ignored.
__pack int c; // oops -- there aren’t inter-member spaces to pack in
an int
(1426) 24-bit floating point types are not supported; * have been changed to 32-bits
(Driver)
Floating-point types must be 32-bits wide to conform to the CCI Standard. These types
will be compiled as 32-bit wide quantities.
--DOUBLE=24
oops -- you cannot set this double size
(1429) attribute "*" is not understood by the compiler; this attribute will be ignored
(Parser)
The indicated attribute you have used is not valid with this implementation. It will be
ignored.
int x __attribute__ ((deprecate)) = 0;
oops -- did you mean deprecated?
(1431) the __section specifier is applicable only to variable and function definitions at
file-scope (Parser)
You cannot attempt to locate local objects using the __section() specifier.
int main(void) {
int __section("myData") counter; // oops -- you cannot specify a
section for autos
(1435) variable "*" is incompatible with other objects in section "*" (Code Generator)
You cannot place variables that have differing startup initializations into the same psect.
That is, variables that are cleared at startup and variables that are assigned an initial
non-zero value must be in different psects. Similarly, bit objects cannot be mixed with
byte objects, like char or int.
int __section("myData") input; // okay
int __section("myData") output; // okay
int __section("myData") lvl = 0x12; // oops -- not with uninitialized
bit __section("myData") mode; // oops again -- no bits with bytes
// each different object to their own new section
(1436) "*" is not a valid nibble; use hexadecimal digits only (Parser)
When using __IDLOC(), the argument must only consist of hexadecimal digits with
no radix specifiers or other characters. Any character which is not a hexadecimal digit
will be programmed as a 0 in the corresponding location.
__IDLOC(0x51); // oops -- you cannot use the 0x radix modifier
(1441) use __at() instead of '@' and ensure the address is applicable (Parser)
You have used the @ address specifier when using the IAR C extensions. Any
address specified is unlikely to be correct on a new architecture. Review the address
in conjunction with your device data sheet. To prevent this warning from appearing
again, use the reviewed address with the __at() specifier instead.
struct foo {
int i;
};
(1452) one or more spaces are defined as data and code (Cromwell)
The options passed to Cromwell indicate memory space is both in the code and data
space. Unless you are explicitly running this application, consider this an internal error.
Contact Microchip Technical Support with details.
--code-space=1,2 --data-space=1
Oops — is space 1 code or data?
(1454) stack size specified (*) is greater than available (*) (Driver)
The --STACK option has been used to specify the maximum sizes for each stack, but
the total amount of memory requested exceeds the amount of memory available.
--STACK=software:1000:1000:20000
Oops, that is too much stack space for a small device.
(1460) function-level profiling is not available for the selected chip (Driver)
Function profiling is only available for PIC18 or enhanced mid-range devices. If you are
not using such a device, do not attempt to use function profiling.
(1462) reentrant data stack model option conflicts with stack management option and will
be ignored (Code Generator)
The managed stack option allows conversion of function calls that would exceed the
hardware stack depth to calls that will use a lookup table. This option cannot be
enabled if the reentrant function model is also enabled. If you attempt to use both the
managed stack and reentrant function model options, this message will be generated.
Code will be compiled with the stack management option disabled. Either disable the
reentrant function model or the managed stack option.
(1463) reentrant data stack model not supported on this device; using compiled stack for
data (Code Generator)
The target device does not support reentrant functions. The program will be compiled
so that stack-based data is placed on a compiled stack.
(1464) number of arguments passed to function "*" does not match function's prototype
(Code Generator)
A function was called with arguments, but the definition of the function had an empty
parameter list (as opposed to a parameter list of void).
int test(); // oops--this should define the parameters
...
test(12, input);
(1465) the stack frame size for function "*" (* bytes) has exceeded the maximum allowable
(* bytes) (Code Generator)
The compiler has been able to determine that the software stack requirements for the
named function’s auto, parameter, and temporary variables exceed the maximum
allowable. The limits are 31 for enhanced mid-range devices and 127 for PIC18
devices. Reduce the size or number of these variables. Consider static local objects
instead of auto objects.
reentrant int addOffset(int offset) {
int report[400]; // oops--this will never fit on the software stack
(1466) registers * unavailable for code generation of this expression (Code Generator)
The compiler has been unable to generate code for this statement. This is essentially
a “can’t generate code” error message (message 712), but the reason for this inability
to compile relates to there not being enough registers available. See message 712 for
suggested workarounds.
(1467) pointer used for writes includes read-only target "*" (Code Generator)
A pointer to a non-const qualified type is being used to write a value, but the compiler
knows that this pointer has targets (the first of which is indicated) that have been
qualified const. This could lead to code failure or other error messages being
generated.
void keepTotal(char * cp) {
*cp += total;
}
char c;
const char name[] = "blender";
keepTotal(&c);
keepTotal(&name[2]); // oops--will write a read-only object
(1469) function specifier "reentrant/software" used with "*" ignored (Code Generator)
The reentrant (or software) specifier was used with a function (indicated) that can-
not be encoded to use the software stack. The specifier will be ignored and the function
will use the compiled stack.
reentrant int main(void) // oops--main cannot be reentrant
...
(1471) indirect function call via a NULL pointer ignored (Code Generator)
The compiler has detected a function pointer with no valid target other than NULL. That
pointer has been used to call a function. The call will not be made.
int (*fp)(int, int);
result = fp(8,10); // oops--this pointer has not been initialized
(1474) read-only target "*" may be indirectly written via pointer (Code Generator)
This is the same as message 1467, but for situations where an error is required. The
compiler has encountered a pointer that is used to write, and one or more of the
pointer’s targets are read-only.
const char c = ‘x’;
char * cp = &c; // will produce warning 359 about address assignment
*cp = 0x44; // oops--you ignored the warning above, now you are
// actually going to write using the pointer?
(1478) initial value for "*" differs to that in *:* (Code Generator)
The named object has been defined more than once and its initial values do not agree.
Remember that uninitialized objects of static storage duration are implicitly initialized
with the value zero (for all object elements or members, where appropriate).
char myArray[5] = { 0 };
// elsewhere
char myArray[5] = {0,2,4,6,8}; // oops--previously initialized
// with zeros, now with different values
(1480) initial value(s) not supplied in braces; zero assumed (Code Generator)
The assignment operator was used to indicate that the object was to be initialized, but
no values were found in the braces. The object will be initialized with the value(s) 0.
int xy_map[3][3] = { }; // oops--did you mean to supply values?
(1481) call from non-reentrant function, "*", to "*" might corrupt parameters
(Code Generator)
If several functions can be called indirectly by the same function pointer, they are called
‘buddy’ functions, and the parameters to buddy functions are aligned in memory. This
allows the parameters to be loaded without knowing exactly which function was called
by the pointer (as is often the case). However, this means that the buddy functions
cannot directly or indirectly call each other.
// fpa can call any of these, so they are all buddies
int (*fpa[])(int) = { one, two, three };
int one(int x) {
return three(x+1); // oops--one() cannot call buddy three()
}
(1484) the branch errata option is turned on and a BRW instruction was detected
(Assembler)
The use of this instruction may cause code failure with the selected device. Check the
published errata for your device to see if this restriction is applicable for your device
revision. If so, remove this instruction from hand-written assembly code.
btfsc status,2
brw next ;oops--this instruction cannot be safely used
call update
(1485) * mode is not available with the current license and other modes are not permitted
by the NOFALLBACK option (Driver)
This compiler’s license does not allow the requested compiler operating mode. Since
the --NOFALLBACK option is enabled, the compiler has produced this error and will not
fall back to a lower operating mode. If you believe that you are entitled to use the com-
piler in the requested mode, this error indicates that your compiler might not be
activated correctly.
(1486) size of pointer cannot be determined during preprocessing. Using default size *
(Preprocessor)
The preprocessor cannot determine the size of pointer type. Do not use the sizeof
operator in expressions that need to be evaluated by the preprocessor.
#if sizeof(int *) == 3 // oops - you can't take the size of a
pointer type
#define MAX 40
#endif
(1488) the stack frame size for function "*" may have exceeded the maximum allowable (*
bytes) (Code Generator)
This message is emitted in the situation where the indicated function's software-stack
data has exceeded the theoretical maximum allowable size. Data outside this stack
space will only be accessible by some instructions that could attempt to access it. In
some situations the excess data can be retrieved, your code will work as expected, and
you can ignore this warning. This is likely if the function calls a reentrant function that
returns a large object, like a structure, on the stack. At other times, instructions that are
unable to access this data will, in addition to this warning, trigger an error message at
the assembly stage of the build process, and you will need to look at reducing the
amount of stack data defined by the function.
(1491) runtime sub-option "*" is not available for this device (Driver)
A specified suboption to the --RUNTIME option is not available for the selected device.
xc8 --CHIP=MCP19114 --RUNTIME=+osccal main.c
Oops, the osccal suboption is not available for this device.
(1492) using updated 32-bit floating-point libraries; improved accuracy might increase
code size (Code Generator)
This advisory message ensures you are aware of the changes in 32-bit floating-point
library code operation that might lead to an increase in code size.
(1493) updated 32-bit floating-point routines might trigger "can't find space" messages
appearing after updating to this release; consider using the smaller 24-bit
floating-point types (Linker)
This advisory message ensures you are aware of the changes in 32-bit floating-point
library code operation which might lead to the Can’t Find Space error message that has
been issued.
MESSAGES 1500-1749
(1504) the PIC18 extended instruction set was enabled but is not supported by this
compiler (Parser)
The MPLAB XC8 compiler does not support generation of code using the PIC18
extended instruction set. The extended instruction set configuration bit must always be
disabled.
#pragma config XINST=ON // oops--this must be disabled at all times
(1506) multiple interrupt functions (* and *) defined at interrupt level * (Code Generator)
More than one interrupt function has been defined for the same priority.
void interrupt low_priority
isr(void)
{ ... }
(1507) asmopt state popped when there was no pushed state (Assembler)
The state of the assembler optimizers was popped in assembly code but there was no
corresponding push.
movlw 20h
movwf LATB
opt asmopt_pop; oops--there was never a state pushed
(1510) non-reentrant function "*" appears in multiple call graphs and has been duplicated
by the compiler (Code Generator)
This message indicates that the generated output for a function has been duplicated
since it has been called from both main-line and interrupt code. It does not indicate a
potential code failure. If you do not want function output duplicated, consider using the
hybrid stack model, if possible, or restructure your source code.
(1513) target "*" of pointer "*" not in the memory space specified by * (Code Generator)
The pointer assigned an address by this statement was defined using a pointer-target
specifier. This assignment might be assigning addresses to the pointer that conflict with
that memory space specifier.
__rom int * ip;
int foobar;
ip = &foobar; // oops -- foobar is in data memory, not program memory
(1515) disabling OCG optimizations for this device is not permitted (Driver)
Due to memory limits, projects targeting some devices cannot be built. Ensure that the
OCG category of optimization is enabled.
(1516) compiler does not support 64-bit integers on the target architecture
Due to memory restrictions, the current device cannot support 64-bit integers, and a
smaller integer will be used instead. Choose a type smaller than long long to sup-
press this warning.
long long int result; // oops - this will not be 64-bits wide
(1518) * function call made with an incomplete prototype (*) (Code Generator)
A function has been called with the compiler not having seen a complete prototype for
that function. Check for an empty parameter list in the declaration.
void foo(); // oops -- how will this call be encoded?
void main(void)
{
foo();
}
MESSAGES 2000-2249
(2011) __interrupt attribute/specifier has a base (*) not supported by this device (Parser)
The address specified with the base() argument to the __interrupt() specifier is
not valid for the target device. It cannot, for example, be lower than the reset value of
the IVTBASE register.
//oops -- the base() address is too low
void __interrupt(irq(TMR0), base(0x00)) tc0Int(void)
(2013) argument "*" used by "*" attribute/specifier not supported by this device (Parser)
The argument of the indicated specifier is not valid for the target device.
// oops -- base() can’t be used with a device that does not
// support vectored interrupts
void __interrupt(base(0x100)) myMidrangeISR(void)
(2014) interrupt vector table @ 0x* already has a default ISR "*" (Code Generator)
You can indicate only one default interrupt function for any vector location not specified
in a vector table. If you have specified this twice, check to make sure that you have
specified the correct base() address for each default.
void __interrupt(irq(default), base(0x100)) tc0Int(void) { ...
void __interrupt(irq(default), base(0x100)) tc1Int(void) { ...
// oops -- did you mean to use different different base() addresses?
(2015) interrupt vector table @ 0x* already has an ISR (*) to service IRQ * (*)
(Parser or Code Generator)
You have specified more than one interrupt function to handle a particular interrupt
source in the same vector table.
void __interrupt(irq(TMR0), base(0x100)) tc0Int(void) { ...
void __interrupt(irq(TMR0), base(0x100)) tc1Int(void) { ...
(2016) interrupt function "*" does not service any interrupt sources (Code Generator)
You have defined an interrupt function but did not indicate which interrupt source this
function should service. Use the irq() argument to indicate the source or sources.
//oops -- what interrupt does this service?
void __interrupt(low_priority, base(0x100)) tc0Int(void)
(2018) interrupt vector table @ 0x* has multiple functions (* and *) defined at interrupt level
* (Code Generator)
The program for a device operating in legacy mode has specified a vector table that
contains more than one function at the same interrupt priority-level in the same table.
In this mode, there can be at most one interrupt function for each priority level in each
vector table.
#pragma config MVECEN=0
void __interrupt(high_priority) tc0Int(void) {...
void __interrupt(high_priority) tc1Int(void) {...
(2020) IRQ * (*) in vector table @ 0x* is unassigned, will be programmed with the address
of a * (Code Generator)
The interrupt vector in the indicated vector table has not been programmed with an
address. The compiler will program this vector with an address as specified by the
--UNDEFINTS option.
(2022) runtime sub-option "ivt" specifies a base address (0x*) not supported by this
device (Driver)
The address specified with the ivt sub-option is not valid for the selected target
device. It cannot, for example, be lower than the reset value of the IVTBASE register.
(2024) runtime sub-option "ivt" specifies an interrupt table (@ 0x*) that has not been
defined (Driver)
The ivt sub-option to the --RUNTIME option was used to specify a IVT address, but
this address has not been specified in the source code with any ISR. Check that the
address in the option is correct, or check that the base() arguments to the __inter-
rupt() specifier are specified and are correct.
--RUNTIME=+ivt:0x100
Oops -- is this the right address? Nothing in the source code uses this base address.
(2025) qualifier * on local variable "*" is not allowed and has been ignored (Parser)
Some qualifiers are not permitted with auto or local static variables. This message
indicates that the indicated qualifier has been ignored with the named variable.
near int foobar; // oops -- auto variables cannot use near
(2026) variables qualified "*" are not supported for this device (Parser)
Some variable qualifiers are not permitted with some devices.
eeprom int serialNo; // oops -- can’t use eeprom with PIC18 devices
(2028) external declaration for identifier "*" doesn't indicate storage location
(Code Generator)
The declaration for an external object (e.g., one defined in assembly code) has no stor-
age specifiers to indicate the memory space in which it might reside. Code produced
by the compiler which accesses it might fail. Use const or a bank specifier as required.
extern int tapCounter; // oops - how does the compiler access this?
(2029) a function pointer cannot be used to hold the address of data (Parser)
A function pointer must only hold the addresses of function, not variables or objects.
int (*fp)(int);
int foobar;
fp = &foobar; // oops - a variable’s address cannot be assigned
(2030) a data pointer cannot be used to hold the address of a function (Parser)
A data pointer (even a generic void * pointer) cannot be used to hold the address of
a function.
void *gp;
int myFunc(int);
gp = foobar; // oops - a function’s address cannot be assigned
(2033) recursively called function might clobber a static register it has allocated in
expression (Code Generator)
The compiler has encountered a situation where a register is used by an expression
that is defined in a function that is called recursively, and that expression is part of a
larger expression that requires this same function to be called. The register might be
overwritten and the code may fail.
unsigned long fib_rec(unsigned long n)
{
// the temporary result of the LHS call to fib_rec() might
// store the result in a temp that is clobbered during the RHS
// call to the same function
return ((n > 1) ? (fib_rec(n-1) + fib_rec(n-2)) : n);
}
(2034) 24-bit floating-point types are not CCI compliant; use 32-bit setting for compliance
(Parser)
The CCI does not permit the use of 24-bit floating point types. If you require compli-
ance, use the -no-short-float and -no-short-double options, which will
ensure the IEEE standard 32-bit floating-point type is used for float and double
types.
(2036) use of @ is not compliant with CCI, use __at() instead (Parser)
The CCI does not permit the definition of absolute functions and objects that use the @
address construct. Instead, place __at(address) after the identifier in the defini-
tion.
int foobar @ 0x100; // oops -- use __at(0x100) instead
(2037) short long integer types are not compliant with CCI (Parser)
The CCI does not permit use of the 3-byte short long type. Instead consider an
equivalent long int type.
short long input; // oops -- consider input to be long when using CCI
(2038) use of short long integer types is deprecated; use __int24 or __uint24 to avoid this
warning (Parser)
The short long type specifiers has been replaced with the more portable __int24
(replacing short long) and __uint24 (replacing unsigned short long) types.
short long input; // oops -- use __int24 as the type for input
(2042) no target device specified; use the -mcpu option to specify a target device
(Driver)
The driver was invoked without selecting what chip to build for. Running the driver with
the -mprint-devices option will display a list of all chips that could be selected to
build for.
xc8 -cc main.c
Oops, use the -mcpu option to specify the device to build for.
(2046) identifier length must be between * and *; using default length * (Driver)
The number of characters specified as the largest significant identifier length is illegal
and the default length of 255 has been used.
-N=16
Oops, the identifier length must be between 32 and 255.
This chapter indicates the compiler’s choice of behavior where that behavior is
implementation defined.
C.2 OVERVIEW
C.3 TRANSLATION
ISO Standard: “How a diagnostic is identified (3.10, 5.1.1.3).”
Implementation: By default, when compiling on the command-line the following formats are
used. The string (warning) is only displayed for warning messages.
filename: function()
linenumber:source line
^ (ID) message (warning)
or
filename: linenumber: (ID) message (warning)
where filename is the name of the file that contains the code (or empty
if no particular file is relevant); linenumber is the line number of the
code (or 0 if no line number is relevant); ID is a unique number that iden-
tifies the message; and message is the diagnostic message itself.
ISO Standard: “Whether each nonempty sequence of white-space characters other than
new-line is retained or replaced by one space character in translation
phase 3 (5.1.1.2).”
Implementation: Clang will replace each leading or interleaved whitespace character
sequences with a space. A trailing sequence of whitespace characters is
replaced with a new-line.
C.4 ENVIRONMENT
ISO Standard: "The mapping between physical source file multibyte characters and the
source character set in translation phase 1 (5.1.1.2)."
Implementation: Multi-byte characters are not supported in source files.
ISO Standard: “The name and type of the function called at program start-up in a
freestanding environment (5.1.2.1).”
Implementation: int main (void);
ISO Standard: “The effect of program termination in a freestanding environment (5.1.2.1).”
Implementation: A soft reset implemented by a branch to the reset vector location.
ISO Standard: “An alternative manner in which the main function may be defined
(5.1.2.2.1).”
Implementation: void main (void);
ISO Standard: “The values given to the strings pointed to by the argv argument to main
(5.1.2.2.1).”
Implementation: No arguments are passed to main. Reference to argc or argv is
undefined.
ISO Standard: “What constitutes an interactive device (5.1.2.3).”
Implementation: Application defined.
ISO Standard: "The set of signals, their semantics, and their default handling (7.14)."
Implementation: Signals are not implemented.
ISO Standard: "Signal values other than SIGFPE, SIGILL, and SIGSEGV that corre-
spond to a computational exception (7.14.1.1)."
Implementation: Signals are not implemented.
ISO Standard: “Signals for which the equivalent of signal(sig, SIG_IGN); is
executed at program start-up (7.14.1.1).”
Implementation: Signals are not implemented.
ISO Standard: “The set of environment names and the method for altering the
environment list used by the getenv function (7.20.4.5).”
Implementation: The host environment is application defined.
ISO Standard: “The manner of execution of the string by the system function (7.20.4.6).”
Implementation: The host environment is application defined.
C.5 IDENTIFIERS
ISO Standard: “Which additional multibyte characters may appear in identifiers and their
correspondence to universal character names (6.4.2).”
Implementation: None.
ISO Standard: “The number of significant initial characters in an identifier (5.2.4.1,
6.4.2).”
Implementation: All characters are significant.
C.6 CHARACTERS
ISO Standard: “The number of bits in a byte (C90 3.4, C99 3.6).”
Implementation: 8.
ISO Standard: “The values of the members of the execution character set (C90 and C99
5.2.1).”
Implementation: The execution character set is ASCII.
ISO Standard: “The unique value of the member of the execution character set produced
for each of the standard alphabetic escape sequences (C90 and C99
5.2.2).”
Implementation: The execution character set is ASCII.
ISO Standard: “The value of a char object into which has been stored any character
other than a member of the basic execution character set (C90 6.1.2.5,
C99 6.2.5).”
Implementation: The value of the char object is the 8-bit binary representation of the char-
acter in the source character set. That is, no translation is done.
ISO Standard: “Which of signed char or unsigned char has the same range, rep-
resentation, and behavior as “plain” char (C90 6.1.2.5, C90 6.2.1.1, C99
6.2.5, C99 6.3.1.1).”
Implementation: By default, unsigned char is functionally equivalent to plain char. The
options -funsigned-char and -fsigned-char can be used to explic-
itly specify the type.
ISO Standard: “The mapping of members of the source character set (in character con-
stants and string literals) to members of the execution character set (C90
6.1.3.4, C99 6.4.4.4, C90 and C99 5.1.1.2).”
Implementation: The binary representation of the source character set is preserved to the
execution character set.
ISO Standard: “The value of an integer character constant containing more than one
character or containing a character or escape sequence that does not
map to a single-byte execution character (C90 6.1.3.4, C99 6.4.4.4).”
Implementation: The previous value is shifted left by eight, and the bit pattern of the next
character is masked in. The final result is of type int. If the result is larger
than can be represented by an int, a warning diagnostic is issued and
the value truncated to int size.
ISO Standard: “The value of a wide character constant containing more than one multib-
yte character, or containing a multibyte character or escape sequence not
represented in the extended execution character set (C90 6.1.3.4, C99
6.4.4.4).”
Implementation: Multi-byte characters are not supported in source files.
ISO Standard: “The current locale used to convert a wide character constant consisting
of a single multibyte character that maps to a member of the extended
execution character set into a corresponding wide character code (C90
6.1.3.4, C99 6.4.4.4).”
Implementation: Multi-byte characters are not supported in source files.
ISO Standard: “The current locale used to convert a wide string literal into corresponding
wide character codes (C90 6.1.4, C99 6.4.5).”
Implementation: Wide strings are not supported.
ISO Standard: “The value of a string literal containing a multibyte character or escape
sequence not represented in the execution character set (C90 6.1.4, C99
6.4.5).”
Implementation: Multi-byte characters are not supported in source files.
C.7 INTEGERS
ISO Standard: “Any extended integer types that exist in the implementation (C99 6.2.5).”
Implementation: The __bit keyword designates a single-bit integer type. The __int24
and __uint24 keywords designate a signed and unsigned, respectively,
24-bit integer type.
ISO Standard: “Whether signed integer types are represented using sign and magnitude,
two’s complement, or one’s complement, and whether the extraordinary
value is a trap representation or an ordinary value (C99 6.2.6.2).”
Implementation: All integer types are represented as two’s complement, and all bit
patterns are ordinary values.
ISO Standard: “The rank of any extended integer type relative to another extended inte-
ger type with the same precision (C99 6.3.1.1).”
Implementation: There are no extended integer types with the same precision.
ISO Standard: “The result of, or the signal raised by, converting an integer to a signed
integer type when the value cannot be represented in an object of that
type (C90 6.2.1.2, C99 6.3.1.3).”
Implementation: When converting value X to a type of width N, the value of the result is the
Least Significant N bits of the 2’s complement representation of X. That is,
X is truncated to N bits. No signal is raised.
ISO Standard: “The results of some bitwise operations on signed integers (C90 6.3, C99
6.5).”
Implementation: The right shift operator sign extends signed values. Thus, an object with
the signed int value 0x0124 shifted right one bit will yield the value
0x0092 and the value 0x8024 shifted right one bit will yield the value
0xC012. Right shifts of unsigned integral values always clear the MSb of
the result. Left shifts (<< operator), signed or unsigned, always clear the
LSb of the result.
Other bitwise operations act as if the operand was unsigned.
C.8 FLOATING-POINT
ISO Standard: “The accuracy of the floating-point operations and of the library functions
in <math.h> and <complex.h> that return floating-point results (C90
and C99 5.2.4.2.2).”
Implementation: The accuracy is unknown.
ISO Standard: “The rounding behaviors characterized by non-standard values of
FLT_ROUNDS (C90 and C99 5.2.4.2.2).”
Implementation: No such values are used.
ISO Standard: “The evaluation methods characterized by non-standard negative values
of FLT_EVAL_METHOD (C90 and C99 5.2.4.2.2).”
Implementation: No such values are used.
ISO Standard: “The direction of rounding when an integer is converted to a floating-point
number that cannot exactly represent the original value (C90 6.2.1.3, C99
6.3.1.4).”
Implementation: The integer is rounded to the nearest floating point representation.
ISO Standard: “The direction of rounding when a floating-point number is converted to a
narrower floating-point number (C90 6.2.1.4, 6.3.1.5).”
Implementation: A floating-point number is rounded down when converted to a narrow
floating-point value.
ISO Standard: “How the nearest representable value or the larger or smaller represent-
able value immediately adjacent to the nearest representable value is
chosen for certain floating constants (C90 6.1.3.1, C99 6.4.4.2).”
Implementation: Not applicable; FLT_RADIX is a power of 2
ISO Standard: “Whether and how floating expressions are contracted when not disal-
lowed by the FP_CONTRACT pragma (C99 6.5).”
Implementation: The pragma is not implemented.
ISO Standard: “The default state for the FENV_ACCESS pragma (C99 7.6.1).”
Implementation: This pragma is not implemented.
ISO Standard: “Additional floating-point exceptions, rounding modes, environments, and
classifications, and their macro names (C99 7.6, 7.12).”
Implementation: None supported.
ISO Standard: “The default state for the FP_CONTRACT pragma (C99 7.12.2).”
Implementation: This pragma is not implemented.
ISO Standard: “Whether the “inexact” floating-point exception can be raised when the
rounded result actually does equal the mathematical result in an IEC
60559 conformant implementation (C99 F.9).”
Implementation: The exception is not raised.
ISO Standard: “Whether the “underflow” (and “inexact”) floating-point exception can be
raised when a result is tiny but not inexact in an IEC 60559 conformant
implementation (C99 F.9).”
Implementation: The exception is not raised.
C.10 HINTS
ISO Standard: “The extent to which suggestions made by using the register stor-
age-class specifier are effective (C90 6.5.1, C99 6.7.1).”
Implementation: The register storage class specifier has no effect.
ISO Standard: “The extent to which suggestions made by using the inline function
specifier are effective (C99 6.7.4).”
Implementation: A function might be inlined if a PRO-licensed compiler has the optimizers
set to level 2 or higher. In other situations, the function will not be inlined.
C.12 QUALIFIERS
ISO Standard: “What constitutes an access to an object that has volatile-qualified
type (C90 6.5.3, C99 6.7.3).”
Implementation: Each reference to the identifier of a volatile-qualified object constitutes
one access to the object.
ISO Standard: “The places that are searched for an included < > delimited header, and
how the places are specified or the header is identified (C90 6.8.2, C99
6.10.2).”
Implementation: The preprocessor searches any directory specified using the -I option,
then, provided the -nostdinc option has not been used, the standard
compiler include directory, <install directory>/pic/include
ISO Standard: “How the named source file is searched for in an included "" delimited
header (C90 6.8.2, C99 6.10.2).”
Implementation: The compiler first searches for the named file in the directory containing
the including file, then the directories which are searched for a < >
delimited header.
ISO Standard: “The method by which preprocessing tokens are combined into a header
name (C90 6.8.2, C99 6.10.2).”
Implementation: All tokens, including whitespace, are considered part of the header file
name. Macro expansion is not performed on tokens inside the delimiters.
ISO Standard: “The nesting limit for #include processing (C90 6.8.2, C99 6.10.2).”
Implementation: No limit.
ISO Standard: "Whether the # operator inserts a \ character before the \ character that
begins a universal character name in a character constant or string literal
(6.10.3.2)."
Implementation: No.
ISO Standard: “The behavior on each recognized non-STDC #pragma directive (C90
6.8.6, C99 6.10.6).”
Implementation: See Section 4.14.3 “Pragma Directives”
ISO Standard: “The definitions for __DATE__ and __TIME__ when respectively, the
date and time of translation are not available (C90 6.8.8, C99 6.10.8).”
Implementation: The date and time of translation are always available.
ISO Standard: “Whether or not the strtod, strtof, strtold, wcstod, wcstof, or
wcstold function sets errno to ERANGE when underflow occurs
(7.20.1.3, 7.24.4.1.1).”
Implementation: No.
ISO Standard: “Whether the calloc, malloc, and realloc functions return a Null
Pointer or a pointer to an allocated object when the size requested is zero
(7.20.3).”
Implementation: Memory allocation functions are not implemented.
ISO Standard: “Whether open output streams are flushed, open streams are closed, or
temporary files are removed when the abort function is called
(7.20.4.1).”
Implementation: Streams are not implemented.
ISO Standard: “The termination status returned to the host environment by the abort
function (7.20.4.1).”
Implementation: The host environment is application defined.
ISO Standard: “The value returned by the system function when its argument is not a
Null Pointer (7.20.4.5).”
Implementation: The host environment is application defined.
ISO Standard: “The local time zone and Daylight Saving Time (7.23.1).”
Implementation: Application defined.
ISO Standard: "The range and precision of times representable in clock_t and time_t
(7.23)"
Implementation: the time_t type is used to hold a number of seconds and is defined as a
long type; clock_t is not defined.
ISO Standard: “The era for the clock function (7.23.2.1).”
Implementation: Application defined.
ISO Standard: “The replacement string for the %Z specifier to the strftime, strfx-
time, wcsftime, and wcsfxtime functions in the “C” locale (7.23.3.5,
7.23.3.6, 7.24.5.1, 7.24.5.2).”
Implementation: These functions are unimplemented.
ISO Standard: “Whether or when the trigonometric, hyperbolic, base-e exponential,
base-e logarithmic, error, and log gamma functions raise the inexact
exception in an IEC 60559 conformant implementation (F.9).”
Implementation: No.
ISO Standard: “Whether the functions in <math.h> honor the Rounding Direction mode
(F.9).”
Implementation: The rounding mode is not forced.
C.15 ARCHITECTURE
ISO Standard: “The values or expressions assigned to the macros specified in the
headers <float.h>, <limits.h>, and <stdint.h> (C90 and C99
5.2.4.2, C99 7.18.2, 7.18.3).”
Implementation: See Table A-4, Table A-7 and the header files in <install direc-
tory>/pic/include/c99.
ISO Standard: “The number, order, and encoding of bytes in any object (when not
explicitly specified in the standard) (C99 6.2.6.1).”
Implementation: Little endian, populated from Least Significant Byte first.
ISO Standard: “The value of the result of the sizeof operator (C90 6.3.3.4, C99
6.5.3.4).”
Implementation: The type of the result is equivalent to unsigned int.
C
C\C++
C is a general-purpose programming language which features economy of expression,
modern control flow and data structures, and a rich set of operators. C++ is the
object-oriented version of C.
Calibration Memory
A special function register or registers used to hold values for calibration of a PIC micro-
controller on-board RC oscillator or other device peripherals.
Central Processing Unit
The part of a device that is responsible for fetching the correct instruction for execution,
decoding that instruction, and then executing that instruction. When necessary, it works
in conjunction with the arithmetic logic unit (ALU) to complete the execution of the
instruction. It controls the program memory address bus, the data memory address
bus, and accesses to the stack.
Clean
Clean removes all intermediary project files, such as object, hex and debug files, for
the active project. These files are recreated from other files when a project is built.
COFF
Common Object File Format. An object file of this format contains machine code,
debugging and other information.
Command Line Interface
A means of communication between a program and its user based solely on textual
input and output.
Compiled Stack
A region of memory managed by the compiler in which variables are statically allocated
space. It replaces a software or hardware stack when such mechanisms cannot be effi-
ciently implemented on the target device.
Compiler
A program that translates a source file written in a high-level language into machine
code.
Conditional Assembly
Assembly language code that is included or omitted based on the assembly-time value
of a specified expression.
Conditional Compilation
The act of compiling a program fragment only if a certain constant expression, specified
by a preprocessor directive, is true.
Configuration Bits
Special-purpose bits programmed to set PIC microcontroller modes of operation. A
Configuration bit can or cannot be preprogrammed.
Control Directives
Directives in assembly language code that cause code to be included or omitted based
on the assembly-time value of a specified expression.
CPU
See Central Processing Unit.
E
EEPROM
Electrically Erasable Programmable Read Only Memory. A special type of PROM that
can be erased electrically. Data is written or erased one byte at a time. EEPROM
retains its contents even when power is turned off.
ELF
Executable and Linking Format. An object file of this format contains machine code.
Debugging and other information is specified in with DWARF. ELF/DWARF provide
better debugging of optimized code than COFF.
Emulation/Emulator
See ICE/ICD.
Endianness
The ordering of bytes in a multi-byte object.
Environment
MPLAB PM3 – A folder containing files on how to program a device. This folder can be
transferred to a SD/MMC card.
Epilogue
A portion of compiler-generated code that is responsible for deallocating stack space,
restoring registers and performing any other machine-specific requirement specified in
the runtime model. This code executes after any user code for a given function,
immediately prior to the function return.
EPROM
Erasable Programmable Read Only Memory. A programmable read-only memory that
can be erased usually by exposure to ultraviolet radiation.
Error/Error File
An error reports a problem that makes it impossible to continue processing your pro-
gram. When possible, an error identifies the source file name and line number where
the problem is apparent. An error file contains error messages and diagnostics gener-
ated by a language tool.
Event
A description of a bus cycle which can include address, data, pass count, external
input, cycle type (fetch, R/W), and time stamp. Events are used to describe triggers,
breakpoints and interrupts.
Executable Code
Software that is ready to be loaded for execution.
Export
Send data out of the MPLAB IDE in a standardized format.
Expressions
Combinations of constants and/or symbols separated by arithmetic or logical
operators.
Extended Microcontroller Mode
In extended microcontroller mode, on-chip program memory as well as external mem-
ory is available. Execution automatically switches to external if the program memory
address is greater than the internal memory space of the PIC18 device.
V
Vector
The memory locations that an application will jump to when either a Reset or interrupt
occurs.
Volatile
A variable qualifier which prevents the compiler applying optimizations that affect how
the variable is accessed in memory.
W
Warning
MPLAB IDE – An alert that is provided to warn you of a situation that would cause phys-
ical damage to a device, software file, or equipment.
16-bit assembler/compiler – Warnings report conditions that can indicate a problem,
but do not halt processing. In MPLAB C30, warning messages report the source file
name and line number, but include the text ‘warning:’ to distinguish them from error
messages.
Watch Variable
A variable that you can monitor during a debugging session in a Watch window.
Watch Window
Watch windows contain a list of watch variables that are updated at each breakpoint.
Watchdog Timer (WDT)
A timer on a PIC microcontroller that resets the processor after a selectable length of
time. The WDT is enabled or disabled and set up using Configuration bits.
Workbook
For MPLAB SIM stimulator, a setup for generation of SCL stimulus.
Index
Symbols _COMMON_ macro ............................................... 161
_ assembly label character .............................151, 186 _delay function ................................................. 32, 272
__at address construct, see absolute variables/func- _EEPROM_INT macro........................................... 161
tions _EEPROMSIZE macro............................118, 119, 161
__bank qualifier...................................................... 109 _ERRATA_TYPES macro........................................ 62
__bit type ................................................................. 96 _FLASH_ERASE_SIZE macro .............................. 161
__builtin_software_breakpoint builtin ......266, 267, 268 _FLASH_WRITE_SIZE macro ............................... 161
__Bxxxx type symbols ........................................... 178 _GPRBITS_ macro ................................................ 161
__compiled qualifier ............................................... 124 _GPRCOUNT_ macro............................................ 161
__conditional_software_breakpoint macro............. 268 _HAS_OSCVAL macro .......................................... 161
__control qualifier..................................................... 92 _HTC_EDITION_ macro ........................................ 162
__DATABANK macro............................................. 162 _PIC12 macro ........................................................ 162
__DATE__ macro .................................................. 162 _PIC14E macro...................................................... 162
__DEBUG macro ....................................224, 268, 269 _PIC18 macro ........................................................ 162
__debug_break macro ........................................... 269 _PROGMEM_ macro ............................................. 162
__delay_ms macro................................................. 269 _RAMSIZE macro .................................................. 162
__delay_us macro.................................................. 269 _READ_OSCCAL_DATA macro.............................. 93
__delaywdt_ms macro ........................................... 269 _ROMSIZE macro.................................................. 162
__delaywdt_us macro ............................................ 269 ;; macro comment suppress character................... 200
__eeprom qualifier ..........................................110, 118 ? assembly label character .................................... 186
__EEPROM_DATA macro ..............................118, 270 ??nnnn type symbols ..................................... 186, 200
__EXTMEM macro................................................. 162 . (dot) linker load address character....................... 222
__far qualifier ......................................................... 110 .h files, see header files
__FILE__ macro .................................................... 162 .hxl files, see hexmate log files
__FLASHTYPE macro ........................................... 162 .i files, see preprocessed files
__fpnormalize function ........................................... 270 .map files, see map files
__Hxxxx type symbols ........................................... 178 .s files, see assembly files
__interrupt qualifier ................................................ 132 .sx files, see assembly files
__LINE__ macro .................................................... 162 xxxx@yyyy type symbols ....................................... 152
__LOG macro (REAL ICE)....................................... 94 @ command file specifier................................. 46, 219
__Lxxxx type symbols ............................................ 178 / psect address symbol .......................................... 222
__MPLAB_ICD__ macro........................................ 161 & macro concatenation character .................. 184, 199
__near qualifier ...............................................110, 117 && bitwise AND operator ....................................... 184
__nonreentrant qualifier ..................................114, 124 # preprocessor operator......................................... 160
__OPTIMIZE_SPEED__ macro ............................. 163 ## preprocessor operator....................................... 160
__osccal_val function............................................. 271 #pragma
__persistent qualifier ...............................111, 143, 144 addrqual .......................................................... 165
__PICC__ macro ................................................... 163 inline................................................................ 165
__PICCPRO__ macro............................................ 163 interrupt_level ................................................. 166
__ram pointer-target specifier ................................ 102 intrinsic............................................................ 165
__reentrant qualifier ........................................114, 124 printf_check..................................................... 166
__RESETBITS_ADDR macro ................................ 163 regsused ......................................................... 167
__rom pointer-target specifier ................................ 102 switch .............................................................. 167
__section qualifier ...........................................111, 175 % macro argument prefix ....................................... 200
__software qualifier ................................................ 124 % message format placeholder character................ 55
__TRACE macro (REAL ICE) .................................. 94 <> macro argument characters ...................... 184, 200
__XC macro ........................................................... 163 $ assembly label character .................................... 186
__XC8 macro ......................................................... 163 $ location counter symbol ...................................... 186
__XC8_VERSION macro ....................................... 163 Numerics
_BANKBITS_ macro .............................................. 161
0b binary radix specifier ......................................... 106
_Bool type ................................................................ 96