Microchip Technology MPLAB® C Compiler User’s Guide

MPLAB® C Compiler
for PIC24 MCUs
and dsPIC® DSCs
User’s Guide
2002-2011 Microchip Technology Inc. DS51284K
Note the following details of the code protection feature on Microchip devices:
Microchip products meet the specification contained in their particular Microchip Data Sheet.
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.
Information contained in this publication regarding device applications and t he lik e is provided only for your convenience and may be su perseded by upda t es . It is y our responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life supp ort and/or safety ap plications is entir ely at the buyer’s risk, and the buyer agrees to defend, indemnify and hold harmless M icrochip from any and all dama ges, claims, suits, or expenses re sulting from such use. No licens es are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.
Trademarks
The Microchip name and logo, the Microchip logo, dsPIC, K
EELOQ, KEELOQ logo, MPLAB, PIC, PICmicro, PICSTART,
32
PIC
logo, rfPIC and UNI/O are registered trademarks of Microchip Technology Incorporated in the U.S.A. and other countries.
FilterLab, Hampshire, HI-TECH C, Linear Active Thermistor, MXDEV, MXLAB, SEEVAL and The Embedded Control Solutions Company are registered trademarks of Microchip Technology Incorporated in the U.S.A.
Analog-for-the-Digital Age, Application Maestro, chipKIT, chipKIT logo, CodeGuard, dsPICDEM, dsPICDEM.net, dsPICworks, dsSPEAK, ECAN, ECONOMONITOR, FanSense, HI-TIDE, In-Circuit Serial Programming, ICSP, Mindi, MiWi, MPASM, MPLAB Certified logo, MPLIB, MPLINK, mTouch, Omniscient Code Generation, PICC, PICC-18, PICDEM, PICDEM.net, PICkit, PICtail, REAL ICE, rfLAB, Select Mode, Total Endurance, TSHARC, UniWinDriver, WiperLock and ZENA are trademarks of Microchip Technology Incorporated in the U.S.A. and other countries.
SQTP is a service mark of Microchip Technology Incorporated in the U.S.A.
All other trademarks mentioned herein are property of their respective companies.
© 2002-2011, Microchip Technology Incorporated, Printed in the U.S.A., All Rights Reserved.
Printed on recycled paper.
ISBN: 978-1-61341-294-7
Microchip received ISO/TS-16949:2002 certification for its worldwide headquarters, design and wafer fabrication facilities in Chandler and Tempe, Arizona; Gresham, Oregon and design centers in California and India. The Company’s quality system processes and procedures are for its PIC devices, Serial EEPROMs, microperipherals, nonvolatile memory and analog products. In addition, Microchip’s quality system for the design and manufacture of development systems is ISO 9001:2000 certified.
®
MCUs and dsPIC® DSCs, KEELOQ
®
code hopping
MPLAB® C COMPILER FOR
®
PIC24 MCUs AND dsPIC
DSCs
USER’S GUIDE

Table of Contents

Preface ...........................................................................................................................7
Chapter 1. Compiler Overview
1.1 Introduction ...................................................................................................13
1.2 Highlight s ......... .. ........................................................................................... 13
1.3 Compiler Des c ription and Do cu mentation .............. .. ........................... .. ....... 1 3
1.4 Compiler and Other Development Tools ......................................................14
1.5 Compiler Feature Set ...................................................................................16
Chapter 2. Differences Between 16-Bit Device C and ANSI C
2.1 Introduction ...................................................................................................17
2.2 Highlight s ......... .. ........................................................................................... 17
2.3 Keyword Di ffe r e n ce s ........ ............................. ............................................... 17
2.4 Statement Difference s .................................................................................. 37
2.5 Expressi on D if fe rences .. ............. ... .. ............. .. .. ........................... .. .. ............ 38
Chapter 3. Using the Compiler on the Command Line
3.1 Introduction ...................................................................................................39
3.2 Highlight s ......... .. ........................................................................................... 39
3.3 Overview ............. ......................................................................................... 39
3.4 File Naming Conventions ............................................................................. 40
3.5 Options ....... .................................................................................................. 40
3.6 Environme n t V a ri a bl e s ........................................................................ .. .. ..... 6 4
3.7 Predefined Macro Names .............................................................................65
3.8 Compiling a Single File on the Command Line ............................................ 66
3.9 Compiling Multiple Files on the Command Line ...........................................67
3.10 Notab le Sym b o l s ....................................................................................... . 67
Chapter 4. Run Time Environment
4.1 Introduction ...................................................................................................69
4.2 Highlight s ......... .. ........................................................................................... 69
4.3 Address Sp a ce s ......... .................................................................................. 69
4.4 Startup and Initialization .......................... .......................................... ...........70
4.5 Memory Sp ac e s ............. ..................................................... .. ... .................... 71
4.6 Memory Models ............................................................................................72
4.7 Locating Code and Data ....................................................................... .. ......74
4.8 Software St a ck ......... ......................................... ........................................... 75
4.9 The C Stack U s a ge .......... ............................................................................ 76
4.10 The C Heap Usage .....................................................................................78
4.11 Function Call Conventions ......................................................................... 79
4.12 Regist e r C o n ven tions ................................................................................. 81
2003-2011 Microchip Technology Inc. Update Draft DS51284J3-page 3
16-Bit C Compiler User’s Guide
4.13 Bit Reversed and Modulo Addressing ........................................................82
4.14 Program Space Visibility (PSV) Usage ......................................................82
4.15 Using L a rg e A rra y s .... ................................................................................. 84
Chapter 5. Data Types
5.1 Introduction ................................................................................................... 85
5.2 Highlight s . ... .................................................................................................. 85
5.3 Data Repre se ntation .................................................................................... 85
5.4 Integer ..........................................................................................................85
5.5 Floating P o in t ... .. .......................................... ................................................ 86
5.6 Pointers ........................................................ ................................................ 86
Chapter 6. Additional C Pointer Types
6.1 Introduction ................................................................................................... 87
6.2 Managed PSV Pointers ................................................................................87
6.3 PMP Pointe rs ... .. .......................................................................................... 89
6.4 External Po in te r s ..... ..................................................................................... 91
6.5 Extended Data Space Pointers ....................................................................95
Chapter 7. Device Support Files
7.1 Introduction ................................................................................................... 97
7.2 Highlight s . ... .................................................................................................. 97
7.3 Processor Header Files ................................................................................97
7.4 Register D e fi n ition Files ..... .. ........................... .. .. ......................................... 9 8
7.5 Using SFRs .. .. .. ............................................................................................ 9 9
7.6 Using Macro s ... .. ........................................................................................ 101
7.7 Accessing EEDATA from C Code – PIC24F MCUS, dsPIC30F/33F DSCs only 102
Chapter 8. Interrupts
8.1 Introduction .................................................................................................105
8.2 Highlight s . ... ................................................................................................ 105
8.3 Writing an Interrupt Service Routine .......................................................... 106
8.4 Writing the In te r ru p t V e c to r .... ................ .......................................... .......... 10 8
8.5 Interrupt S e rv ic e R o u tin e Co ntext Saving ........................................ .. .. ...... 118
8.6 Latency .... ... ............. .. .. ................................................................... .. .. ........ 118
8.7 Nesting In te r ru p ts ............. .. ............................. ........................................... 118
8.8 Enabling/D isabling Interrupts ............................................................... ...... 119
8.9 Sharing Memory Between Interrupt Service Routines and Mainline Code 120
8.10 PSV Usage with Interrupt Service Routines ............................. ................123
Chapter 9. Mixing Assembly Language and C Modules
9.1 Introduction .................................................................................................125
9.2 Highlight s . ... ................................................................................................ 125
9.3 Mixing Assembly Language and C Variables and Functions ................ .. ... 125
9.4 Using Inline Assembly Language ............................................................... 127
Appendix A. Implementation-Defined Behavior
A.1 Introduction ................................................................................................135
DS51284J3-page 4 Update Draft 2003-2011 Microchip Technology Inc.
Table of Contents
A.2 Highlight s .......... .. ....................................................................................... 135
A.3 Translati o n .......... .. ..................................................................................... 13 6
A.4 Environme n t ........................................................................................ .. .. ... 136
A.5 Identifiers ...................................................................................................137
A.6 Character s ............ ..................................................................................... 1 3 7
A.7 Integers ......................................................................................................138
A.8 Floating Po in t ...... .. .................................................................................. ... 138
A.9 Arrays and P o in te r s ............ ....................................................................... 139
A.10 Registers .................. ............... ................................................................. 139
A.11 Structures, Unions, Enumerations and Bit fields ......................................140
A.12 Qualifiers .................. .................................................................... ............ 140
A.13 Declara to r s .......... .............. .. .. ..................................................... .. .. .......... 140
A.14 Stateme nt s ................... .. .......................................................................... 140
A.15 Preproce s s in g Di re c tives .... .....................................................................141
A.16 Library F u n ct io n s .............................................................................. .. .. ... 142
A.17 Signals .....................................................................................................143
A.18 Streams and Files ....................................................................................143
A.19 tmpfile ............. .. .. ..................................................................................... 1 4 4
A.20 errno ......................................................................................................... 144
A.21 Memory ...... ... .. ......................................................................................... 144
A.22 abort .................... ... ..................................................................................144
A.23 exit ................ .. ............................................................................... ... .. ..... 1 4 4
A.24 getenv ........ ... ........................................................................................... 145
A.25 system ........... .. ......................................................................................... 145
A.26 strerror .......... ............. .. .. ................................................................... .. .. ... 145
Appendix B. Built-in Functions
B.1 Introduction ................................................................................................147
B.2 Built-In Fun ction List .. ............................ .................................................... 148
Appendix C. MPLAB C Compiler for PIC18 MCUs vs. 16-Bit Devices
C.1 Introduction ................................................................................................173
C.2 Highlight s ........ ............................................................................... .. ... ....... 173
C.3 Data Forma ts ...... ....................................................................................... 174
C.4 Pointers ........... .. .................................................................................. ....... 174
C.5 Storage Cla s s e s ........................................................................................ 174
C.6 Stack Usage ..............................................................................................174
C.7 Storage Qu a lif ie r s ...... .. .......................................... .................................... 175
C.8 Predefined Macro Names ..........................................................................175
C.9 Integer Pr om o tions .... .. .............................................................................. 175
C.10 String Con s ta n t s ........................................................................ .. .. .......... 175
C.11 Access Memory .. ... .................................................................................. 175
C.12 Inline Ass embly ... ................ ..................................................................... 175
C.13 Pragmas ............. ... .................................................................................. 176
C.14 Memory Models .......................................................................................177
C.15 Calling Co n v en t io n s ................ ............. ... .. ............................................... 1 7 7
2003-2011 Microchip Technology Inc. Update Draft DS51284J3-page 5
16-Bit C Compiler User’s Guide
C.16 Startup Code ............................................................................................177
C.17 Compiler-Managed Resources ................................................................177
C.18 Optimiz ations ................... .. ...................................................................... 178
C.19 Object Module Format ............................................................................. 178
C.20 Implementation-Defined Behavior ...........................................................178
C.21 Bit fields ... .. .. ............................................................................................ 1 7 9
Appendix D. Diagnostics
D.1 Introduction ................................................................................................ 181
D.2 Errors ............... .. .................................................................................. ...... 181
D.3 Warnings . ... .. .......................................... .......................................... .......... 20 0
Appendix E. Deprecated Features
E.1 Introduction ................................................................................................221
E.2 Highlight s ... .. .. ............................................................................................ 2 2 1
E.3 Predefined Constants ................................................................................221
E.4 Variable s in Sp ecified Regist e rs ................................................................ 22 2
Appendix F. ASCII Character Set .............................................................................225
Appendix G. GNU Free Documentation License
G.1 PREAMBLE ............ .. .. ............................................................................... 2 2 7
G.2 APPLICABILITY AND DEFINITIONS ........................................................ 227
G.3 VERBATI M COPYING ..... .. .......................................... .............................. 229
G.4 COPYING IN Q U AN T IT Y ............. ....................................................... ...... 229
G.5 MODIFICA TIONS ................ .. ............................. ....................................... 23 0
G.6 COMBINI N G DOCUMENTS .. ... ................................................................. 2 3 1
G.7 COLLECTIONS OF DOCUMENTS ........................................................... 231
G.8 AGGREGATION WITH INDEPENDENT WORKS .................................... 232
G.9 TRANSLAT ION .................................................... ..................................... 23 2
G.10 TERMIN A T ION ... ..................................................................................... 232
G.11 FUTURE REVISIONS OF THIS LICENSE .............................................. 233
G.12 RELICENSING ....... .. ... ............................................................................ 233
Glossary .....................................................................................................................235
Index ...........................................................................................................................255
Worldwide Sales and Service ...................................................................................265
DS51284J3-page 6 Update Draft 2003-2011 Microchip Technology Inc.
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC
®
DSCs
USER’S GUIDE

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 may 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 p age 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 Select the Help menu, and then Topics to open a list of available on-line help files.
®
IDE on-line help.
INTRODUCTION
This chapter contains general information that will be useful to know before using the MPLAB C Compiler for PIC24 MCUs and dsPIC
• Document Layout
• Conventions Used in this Guide
• Recommended Reading
• The Microchip Web Site
• Development Systems Customer Change Notification Service
• Customer Support
®
DSCs. Items discussed include:
2002-2011 Microchip Technology Inc. DS51284K-page 7
16-Bit C Compiler User’s Guide
DOCUMENT LAYOUT
This document describes how to use GNU language tools to write code for 16-bit applications. The document layout is as follows:
• Chapter 1: Compiler Overview – describes the compiler, development tools and feature set.
• Chapter 2: Differences between 16-Bit Device C and ANSI C – describes the differences between the C language supported by the compiler syntax and the standard ANSI-89 C.
• Chapter 3: Using the Compiler on the Command Line – describes how to use the compiler from the command line.
• Chapter 4: Run Time Environment – describes the compiler run-time model, including information on sections, initialization, memory models, the software stack and much more.
• Chapter 5: Data Types – describes the compiler integer, floating point and pointer data types.
• Chapter 6: Additional C Pointers – describes additional C pointers available.
• Chapter 7: Device Support Files – describes the compiler header and register
definition files, as well as how to use with SFRs.
• Chapter 8: Interrupts – describes how to use interrupts.
• Chapter 9: Mixing Assembly Language and C Modules – provides guidelines to
using the compiler with 16-bit assembly language modules.
• Appendix A: Implementation-Defined Behavior – details compiler-specific parameters described as implementation-defined in the ANSI standard.
• Appendix B: Built-in Functions – lists the built-in functions of the C compiler.
• Appendix C: Diagnostics – lists error and warning messages generated by the
compiler.
• Appendix D: MPLAB C C o mpi ler f or PIC 18 MC Us v s. 16 -Bi t D evice s – highlights the differences be tween the PI C18 MCU C compil er and th e 16-bit C com piler.
• Appendix E: Deprecated Features – details features that are considered obsolete.
• Appendix F: ASCII Character Set – contains the ASCII character set.
• Appendix G: GNU Free Documentation License – usage license for the Free
Software Foundation.
CONVENTIONS USED IN THIS GUIDE
STD
DD
The following conventions may appear in this documentation:
DOCUMENTATION CONVENTIONS
Description Represents Examples
Arial font:
Italic chara c ters Referenced books MPLAB
Initial caps A window the Output window
Quotes A field name in a window or
Underlined, italic text with right angle bracket
Bold characters A dialog button Click OK
Text in angle brackets < > A key on the keyboard Press <Enter>, <F1>
Courier font:
Plain Courier Sample source code #define START
Italic Courier A variable argument file.o, where file can be
Square brackets [ ] Optional arguments mpasmwin [options]
Curly brackets and pipe character: { | }
Ellipses... Replaces r epeated text var_name [,
Sidebar T e xt
Preface
®
IDE User’s Guide
Emphasized text ...is the only compiler...
A dialog the Settings dialog A menu selection select Enable Programmer
“Save project before build”
dialog A menu path File>Save
A tab Click the Power tab
Filenames autoexec.bat File paths c:\mcc18\h Keywords _asm, _endasm, static Command-line options -Opa+, -Opa- Bit values 0, 1 Constants 0xFF, ’A’
any valid filename
file [options]
Choice of mut ually exclus ive arguments; an OR selection
Represents code supplied by user
Standard edition only. This feature su ppo rted only in the standard edition of the software, i.e., not suppo rted in standard evaluation (after 60 days) or lite editions.
Device Dependent. This feature is not supported on all devices. Devices sup­ported will be listed in the title or text.
errorlevel {0|1}
var_name...] void main (void)
{ ... }
-mpa option
xmemory attribute
2002-2011 Microchip Technology Inc. DS51284K-page 9
16-Bit C Compiler User’s Guide
RECOMMENDED READING
This documentation describes how to use the MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs. Other useful documents are listed below. The following Microchip documents are available and recommended as supplemental reference resources.
Readme Files
For the latest information on Microchip tools, read the associated Readme files (HTML files) included with the software.
16-Bit Language Tools Getting Started (DS70094)
A guide to installing and working with the Microchip language tools for 16-bit devices. Examples using the 16-bit simulator SIM30 (a component of MPLAB SIM) are provided.
MPLAB User’s Guide (DS51317 )
A guide to using the 16-bit assembler, object linker, object archiver/librarian and various utilities.
16-Bit Language Tools Libraries (DS51456)
A descriptive listing of libraries available for Microchip 16-bit devices. This includes standard (including math) libraries and C compiler built-in functions. DSP and 16-bit peripheral libraries are described in Readme files provided with each peripheral library type.
Device-Specific Documentation
The Microchip website contains many documents that describe 16-bit device functions and features. Among these are:
• Individual and family data sheets
• Family reference manuals
• Programmer’s reference manuals
C Standards Information
American National Standard for Information Systems – Programming Language – C.
®
Assembler, Linker and Utilities for PIC24 MCUs and dsPIC® DSCs
American National Standards Institute (ANSI), 11 West 42nd. Street, New York, New York, 10036.
This standard specifies the form and establishes the interpretation of programs expressed in the programming language C. Its purpose is to promote portability, reliability, maintainability and efficient execution of C language program s on a variety of computing systems.
C Reference Manuals
Harbison, Samuel P . and Steele, Guy L., C A Reference Manual, Fourth Edition,
Prentice-Hall, Englewood Cliffs, N.J. 07632.
Kernighan, Brian W. and Ritchie, Dennis M., The C Programming Language, Secon d
Edition. Prentice Hall, Englewood Cliffs, N.J. 07632.
Kochan, Steven G., Programming In ANSI C, Revised Edition. Hayden Books,
Indianapolis, Indiana 46268. Plauger, P.J., The Standard C Library, Prentice-Hall, Englewood Cliffs, N.J. 07632. Van Sickle, Ted., Programming Microcontrollers in C, First Edition. LLH Technology
Publishing, Eagle Rock, Virginia 24085.
THE MICROCHIP WEB SITE
Microchip provides online support via our web site at www.microchip.com. This web site is used as a means to make files and information easily available to customers. Accessible by using your favorite Internet browser, the web site contains the following information:
Product Support – Data sheets and errata, application notes and sample
programs, design resources, user’s guides and hardware support documents, latest software releases and archived software
General Technical Support – Frequently Asked Questions (FAQs), technical
support requests, online discussion groups, Microchip consultant program member listing
Business of Microchip – Product selector and ordering guides, latest Microchip
press releases, listing of seminars and events, listings of Microchip sales offices, distributors and factory representatives
Preface
2002-2011 Microchip Technology Inc. DS51284K-page 11
16-Bit C Compiler User’s Guide
DEVELOPMENT SYSTEMS CUSTOMER CHANGE NOTIFICATION SERVICE
Microchip’s customer notification service helps keep customers current on Microchip products. Subscribers will receive e-mail notification whenever there are changes, updates, revisions or errata related to a specified product family or development tool of interest.
To register, access the Microchip web site at www.microchip.com, click on Customer Change Notification and follow the registration instructions.
The Development Systems product group categories are:
Compilers – The latest info rmatio n on Microc hip C comp ilers, as semblers , linkers and other language tools. These include all MPLAB C compilers; all MPLAB assemblers (including MPASM™ assembler); all MPLAB linkers (including MPLINK™ object linker); and all MPLAB librarians (including MPLIB™ object librarian).
Emulators – The latest information on Microchip in-circuit emulators. These include the MPLAB REAL ICE™ and MPLAB ICE 2000 in-circuit emulators
In-Circuit Debuggers – The latest information on Microchip in-circuit debuggers. These include the MPLAB ICD 2 and 3 in-circuit debuggers and PICkit™ 2 and 3 debug express.
MPLAB Integrated Development Environment for development systems tools. This list is focused on the MPLAB IDE, MPLAB IDE Project Manager, MPLAB Editor and MPLAB SIM simulator, as well as general editing and debugging features.
Programmers – The latest information on Microchip programmers. These include the device (production) programmers MPLAB REAL ICE in-circuit emulator, MPLAB ICD 3 in-circuit debugger, MPLAB PM3, and PRO MATE II and development (nonproduction) programmers MPLAB ICD 2 in-circuit debugger, PICSTART
®
IDE – The latest information on Microchip MPLAB IDE, the Windows®
®
Plus and PICkit 1, 2 and 3.
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://support.microchip.com

Chapter 1. Compiler Overview

1.1 INTRODUCTION

The dsPIC® family of Digital Signal Controllers (dsPIC30F and dsPIC33F DSCs) com­bines the high performance required in DSP applications with standard microcontroller features needed for embedded applications. PIC24 MCUs are identical to the dsPIC DSCs with the exception that they do not have the digital signal controller module or that subset of instructions. They are a subset and are high-performance micro­controllers intended for applications that do not require the power of the DSC capabilities.
All of these devices are fully supported by a complete set of software development tools, including an optimizing C compiler, an assembler, a linker and an archiver/ librarian.
This chapter provides an overview of these tools and introduces the features of the optimizing C compiler, including how it works with the assembler and linker. The assembler and linker are discussed in detail in the “MPLAB
Utilities for PIC24 MCUs and dsPIC
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC
USER’S GUIDE
®
®
DSCs User’s Guide” (DS51317).
Assembler, Linker and
®
DSCs

1.2 HIGHLIGHTS

Items discussed in this chapter are:
• Compiler Description and Documentation
• Compiler and Other Development Tools
• Compiler Feature Set

1.3 COMPILER DESCRIPTION AND DOCUMENTATION

There are three Microchip compilers that support various Microchip 16-bit devices. Also, each one of these compilers comes in different editions, which support different levels of optimization.
MPLAB® C Compiler for Device Support Edition Support
1 PIC24 MCUs and dsPIC 2 dsPIC DSCs dsPIC30F/33F DSCs Std, Std Eval, Lite 3 PIC24 MCUs PIC24F/H MCUs Std, Std Eval, Lite
Each compiler is an ANSI x3.159-1989-compliant, optimizing C compiler. Each com­piler is a Windows Each compiler is a port of the GCC compiler from the Free Software Foundation.
The first and second compilers include language extensions for dsPIC DSC embedded-control applications.
®
console application that provides a platform for developing C code.
®
DSCs All 16-bit devices Std, Std Eval
2002-2011 Microchip Technology Inc. DS51284K-page 13
16-Bit C Compiler User’s Guide
1.3.1 Compiler Editions
Each of the three compilers in Section 1.3 “Compiler Description and Documenta­tion” come in one or more of the following editions:
• Standard (Purchased Compiler) – All optimization levels enabled.
• Standard Evaluation (Free) – All optimization levels enabled for 60 days, but then reverts to optimization level 1 only.
• Lite (Free) – Optimization level 1 only.
1.3.2 Compiler Documented in this Manual
This manual describes the standard edition of the Standard (purchased) compiler, since the Standard Evaluation and Lite compilers are subsets of the first. Features that are unique to specific devices, and therefore specific compilers, are noted with “DD” text the column (see the Preface) and text identifying the devices to which the information applies.

1.4 COMPILER AND OTHER DEVELOPMENT TOOLS

The MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs compiles C source files, producing assembly language files. These compiler-generated files are assembled and linked with other object files and libraries to produce the final application program in executable COFF or ELF file format. The COFF or ELF file can be loaded into the MPLAB IDE, where it can be tested and debugged, or the conversion utility can be used to convert the COFF or ELF file to Intel mand-line simulator or a device programmer. See Figure 1-1 for an overview of the software development data flow.
®
hex format, suitable for loading into the com-
DS51284K-page 14 2002-2011 Microchip Technology Inc.
Compiler Overview
Object File Libraries
(*.a)
Assembler
Linker
C Source Files
(*.c)
C Compiler
Source Files (*.s)
Assembly Source
Files (*.s)
COFF/ELF Object Files
(*.o)
Executable File
(*.exe)
Archiver (Librarian)
Command-Line
Simulator
Compiler Driver Program
MPLAB
®
IDE
Debug Tool
FIGURE 1-1: SOFTWARE DEVELOPMENT TOOLS DATA FLOW
2002-2011 Microchip Technology Inc. DS51284K-page 15
16-Bit C Compiler User’s Guide

1.5 COMPILER FEATURE SET

The compiler is a full-featured, optimizing compiler that translates standard ANSI C programs into 16-bit device assembly language source. The compiler also supports many command-line options and language extensions that allow full access to the 16-bit device hardware capabilities, and affords fine control of the compiler code gen­erator. This section describes key features of the compiler.
1.5.1 ANSI C Standard
The compiler is a fully validated compiler that conforms to the ANSI C standard as defined by the ANSI specification and described in Kernighan and Ritchie’s The C Pro- gramming Language (second edition). The ANSI standard includes extensions to the original C definition that are now standard features of the language. These extensions enhance portability and offer increased capability.
1.5.2 Optimization
The compiler uses a set of sophisticated optimization passes that employ many advanced techniques for generating efficient, compact code from C source. The optimization passes include high-level optimizations that are applicable to any C code, as well as 16-bit device-specific optimizations that take advantage of the particular features of the device architecture.
1.5.3 ANSI Standard Library Support
The compiler is distributed with a complete ANSI C standard library. All library functions have been validated, and conform to the ANSI C library standard. The library includes functions for string manipulation, dynamic memory allocation, data conversion, time­keeping and math functions (trigonometric, exponential and hyperbolic). The standard I/O functions for file handling are also included, and, as distributed, they support full access to the host file system using the command-line simulator. The fully functional source code for the low-level file I/O functions is provided in the compiler distribution, and may be used as a starting point for applications that require this capability.
1.5.4 Flexible Memory Models
The compiler supports both large and small code and data models. The small code model takes advantage of more efficient forms of call and branch instructions, while the small data model supports the use of compact instructions for accessing data in SFR space.
The compiler supports two models for accessing constant data. The “constants in data” model uses d ata memory, which is initiali ze d b y t h e ru n -t ime li brary. The “constants in code” model uses program memory, which is accessed through the Program Space Visibility (PSV) window.
1.5.5 Compiler Driver
The compiler includes a powerful command-line driver program. Using the driver program, application programs can be compiled, assembled and linked in a single step (see Figure 1-1).
DS51284K-page 16 2002-2011 Microchip Technology Inc.
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC® DSCs
USER’S GUIDE

Chapter 2. Differences Between 16-Bit Device C and ANSI C

2.1 INTRODUCTION

This section discusses the differences between the C language supported by MPLAB C Compiler for PIC24 MCUs and dsPIC 1989 standard ANSI C.

2.2 HIGHLIGHTS

Items discussed in this chapter are:
• Keyword Differences
• Statement Differences
• Expression Differences

2.3 KEYWORD DIFFERENCES

This section describes the keyword differences between plain ANSI C and the C accepted by the 16-bit device compiler. The new keywords are part of the base GCC implementation, and the discussion in t his section is b ased on the st andard GCC do cu­mentation, tailored for the specific syntax and semantics of the 16-bit compiler por t of GCC.
• Specifying Attributes of Variables
• Specifying Attributes of Functions
• Inline Functions
• Variables in Specified Registers
• Complex Numbers
• Double-Word Integers
• Referring to a Type with typeof
®
DSCs (formerly MPLAB C30) syntax and the
2002-2011 Microchip Technology Inc. DS51284K-page 17
16-Bit C Compiler User’s Guide
2.3.1 Specifying Attributes of Variables
The compiler keyword __attribute__ allows you to specify special attributes of variables or structure fields. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently supported for variables:
address (addr)
• aligned (alignment)
boot
deprecated
eds
fillupper
far
mode (mode)
near
noload
page
packed
persistent
reverse (alignment)
section ("section-name")
secure
sfr (address)
space (space)
transparent_union
unordered
unused
weak
You may also specify attributes with __ (double underscore) preceding and following each keyword (e.g., __aligned__ instead of aligned). This allows you to use them in header files without being concerned about a possible macro of the same name.
To specify multiple attributes, separate them by commas within the double parentheses, for example:
__attribute__ ((aligned (16), packed)).
Note: It is important to use variable attributes consistently throughout a project.
For example, if a variable is defined in file A with the far attribute, and declared extern in file B without far, then a link error may result.
address (addr)
The address attribute specifies an absolute address for the variable. This attribute can be used in conjunction with a section attribute. This can be used to start a group of variables at a specific address:
int foo __attribute__((section("mysection"),address(0x900))); int bar int baz
A variable with the address attribute cannot be placed into the auto_psv space (see the space() attribute or the -mconst-in-code option); attempts to do so will cause a warning and the compiler will place the variable into the PSV space. If the variable is to be placed into a PSV section, the address should be a program memory address.
DS51284K-page 18 2002-2011 Microchip Technology Inc.
__attribute__((section("mysection"))); __attribute__((section("mysection")));
Differences Between 16-Bit Device C and ANSI C
int var __attribute__ ((address(0x800)));
aligned (alignment)
This attribute specifies a minimum alignment for the variable, measured in bytes. The alignment must be a power of two. For example, the declaration:
int x __attribute__ ((aligned (16))) = 0;
causes the compiler to allocate the global variable x on a 16-byte boundary. On the dsPIC DSC device, this could be used in conjunction with an asm expression to access DSP instructions and addressing modes that require aligned operands.
As in the preceding example, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given variable. Alternatively, you can leave out the alignment factor and just ask the compiler to align a variable to the maximum useful alignment for the dsPIC DSC device. For example, you could write:
short array[3] __attribute__ ((aligned));
Whenever you leave out the alignment factor in an aligned attribute specification, the compiler automatically sets the alignment for the declared variable to the largest alignment for any data type on the target machine – which in the case of the dsPIC DSC device is two bytes (one word).
The aligned attribute can only increase the alignment; but you can decrease it by specifying packed (see below). The aligned attribute conflicts with the reverse attribute. It is an error condition to specify both.
The aligned att ribute can be combin ed with th e section attribute. This will allow the alignment to take place in a named section. By default, when no section is specified, the compiler will generate a unique section for the variable. This will provide the linker with the best opportunity for satisfying the alignment restriction without using internal padding that may happen if other definitions appear within the same aligned section.
boot
This attribute can be used to define protected variables in Boot Segment (BS) RAM:
int __attribute__((boot)) boot_dat[16];
V ariables defined in BS RAM will not be initialized on startup. Therefore all variables in BS RAM must be initialized using inline code. A diagnostic will be reported if initial values are specified on a boot variable.
An example of initialization is as follows:
int __attribute__((boot)) time = 0; /* not supported */ int __attribute__((boot)) time2; void __attribute__((boot)) foo() { time2 = 55; /* initial value must be assigned explicitly */ }
2002-2011 Microchip Technology Inc. DS51284K-page 19
16-Bit C Compiler User’s Guide
deprecated
The deprecated attribute causes the declaration to which it is attached to be specially recognized by the compiler. When a deprecated function or variable is used, the compiler will emit a warning.
A deprecated definition is still defined and, therefore, present in any object file. For example, compiling the following file:
int __attribute__((__deprecated__)) i; int main() { return i; }
will produce the warning:
deprecated.c:4: warning: `i’ is deprecated (declared at deprecated.c:1)
i is still defined in the resulting object file in the normal way.
eds
In the attribute context the eds, for extended data space, attribute indicates to the com­piler that the variable will may be allocated anywhere within data memory. Variables with this attribute will likely also need the __eds__ type qualifier (see Chapter
6. “Additional C Pointer Types”) in order for the compiler to properly generate the
correct access sequence. Note that the __eds__ qualifier and the eds attribute are closely related, but not identical. On some devices, eds may need to be specified when allocating variables into certain memory spaces such as space(ymemory) or space(dma) as this memory may only exist in the extended data space.
fillupper
This attribute can be used to specify the upper byte of a variable stored into a space(prog) section.
For example:
int foo[26] __attribute__((space(prog),fillupper(0x23))) = { 0xDEAD };
will fill the upper bytes of array foo with 0x23, instead of 0x00. foo[0] will still be initialized to 0xDEAD.
The command line option -mfillupper=0x23 will perform the same function.
far
The far attribute tells the compiler that the variable will not necessarily be allocated in near (first 8 KB) data space, (i.e., the variable can be located anywhere in data memory between 0x0000 and 0x7FFF).
mode (mode)
This attribute specifies the data type for the declaration as whichever type corresponds to the mode mode. This in effect lets you request an integer or floating point type according to its width. Valid values for mode are as follows:
Mode Width Compiler Type
QI 8 bits char HI 16 bits int SI 32 bits long
DI 64 bits long long SF 32 bits float DF 64 bits long double
DS51284K-page 20 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
This attribute is useful for writing code that is portable across all supported compiler tar­gets. For example, the following function adds two 32-bit signed integers and returns a 32-bit signed integer result:
typedef int __attribute__((__mode__(SI))) int32; int32 add32(int32 a, int32 b) { return(a+b); }
Y ou may also specify a mode of byte or __byte__ to indicate the mode correspond­ing to a one-byte integer, word or __word__ for the mode of a one-word integer, and pointer or __pointer__ for the mode used to represent pointers.
near
The near attribute tells the compiler that the variable is allocated in near data space (the first 8 KB of data memory). Such variables can sometimes be accessed more efficiently than variables not allocated (or not known to be allocated) in near data space.
int num __attribute__ ((near));
noload
The noload attribute indicates that space should be allocated for the variable, but that initial values should not be loaded. This attribute could be useful if an application is designed to load a variable into memory at run time, such as from a serial EEPROM.
int table1[50] __attribute__ ((noload)) = { 0 };
page
The page attribute places variable definitions into a specific page of memory. The page size depends on the type of memory selected by a space attribute. Objects residing in RAM will be constrained to a 32K page while objects residing in Flash will be con­strained to a 64K page (upper byte not included).
unsigned int var[10] __attribute__ ((space(auto_psv)));
The space(auto_psv) or space(psv) attribute will use a single memory page by default.
__eds__ unsigned int var[10] __attribute__ ((space(eds), page));
When dealing with space(eds), please refer to Chapter 6. “Additional C Pointer Types” for more information.
packed
The packed attribute specifies that a structure member should have the smallest possible alignment unless you specify a larger value with the aligned attribute.
Here is a structure in which the member x is packed, so that it immediately follows a, with no padding for alignment:
struct foo { char a; int x[2] };
__attribute__ ((packed));
Note: The device architecture requires that words be aligned on even byte
boundaries, so care must be taken when using the packed attribute to avoid run-time addressing errors.
2002-2011 Microchip Technology Inc. DS51284K-page 21
16-Bit C Compiler User’s Guide
persistent
The persistent attribute specifies that the variable should not be initialized or cleared at startup. A variable with the persistent attribute could be used to store state information that will remain valid after a device reset.
int last_mode __attribute__ ((persistent));
Persistent data is not normally initialized by the C run-time. However, from a cold-restart, persistent data may not have any meaningful value. This code example shows how to safely initialize such data:
#include "p24Fxxxx.h"
int last_mode __attribute__((persistent));
int main() { if ((RCONbits.POR == 0) && (RCONbits.BOR == 0)) { /* last_mode is valid */ } else { /* initialize persistent data */ last_mode = 0; } }
reverse (alignment)
The reverse attribute specifies a minimum alignment for the ending address of a variable, plus one. The alignment is specified in bytes and must be a power of two. Reverse-aligned variables can be used for decrementing modulo buffers in dsPIC DSC assembly language. This attribute could be useful if an application defines variables in C that will be accessed from assembly language.
int buf1[128] __attribute__ ((reverse(256)));
The reverse attribute conflicts with the aligned and section attributes. An attempt to name a section for a reverse-aligned variable will be ignored with a warning. It is an error conditi on to specify both reverse and aligned for the same variable. A variable with the reverse attribute cannot be placed into the auto_psv space (see the space() attribute or the -mconst-in-code option); attempts to do so will cause a warning and the compiler will place the variable into the PSV space.
section ("section-name")
By default, the compiler places the objects it generates in sections such as .data and .bss. The section attribute allows you to override this behavior by specifying that a
variable (or function) lives in a particular section.
struct a { int i[32]; }; struct a buf
__attribute__((section("userdata"))) = {{0}};
secure
This attribute can be used to define protected variables in Secure Segment (SS) RAM:
int __attribute__((secure)) secure_dat[16];
V ariables defined in SS RAM will not be initialized on startup. Therefore all variables in SS RAM must be initialized using inline code. A diagnostic will be reported if initial values are specified on a secure variable.
DS51284K-page 22 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
DD
DD
String literals can be assigned to secure variables using inline code, but they require extra processing by the compiler. For example:
char *msg __attribute__((secure)) = "Hello!\n"; /* not supported */ char *msg2 __attribute__((secure)); void __attribute__((secure)) foo2() { *msg2 = "Goodbye..\n"; /* value assigned explicitly */ }
In this case, storage must be allocated for the string literal in a memory space which is accessible to the enclosing secure function. The compiler will allocate the string in a psv constant section designated for the secu re segment.
sfr (address)
The sfr attribute tells the compiler that the variable is an SFR and also specifies the run-time address of the variable, using the address parameter.
extern volatile int __attribute__ ((sfr(0x200)))u1mod;
The use of the extern specifier is required in order to not produce an error.
Note: By convention, the sfr attribute is used only in processor header files. To
define a general user variable at a specific address use the address attri­bute in conjunction with near or far to specify the correct addressing mode.
space (space)
Normally, the compiler allocates variables in general data space. The space attribute can be used to direct the compiler to allocate a variable in specific memory spaces. Memory spaces are discussed further in Section 4.5 “Memory Spaces”. The following arguments to the space attribute are accepted:
data
Allocate the variable in general data space. V ariables in general data space can be accessed using ordinary C statements. This is the default allocation.
eds
Allocate the variable in the extended data space. For devices that do not have extended data space, this is equivalent to space(data). Variables in
space(eds) will generally require special handling to access. Refer to Chapter
6. “Additional C Pointer Types” for more information.
space(eds) has been deprecated in favour of the eds attribute.
xmemory - dsPIC30F/33F DSCs only Allocate the variable in X data space. Variables in X data space can be accessed
using ordinary C statements. An example of xmemory space allocation is:
int x[32] __attribute__ ((space(xmemory)));
ymemory - dsPIC30F/33F DSCs only Allocate the variable in Y data space. Variables in Y data space can be accessed
using ordinary C statements. An example of ymemory space allocation is:
int y[32] __attribute__ ((space(ymemory)));
2002-2011 Microchip Technology Inc. DS51284K-page 23
16-Bit C Compiler User’s Guide
DD
DD
prog
Allocate the variable in program space, in a section designated for executable code. Variables in program space can not be accessed using ordinary C statements. They must be explicitly accessed by the programmer, usually using table-access inline assembly instructions, or using the program space visibility window.
auto_psv
Allocate the variable in program space, in a compiler-managed section designated for automatic program space visibility window access. Variables in auto_psv space can be read (but not written) using ordinary C statements, and are subject to a maximum of 32K total space allocated. When specifying
space(auto_psv), it is not possible to assign a section name using the sec­tion attribute; any section name will be ignored with a warning. A variable in the auto_psv space cannot be placed at a specific address or given a reverse
alignment.
Note: Variables placed in the auto_psv section are not loaded into data
memory at startup. This attribute may be useful for reducing RAM usage.
dma - PIC24H MCUs, dsPIC33F DSCs only Allocate the variable in DMA memory. Variables in DMA memory can be
accessed using ordinary C statements and by the DMA peripheral. __builtin_dmaoffset() (see Appendix B. “Built-in Functions”) can be used to find the correct offset for configuring the DMA peripheral.
#include <p24Hxxxx.h> unsigned int BufferA[8] unsigned int BufferB[8]
int main() { DMA1STA = DMA1STB = /* ... */ }
psv
Allocate the variable in program space, in a section designated for program sp ace visibility window access. The linker will locate the section so that the entire vari­able can be accessed using a single setting of the PSVPAG register. Variables in PSV space are not managed by the compiler and can not be accessed using ordi­nary C statements. They must be explicitly accessed by the programmer , usually using table-access inline assembly instructions, or using the program space visibility window.
eedata - PIC24F, dsPIC30F/33F DSCs only Allocate the variable in EEData space. Variables in EEData space can not be
accessed using ordinary C statements. They must be explicitly accessed by the programmer, usually using table-access inline assembly instructions, or using the program space visibility window.
pmp
Allocate the variable in off chip memory associated with the PMP peripheral. For complete details please see Section 6.3 “PMP Pointers”.
__builtin_dmaoffset(BufferA); __builtin_dmaoffset(BufferB);
__attribute__((space(dma))); __attribute__((space(dma)));
DS51284K-page 24 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
external
Allocate the variable in a user defined memory space. For complete details please see Section 6.4 “External Pointers”.
transparent_union
This attribute, attached to a function parameter which is a union, means that the corresponding argument may have the type of any union member, but the argument is passed as if its type were that of the first union member. The argument is passed to the function using the calling conventions of the first member of the transparent union, not the calling conventions of the union itself. All members of the union must have the same machine representation; this is necessary for this argument passing to work properly.
unordered
The unordered attribute indicates that the placement of this variable may move relative to other variables within the current C source file.
const int __attribute__ ((unordered)) i;
unused
This attribute, attached to a variable, means that the variable is meant to be possibly unused. The compiler will not produce an unused variable warning for this variable.
weak
The weak attribute causes the declaration to be emitted as a weak symbol. A weak symbol may be superseded by a global definition. When weak is applied to a reference to an external symbol, the symbol is not required for linking. For example:
extern int __attribute__((__weak__)) s; int foo() { if (&s) return s; return 0; /* possibly some other value */ }
In the above program, if s is not defined by some other module, the program will still link but s will not be given an address. The conditional verifies that s has been defined (and returns its value if it has). Otherwise ‘0’ is returned. There are many uses for this feature, mostly to provide generic code that can link with an optional library.
The weak attribute may be applied to functions as well as variables:
extern int __attribute__((__weak__)) compress_data(void *buf); int process(void *buf) { if (compress_data) { if (compress_data(buf) == -1) /* error */ } /* process buf */ }
In the above code, the function compress_data will be used only if it is linked in from some other module. Deciding whether or not to use the feature becomes a link-time decision, not a compile time decisio n.
2002-2011 Microchip Technology Inc. DS51284K-page 25
16-Bit C Compiler User’s Guide
The affect of the weak attribute on a definition is more complicated and requires multiple files to describe:
/* weak1.c */ int
void foo() { i = 1; }
/* weak2.c */ int i; extern void foo(void);
void bar() { i = 2; }
main() { foo(); bar(); }
Here the definition in weak2.c of i causes the symbol to become a strong definition. No link error is emitted and both i’s refer to the same storage location. Storage is allocated for weak1.c’s version of i, but this space is not accessible.
There is no check to ensure that both versions of i have the same type; changing i in weak2.c to be of type float will still allow a link, but the behavior of function foo will be unexpected. foo will write a value into the least significant portion of our 32-bit float value. Conversely, changing the type of the weak definition of i in weak1.c to type float may cause disastrous results. We will be writing a 32-bit floating point value into a 16-bit integer allocation, overwriting any variable stored immediately after our i.
In the cases wh ere only weak definitions exist, the linker will choose the storage of the first such definition. The remaining definitions become in-accessible.
The behavior is identical, regardless of the type of the symbol; functions and variables behave in the same manner.
__attribute__((__weak__)) i;
DS51284K-page 26 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
2.3.2 Specifying Attributes of Functions
In the compiler, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.
The keyword __attribute__ allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently supported for functions:
address (addr)
alias ("target")
auto_psv, no_auto_psv
boot
const
deprecated
far
format (archetype, string-index, first-to-check)
format_arg (string-index)
• interrupt [ ( [ save(list) ] [, irq(irqid) ] [, altirq(altirqid)] [, preprologue(asm) ] ) ]
near
no_instrument_function
noload
noreturn
section ("section-name")
secure
shadow
unused
user_init
weak
You may also specify attributes with __ (double underscore) preceding and following each keyword (e.g., __shadow__ instead of shadow). This allows you to use them in header files without being concerned about a possible macro of the same name.
You can specify multiple attributes in a declaration by separating them by commas within the double parentheses or by immediately following an attribute declaration with another attribute declaration.
address (addr)
The address attribute specifies an absolute address for the function. This attribute cannot be used in conjunction with a section attribute; the address attribute will take precedence.
void __attribute__ ((address(0x100))) foo() { ... }
Alternatively, you may define the address in the function prototype:
void foo() __attribute__ ((address(0x100)));
alias ("target")
The alias attribute causes the declaration to be emitted as an alias for another symbol, which must be specified.
Use of this attribute results in an external reference to target, which must be resolved during the link phase.
2002-2011 Microchip Technology Inc. DS51284K-page 27
16-Bit C Compiler User’s Guide
auto_psv, no_auto_psv
The auto_psv attribute, when combined with the interrupt attribute, will cause the compiler to generate additional code in the function prologue to set the PSVPAG SFR to the correct value for accessing space(auto_psv) (or constants in the con­stants-in-code memory model) variables. Use this option when using 24-bit pointers and an interrupt may occur while the PSVP AG has been modified and the interrupt rou­tine, or a function it calls, uses an auto_psv variable. Compare this with no_auto_psv. If neither auto_psv nor no_auto_psv option is specified for an interrupt routine, the compiler will issue a warning and select this option.
The no_auto_psv attribute, when combined with the interrupt attribute, will cause the compiler to not generate additional code for accessing space(auto_psv) (or con­stants in the constants-in-code memory model) variables. Use this option if none of the conditions under auto_psv hold true. If neither auto_psv nor no_auto_psv option is specified for an interrupt routine, the compiler will issue a warning and assume auto_psv.
boot
This attribute directs the compiler to allocate a function in the boot segment of program Flash.
For example, to declare a protected function:
void __attribute__((boot)) func();
An optional argument can be used to specify a protected access entry point within the boot segment. The argument may be a literal integer in the range 0 to 31 (except 16), or the word unused. Integer arguments correspond to 32 instruction slots in the seg­ment access area, which occupies the lowest address range of each secure segment. The value 16 is excluded because access entry 16 is reserved for the secure segment interrupt vector. The value unused is used to specify a function for all of the unused slots in the access area.
Access entry points facilitate the creation of application segments from different ven­dors that are combined at run time. They can be specified for external functions as well as locally defined functions. For example:
/* an external function that we wish to call */ extern void __attribute__((boot(3))) boot_service3(); /* local function callable from other segments */ void __attribute__((secure(4))) secure_service4() { boot_service3(); }
Note: In order to allocate functions with the boot or secure attribute, memory
for the boot and/or secure segment must be reserved. This can be accom­plished by setting configuration words in source code, or by specifying linker command options. For more information, see Chapter 8.8, “Options that Specify CodeGuard Security Features”, in the linker manual (DS51317).
If attributes boot or secure are used, and memory is not reserved, then a link error will result.
To specify a secure interrupt handler, use the boot attribute in combination with the interrupt attribute:
void __attribute__((boot,interrupt)) boot_interrupts();
DS51284K-page 28 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
When an access entry point is specified for an external secure function, that function need not be included in the project for a successful link. All references to that function will be resolved to a fixed location in Flash, depending on the security model selected at link time.
When an access entry point is specified for a locally defined function, the linker will insert a branch instruction into the secure segment access area. The exception is for access entry 16, which is represented as a vector (i.e, an instruction address) rather than an instruction. The actual function definition will be located beyond the access area; therefore the access area will contain a jump table through which control can be transferred from another security segment to functions with defined entry points.
Automatic variables are owned by the enclosing function and do not need the boot attribute. They may be assigned initial values, as shown:
void __attribute__((boot)) chuck_cookies() { int hurl; int them = 55; char *where = "far"; splat(where); /* ... */ }
Note that the initial value of where is based on a string literal which is allocated in the PSV constant section .boot_const. The compiler will set PSVPAG to the correct value upon entrance to the function. If necessary, the compiler will also restore PSVPAG after the call to splat().
const
Many functions do not examine any values except their arguments, and have no effects except the return value. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute const. For example:
int square (int) __attribute__ ((const int));
says that the hypothetical function square is safe to call fewer times than the program says.
Note that a function that has pointer arguments and examines the data pointed to must not be declared const. Likewise, a function that calls a non-const function usually must not be const. It does not make sense for a const function to have a void return type.
deprecated
See Section 2.3.1 “Specifying Attributes of Variables” for information on the deprecated attribute.
far
The far attribute tells the compiler that the function should not be called using a more efficient form of the call instruction.
format (archetype, string-index, first-to-check)
The format attribute specifies that a function takes printf, scanf or strftime style arguments which should be type-checked against a format string. For example, consider the declaration:
extern int my_printf (void *my_object, const char *my_format, ...)
__attribute__ ((format (printf, 2, 3)));
2002-2011 Microchip Technology Inc. DS51284K-page 29
16-Bit C Compiler User’s Guide
This causes the compiler to check the arguments in calls to my_printf for consistency with the printf style format string argument my_format.
The parameter archetype determines how the format string is interpreted, and should be one of printf, scanf or strftime. The parameter string-index specifies which argument is the format string argument (arguments are numbered from the left, starting from 1), while first-to-check is the number of the first argument to check against the format string. For functions where the arguments are not available to be checked (such as vprintf), specify the third parameter as zero. In this case, the compiler only checks the format string for consistency.
In the example above, the format string (my_format) is the second argument of the function my_print, and the arguments to check start with the third argument, so the correct parameters for the format attribute are 2 and 3.
The format attribute allows you to identify your own functions that take format strings as arguments, so that the compiler can check the calls to these functions for errors. The compiler always checks formats for the ANSI library functions printf, fprintf,
sprintf, scanf, fscanf, sscanf, strftime, vprintf, vfprintf and vsprintf, whenever such warnings are requested (using -Wformat), so there is no need to modify the header file stdio.h.
format_arg (string-index)
The format_arg attribute specifies that a function takes printf or scanf style arguments, modifies it (for example, to translate it into another language), and passes it to a printf or scanf style function. For example, consider the declaration:
extern char * my_dgettext (char *my_domain, const char *my_format) __attribute__ ((format_arg (2)));
This causes the compiler to check the arguments in calls to my_dgettext, whose result is passed to a printf, scanf or strftime type function for consistency with the printf style format string argument my_format.
The parameter string-index specifies which argument is the format string argument (starting from 1).
The format-arg attribute allows you to identify your own functions which modify format strings, so that the compiler can check the calls to printf, scanf or strftime function, whose operands are a call to one of your own functions.
interrupt [ ( [ save(list) ] [, irq(irqid) ] [, altirq(altirqid)] [, preprologue(asm) ] ) ]
Use this option to indicate that the specified function is an interrupt handler. The compiler will generate function prologue and epilogue sequences suitable f or u se in an inter­rupt handl er wh en t his at tr ibute is pr esen t. Th e op tion al p arame ter save specifies a list of variables to be saved and restored in the function prologue and epilogue, respectively. The optional parameters irq and altirq spec ify interrupt ve ctor table ID’s to be used. The optiona l p a ram et e r preprologue specif ie s asse mbly co de th at is to be emi tte d before the comp il er -g en era t ed p rol og ue cod e. See Chapter 8. “Interrupts” for a full description, including examples.
When using the interrupt attribute, please specify either auto_psv or no_auto_psv. If none is specified a warning will be produced and auto_psv will be assumed.
near
The near attribute tells the compiler that the function can be called using a more efficient form of the call instruction.
DS51284K-page 30 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
no_instrument_function
If the command line option -finstrument-function is given, profiling function calls will be generated at entry and exit of most user-compiled functions. Functions with this attribute will not be so instrumented.
noload
The noload attribute indicates that space should be allocated for the function, but that the actual code should not be loaded into memory. This attribute could be useful if an application is designed to load a function into memory at run time, such as from a serial EEPROM.
void bar() __attribute__ ((noload)) { ... }
noreturn
A few standard library functions, such as abort and exit, cannot return. The com­piler knows this automatically. Some programs define their own functions that never return. You can declare them noreturn to tell the compiler this fact. For example:
void fatal (int i) __attribute__ ((noreturn));
void fatal (int i) { /* Print error message. */ exit (1); }
The noreturn keyword tells the compiler to assume that fatal cannot return. It can then optimize without regard to what would happen if fatal ever did return. This makes slightly better code. Also, it helps avoid spurious warnings of uninitialized variables.
It does not make sense for a noreturn function to have a return type other than void.
section ("section-name")
Normally, the compiler places the code it generates in the .text section. Sometimes, however, you need additional sections, or you need certain functions to appear in special sections. The section attribute specifies that a function lives in a particular section. For example, consider the declaration:
extern void foobar (void) __attribute__ ((section (".libtext")));
This puts the function foobar in the .libtext section. The section attribute conflicts with the address attribute. The section name will be
ignored with a warning.
secure
This attribute directs the compiler to allocate a function in the secure segment of program Flash.
For example, to declare a protected function:
void __attribute__((secure)) func();
2002-2011 Microchip Technology Inc. DS51284K-page 31
16-Bit C Compiler User’s Guide
An optional argument can be used to specify a protected access entry point within the secure segment. The argument may be a literal integer in the range 0 to 31 (except
16), or the word unused. Integer arguments correspond to 32 instruction slots in the segment access area, which occupies the lowest address range of each secure seg­ment. The value 16 is excluded because access entry 16 is reserved for the secure segment interrupt vector. The value unused is used to specify a function for all of the unused slots in the access area.
Access entry points facilitate the creation of application segments from different ven­dors that are combined at run time. They can be specified for external functions as well as locally defined functions. For example:
/* an external function that we wish to call */ extern void __attribute__((boot(3))) boot_service3(); /* local function callable from other segments */ void __attribute__((secure(4))) secure_service4() { boot_service3(); }
Note: In order to allocate functions with the boot or secure attribute, memory
for the boot and/or secure segment must be reserved. This can be accom­plished by setting configuration words in source code, or by specifying linker command options. For more information, see Chapter 8.8, “Options that Specify CodeGuard Security Features”, in the linker manual (DS51317).
If attributes boot or secure are used, and memory is not reserved, then a link error will result.
To specify a secure interrupt ha ndler , us e the secure attribute in combination with the interrupt attribute:
void __attribute__((secure,interrupt)) secure_interrupts();
When an access entry point is specified for an external secure function, that function need not be included in the project for a successful link. All references to that function will be resolved to a fixed location in Flash, depending on the security model selected at link time.
When an access entry point is specified for a locally defined function, the linker will insert a branch instruction into the secure segment access area. The exception is for access entry 16, which is represented as a vector (i.e, an instruction address) rather than an instruction. The actual function definition will be located beyond the access area; therefore the access area will contain a jump table through which control can be transferred from another security segment to functions with defined entry points.
Automatic variables are owned by the enclosing function and do not need the secure attribute. They may be assigned initial values, as shown:
void __attribute__((secure)) chuck_cookies() { int hurl; int them = 55; char *where = "far"; splat(where); /* ... */ }
Note that the initial value of where is based on a string literal which is allocated in the PSV constant section .secure_const. The compiler will set PSVPAG to the correct value upon entrance to the function. If necessary, the compiler will also restore PSVPAG after the call to splat().
DS51284K-page 32 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
shadow
The shadow attribute causes the compiler to use the shadow registers rather than the software stack for saving registers. This attribute is usually used in conjunction with the
interrupt attribute.
void __attribute__ ((interrupt, shadow)) _T1Interrupt (void);
unused
This attribute, attached to a function, means that the function is meant to be possibly unused. The compiler will not produce an unused function warning for this function.
user_init
The user_init attribute may be applied to any non-interrupt function with void parameter and return types. Applying this attribute will cause default C start-up mod­ules to call this function before the user main is executed. There is no guarantee of ordering, so these functions cannot rely on other user_init functions having been previously run; these functions will be called after PSV and data initialization. A
user_init may still be called by the executing program. For example:
void __attribute__((user_init)) initialize_me(void) { // perform initalization sequence alpha alpha beta }
weak
See Section 2.3.1 “Specifying Attributes of Varia bles” for information on the weak attribute.
2.3.3 Inline Functions
By declaring a function inline, you can direct the compiler to integrate that function’s code into the code for its callers. This usually makes execution faster by eliminating the function-call overhead. In addition, if any of the actual argument values are constant, their known values may permit simplifications at compile time, so that not all of the inline function’s code needs to be included. The effect on code size is less predictable. Machine code may be larger or smaller with inline functions, depending on the particular case.
Note: Function inlining will only take place when the function’s definition is visible
(not just the prototype). In order to have a function inlined into more than one source file, the function definition may be placed into a header file that is included by each of the source files.
To declare a function inline, use the inline keyword in its declaration, like this:
inline int inc (int *a) { (*a)++; }
(If you are using the -traditional option or the -ansi option, write __inline__ instead of inline.) You can also make all “simple enough” functions inline with the command-line option -finline-functions. The compiler heuristically decides which functions are simple enough to be worth integrating in this way, based on an estimate of the function’s size.
Note: The inline keyword will only be recognized with -finline or
optimizations enabled.
2002-2011 Microchip Technology Inc. DS51284K-page 33
16-Bit C Compiler User’s Guide
Certain usages in a function definition can make it unsuitable for inline substitution. Among these usages are: use of varargs, use of alloca, use of variable-s ized d ata, use of computed goto and use of nonlocal goto. Using the command-line option
-Winline will warn when a function marked inline could not be substituted, and will give the reason for the failure.
In compiler syntax, the inline keyword does not affect the linkage of the function. When a function is both inline and static, if all calls to the function are integrated
into the caller and the function’s address is never used, then the function’s own assembler code is never referenced. In this case, the compiler does not actually output assembler code for the function, unless you specify the command-line option
-fkeep-inline-functions. Some calls cannot be integrated for various reasons (in particular, calls that precede the function’s definition cannot be integrated and neither can recursive calls within the definition). If there is a nonintegrated call, then the function is compiled to assembler code as usual. The function must also be compiled as usual if the program refers to its address, because that can’t be inlined. The compiler will only eliminate inline functions if they are declared to be static and if the function definition precedes all uses of the function.
When an inline function is not static, then the compiler must assume that there may be calls from other source files. Since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. There for e, a non-static inline function is always compiled on its own in the usual fashion.
If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function and had not defined it.
This combination of inline and extern has a similar effect to a macro. Put a function definition in a header file with these keywords and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file will cause most calls to the function to be inlined. If any uses of the function remain, they will refer to the single copy in the library.
2.3.4 Variables in Specified Registers
Note: Using variables specified in compiler-allocated registers - fixed registers -
is usually unnecessary and occasionally dangerous. This feature is deprecated and not recommended.
You may specify a fixed register assignment for a particular C variable. It is not recom­mended that this be done.
Accumulator registers are not allocated by the compiler so it is safe to allocate them using the following syntax:
register int Accum_A asm(“A”);
No other register should be allocated.
DS51284K-page 34 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C
2.3.5 Complex Numbers
The compiler supports complex data types. You can declare both complex integer types and complex floating types, using the keyword __complex__ .
For example, __complex__ float x; declares x as a variable whose real part and imaginary part are both of type float. __complex__ short int y; declares y to have real and imaginary parts of type short int.
To write a constant with a complex data type, use the suffix ‘i’ or ‘j’ (either one; they are equivalent). For example, 2.5fi has type __complex__ float and 3i has type __complex__ int. Such a constant is a purely imaginary value, but you can form any complex value you like by adding one to a real constant.
To extract the real part of a complex-valued expression exp, write __real__ exp. Similarly, use _ _imag__ to extract the imaginary part. For example;
__complex__ float z; float r; float i;
r = i =
The operator ‘~’ performs complex conjugation when used on a value with a complex type.
The compiler can allocate complex automatic variables in a noncontiguous fashion; it’s even possible for the real part to be in a register while the imaginary part is on the stack (or vice-versa). The debugging information format has no way to represent noncontig­uous allocations like these, so the compiler describes noncontiguous complex variables as two separate variables of noncomplex type. If the variable’s actual name is foo, the two fictitious variables are named foo$real and foo$imag.
__real__ z; __imag__ z;
2.3.6 Double-Word Integers
The compiler supports data types for integers that are twice as long as long int. Simply write long long int for a signed integer, or unsigned long long int for an unsigned integer. To make an integer constant of type long long int, add the suffix LL to the integer. To make an integer constant of type unsigned long long int, add the suffix ULL to the integer.
Y ou can use these types in arithmetic like any other integer types. Addition, subtraction and bitwise boolean operations on these types are open-coded, but division and shifts are not open-coded. The operations that are not open-coded use special library routines that come with the compiler.
2002-2011 Microchip Technology Inc. DS51284K-page 35
16-Bit C Compiler User’s Guide
2.3.7 Referring to a Type with typeof
Another way to refer to the type of an expression is with the typeof keyword. The syntax for using this keyword looks like sizeof, but the construct acts semantically like a type name defined with typedef.
There are two ways of writing the argument to typeof: with an expression or with a type. Here is an example with an expression:
typeof (x[0](1))
This assumes that x is an array of functions; the type described is that of the values of the functions.
Here is an example with a typename as the argument:
typeof (int *)
Here the type described is a pointer to int. If you are writing a header file that must work when included in ANSI C programs, write
__typeof__ instead of typeof. A typeof construct can be used anywhe re a typedef name could be used. For
example, you can use it in a declaration, in a cast, or inside of sizeof or typeof.
• This declares y with the type of what x points to:
typeof (*x) y;
• This declares y as an array of such values:
typeof (*x) y[4];
• This declares y as an array of pointers to characters:
typeof (typeof (char *)[4]) y;
It is equivalent to the following traditional C declaration:
char *y[4];
To see the meaning of the declaration using typeof, and why it might be a useful way to write, let’s rewrite it with these macros:
#define pointer(T) typeof(T *) #define array(T, N) typeof(T [N])
Now the declaration can be rewritten this way:
array (pointer (char), 4) y;
Thus, array (pointer (char), 4) is the type of arrays of four pointers to char.
DS51284K-page 36 2002-2011 Microchip Technology Inc.
Differences Between 16-Bit Device C and ANSI C

2.4 STATEMENT DIFFERENCES

This section describes the statement differences between plain ANSI C and the C accepted by the compiler. The statement differences are part of the base GCC implementation, and the discussi on in the sec ti on is based on the standard GC C documentation, tailored for the specific syntax and semantics of the 16-bit compiler port of GCC.
• Labels as Values
• Conditionals with Omitted Operands
• Case Ranges
2.4.1 Labels as Values
You can get the address of a label defined in the current function (or a containing function) with the unary operator ‘&&’. The value has type void *. This value is a constant and can be used wherever a constant of that type is valid. For example:
void *ptr; ... ptr = &&foo;
To use these values, you need to be able to jump to one. This is done with the computed goto statement, goto *exp;. For example:
goto *ptr;
Any expression of type void * is allowed. One way of using these constants is in initializing a static array that will serve as a jump
table:
static void *array[] = { &&foo, &&bar, &&hack };
Then you can select a label with indexing, like this:
goto *array[i];
Note: This does not check whether the subscript is in bounds. (Array indexing in
C never does.)
Such an array of label values serves a purpose much like that of the switch statement. The switch statement is cleaner and therefore preferable to an array.
Another use of label values is in an interpreter for threaded code. The labels within the interpreter function can be stored in the threaded code for fast dispatching.
This mechanism can be misused to jump to code in a different function. The compiler cannot prevent this from happening, so care must be taken to ensure that target addresses are valid for the current function.
2002-2011 Microchip Technology Inc. DS51284K-page 37
16-Bit C Compiler User’s Guide
2.4.2 Conditionals with Omitted Operands
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression:
x ? : y
has the value of x if that is nonzero; otherwise, the value of y. This example is perfectly equivalent to:
x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.
2.4.3 Case Ranges
You can specify a range of consecutive values in a single case label, like this:
case low ... high:
This has the same effect as the proper number of individual case labels, one for each integer value from low to high, inclusive.
This feature is especially useful for ranges of ASCII character codes:
case 'A' ... 'Z':
Be careful: Write spaces around the ..., otherwise it may be parsed incorrectly when you use it with integer values. For example, write this:
case 1 ... 5:
rather than this:
case 1...5:

2.5 EXPRESSION DI FFER ENC ES

This section describes the expression differences between plain ANSI C and the C accepted by the compiler.
2.5.1 Binary Literals
A sequence of binary digits preceded by 0b or 0B (the numeral ‘0’ followed by the letter ‘b’ or ‘B’) is taken to be a binary integer. The binary digits consist of the numerals ‘0’ and ‘1’. For example, the (decimal) number 255 can be written as 0b11111111.
Like other integer literals, a binary literal may be suffixed by the letter ‘u’ or ‘U’, to spec­ify that it is unsigned. A binary literal may also be suffixed by the letter ‘l’ or ‘L’, to specify that it is long. Similarly, the suffix ‘ll’ or ‘LL’ denotes a long, long binary literal.
DS51284K-page 38 2002-2011 Microchip Technology Inc.
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC
USER’S GUIDE

Chapter 3. Using the Compiler on the Command Line

3.1 INTRODUCTION

This chapter discusses using the MPLAB C Compiler for PIC24 MCUs and dsPIC® DSCs (formerly MPLAB C30) on the command line. For information on using the com­piler with MPLAB IDE, please refer to the “16-bit Language Tools Getting Started” (DS70094).

3.2 HIGHLIGHTS

Items discussed in this chapter are:
•Overview
• File Naming Conventions
• Options
• Environment Variables
• Predefined Macro Names
• Compiling a Single File on the Command Line
• Compiling Multiple Files on the Command Line
• Notable Symbols
®
DSCs

3.3 OVERVIEW

The compilation driver program (pic30-gcc) compiles, assembles and links C and assembly language modules and library archives. Most of the compiler command-line options are common to all implementations of the GCC toolset. A few are specific to the compiler.
The basic form of the compiler command line is:
pic30-gcc [options] files
The available options are described in Section 3.5 “Options”.
For example, to compile, assemble and link the C source file hello.c, creating the absolute executable hello.exe.
pic30-gcc -o hello.exe hello.c
Note: This executable name applies for all 16-bit compilers, i.e., MPLAB C Com-
piler for PIC24 MCUs and dsPIC DSCs, MPLAB C Compiler for dsPIC DSCs, and MPLAB C Compiler for PIC24 MCUs.
Note: Command line options and file name extensions are case-sensitive.
2002-2011 Microchip Technology Inc. DS51284K-page 39
16-Bit C Compiler User’s Guide

3.4 FILE NAMING CONVENTIONS

The compilation driver recognizes the following file extensions, which are case-sensitive.
TABLE 3-1: FILE NAMES
Extensions Definition
file.c A C source file that must be preprocessed. file.h A header file (not to be compiled or linked). file.i A C source file that should not be preprocessed. file.o An object file. file.p A pre procedural-abstraction assembly language file. file.s Assembler code. file.S Assembler code that must be preprocessed.
other A file to be passed to the linker.

3.5 OPTIONS

The compiler has many options for controlling compilation, all of which are case-sensitive.
• Options Specific to 16-Bit Devices
• Options for Controlling the Kind of Output
• Options for Controlling the C Dialect
• Options for Controlling Warnings and Errors
• Options for Debugging
• Options for Controlling Optimization
• Options for Controlling the Preprocessor
• Options for Assembling
• Options for Linking
• Options for Directory Search
• Options for Code Generation Conventions
DS51284K-page 40 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
STD
3.5.1 Options Specific to 16-Bit Devices
For more information on the memory models, see Section 4.6 “Memory Models”. TABLE 3-2: dsPIC
Option Definition
-mconst-in-code Put constants in the auto_psv space. The compiler will access these
-mconst-in-data Put cons t an ts in the data memory space.
-mconst-in­auxflash
-merrata= id[,id]*
-mfillupper Specif y the up per byte of variab les st ored into space(prog) sections.
-mlarge-arrays Specifies that arrays may be larger than the default maximum size of
-mlarge-code Compile using the large code model. No assumptions are made about
-mlarge-data Compile using the large data model. No assumptions are made about
-mcpu= target
(1)
-mpa
Note 1: The procedure abstractor behaves as the inverse of inlining functions. The pass is
designed to extract common code sequences from multiple sites throughout a translation unit and place them into a common area of code. Although this option generally does no t im pro ve the run -tim e p erformance of the gene rate d c ode , it ca n reduce the code size significantly. Programs compiled with -mpa can be harder to debug; it is not recommended that this option be used while debugging using the COFF object format. The procedure abstractor is invoked as a separate phase of compilation, after the production of an assembly file. This phase does not optimize across translation units. When the proc edure-opti mizing pha se is enabl ed, inline as sembly cod e must be limited to valid machine instructions. Invalid machine instructions or instruction sequences, or assemb ler dire ct ive s (se cti oni ng directives, macros, include files, etc.) must not be used, or the procedure abstraction phase will fail, inhibiting the creation of an output file.
®
DSC DEVICE-SPECIFIC OPTIONS
constants using the PSV window. (This is the default.)
When combined with -mconst-in-code, put call const qualified file scope variables i nto auxil iary FLASH. Al l modules with auxil iary FLASH should be compiled with this option; otherwise a link error may occur.
This option enabl es sp ec ific er rat a work arounds identified by id. Valid values for id change from time to time and may not be required for a particular variant. An id of list will display the currently supported errata identifiers along with a brief description of the errata. An id of all will enable all currently supported errata work arounds.
The fillupper attribute will perform the same function on individual variables.
32K. See Section 4.15 “Using Large Arrays” for more information.
the locality of called functions. When this option is chosen, single functions that are larger than 32k are not supported and may cause assembly-time errors since all branches inside of a function are of the short form.
the location of static and external variables. This option selects the target processor ID (and communicates it to the
assembler and linker if tho se tools are invo ked). This optio n affect s how some predefined constants are set; see Section 3.7 “Predefined Macro Names” for more info rmation. A full list of accepted t arg et s can be seen in the Readme.htm file that came with the release.
Enable the procedure abstraction optimization. There is no limit on the nesting level.
2002-2011 Microchip Technology Inc. DS51284K-page 41
16-Bit C Compiler User’s Guide
STD
STD
TABLE 3-2: dsPIC® DSC DEVICE-SPECIFIC OPTIONS (CONTINUED)
Option Definition
-mpa=n
-mno-pa
-mno-isr-warn By default the compiler will produce a warning if the
-omf Selects the OMF (Object Module Format) to be used by the compiler.
-msmall-code Compile using the small code model. Called functions are assumed to
-msmall-data Compile using the small data model. All static and external variables
-msmall-scalar Like -msmall-data, except that only static and external scalars are
-mtext=name Specifying -mtext=name will cause text (program code) to be placed
-mauxflash Place all code from the current translation unit into auxiliary FLASH.
-msmart-io [=0|1|2]
Note 1: The procedure abstractor behaves as the inverse of inlining functions. The pass is
(1)
(1)
designed to extract common code sequences from multiple sites throughout a translation unit and place them into a common area of code. Although this option generally does no t im pro ve the run -tim e p erformance of the gene rate d c ode , it ca n reduce the code size significantly. Programs compiled with -mpa can be harder to debug; it is not recommended that this option be used while debugging using the COFF object format. The procedure abstractor is invoked as a separate phase of compilation, after the production of an assembly file. This phase does not optimize across translation units. When the proc edure-opti mizing ph ase is enabl ed, inline as sembly cod e must be limited to valid machine instructions. Invalid machine instructions or instruction sequences, or assemb ler dire ct ive s (se cti oni ng directives, macros, include f ile s, etc.) must not be used, or the procedure abstraction phase will fail, inhibiting the creation of an output file.
Enable the procedure ab straction optimi zation up to level n. If n is zero, the optimization is disabled. If n is 1, first level of abs traction is allowed; that is, instruction sequences in the source code may be abstracted into a subroutine. If n is 2, a second level of abs tracti on is allowe d; that is, instructions that were put into a subroutine in the first level may be abstracted into a subroutin e one lev el dee per. This pattern continues for larger values of n. The net effec t is to limi t the sub routine call nest ing de pth to a m aximum of n.
Do not enable the procedure abstraction optimization.
(This is the default.)
is not attached to a recognized interrupt vector name. This option will disable that feature.
The omf specifier can be one of the following:
coff Produce COFF object files. (This is the default.) elf Produce ELF object files.
The debugging format used for ELF object files is DWARF 2.0.
be proximate (within 32 Kwords of the caller). (This is the default.)
are assumed to be located in the lower 8 KB of data memory space.
(This is the default.)
assumed to be in the lower 8 KB of data memory space. (This is the default.)
in a section named name rather than the default .text section. No white spaces should appear around the =.
This option is only available on devices that have auxiliary FLASH. This option attempts to statically analyze format strings passed to
printf, scanf and the ‘f’ and ‘v’ variati ons of thes e function s. Uses of nonfloating point format arguments will be converted to use an integer-only variation of the library functions.
-msmart-io=0 disables this op tion, whi le -msmart-io=2 causes the compiler to be optimistic and convert function calls with variable or unknown format argument s . -msmart-io=1 is the default and will only convert the literal values it can prove.
__interrupt__
DS51284K-page 42 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
3.5.2 Options for Controlling the Kind of Output
The following options control the kind of output produced by the compiler.
TABLE 3-3: KIND-OF-OUTPUT CONTROL OPTIONS
Option Definition
-c Compile or assemble the source files, but do not link. The default file extension is .o.
-E Stop after the preprocessing stage, i.e., before running the compiler proper. The default output file is stdout.
-o file Place the output in file.
-S Stop af ter c ompilat ion pro pe r (i.e., before invok ing t he as semb ler). The default output file extension is .s.
-v Print the commands executed during each stage of compilation.
-x You can specify the input language explicitly with the -x option:
-x
language
Specify explicitly the language for the following input files (rather than letting the compiler choose a default based on the file name suffix). This option applies to all following input files until the next -x option. The following values are supported by the compiler:
c c-header cpp-output assembler assembler-with-cpp
-x none Turn off any specification of a language, so that subsequent files are handled according to their file name suffixes. This is the default behavior but is needed if another -x option has been used. For example:
pic30-gcc -x assembler foo.asm bar.asm -x none main.c mabonga.s
Without the -x none, the compi ler will assum e all t he inpu t files are for the assembler.
--help Print a description of the command line options.
2002-2011 Microchip Technology Inc. DS51284K-page 43
16-Bit C Compiler User’s Guide
3.5.3 Options for Controlling the C Dialect
The following options define the kind of C dialect used by the compiler.
TABLE 3-4: C DIALECT CONTROL OPTIONS
Option Definition
-ansi Support all (and only) ANSI-standard C programs.
-aux-info filename Output to the given filename prototyped declarations for all
functions declared and/or defined in a translation unit, including those in header files. This option is silently ignored in any language other than C. Besides declarations, the file indicate s, in com m ents, the origin of each declaration (source file and lin e), whe ther the declara­tion was implicit, prototyped or unprototyped (I, N for new or O for old, respectively, in the first character after the line number and the colon), and whether it came from a declaration or a definition (C or F, respectively, in the following character). In the case of functio n defin iti ons , a K&R-style list of argum ents followed by their dec larations is also provided, inside comment s , af ter the dec la rati on.
-ffreestanding Assert that compilation takes place in a freestanding environment. This implies -fno-builtin. A freestanding environment is one in which the standard library may not exist, and program sta r tup may not nec es sari ly be at mai n. The most obvious example is an OS kernel. This is equivalent to -fno-hosted.
-fno-asm Do not recognize asm, inline or typeof as a keyword, so that cod e can use these words as ide ntifiers. You can use the keywords
__typeof__ instead.
-ansi implies -fno-asm.
-fno-builtin
-fno-builtin-function
-fsigned-char Let the type char be signed, like signed char.
-fsigned-bitfields
-funsigned-bitfields
-fno-signed-bitfields
-fno-unsigned-bitfields
-funsigned-char Let the type char be unsigned, like unsigned char.
Don’t recognize built-in functions that do not begin with
__builtin_ as prefix.
(This is the default.)
These options control whether a bit field is signed or unsigned, when the declaration does not use either signed or unsigned. By default, such a bit field is signed, unless
-traditional is used, in which case bi t fields are alw ays unsigned.
__asm__, __inline__ and
DS51284K-page 44 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
3.5.4 Options for Controlling Warnings and Errors
Warnings are diagnostic messages that report constructions that are not inherently erroneous but that are risky or suggest there may have been an error.
You can request many specific warnings with options beginning -W, for example,
-Wimplicit, to request warnings on implicit declarations. Each of these specific warning options also has a negative form beginning -Wno- to turn off warnings, for example, -Wno-implicit. This manual lists only one of the two forms, whichever is not the default.
The following options control the amount and kinds of warnings produced by the compiler.
TABLE 3-5: WARNING/ERROR OPTIONS IMPLIED BY -WALL
Option Definition
-fsyntax-only Check the code for syntax, but don’t do anythin g beyon d that.
-pedantic Issue all the warnings demanded by strict ANSI C; reject all
programs that use forbidden extensions.
-pedantic-errors Like -pedantic, except that errors are p roduced rather th an warnings.
-w Inhibit all warning messages.
-Wall All of the -W options listed in this table c ombined. This
enables all the warnings a bout con struction s that so me users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.
-Wchar-subscripts Warn if an array subscript has type char.
-Wcomment
-Wcomments
-Wdiv-by-zero Warn about compile-time integer division by zero. To inhibit
-Werror-implicit-
function-declaration
-Wformat Check calls to printf and scanf, etc., to make sure that
-Wimplicit Equivalent to specifying both -Wimplicit-int and
-Wimplicit-function-
declaration
-Wimplicit-int Warn when a declaration does not specify a type.
-Wmain Warn if the type of main is suspicious. main should be a
-Wmissing-braces Warn if a n agg regate or uni on in iti alize r is not fu lly b racke ted.
Warn whenever a comment-start sequence /* appears in a /* comment, or whenever a Bac kslash-Ne wline appear s in a // comment.
the warning messages, use -Wno-div-by-zero. Floating point division by zero is not warned about, as it can be a legitimate way of obtaining infinities and NaNs.
(This is the default.)
Give an error whenever a function is used before being declared.
the arguments supp lie d hav e typ es appro pria t e to the for mat string specified.
-Wimplicit-function-declaration. Give a warning whenever a function is used before being
declared.
function with external linkage, returning int, taking either zero, two or three arguments of appropriate types.
In the following example, the initializer for a is not fully bracketed, but that for b is fully bracketed.
int a[2][2] = { 0, 1, 2, 3 }; int b[2][2] = { { 0, 1 }, { 2, 3 } };
2002-2011 Microchip Technology Inc. DS51284K-page 45
16-Bit C Compiler User’s Guide
TABLE 3-5: WARNING/ERROR OPTIONS IMPLIED BY -WALL (CONTINUED)
Option Definition
-Wmultichar
-Wno-multichar
-Wparentheses Warn if parentheses are omitted in certain contexts, such as
-Wreturn-type Warn whenever a function is defined with a return-type that
-Wsequence-point Warn about code that may have undefined semantics
Warn if a multi-char acter character constant is used. Usually, such constants are typographical errors. Since they have implementation-defined values, they should not be used in portable code. The following example illustrates the use of a multi-character character constant:
char xx(void) { return('xx'); }
when there is an assignme nt in a contex t where a truth value is expected, or when operators are nested whose precedence people often find confusing.
defaults to int. Also warn about any return statement with no return-value in a function whose return-type is not void.
because of violations of sequence point rules in the C standard. The C standard defin es the order in which expression s in a C program are evaluated in terms of sequence points, which represent a partial orderi ng betw een the ex ecution of p art s of the program: those executed before the sequence point and those executed after it. These occur after the evaluation of a full expression (one which is not part of a larger expression), after the evaluation of the first operand of a &&, ||, ? : or , (comma) operator, before a function is called (but after the evaluation of its arguments and the expression denoting the called function), and in certain other places. Other than as expressed by the sequence point rules, the order of evaluation of subexpressions of an expression is not specified. All these rules describe only a partial order rather than a total order, since, for example, if two functions are called within one express ion with n o sequen ce point between them, the order in which the functions are called is not specified. However, the standards committee has ruled that function calls do not overlap. It is not specified, when, between sequence points modifications to the values of objects take effect. Programs whose behavior depends on this have undefined behavior; the C standard specifi es that “Between the previou s and next sequence point, an object shall have its stored value modified, at most once, by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.” If a program breaks these rules, the results on any particular implementation are entirely unpredictable. Examples of code with undefined behavior are a = a++;, a[n] = b[n++] and a[i++] = i;. Some more complicated cases are not diagnosed by this option, and it may give an occasional false positive result, but in general it has been found fairly effective at detecting this sort of problem in programs.
DS51284K-page 46 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-5: WARNING/ERROR OPTIONS IMPLIED BY -WALL (CONTINUED)
Option Definition
-Wswitch Warn whenever a switch statement has an index of enumeral type and lacks a cas e for one or more of the nam ed codes of that enumeration. (The presence of a default label prevents this warning.) case labels outside the enumeration range also provoke warnings when this option is used.
-Wsystem-headers Print warning messages for constructs found in system header files. Warnings from system headers are normally suppressed, on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read. Using this command line option tells the compiler to e mi t w a rnin gs f r om s ystem h eaders as if they occurred in user code. However, note that using -Wall in conjunction with this option will not warn about unknown pragmas in system headers; for that, -Wunknown-pragmas must also be used.
-Wtrigraphs Warn if any trigraphs are encountered (assuming they are enabled).
-Wuninitialized Warn if an automatic variable is used without first being initialized. These warnings are possible only when optimization is enabled, because they require data flow information that is computed only when optimizing. These warnings occur only for variables that are candidates for register allocation. Therefore, they do not occur for a variable that is declared volatile, or whose address is taken, or whose size is other than 1, 2, 4 or 8 bytes. Also, they do not occur for structures , unions or arrays, eve n when they are in registers. Note that there may be no warning about a variable that is used only to compute a value that itself is never used, because such computations may be deleted by data flow analysis before the warnings are printed.
-Wunknown-pragmas Warn when a #pragma directive is encountered which is not understood by the compiler. If this command line option is used, warnings will even be issued for unknown pragmas in system header files. Th is is n ot the ca se if the warnin gs were only enabled by the -Wall command line option.
-Wunused Warn whenever a variable is unused aside from its declaration, whenever a function is declared static but never defined, whenever a label is declared but not used, and whenever a statement computes a result that is explicitly not used. In order to get a warning about an unused function parameter, both -W and -Wunused must be specified. Casting an expression to void suppresses this warning for an expression. Similarly, the unused attribute suppresses this warning for unused variables, parameters and labels.
-Wunused-function Warn whenever a st at ic func ti on is dec la red but not def ine d or a non-inline static function is unused.
-Wunused-label Warn whenever a labe l is decla red bu t not used. To suppress this warning, use the unused attribute (see Section 2.3.1 “Specifying Attributes of Variables”).
2002-2011 Microchip Technology Inc. DS51284K-page 47
16-Bit C Compiler User’s Guide
TABLE 3-5: WARNING/ERROR OPTIONS IMPLIED BY -WALL (CONTINUED)
Option Definition
-Wunused-parameter Warn whenever a function parameter is unu sed aside from it s declarati on. To suppress th is warning, use the unused attri­bute (see Section 2.3.1 “Specifying Attributes of Variables”).
-Wunused-variable Warn whenever a local variable or non-constant static variable is unused aside from it s declara tion. To suppress this warning, use the unused attribute (see Section 2.3.1 “Specifying Attributes of Variables”).
-Wunused-value Warn whenever a statement computes a result tha t is explicitly not used. To suppress this warning, cast the expression to void.
The following -W options are not implied by -Wall. Some of them warn about construc­tions that users generally do not consider questionable, but which occasionally you might wish to check for. Others warn about constructions that are necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning.
DS51284K-page 48 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-6: WARNING/ERROR OPTIONS NOT IMPLIED BY -WALL
Option Definition
-W Print extra warning mes s ages for these events:
• A nonvolatile automatic variable might be changed by a call to longjmp. These warnings are possible only in optimizing compilation. The compiler sees only the calls to setjmp. It cannot know where longjmp will be called; in fact, a signal handler could call it at any point in the code. As a result, a warning may be generated even when there is in fact no problem, because longjmp cannot in fact be called at the place that would cause a problem.
• A function could exit both via return value; and return;. Completing the function body without passing any return statement is treated as return;.
• An expression-statement or the left-hand side of a comma expression contains no side effects. To suppress the warning, cast the unused expression to void. For example, an expression such as x[i,j] will cause a warning, but x[(void)i,j] will not.
• An unsigned value is compared agai nst ze ro wi th < or <=.
•A comparison like x<=y<=z appears; this is equivalent to (x<=y ? 1 : 0) <= z, which is a different interpretation from that of ordinary mathematical notation.
• Storage-class specifiers like static are not the first things in a declaration. According to the C Standard, this usage is obsolescent.
•If -Wall or -Wunused is also specified, warn about unused arguments .
• A comparison between s igned and uns igned value s could produce an incorrect result when the signed value is converted to unsigned. (But don’t warn if
-Wno-sign-compare is also specified.)
• An aggregate has a partly bracketed initializer. For example, the follow ing code w ould ev oke such a warning, because braces are mi ss ing around the initiali zer for x.h:
struct s { int f, g; }; struct t { struct s h; int i; }; struct t x = { 1, 2, 3 };
• An aggregate has an initializer that does not initialize all members. For example, the following code would cause such a warning, because x.h would be implicitly initialized to zero:
struct s { int f, g, h; }; struct s x = { 3, 4 };
-Waggregate-return Warn if any functions that return structures or unions are
defined or called.
-Wbad-function-cast Warn whenev er a fu nc tio n call is cast to a non-ma tch ing type. For example, warn if int foof() is cast to anything *.
-Wcast-align Warn whenever a pointer is cast, s uch that the required alignment of the target is increased. For example, warn if a
char * is cast to an int * .
-Wcast-qual Warn whenever a pointer is cast, so as to remove a type
qualifier from the target type. For example, warn if a const char * is cast to an ordinary char *.
2002-2011 Microchip Technology Inc. DS51284K-page 49
16-Bit C Compiler User’s Guide
TABLE 3-6: WARNING/ERROR OPTIONS NOT IMPLIED BY -WALL
Option Definition
-Wconversion Warn if a prototype causes a type conversion that is different from what would happen to the same argument in the absence of a prototype. This includes conversions of fixed point to floating an d vice v ersa, a nd con versi ons c hangin g the width or signedness of a fixed point argument, except when the same as the default promotion. Also, warn if a negative integer co nstant expres sion is implicitly converted to an unsigned type. For example, warn about the assignment x = -1 if x is unsigned. But do not warn about explicit casts like (unsigned) -1.
-Werror Make all warnings into errors.
-Winline Warn if a function can not be inlined, and either it was
declared as inline, or else the -finline-functions option was given.
-Wlarger-than-len Warn whene ver an obj ec t of larger than len bytes is defined.
-Wlong-long
-Wno-long-long
-Wmissing-declarations Warn if a global function is defined without a previous
-Wmissing-
format-attribute
-Wmissing-noreturn Warn about functions that might be candidates for attribute
-Wmissing-prototypes Warn if a global function is defined without a previous
-Wnested-externs Warn if an extern declaration is encountered within a
-Wno-deprecated-
declarations
-Wpadded Warn if padding is included in a structure, either to align an
-Wpointer-arith Warn about anything that depends on the size of a function
-Wredundant-decls Warn if anything is declared more than once in the same
-Wshadow Warn whenever a local variable shadows another local
Warn if long long type is used. This is default. To inhibit the warning messages, use -Wno-long-long. Flags
-Wlong-long and -Wno-long-long are taken int o account only when -pedantic flag is used.
declaration. Do so even if the definition itself provides a prototype.
If -Wformat is enabled, also warn about functions that might be candidates for format attributes. Note these are only possi­ble candidates, not absolute ones. This option has no effect unless -Wformat is enabled.
noreturn. These are only possible candidates, not absolute ones. Care should be taken to manually verify functions. Actually, do not ever return before adding the noreturn attri- bute; otherwise subtle code generation bugs could be intro­duced.
prototype declaration. This warning is issued even if the definition itse lf pro vi des a prot oty pe. (This opt ion can be us ed to detect global fu nction s that are not d eclare d in he ader fi les.)
function. Do not warn about uses of functions, variables and types
marked as deprecated by using the deprecated attribute.
element of the structure or to align the whole structure.
type or of void. The compiler assigns these types a siz e of 1, for convenience in calculations with void * pointers and pointers to functions.
scope, even in cases where multiple declaration is valid and changes nothing.
variable.
DS51284K-page 50 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-6: WARNING/ERROR OPTIONS NOT IMPLIED BY -WALL
Option Definition
-Wsign-compare
-Wno-sign-compare
-Wstrict-prototypes Warn if a func tion i s decla red or defi ned wi thout s peci fying the
-Wtraditional Warn about certain constructs that behave differently in
-Wundef Warn if an undefined identifier is evaluated in an #if
-Wunreachable-code Warn if the co mp ile r detects that code wi ll ne ve r be ex ec ute d.
-Wwrite-strings Give string constants the ty pe const char[length] so that
Warn when a comparison between signed and unsigned values could produce an incorre ct resu lt wh en the signe d value is converted to unsigned. This warning is also enabled by -W; to get the other warnings of -W without this warning, use -W -Wno-sign-compare.
argument types. (An old-style function definition is permitted without a warning i f preced ed by a decl aration which s peci fies the argument types.)
traditional and ANSI C.
• Macro arguments occurring within string constants in the macro body. These would substitute the argument in traditio nal C, but ar e part of the constant in ANSI C.
• A function declared external in one block and then used after the end of the block.
• A switch statement has an operand of type long.
• A nonstatic function declaration follows a static one. This construct is not accepted by some traditional C compilers.
directive.
It is possible for this opti on to produ ce a warning even though there are circumstances unde r whi ch p art of the aff ec ted lin e can be executed, so care should be taken when removing apparently- unreachable code. For instance, when a functi on is inlined, a warning may mean that the line is unreachable in only one inlined copy of the function.
copying the address of one into a non-const char * pointer will get a warning. These warnings will help you find at compile time code that you can try to write into a string constant, but only if you have been very careful about using const in declarations and prototype s. Otherwise, it will just be a nuisance, which is why -Wall does not request these warnings.
2002-2011 Microchip Technology Inc. DS51284K-page 51
16-Bit C Compiler User’s Guide
3.5.5 Options for Debugging
The following options are used for debugging.
TABLE 3-7: DEBUGGING OPTIONS
Option Definition
-g Produce debugging information. The compiler supports the use of -g with -O making it possible to debug optimize d code. T he shortc uts t ake n by opti mized c ode may occasionally produce surprising results:
• Some declared variables may not exist at all;
• Flow of control may briefly move unexpectedly;
• Some statements may not be executed because they
compute constant results or their values were already at hand;
• Some statements may execute in different places because
they were moved out of loops. Nevertheless it proves possible to debug optimized output. This makes it reasonable to use the optimizer for programs that might have bugs.
-Q Makes the compiler print out each function name as it is compiled, and print some statistics about each pass when it finishes.
-save-temps Don’t delete intermediate files. Place them in the current direc­tory and name them based on the source file. Thus, compiling foo.c with -c -save-temps would produce the following files:
foo.i (preprocessed file) foo.p (pre procedure abstraction assembly language file) foo.s (assembly language file) foo.o (object file)
3.5.6 Options for Controlling Optimization
The following options control compiler optimizations.
TABLE 3-8: GENERAL OPTIMIZATION OPTIONS
Option Definition
-O0 Do not optimize. (This is the default.)
Without -O, the compiler’s goal is to reduce the cost of compi­lation and to make debugging produce the expected results. Statements are independent: if you stop the program with a breakpoint between statements, you can then assign a new value to any variable or change the program counter to any other statement in the function and get exactly the results you would expect from the source code. The compiler only allocates variables declared register in registers.
-O
-O1
Optimize. Optimizin g com pil ati on t ak es some w hat lon ger, and a lot more host memory for a large function. With -O, the compiler tries to reduce code size and execution time. When -O is specified, the compi le r turns on
-fthread-jumps and
-fdefer-pop. The compiler turns on
-fomit-frame-pointer.
DS51284K-page 52 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
STD
STD
STD
STD
STD
STD
TABLE 3-8: GENERAL OPTIMIZATION OPTIONS (CONTINUED)
Option Definition
-O2 Optimize even more. The compiler performs nearly all supported optimizations that do not involve a space-speed trade-off. -O2 turns on all optional optimizations except for loop unrolling (-funroll-loops), function inlining (-finline-functions), and strict aliasing optimizati ons (-fstrict-aliasing). It also turns on force copy of memory operands (-fforce-mem) and Frame Pointer elimi­nation (-fomit-frame-pointer). As compared to -O, this option increases b oth compi lation tim e and the pe rformance of the generated code.
-O3 Optimize yet more. -O3 turns on all optimizations specified by
-O2 and also turns on the inline-functions option.
-Os Optimize for size. -Os enables all -O2 optimizations that do
not typically increase code size. It also performs further optimizations designed to reduce code size.
The following options control specific optimizations. The -O2 option turns on all of these optimizations except -funroll-loops, -funroll-all-loops and
-fstrict-aliasing. Y ou can use the following flags in the rare cases when “fine-tuning” of optimizations to
be performed is desired.
TABLE 3-9: SPECIFIC OPTIMIZATION OPTIONS
Option Definition
-falign-functions
-falign-functions=n
-falign-labels
-falign-labels=n
-falign-loops
-falign-loops=n
-fcaller-saves Enable values to be allocated in registers that will be
Align the start of functions to the next power-of-two greater than n, skipping up to n bytes. For instance,
-falign-functions=32 aligns functions to the next 32-byte boundary, but -falign-functions=24 would align to the next 32-byte boundary only if this can be done by skipping 23 bytes or less.
-fno-align-functions and -falign-functions=1 are equivalent and mean that functions will not be aligned. The assembler only supports this flag when n is a power of two; so n is rounded up. If n is not specified, use a machine-dependent default.
Align all branch targets to a power-of-two boundary, skipping up to n bytes like -falign-functions. This option can easily make code slower, because it must insert dummy operations for when the branch targ et is reac he d in the usua l flow of the code. If -falign-loops or -falign-jumps are applicable and are greater than this va lue , then their values are used ins tea d. If n is not spec ified, us e a machin e-depende nt default which is very likely to be 1, meani ng no alignment.
Align loops to a po wer-of-two b oundar y, skipping up to n bytes like -falign-functions. The hope is that the loop will be executed many times, which will make up for any execution of the dummy operations. If n is not specified, use a machine-dependent default.
clobbered by function calls, by emitting extra instructions to save and restore the registers arou nd suc h cal ls . Such allocation is done only when it seems to result in better code than would otherwise be produced.
2002-2011 Microchip Technology Inc. DS51284K-page 53
16-Bit C Compiler User’s Guide
STD
STD
STD
STD
STD
STD
STD
TABLE 3-9: SPECIFIC OPTIMIZATION OPTIONS (CONTINUED)
Option Definition
-fcse-follow-jumps In common subexpression elimination, scan through jump instructions when the target of the ju mp is not reac he d by an y other path. For example, when CSE encounters an if statement with an else clause, CSE will follow the jump when the condition tested is false.
-fcse-skip-blocks This is similar to -fcse-follow-jumps, but causes CSE to follow jumps which conditionally skip over blocks. When CSE encounters a simple if statement with no else clause,
-fcse-skip-blocks causes CSE to follow the jump around the body of the if.
-fexpensive-
optimizations
-ffunction-sections
-fdata-sections
-fgcse Perform a global common subexpression elimination pass.
-fgcse-lm When -fgcse-lm is ena ble d, g lob al common subexpre ss io n
-fgcse-sm When -fgcse-sm is enabled, a store motion pass is run after
-fno-defer-pop Always pop the arguments to each function call as soon as
-fno-peephole
-fno-peephole2
-foptimize-
register-move
-fregmove
-frename-registers Attempt to avoid false dependencies in scheduled code by
Perform a number of minor optimizations that are relatively expensive.
Place each function or data item into its own section in the output file. The name of the function or the name of the data item determines the section’s name in the output file. Only use these options when there are significant benefits for doing so. When y ou sp eci f y the se op tion s, the assembler and linker may create larger object and executable files and will also be slower.
This pass also performs global constant and copy propagation.
elimination will attempt to move loads which are only killed by stores into themselves . This allows a loop containing a load/store sequence to be chan ged to a load outs ide the loop, and a copy/store within the loop.
global common subexpression elimination. This pass will attempt to move stores out of loop s. When used in conjun ction with -fgcse-lm, loops co ntaining a load/s tore sequence can be changed to a load before the loop and a store after the loop.
that function returns. The compiler normally lets arguments accumulate on the stack for several function calls and pops them all at once.
Disable machine specific peephole optimizations. Peephole optimizations occur at various points during the compilation.
-fno-peephole disables p eep hol e opti mi za tion on machine instructions, while -fno-peephole2 disables high level peephole optimizati ons. To disable peephole entirely, use both options.
Attempt to reassign re gister numbe rs in move i nstructio ns and as operands of other simple instructions in order to maximize the amount of register tying.
-fregmove and -foptimize-register-moves are the same optimization.
making use of registers left over after register allocation. This optimization will most bene fit proce ssors wi th lot s of regi sters. It can, however, make debugging impossible, since variables will no longer stay in a “home register”.
DS51284K-page 54 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
STD
STD
STD
STD
STD
TABLE 3-9: SPECIFIC OPTIMIZATION OPTIONS (CONTINUED)
Option Definition
-frerun-cse-after­ loop
-frerun-loop-opt Run the loop optimizer twice.
-fschedule-insns Attempt to reorder instructions to eliminate dsPIC® DSC
-fschedule-insns2 Similar to -fschedule-insns, but requests an addi tio nal
-fstrength-reduce Perform the optimizations of loop strength reduction and
-fstrict-aliasing Allows the compiler to assume the strictest aliasing rules
Rerun common subexpression elimination after loop optimizations has been performed.
Read-After-Write stalls (see the “dsPIC30F Family Reference Manual” (DS70046) for more details). Typically improves performance with no impac t on code size.
pass of instruction scheduling after register allocation has been done.
elimination of iteration variables.
applicable to the language being compiled. For C, this activates optimizations based on the type of expressions. In particular, an object o f on e ty pe i s a ssum ed n ev er to resi de at the same address as an object of a different type, unless the types are almost the same. For example, an unsigned int can alias an int, but not a void* or a double. A character type may alias any other type. Pay special attention to code like this:
union a_union { int i; double d; };
int f() { union a_union t; t.d = 3.0; return t.i; }
The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. So, the code abo ve will wo rk as ex pecte d. Howe ver, this code might not:
int f() { a_union t; int* ip; t.d = 3.0; ip = &t.i; return *ip; }
-fthread-jumps Perform optimizations where a che ck is ma de to see if a jump
branches to a location where another comparison subsumed by the first is found. If s o, the first bra nch is red irected to eith er the destination of the second branch or a point immediately following it, depending on whether the condition is known to be true or false.
-funroll-loops Perform the optimization of loop unrolling. This is only done for loops whose number of iterations can be determined at compile time or run time. -funroll-loops implies both
-fstrength-reduce and -frerun-cse-after-loop.
2002-2011 Microchip Technology Inc. DS51284K-page 55
16-Bit C Compiler User’s Guide
STD
TABLE 3-9: SPECIFIC OPTIMIZATION OPTIONS (CONTINUED)
Option Definition
-funroll-all-loops Perform the optimization of loop unrolling. This is done for all loops and usually makes programs run more slowly.
-funroll-all-loops implies -fstrength-reduce, as well as -frerun-cse-after-loop.
Options of the form -fflag specify machine-independent flags. Most flags have both positive and negative forms; the negative form of -ffoo would be -fno-foo. In the table below, only one of the forms is listed (the one that is not the default.)
TABLE 3-10: MACHINE-INDEPENDENT OPTIMIZATION OPTIONS
Option Definition
-fforce-mem Force memory operands to be copied into registers
before doing arithmetic on them. This produces better code by making all memory references potential co mmon subexpressions. When they are not common subexpres­sions, instruction combination should eliminate the separate register-load. The -O2 option turns on this option.
-finline-functions Integrate all simple functions into their callers. The
compiler heuristically decides which functions are simple enough to be worth integrating in this way. If all calls to a given function are in tegrated, an d the functio n is decla red static, then the function is normally not output as assembler code in its own right.
-finline-limit=n By default, the compiler limits the size of functions that
can be inlined. This flag allows the control of this limit for functions that are expli cit ly marked as inlin e (i.e ., mark ed with the inline keyword). n is the size of functions that can be inlined in number of pseudo instructions (not counting parameter handling). The default value of n is
10000. Increasing this value can result in more inlined code at the cost of compilation time and memory consumption. Decreasing usually makes the comp ilation faster an d less code will be inlined (which presumably means slower programs). This option is particularly useful for programs that use inlining.
Note: Pseudo instruction represents, in this particular context, an abstrac t measurement o f function’s size. In no way does it represent a count of assembly instructions and as such, its exact meaning might change from one release of the compiler to an another.
-fkeep-inline-functions Even if all calls to a given function are int egrated , and the
function is declared static, output a separate run time callable version of the function. This switch does not affect extern inline functions.
-fkeep-static-consts Emit variables declared static const when optimization
isn’t turned on, even if the variables aren’t referenced. The compiler enables th is option by default . If you w ant to force the compiler to chec k if the variabl e was referenced, regardless of whether or not optimization is turned on, use the -fno-keep-static-consts option.
DS51284K-page 56 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-10: MACHINE-INDEPENDENT OPTIMIZATION OPTIONS
Option Definition
-fno-function-cse Do not put function addresses in registers; make each instruction that calls a constant function contain the function’s address explicitly. This option results in less efficient code, but some strange hacks that alter the assembler output may be confused by the o ptimization s performe d when this option is not used.
-fno-inline Do no t pay attention to the inline keyword. Normally this option is used to keep the compiler from expanding any functions inline. If optimization is not enabled, no functions can be expanded inline.
-fomit-frame-pointer Do not keep the Frame Pointer in a register for functions that don’t need one. This avoids the instructions to save, set up and restore Frame Pointe rs; it also makes an extra register available in many functions.
-foptimize-sibling-calls Optimize sibling and tail recursive calls.
3.5.7 Options for Controlling the Preprocessor
The following options control the compiler preprocessor.
TABLE 3-11: PREPROCESSOR OPTIONS
Option Definition
-Aquestion (answer) Assert the answe r answer for qu estion question, in case it is
tested with a preprocessing conditional such as #if #question(answer). -A- disables the standard assertions that normally describe the target machine. For example, the fu nc tion p r oto typ e f or m ai n m ig ht be declared as follows:
#if #environ(freestanding) int main(void); #else int main(int argc, char *argv[]); #endif
A -A command-line option could then be used to select between the two prototypes. For example, to select the first of the two, the following command-line option could be used:
-Aenviron(freestanding)
-A -predicate =answer Cancel an asse rtion with the predi cate predicate and answer
answer.
-A predicate =answer Make an assertion with the predicate predicate and answer
answer. This form is preferred to the older form
-A predicate(answer), which is still supported, because it does not use shell special characters.
-C Tell the preprocessor not to discard comments. Used with the
-E option.
-dD Tell the preprocessor to not remove macro definitions into the
output, in their proper sequence.
-Dmacro Define macro macro with the string 1 as its definition.
-Dmacro=defn Define macro macro as defn. All instances of -D on the
command line are processed before any -U options.
-dM Tell the preprocessor to output only a list of the macro
definitions that are in effect at the end of preprocessing. Used with the -E option.
2002-2011 Microchip Technology Inc. DS51284K-page 57
16-Bit C Compiler User’s Guide
TABLE 3-11: PREPROCESSOR OPTIONS (CONTINUED)
Option Definition
-dN Like -dD except that the macro arguments and contents are omitted. Only #define name is included in the output.
-fno-show-column Do not print column numbers in diagnostics. This may be necessary if diagnosti c s are being scanned by a program that does not understand the column numbers, such as dejagnu.
-H Print the name of each header file used, in addition to other normal activities.
-I- Any directories you specify with -I options before the -I- options are searched only for the case of #include "file"; they are not searched for #include <file>. If additional directories are specified with -I options after the
-I-, these directories are searched for all #include directives. (Ordinarily all -I directories are used this way.) In addition, the -I- option inhibits the u se of the current directory (where the current input file came from) as the first search directory for #include "file". There is no way to override this effect of -I-. With -I. you can specify searching the directory that was current when the compiler was invoked. That is not exactly the same as wh at the prepro ces s or doe s by default, but it is often satisfactory.
-I- does not inhibit the use of the standard system directories for header files. Thus, -I- and -nostdinc are independent.
-Idir Add the directory dir to the head of the list of directories to be searched for header files. This can be used to override a system header file, substituting your own version, since these directories are searched before the system header file directories. If you use more than one -I option, the directories are scanned in left-to-right order; the standard system directories come after.
-idirafter dir Add the directory dir to the second include path. The directories on the second include path are searched when a header file is not found in any of the directories in the main include path (the one that -I adds to).
-imacros file Process file as input, discarding the resulting output, before processing the regular inp ut file. Bec ause the outp ut genera ted from the file is discarde d, th e onl y effect of -imacros file is to make the macros defined in file available for use in the main input. Any -D and -U options on the command line are always processed before -imacros which they are written. All the -include and -imacros options are processed in the order in which they are written.
-include file Process file as input before processing the regular input file. In effect, the contents of file are compiled first. Any -D and -U options on the command line are always processed before
-include file, regardless of the order in which they are written. All the -include and -imacros options are processed in the order in which they are written.
-iprefix prefix Specify prefix as the prefix for subsequent -iwithprefix options.
-isystem dir Add a directory to the beginning of the second include path, marking it as a system direc tory , so that it ge ts the same sp ecial treatment as is applied to the standard system directories.
file, regardless of the order in
DS51284K-page 58 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-11: PREPROCESSOR OPTIONS (CONTINUED)
Option Definition
-iwithprefix dir Add a directory to the second include path. The directory’s name is made by concatenating prefix and dir, where prefix was specified previo us ly wi th -iprefix. If a prefix has not yet been specified, the direct ory co ntaining the installe d passes of the compiler is used as the default.
-iwithprefixbefore
dir
-M Tell the preprocessor to output a rule suitable for make describ-
-MD Like -M but the dependency information is written to a file and
-MF file When used with -M or -MM, specifies a file in which to write the
-MG Treat missing header files as generated files and assume they
-MM Like -M but the output mentions only the user header files
-MMD Like
-MP This option instruc ts CPP to ad d a phony targ et for eac h depe n-
-MQ Same as -MT, but it quotes any chara cte rs wh ic h are special to
Add a directory to the main include path. The directory’s name is made by concatenating prefix and dir, as in the case of
-iwithprefix.
ing the dependencies of each object file. For each source file, the preprocessor outputs one make-rule whose target is the object file name for that source file and whose dependencies are all the #include header files it uses. This rule may be a single line or may be continued with \-newline if it is long. The list of rules is printed on standard output instead of the prepro­cessed C program.
-M implies -E (see Section 3.5.2 “Options for Controlling the Kind of Output”).
compilation continues. The file containing the dependency information is given the sam e name as the sour ce fil e with a .d extension.
dependencies. If no -MF switch is given, the preprocessor sends the rules to the same place it would have sent preprocessed output. When used with the driver options, -MD or -MMD, -MF, overrides the default dependency output file.
live in the same directory as the source file. If -MG is specified, then either -M or -MM must also be specified. -MG is not supported with -MD or -MMD.
included with #include “file”. System header files included with #include <file> are omitted.
-MD except mention only user header files, not system
header files.
dency other than th e main file, cau sing e ach to depen d on not h­ing. These dummy rules work around errors make gives if you remove header files without upd ati ng t he make-f ile to match. This is typical output:
test.o: test.c test.h test.h:
make.
-MQ '$(objpfx)foo.o' gives $$(objpfx)foo.o: foo.c
The default target is automatically quoted, as if it were given with -MQ.
2002-2011 Microchip Technology Inc. DS51284K-page 59
16-Bit C Compiler User’s Guide
TABLE 3-11: PREPROCESSOR OPTIONS (CONTINUED)
Option Definition
-MT target Change the target of the rule emitted by dependency generation. By default, CPP takes the name of the main input file, including any path, deletes any file suffix such as .c, and appends the platform’s usual object suffix. The result is the target. An -MT option will set the target to be exactly the string you specify. If you want multiple targets, you can specify them as a single argument to -MT, or use multiple -MT options. For example:
-MT '$(objpfx)foo.o' might give $(objpfx)foo.o: foo.c
-nostdinc Do not search the standard system directories for header files.
Only the directories you hav e specifie d with -I options (a nd the current directory, if appropriate) are searched. (See Section 3.5.10 “Options for Directory Search”) for information on -I. By using both -nostdinc and -I-, the include-file search path can be limited to only those directories explicitly specified.
-P Tell the preprocessor not to generate #line directives. Used with the -E option (see Section 3.5.2 “Options for Controlling the Kind of Output”).
-trigraphs Support ANSI C trigraphs. The -ansi option also has this effect.
-Umacro Undefine macro macro. -U options are evaluated after a ll -D options, but before any -include and -imacros options.
-undef Do not predefine any nonstandard macros (including architecture flags).
3.5.8 Options for Assembling
The following options control assembler operations.
TABLE 3-12: ASSEMBLY OPTIONS
Option Definition
-Wa,option Pass option as an option to the assembler. If option contains
commas, it is split into multiple options at the commas.
3.5.9 Options for Linking
If any of the options -c, -S or -E are used, the linker is not run and object file names should not be used as arguments.
TABLE 3-13: LINKING OPTIONS
Option Definition
--gc-sections Remove dead functions from code at link time.
Support is for ELF projects only. In order to make the best use of this feature, add the -ffunction-sections option to the compiler command line.
-Ldir Add directory dir to the list of directories to be searched for libraries
specified by the command-line option -l.
-legacy-libc Use legacy include files and libraries (v3.24 and before).
The format of include file and libraries changed in v3.25 to match HI-TECH C compiler format.
DS51284K-page 60 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-13: LINKING OPTIONS (CONTINUED)
Option Definition
-llibrary Search the library named library when linking. The linker searches a standard list of directories for the library, which is actually a file nam ed liblibrary.a. The linker then uses this file as if it had been specified precisely by name. It makes a difference where in the command you write this option; the linker processes librarie s and obj ect file s in the order they are spec ified. Thus, foo.o -lz bar.o sea rch es li brary z after file foo.o but before bar.o. If bar.o refers to functions in libz.a, those functions may not be loaded. The directories searched include several standard system directories, plus any that you specify with -L. Normally the files found this way are library files (archive files whose members are object file s). The linke r handles an arch ive file by sca nning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option (e.g., -lmylib) and specifying a file name (e.g., libmylib.a) is that -l searches several directories, as specified. By default the linker is directed to search:
<install-path>\lib
for libraries speci fied wit h th e -l opt ion. Fo r a co mpile r in sta lled i nto the default location, this would be:
c:\Program Files\Microchip\MPLAB C30\lib
This behavior can be overridden using the environment variables defined in Section 3.6 “Environment Variables”.
-nodefaultlibs Do not use the st anda rd syst em lib raries w hen li nking . On ly the librarie s you specify will be pas sed to the linker. The compiler may generate ca lls to memcmp, memset and memcpy. These entries are usua lly res olve d by entries in the standard compiler libraries. These entry points should be supplied through some other mechanism when this option is specified.
-nostdlib Do not use the standard system startup f iles or libraries whe n linking. No startup files and only the libraries you specify will be passed to the linker. The compiler may generate calls to memcmp, memset and memcpy. These entries are usually resolved by entries in standard compiler libraries. These entry points should be supplied through some other mechanism when this option is specified.
-s Remove all symbol table and relocation information from the executable.
-u symbol Pretend symbol is undefined to force linking of library modules to define the symbol. It is legitimate to use -u multiple times with different symbols to force loading of additional library modules.
-Wl,option Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas.
-Xlinker option Pass option as an option to the linker. You can use this to supply system-specific linker options that the compiler does not know how to recognize.
2002-2011 Microchip Technology Inc. DS51284K-page 61
16-Bit C Compiler User’s Guide
3.5.10 Options for Directory Search
The following options specify to the compiler where to find directories and files to search.
TABLE 3-14: DIRECTORY SEARCH OPTIONS
Option Definition
-Bprefix This option specifies where to find the executables, libraries, include files and data files of the compiler itself. The compiler driver program runs one or more of the sub-programs pic30-cpp, pic30-cc1, pic30-as and pic30-ld. It tries prefix as a prefix for each program it tries to run. For each sub-program to be run, the compiler driver first tries the
-B prefix, if any. If the sub-program is not found, or if -B was not specified, the driver uses the value held in the PIC30_EXEC_PREFIX environment variable, if set. See Section 3.6 “Environment Variables”, for more information. Lastly, the driver will search the current PATH enviro nm ent variable for the subprogram.
-B prefixes that effectively specify directory names also apply to libraries in the linker, because the compiler translates these options into -L options for the linker. They also apply to include files in the preprocessor, because the compiler translates these options into -isystem options for the preprocessor. In this case, the compiler appends include to the prefix. Another way to specify a prefix much like the -B prefix is to use the environment variable PIC30_EXEC_PREFIX.
-specs=file Process file after the compiler read s in t he standard specs file, in order to override the defaults that the pic30-gcc driver program uses when determining what switches to pass to pic30-cc1, pic30-as, pic30-ld, etc. More th an one -specs=file can be specified on the command line, and they are processed in order, from left to right.
3.5.11 Options for Code Generation Conventions
Options of the form -fflag specify machine-independent flags. Most flags have both positive and negative forms; the negative form of -ffoo would be -fno-foo. In the table below, only one of the forms is listed (the one that is not the default.)
TABLE 3-15: CODE GENERATION CONVENTION OPTIONS
Option Definition
-fargument-alias
-fargument-noalias
-fargument-
noalias-global
Specif y the poss ible relations hips among p arameters and b etween parameters and global data.
-fargument-alias specifies that arguments (parameters) may alias each other and may alias global storage.
-fargument-noalias specifies that arguments do not alias each other, but may alias global storage.
-fargument-noalias-global specifies th at a r gum en t s do n ot alias each other and do not alias global storage. Each language will automatically use whatever option is required by the language standard. You should not need to use these options yourself.
DS51284K-page 62 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line
TABLE 3-15: CODE GENERATION CONVENTION OPTIONS (CONTINUED)
Option Definition
-fcall-saved-reg Treat the register named reg as an allocatable register saved by functions. It may be allocated even for temporaries or variables that live across a call. Functions compiled this way will save and restore the register reg if they use it. It is an error to used this flag with the Frame Pointer or Stack Pointer. Use of this flag for other registers that have fixed perva­sive roles in the machine’s execution model will produce disas­trous results. A different sort of disaster will result from the use of this flag for a register in which function values may be returned. This flag should be used consistently through all modules.
-fcall-used-reg Treat the register named reg as an allocatable register that is clobbered by function calls. It may be allocated for temporaries or variables that do not live across a cal l. Functions com piled this wa y will not save and restore the register reg. It is an error to use this flag with the Frame Pointer or Stack Pointer. Use of this flag for other registers that have fixed perva­sive roles in the machine’s execution model will produce disas­trous results. This flag should be used consistently through all modules.
-ffixed-reg Treat the register named reg as a fixed register; generated code should never refer to it (except perhaps as a Stack Pointer, Frame Pointer or in some other fixed role).
reg must be the name of a register, e.g., -ffixed-w3.
-fno-ident Ignore the #ident directive.
-fpack-struct Pack all structure members together without holes. Usually you
would not want to use this option, since it makes the code sub-optimal, and t he offs ets o f struct ure membe rs won’t agree wit h system libraries. The dsPIC byte boundaries, so care must be taken when using the packed attribute to avoid run time addressing errors.
-fpcc-struct-
return
-fno-short-double By default, the compiler u ses a double type equivalent to float.
-fshort-enums Allocate to an enum type only as many bytes as it needs for the
-fverbose-asm
-fno-verbose-asm
-fvolatile Consider all memory references through pointers to be volatile.
-fvolatile-global Consider all memory references to external and global data items
-fvolatile-static Consider all memory references to static data to be volatile.
Return short struct and union values in memory like longer ones, rather than in registers. This convention is less efficient, but it has the advantage of allowing capability between the 16-bit com­piler compiled files and files compiled with other compilers. Short structures and unions are those whose size and alignment match that of an integer type.
This option makes double equivalent to long double. Mixing this option across modules can have unexpected results if modules share double data either directly through argument passage or indirectly through shared buffer space. Libraries provided with the product function with either switch setting.
declared range of possible values. Specifically, the enum type will be equivalent to the smallest integer type which has enough room.
Put extra commenta ry informa tion in the generated assembly c ode to make it more readable.
-fno-verbose-asm, the default, causes the extra information to be omitted and is useful when comparing two assembler files.
to be volatile. The use of this switch has no effect on static data.
®
DSC device requires that words be aligned on even
2002-2011 Microchip Technology Inc. DS51284K-page 63
16-Bit C Compiler User’s Guide

3.6 ENVIRONMENT VARIABLES

The variables in this section are optional, but, if defined, they will be used by the compiler. The compiler driver, or other subprogram, may choose to determine an appropriate value for some of the following environment variables if they are unset. The driver, or other subprogram, takes advantage of internal knowledge about the installation of the compiler. As long as the installation structure remains intact, with all subdirectories and executables remaining in the same relative position, the driver or subprogram will be able to determine a usable value.
TABLE 3-16: COMPILER-RELATED ENVIRONMENTAL VARIABLES
Option Definition
PIC30_C_INCLUDE_ PATH
PIC30_COMPILER_ PATH
PIC30_EXEC_ PREFIX
PIC30_LIBRARY_ PATH
PIC30_OMF Specifies the O MF (Objec t Module Format) to be us ed by the compil er .
TMPDIR If TMPDIR is set, it specifies the directory to use for temporary files.
This variable’ s value i s a semic olon-s ep arated li st of direct orie s, much like PATH. When the compiler searches for header files, it tries the directories listed in the variable, after the directories specified with -I but before the standard header file directories. If the environment vari able is und efined , the p reproce ssor choos es an appropriate value based on the standard installation. By default, the following directories are searched for include files:
<install-path>\include and <install-path>\support\h
The value of PIC30_COMPILER_PATH is a semicolon-separated list of directories, much like PATH. The compiler tries the directories thus specified when searching for subprograms, if it can’t find the subprograms using PIC30_EXEC_PREFIX.
If PIC30_EXEC_PREFIX is set, it specifies a prefix to use in the names of subprograms executed by the compiler. No directory delimiter is added when this prefix is combined with the name of a subprogram, but you can specify a prefix that ends with a slash if you wish. If the compiler cannot find the subprogram using the specified prefix, it tries looking in your PATH environment variable. If the PIC30_EXEC_PREFIX environment variable is unset or set to an empty value, the compiler driver chooses an appropriate value based on the standard installation. If the installation has not been modified, this will result in the driver being able to locate the required subprograms. Other prefixes specified with the -B command line option take precedence over the user- or driver-defined value of PIC30_EXEC_PREFIX. Under normal circumstances it is bes t to leave this value undefined and let the driver locate subprograms itself.
This variable’ s value i s a semic olon-s ep arated li st of direct orie s, much like PATH. This variable specifies a list of directories to be passed to the linker. The driver’s default evaluation of this variable is: <install-path>\lib; <install-path>\support\gld.
By default, the tools create COFF object files. If the environment variable PIC30_OMF has the value elf, the tools will create ELF object files.
The compiler uses temporary files to hold the output of one stage of compilation that is to be used as input to the next stage: for example, the output of the preprocessor, which is the input to the compiler proper.
DS51284K-page 64 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line

3.7 PREDEFINED MACRO NAMES

The compiler predefines several macros which can be tested by conditional directives in source code.
The following preprocessing symbols are defined by the compiler being used.
Compiler Symbol Defined with -ansi command-line option?
16-Bit Compiler C30 No
__C30 Yes __C30__ Yes
ELF-specific C30ELF No
__C30ELF Yes __C30ELF__ Yes
COFF-specific C30COFF No
__C30COFF Yes __C30COFF__ Yes
The following symbols define the target family.
Symbol Defined with -ansi command-line option?
__dsPIC30F__ dsPIC30F target device family __dsPIC33E__ dsPIC33E target device family __dsPIC33F__ dsPIC33F target device family __PIC24E__ PIC24E target device family __PIC24F__ PIC24FJ target device family __PIC24FK__ PIC24FK target device family __PIC24H__ PIC24H target device family
The following symbols define device features.
Symbol Defined with -ansi command-line option?
__HAS_DSP__ Device has a DSP engi ne __HAS_EEDATA__ Device has EEDATA memory __HAS_DMA__ Device has DMA memory __HAS_CODEGUARD__ Device has CodeGuard™ Security __HAS_PMP__ Device has Paral lel Master Port __HAS_PMP_ENHANCED__ Device has Enhanced Parallel Master Port __HAS_EDS__ Device has Extended Data Space
In addition, the compiler defines a symbol based on the target device set with -mcpu=. For example, -mcpu=30F6014, which defines the symbol __dsPIC30F6014__.
The compiler will define the constant __C30_VERSION__, giving a numeric value to the version identifier. This can be used to take advantage of new compiler features while still remaining backward compatible with older vers ions.
The value is based upon the major and minor version numbers of the current release. For example, release version 2.00 will have a __C30_VERSION__ definition of 200. This macro can be used, in conjunction with standard preprocessor comparison state­ments, to conditionally include/exclude various code construct s.
The current definition of __C30_VERSION__ can be discovered by adding
--version to the command line, or by inspecting the README.html file that came with the release.
Constants that have been deprecated may be found in Appendix E. “Deprecated Features”.
2002-2011 Microchip Technology Inc. DS51284K-page 65
16-Bit C Compiler User’s Guide

3.8 COMPILING A SINGLE FILE ON THE COMMAND LINE

This section demonstrates how to compile and link a single file. For the purpose of this discussion, it is assumed the compiler is installed on your c: drive in the standard directory location. Therefore, the following will apply:
c:\Program Files\Microchip\MPLAB C30\include - Include directory for ANSI C header file. This directory is where the compiler stores the standard C library system header files. The PIC30_C_INCLUDE_PATH environment variable can point to that directory. (From the DOS command prompt, type set to check this.)
c:\Program Files\Microchip\MPLAB C30\support\dsPIC30F\h ­Include directory for dsPIC® DSC device-specific header files. This directory is where the compiler stores the dsPIC DSC device-specific header files.
c:\Program Files\Microchip\MPLAB C30\lib - Library directory: this directory is where the libraries and precompiled object files reside.
c:\Program Files\Microchip\MPLAB C30\support\dsPIC30F\gld ­Linker script directory: this directory is where device-specific linker script files may be found.
c:\Program Files\Microchip\MPLAB C30\bin - Executables directory: this directory is where the compiler programs are located. Y our PATH environment variable should include this directory.
The following is a simple C program that adds two numbers. Create the following program with any text editor and save it as ex1.c.
#include <p30f2010.h> int main(void); unsigned int Add(unsigned int a, unsigned int b); unsigned int x, y, z; int main(void) { x = 2; y = 5; z = Add(x,y); return 0; } unsigned int Add(unsigned int a, unsigned int b) { return(a+b); }
The first line of the program includes the header file p30f2010.h, which provides definitions for all special function registers on that part. For more information on header files, see Chapter 7. “Device Support Files”.
Compile the program by typing the following at a DOS prompt:
C:\> pic30-gcc -mcpu=30f2010 -o ex1.o ex1.c
The command-line option -o ex1.o names the output COFF executable file (if the -o option is not specified, then the output file is named a.exe). The COFF executable file may be loaded into the MPLAB IDE.
If a hex file is required, for example to load into a device programmer, then use the following command:
C:\> pic30-bin2hex ex1.o
This creates an Intel hex file named ex1.hex.
DS51284K-page 66 2002-2011 Microchip Technology Inc.
Using the Compiler on the Command Line

3.9 COMPILING MULTIPLE FILES ON THE COMMAND LINE

Move the Add() function into a file called add.c to demonstrate the use of multiple files in an application. That is:
File 1
/* ex1.c */ #include <p30f2010.h> int main(void); unsigned int Add(unsigned int a, unsigned int b); unsigned int x, y, z; int main(void) { x = 2; y = 5; z = Add(x,y); return 0; }
File 2
/* add.c */ #include <p30f2010.h> unsigned int Add(unsigned int a, unsigned int b) { return(a+b); }
Compile both files by typing the following at a DOS prompt:
C:\> pic30-gcc -mcpu=30f2010 -o ex1.o ex1.c add.c
This command compiles the modules ex1.c and add.c. The compiled modules are linked with the compiler libraries and the executable file ex1.o is created.

3.10 NOTABLE SYMBOLS

The 16-bit linker defines several symbols that may be used in your C code develop­ment. Please see the MPLAB Assembler, Linker and Utilities for PIC24 MCUs and
®
dsPIC
A useful address symbol, _PROGRAM_END, is defined i n pr og ra m me mo ry to mark the highest address used by a CODE or PSV section. It should be referenced with the address operator (&) in a built-in function call that accepts the address of an object in program memory. This symbol can be used by applications as an end point for check­sum calculations.
For example:
__builtin_tblpage(&_PROGRAM_END) __builtin_tbloffset(&_PROGRAM_END)
_prog_addressT big_addr; _init_prog_address(big_addr, _PROGRAM_END)
DSCs User’s Guide (DS51317) for more information.
2002-2011 Microchip Technology Inc. DS51284K-page 67
16-Bit C Compiler User’s Guide
NOTES:
DS51284K-page 68 2002-2011 Microchip Technology Inc.

Chapter 4. Run Time Environment

4.1 INTRODUCTION

This section discusses the MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs (formerly MPLAB C30) run-time environment.

4.2 HIGHLIGHTS

Items discussed in this chapter are:
• Address Spaces
• Startup and Initialization
• Memory Spaces
• Memory Models
• Locating Code and Data
• Software Stack
• The C Stack Usage
• The C Heap Usage
• Function Call Conventions
• Register Conventions
• Bit Reversed and Modulo Addressing
• Program Space Visibility (PSV) Usage
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC® DSCs
USER’S GUIDE

4.3 ADDRESS SPACES

The dsPIC Digital Signal Controller (DSC) devices are a combination of traditional PIC® Microcontroller (MCU) features (peripherals, Harvard architecture, RISC) and new DSP capabilities. The dsPIC DSC devices have two distinct memory regions:
• Program Memory contains executable code and optionally constant data.
• Data Memory contains external variables, static variables, the system stack and file registers. Data memory consists of near data, which is memory in the first 8 KB of the data memory space, and far data, which is in the upper 56 KB of data memory space.
Although the program and data memory regions are distinctly separate, the compiler can access constant data in program memory through the program space visibility window.
2002-2011 Microchip Technology Inc. DS51284K-page 69
16-Bit C Compiler User’s Guide

4.4 STARTUP AND INITIALIZATION

Two C run-time startup modules are included in the libpic30.a archive/library. The entry point for both startup modules is __reset. The linker scripts construct a GOTO __reset instruction at location 0 in program memory, which transfers control upon device reset.
The primary startup module (crt0.o) is linked by default and performs the following:
1. The Stack Pointer (W15) and Stack Pointer Limit register (SPLIM) are initialized, using values provided by the linker or a custom linker script. For more information, see Section 4 .8 “Software Stack”.
2. If a .const section is defined, it is mapped into the program space visibility window by initializing the PSVPAG and CORCON registers. Note that a .const section is defined when the “Constants in code space” option is selected in MPLAB IDE, or the default -mconst-in-code option is specified on the compiler command line.
3. The data initialization template in section .dinit is read, causing all uninitialized sections to be cleared, and all initialized sections to be initialized with values read from program memory. The data initialization template is created by the linker, and supports the standard sections listed in
Section 4.3 “Address Spaces”, as well as the user-defined sections.
Note: The persistent data section .pbss is never cleared or initialized.
4. If the application has defined user_init functions, these are invoked. The order of execution depends on link order.
5. The function main is called with no parameters.
6. If main returns, the processor will reset.
The alternate startup module (crt1.o) is linked when the -Wl, --no-data-init option is specified. It performs the same operations, except for step (3), which is omitted. The alternate startup module is smaller than the primary module, and can be selected to conserve program memory if data initialization is not required.
Source code (in dsPIC DSC assembly language) for both modules is provided in the c:\Program Files\Microchip\MPLAB C30\src directory. The startup modules may be modified if necessary. For example, if an application requires main to be called with parameters, a conditional assembly directive may be changed to provide this support.
DS51284K-page 70 2002-2011 Microchip Technology Inc.

4.5 MEMORY SPACES

DD
DD
Static and external variables are normally allocated in general purpose data memory. Const-qualified variables will be allocated in general purpose data memory if the constants-in-data memory model is selected, or in program memory if the constants-in-code memory model is selected.
The compiler defines several special purpose memory spaces to match architectural features of 16-bit devices. Static and external variables may be allocated in the special purpose memory spaces through use of the space attribute, described in Section 2.3.1 “Specifying Attributes of Variables”.
data
General data space. Variables in general data space can be accessed using ordinary C statements. This is the default allocation.
eds
Allocate the variable in the extended data space. For devices that do not have extended data space, this is equivalent to space(data). Variables in space(eds) will generally require special handling to access. Refer to Chapter 6. “Additional C Pointer Types” for more information.
space(eds) has been deprecated in favour of the eds attribute.
Run Time Environment
xmemory - dsPIC30F/dsPIC33F devices only
X data address space. Variables in X data space can be accessed using ordinary C statements. X data address space has special relevance for DSP-oriented libraries and/or assembly language instructions.
ymemory - dsPIC30F/dsPIC33F devices only
Y data address space. Variables in Y data space can be accessed using ordinary C statements. Y data address space has special relevance for DSP-oriented libraries and/or assembly language instructions.
prog
General program space, which is normally reserved for executable code. Variables in program space can not be accessed using ordinary C statements. They must be explicitly accessed by the programmer, usually using table-access inline assembly instructions, or using the program space visibility window.
auto_psv
A compiler-managed area in program space, designated for program space visibility window access. Variables in this space can be read (but not written) using ordinary C statements and are subject to a maximum of 32K total space allocated.
psv
Program space, designated for program space visibility window access. Variables in PSV space are not managed by the compiler and can not be accessed using ordinary C statements. They must be explicitly accessed by the programmer, usually using table-access inline assembly instructions, or using the program space visibility window. V ariables in PSV space can be accessed using a single setting of the PSVPAG register .
2002-2011 Microchip Technology Inc. DS51284K-page 71
16-Bit C Compiler User’s Guide
DD
DD
eedata - PIC24F MCUs, dsPIC30F/33F devices only
Data EEPROM space, a region of 16-bit wide non-volatile memory located at high addresses in program memory. Variables in eedata space can not be accessed using ordinary C statements. They must be explicitly accessed by the programmer, usually using table-access inline assembly instructions, or using the program space visibility window.
dma - PIC24H MCUs, dsPIC33F DSCs only
DMA memory. V ariables in DMA memory can be accessed using ordinary C statements and by the DMA peripheral.

4.6 MEMORY MODE LS

The compiler supports several memory models. Command-line options are available for selecting the optimum memory model for your application, based on the specific dsPIC DSC device part that you are using and the type of memory usage.
TABLE 4-1: MEMORY MODEL COMMAND LINE OPTIONS
Option Memory Definition Description
-msmall-data Up to 8 KB of data memory.
This is the default.
-msmall-scalar Up to 8 KB of data memory.
This is the default.
-mlarge-data Greater than 8 KB of data memory.
-msmall-code Up to 32 Kwords of program memory. This is the default.
-mlarge-code Greater than 32 Kwords of program memory.
-mconst-in-data Constants located in data memory.
-mconst-in-code Constants located in program memory. This is the default.
-mconst-in-aux-
flash
The command-line options apply globally to the modules being compiled. Individual variables and functions can be declared as near, far or eds to better control the code generation. For information on setting individual variable or function attributes, see
Section 2.3.1 “Specifying Attributes of Variables” and Section 2.3.2 “Specifying Attributes of Functions”.
Constants in auxiliary FLASH Values are accessed via Program
Permits use of PIC18 like instructions for accessing data memory.
Permits use of PIC18 like instructions for accessing scalars in data memory.
Uses indirection for data references.
Function pointers will not go thro ugh a jump table. Function calls use RCALL instruction.
Function pointers might go through a jump table. Function calls use CALL instruction.
Values copied from program memory by startup code.
Values are accessed via P rogram Space Visibility (PSV) data window.
Space visibility window.
DS51284K-page 72 2002-2011 Microchip Technology Inc.
Run Time Environment
4.6.1 Near and Far Data
If variables are allocated in the near data section, the compiler is often able to generate better (more compact) code than if the variables are not allocated in the near data section. If all variables for an application can fit within the 8 KB of near data, then the compiler can be requested to place them there by using the default -msmall-data command line option when compiling each module. If the amount of data consumed by scalar types (no arrays or structures) totals less than 8 KB, the default
-msmall-scalar may be used. This requests that the compiler arrange to have just the scalars for an application allocated in the near data section.
If neither of these global options is suitable, then the following alternatives are available.
1. It is possible to compile some modules of an application using the
-mlarge-data or -mlarge-scalar command line options. In this case, only the variables used by those modules will be allocated in the far data section. If this alternative is used, then care must be taken when using externally defined variables. If a variable that is used by modules compiled using one of these options is defined externally, then the module in which it is defined must also be compiled using the same option, or the variable declaration and definition must be tagged with the far attribute.
2. If the command line options -mlarge-data or -mlarge-scalar have been used, then an individual variable may be excluded from the far data space by tagging it with the near attribute.
3. Instead of using command-line options, which have module scope, individual variables may be placed in the far data section by tagging them with the far attribute.
The linker will produce an error message if all near variables for an application cannot fit in the 8K near data space.
4.6.2 Near and Far Code
Functions that are near (within a radius of 32 Kwords of each other) may call each other more efficiently that those which are not. If it is known that all functions in an application are near, then the default -msmall-code command line option can be used when compiling each module to direct the compiler to use a more efficient form of the function call.
If this default option is not suitable, then the following alternatives are available:
1. It is possible to compile some modules of an application using the
-msmall-code command line option. In this case, only function calls in those modules will use a more efficient form of the function call.
2. If the -msmall-code command-line option has been used, then the compiler may be directed to use the long form of the function call for an individual function by tagging it with the far attribute.
3. Instead of using command-line options, which have module scope, the compiler may be directed to call individual functions using a more efficient form of the function call by tagging their declaration and definition with the near attribute.
The -msmall-code command-line option differs from the -msmall-data command-line option in that in the former case, the compiler does nothing special to ensure that functions are allocated near one another, whereas in the latter case, the compiler will allocate variables in a special section.
The linker will produce an error message if the function declared to be near cannot be reached by one of its callers using a more efficient form of the function call.
2002-2011 Microchip Technology Inc. DS51284K-page 73
16-Bit C Compiler User’s Guide

4.7 LOCATING CODE AND DATA

As described i n Section 4.3 “Address Spaces”, the compiler arranges for code to be placed in the .text section, and data to be placed in one of several named sections, depending on the memory model used and whether or not the data is initialized. When modules are combined at link time, the linker determines the starting addresses of the various sections based on their attributes.
Cases may arise when a specific function or variable must be located at a specific address, or within some range of addresses. The easiest way to accomplish this is by using the address attribute, described in Section 2.3 “Keyword Differences”. For example, to locate function PrintString at address 0x8000 in program memory:
int __attribute__ ((address(0x8000))) PrintString (const char *s);
Likewise, to locate variable Mabonga at address 0x1000 in data memory:
int __attribute__ ((address(0x1000))) Mabonga = 1;
Another way to locate code or data is by placing the function or variable into a user-defined section, and specifying the starting address of that section in a custom linker script. This is done as follows:
1. Modify the code or data declaration in the C source to specify a user-defined section.
2. Add the user-defined section to a custom linker script file to specify the starting address of the section.
For example, to locate the function PrintString at address 0x8000 in program memory, first declare the function as follows in the C source:
int __attribute__((__section__(".myTextSection"))) PrintString(const char *s);
The section attribute specifies that the function should be placed in a section named .myTextSection, rather than the default .text section. It does not specify where the user-defined section is to be located. That must be done in a custom linker script, as follows. Using the device-specific linker script as a base, add the following section definition:
.myTextSection 0x8000 : { *(.myTextSection); } >program
This specifies that the output file should contain a section named .myTextSection starting at location 0x8000 and containing all input sections named.myTextSection. Since, in this example, there is a single function PrintString in that section, then the function will be located at address 0x8000 in program memory.
Similarly, to locate the variable Mabonga at address 0x1000 in data memory, first declare the variable as follows in the C source:
int __attribute__((__section__(".myDataSection"))) Mabonga = 1;
DS51284K-page 74 2002-2011 Microchip Technology Inc.
The section attribute specifies that the function should be placed in a section named.myDataSection, rather than the default .data section. It does not specify where the user-defined section is to be located. Again, that must be done in a custom linker script, as follows. Using the device-specific linker script as a base, add the fol­lowing section definition:
.myDataSection 0x1000 : { *(.myDataSection); } >data
This specifies that the output file should contain a section named.myDataSection starting at location 0x1000 and containing all input sections named.myDataSection. Since, in this example, there is a single variable Mabonga in that section, then the variable will be located at address 0x1000 in data memory.

4.8 SOFTWARE STACK

The dsPIC DSC device dedicates register W15 for use as a software Stack Pointer. All processor stack operations, including function calls, interrupts and exceptions, use the software stack. The stack grows upward, towards higher memory addresses.
The dsPIC DSC device also supports stack overflow detection. If the Stack Pointer Limit register, SPLIM, is initialized, the device will test for overflow on all stack opera­tions. If an overfl ow shoul d occur, the processor wil l initi ate a s tac k error except ion. By default, this will result in a processor reset. Applications may also install a stack error exception handler by defining an interrupt function named _StackError. See Chap- ter 8. “Interrupts” for details.
The C run-time startup module initializes the Stack Pointer (W15) and the Stack Pointer Limit register during the startup and initialization sequence. The initial values are normally provided by the linker, which allocates the largest stack possible from unused data memory. The location of the stack is reported in the link map output file. Applications can ensure that at least a minimum-sized stack is available with the
--stack linker command-line option. See the “MPLAB Utilities for PIC24 MCUs and dsPIC
Alternatively, a stack of specific size may be allocated with a user-defined section from an assembly source file. In the following example, 0x100 bytes of data memory are reserved for the stack:
<verbose>
.section *,data,stack .space 0x100
<end> The linker will allocate an appropriately sized section and initialize __SP_init and
__SPLIM_init so that the run-time startup code can properly initialize the stack. Note that since this is a normal assembly code, section attributes such as address may be used to further define the stack. Please see the “MPLAB
ties for PIC24 MCUs and dsPIC
Run Time Environment
®
®
DSCs User’s Guide” (DS51317) for details.
®
DSCs User’s Guide” (DS51317) for more information.
Assembler, Linker and
®
Assembler, Linker and Utili-
2002-2011 Microchip Technology Inc. DS51284K-page 75
16-Bit C Compiler User’s Guide
Stack grows toward greater addresses
SP (W15)
FP (W14)
Function Frame

4.9 THE C STACK USAGE

The C compiler uses the software stack to:
• Allocate automatic variables
• Pass arguments to functions
• Save the processor status in interrupt functions
• Save function return address
• Store temporary results
• Save registers across function calls
The run-time stack grows upward from lower addresses to higher addresses. The compiler uses two working registers to manage the stack:
• W15 – This is the Stack Pointer (SP). It points to the top of stack which is defined
to be the first unused location on the stack.
• W14 – This is the Frame Pointer (FP). It points to the current function’s frame.
Each function, if required, creates a new frame at the top of the stack from which automatic and temporary variables are allocated. The compiler option
-fomit-frame-pointer can be used to restrict the use of the FP.
FIGURE 4-1: STACK AND FRAME POINTERS
The C run-time startup modules (crt0.o and crt1.o in libpic30.a) initialize the Stack Pointer W15 to point to the bottom of the stack and initialize the Stack Pointer Limit register to point to the top of the stack. The stack grows up and if it should grow beyond the value in the Stack Pointer Limit register, then a stack error trap will be taken. The user may initialize the Stack Pointer Limit register to further restrict stack growth.
The following diagrams illustrate the steps involved in calling a function. Executing a CALL or RCALL instruction pushes the return address onto the software stack. See Figure 4-2.
DS51284K-page 76 2002-2011 Microchip Technology Inc.
Run Time Environment
Stack grows toward greater addresses
SP (W15)
FP (W14)
Return addr [23:16] Return addr [15:0] Parameter 1
: Parameter n-1 Parameter n
Caller Frame
Stack grows toward greater addresses
SP (W15)
FP (W14)
Local Variables
Return addr [15:0] Parameter 1
: Parameter n-1 Parameter n
Caller Frame
Return addr [23:16]
and Temporaries
Previous FP
FIGURE 4-2: CALL OR RCALL
The called function (callee) can now allocate space for its local context (Figure 4-3).
FIGURE 4-3: CALLEE SPACE ALLOCATION
2002-2011 Microchip Technology Inc. DS51284K-page 77
16-Bit C Compiler User’s Guide
Stack grows toward greater addresses
SP (W15)
FP (W14)
Callee-Saved
Return addr [15:0] Parameter 1
: Parameter n-1 Parameter n
Caller Frame
Return addr [23:16]
Registers
Previous FP
Local Variables and Temporaries
[W14+n] accesses local context
[W14-n] accesses function parameters
stack-based
Finally, any callee-saved registers that are used in the function are pushed (Figure 4-4).
FIGURE 4-4: PUSH CALLEE-SAVED REGISTERS

4.10 THE C HEAP USAGE

The C run-time heap is an uninitialized area of data memory that is used for dynamic memory allocation using the standard C library dynamic memory management functions, calloc, malloc and realloc. If you do not use any of these functions, then you do not need to allocate a heap. By default, a heap is not created.
If you do want to use dynamic memory allocation, either directly, by calling one of the memory allocation functions, or indirectly, by using a standard C library input/output function, then a heap must be created. A heap is created by specifying its size on the linker command line, using the --heap linker command-line option. An example of allocating a heap of 512 bytes using the command line is:
pic30-gcc foo.c -Wl,--heap=512
The linker allocates the heap immediately below the stack. If you use a standard C library input/output function, then a heap must be allocated. If
stdout is the only file that you use, then the heap size can be zero, that is, use the command-line option:
-Wl,--heap=0
If you open files, then the heap size must include 40 bytes for each file that is simulta­neously open. If there is insufficient heap memory, then the open function will return an error indicator. For each file that should be buffered, 514 bytes of heap space is required. If there is insufficient heap memory for the buffer, then the file will be opened in unbuffered mode.
DS51284K-page 78 2002-2011 Microchip Technology Inc.

4.11 FUNCTION CALL CONVENTIONS

When calling a function:
• Registers W0-W7 are caller saved. The calling function must push these values onto the stack for the register values to be preserved.
• Registers W8-W14 are callee saved. The function being called must save any of these registers it will modify.
• Registers W0-W4 are used for function return values.
TABLE 4-2: REGISTERS REQUIRED
Data Type Number of Registers Required
char 1 int 1 short 1 pointer 1 long 2 (contiguous – aligned to even numbered register) float 2 (contiguous – aligned to even numbered register) double* 2 (contiguous – aligned to even numbered register) long double 4 (contiguous – aligned to quad numbered register) structure 1 register per 2 bytes in structure
* double is equivalent to long double if -fno-short-double is used.
Parameters are placed in the first aligned contiguous register(s) that are available. The calling function must preserve the parameters, if required. Structures do not have any alignment restrictions; a structure parameter will occupy registers if there are enough registers to hold the entire structure. Function results are stored in consecutive registers, beginning with W0.
Run Time Environment
4.11.1 Function Parameters
The first eight working registers (W0-W7) are used for function parameters.Parameters are allocated to registers in left-to-right order, and a parameter is assigned to the first available register that is suitably aligned.
In the following example, all parameters are passed in registers, although not in the order that they appear in the declaration. This format allows the compiler to make the most efficient use of the available parameter registers.
EXAMPLE 4-1: FUNCTION CALL MODEL
void params0(short p0, long p1, int p2, char p3, float p4, void *p5) { /* ** W0 p0 ** W1 p2 ** W3:W2 p1 ** W4 p3 ** W5 p5 ** W7:W6 p4 */ ... }
The next example demonstrates how structures are passed to functions. If the complete structure can fit in the available registers, then the structure is passed via registers; otherwise the structure argument will be placed onto the stack.
2002-2011 Microchip Technology Inc. DS51284K-page 79
16-Bit C Compiler User’s Guide
EXAMPLE 4-2: FUNCTION CALL MODEL, PASSING STRUCTURES
typedef struct bar { int i; double d; } bar;
void params1(int i, bar b) { /* ** W0 i ** W1 b.i ** W5:W2 b.d */
}
Parameters corresponding to the ellipses (...) of a variable-length argument list are not allocated to registers. Any parameter not allocated to registers is pushed onto the stack, in right-to-left order.
In the next example, the structure parameter cannot be placed in registers because it is too large. However, this does not prevent the next parameter from using a register spot.
EXAMPLE 4-3: FUNCTION CALL MODEL, STACK BASED ARGUMENTS
typedef struct bar { double d,e; } bar;
void params2(int i, bar b, int j) { /* ** W0 i ** stack b ** W1 j */ }
Accessing arguments that have been placed onto the stack depends upon whether or not a Frame Pointer has been created. Generally the compiler will produce a Frame Pointer (unless otherwise told not to do so), and stack-based parameters will be accessed via the Frame Pointer register (W14). The above example, b will be accessed from W14-22. The Frame Pointer offset of negative 22 has been calculated (refer to Figure 4-4) by removing 2 bytes for the previous FP, 4 bytes for the return address, followed by 16 bytes for b.
When no Frame Pointer is used, the assembly programmer must know how much stack space has been used since entry to the procedure. If no further stack space is used, the calculation is similar to the above. b would be accessed via W15-20; 4 bytes for the return address and 16 bytes to access the start of b.
4.11.2 Return Value
Function return values are returned in W0 for 8- or 16-bit scalars, W1:W0 for 32-bit scalars, and W3:W2:W1:W0 for 64-bit scalars. Aggregates are returned indirectly through W0, which is set up by the function caller to contain the address of the aggregate value.
4.1 1.3 Preserving Registers Across Function Calls
DS51284K-page 80 2002-2011 Microchip Technology Inc.
The compiler arranges for registers W8-W15 to be preserved across ordinary function calls. Registers W0-W7 are available as scratch registers. For interrupt functions, the compiler arranges for all necessary registers to be preserved, namely W0-W15 and RCOUNT.

4.12 REGISTER CONVENTIONS

Specific registers play specific roles in the C run-time environment. Register variables use one or more working registers, as shown in Table 4-3.
TABLE 4-3: REGISTER CONVENTIONS
Variable Working Register
char, signed char, unsigned char W0-W13, and W14 if not used as a Frame
short, signed short, unsigned short
int, signed int,unsigned int W0-W13, an d W14 if not used as a Frame
void * (or any pointer) W0-W13, and W1 4 if not used as a Frame
long, signed long, unsigned long A pair of contiguous registers, the first of which
long long, signed long long, unsigned long long
float A pair of contiguous registers, the first of which
double* A pair of contiguous registers, the first of which
long double A quadruplet of contiguous registers, the first of
structure 1 contiguous register per 2 bytes in the
* double is equivalent to long double if -fno-short-double is used.
Run Time Environment
Pointer. W0-W13, and W14 if not used as a Fram e
Pointer.
Pointer.
Pointer.
is a register from the set {W 0, W2, W4, W6, W8, W10, W12}. The lower-numbered register contains the lea st sig nif ica nt 16 bits of the value.
A quadruplet of contiguous registers, the first of which is a register from the set {W0, W4, W8}. The lower-numbered register contains the least significant 16 bits of the value. Successively higher-numbere d registers contain successively more significant bits.
is a register from the set {W 0, W2, W4, W6, W8, W10, W12}. The lower-numbered register contains the least significant 16 bits of the significant.
is a register from the set {W 0, W2, W4, W6, W8, W10, W12}. The lower-numbered register contains the least significant 16 bits of the significant.
which is a register from the set {W0, W4, W8}. The lower-numbered register contains the least significant 16 bits of the significant.
structure.
2002-2011 Microchip Technology Inc. DS51284K-page 81
16-Bit C Compiler User’s Guide

4.13 BIT REVERSED AND MODULO ADDRESSING

The compiler does not directly support the use of bit reversed and modulo addressing. If either of these addressing modes is enabled for a register, then it is the programmer’s responsibility to ensure that the compiler does not use that register as a pointer. Particular care must be exercised if interrupts can occur while one of these addressing modes is enabled.
It is possible to define arrays in C that will be suitably aligned in memory for modulo addressing by assembly language functions. The aligned attribute may be used to define arrays that are positioned for use as incrementing modulo buffers. The reverse attribute may be used to define arrays that are positioned for use as decrementing modulo buffers. For more information on these attributes, see Section 2.3 “Keyword Differences”. For more information on modulo addressing, see chapter 3 of the “dsPIC30F Family Reference Manual” (DS70046).

4.14 PROGRAM SPACE VISIBILITY (PSV) USAGE

By default, the compiler will automatically arrange for strings and const-qualified initialized variables to be allocated in the .const section, which is mapped into the PSV window. Then PSV management is left up to compiler management, which does not move it, limiting the size of accessible program memory to the size of the PSV window itself.
Alternatively, an application may take control of the PSV window for its own purposes. The advantage of directly controlling the PSV usage in an application is that it affords greater flexibility than having a single .const section permanently mappe d into the PSV window. The disadvantage is that the application must manage the PSV control registers and bits. Specify the -mconst-in-data option to direct the compiler not to use the PSV window.
The space attribute can be used to define variables that are positioned for use in the PSV window. To specify certain variables for allocation in the compiler-managed section .const, use attribute space(auto_psv). To allocate variables for PSV access in a section not managed by the compiler, use attribute space(psv). For more information on these attributes, see Section 2.3 “Keyword Differences”.
For more on PSV usage, see the “MPLAB
MCUs and dsPIC
®
DSCs User’s Guide” (DS51317).
®
Assembler, Linker and Utilities for PIC24
4.14.1 Boot and Secure Constants
Two new psv constant sections will be defined: .boot_const and .secure_const. These sections are analogous to the generic section .const, except that the compiler uses them independently of the user-selectable constants memory model.
Regardless of whether you have selected the constants-in-code or constants-in-data memory model, the compiler will create and manage psv constant sections as needed for secure segments. Consequently, PSVPAG and CORCONbits.PSV must become compiler managed resources. Support for user-managed PSV sections is maintained through an object compatibility model explained below.
Upon entrance to a boot or secure function, PSVPAG will be set to the correct value. This value will be restored after any external function call.
DS51284K-page 82 2002-2011 Microchip Technology Inc.
Run Time Environment
4.14.2 String Literals as Arguments
In addition to being used as initializers, string literals may also be used as function arguments. For example:
myputs("Enter the Dragon code:\n");
Here allocation of the string literal depends on the surrounding code. If the statement appears in a boot or secure function, the literal will be allocated in a corresponding PSV constant section. Otherwise it will be placed in general (non-secure) memory, according to the constants memory model.
Recall that data stored in a secure segment can not be read by any other segment. For example, it is not possible to call the standard C library function puts() with a string that has been allocated in a secure segment. Therefore literals which appear as func­tion arguments can only be passed to functions in the same security segment. This is also true for objects referenced by pointers and arrays. Simple scalar types such as char, int, and float, which are passed by value, may be passed to functions in different segments.
4.14.3 Const-qualified Variables in Secure Flash
const-qualified variables with initializers can be supported in secure Flash segments using PSV constant sections managed by the compiler. For example:
const int __attribute__((boot)) time_delay = 55;
If the const qualifier was omitted from the definition of time_delay, this statement would be rejected with an error message. (Initialized variables in secure RAM are not supported).
Since the const qualifier has been specified, variable time_delay can be allocated in a PSV constant section that is owned by the boot segment. It is also possible to spec­ify the PSV constant section explicitly with the space(auto_psv) attribute:
int __attribute__((boot,space(auto_psv))) bebop = 20;
Pointer variables initialized with string literals require special processing. For example:
char * const foo __attribute__((boot)) = "eek";
The compiler will recognize that string literal "eek" must be allocated in the same PSV constant section as pointer variable foo. The logi c for maki ng that as so ci ati on is already supported in the compiler for named PSV sections.
4.14.4 Object Compatibility Model
Since functions in secure segments set PSVPAG to their respective psv constant sec­tions, a convention must be established for managing multiple values of the PSVPAG register. In previous versions of the compiler, a single value of PSVPAG was set during program startup if the default constants-in-code memory model was selected. The compiler relied upon that preset value for accessing const variables and string literals, as well as any variables specifically nominated with space(auto_psv).
Compiler v3.0 will provide automatic support for multiple values of PSVPAG. Variables declared with space(auto_psv) may be combined with secure segment constant variables and/or managed psv pointer variables in the same source file. Precompiled objects that assume a single, pre-set value of PSVPAG will be link-compatible with objects that define secure segment psv constants or managed psv variables.
Even though PSVPAG is now considered to be a compiler-managed resource, there is no change to the function calling conventions. Objects and libraries created with earlier versions are compatible with 3.0 objects, with the exception of some Interrupt Service Routines as noted in Section 8.10 “PSV Usage with Interrupt Service Routines”.
2002-2011 Microchip Technology Inc. DS51284K-page 83
16-Bit C Compiler User’s Guide

4.15 USING LARGE ARRAYS

The compiler option -mlarge-arrays allows you to define and access arrays larger than 32K. You must ensure that there is enough space to allocate such an array by nominating a memory space large enough to contain such an object.
Using this option will have some effect on how code is generated as it effects the defi­nition of the size_t type, increasing it to an unsigned long int. If used as a global option, this will affect many operations used in indexing (making the operation more complex). Using this option locally may effect how variables can be accessed. With these considerations in mind, using large arrays is requires careful planning. This sec­tion discusses some techniques for its use.
Two things occur when the -mlarge-arrays option is selected:
1. The compiler generates code in a different way for accessing arrays.
2. The compiler defines the size_t type to be unsigned long int. Item 1 can have a negative effect on code size, if used throughout the whole program.
It is possible to only compile a single module with this option and have it work, but there are limitations which will be discussed shortly.
Item 2 affects the calling convention when external functions receive or return objects of type size_t. The compiler provides libraries built to handle a larger size_t and these objects will be selected automatically by the linker (provided they exist).
Mixing -mlarge-arrays and normal-sized arrays together is relatively straightfor­ward and might be the best way to make use of this new feature. There are a few usage restrictions: functions defined in such a module should not call external routines that use size_t, and functions defined in such a module should not receive size_t as a parameter.
For example, one could define a large array and an accessory function which is then used by other code modules to access the array. The benefit is that only one module needs to be compiled with -mlarge-array with the defect that an accessory is required to access the array . This is useful in cases where compiling the whole program with -mlarge-arrays will have negative effect on code size and speed.
A code example for this would be:
/* to be compiled -mlarge-arrays */ __prog__ int array1[48000] __attribute__((space(prog))); __prog__ int array2[48000] __attribute__((space(prog)));
int access_large_array(__prog__ int *array, unsigned long index) { return array[index]; }
/* to be compiled without -mlarge-arrays */ extern __prog__ int array1[] __attribute__((space(prog))); extern __prog__ int array2[] __attribute__((space(prog)));
extern int access_large_array(__prog__ int *array, unsigned long index);
main() { fprintf(stderr,"Answer is: %d\n", access_large_array(array1,
39543)); fprintf(stderr,"Answer is: %d\n", access_large_array(array2,
16)); }
DS51284K-page 84 2002-2011 Microchip Technology Inc.
MPLAB® C COMPILER FOR

Chapter 5. Data Types

5.1 INTRODUCTION

This section discusses the MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs (formerly MPLAB C30) data types.

5.2 HIGHLIGHTS

Items discussed in this chapter are:
• Data Representation
• Integer
• Floating Point
• Pointers

5.3 DAT A REPR ES EN TATION

Multibyte quantities are stored in “little endian” format, which means:
• The least significant byte is stored at the lowest address
• The least significant bit is stored at the lowest-numbered bit position
As an example, the long value of 0x12345678 is stored at address 0x100 as follows:
PIC24 MCUs AND dsPIC
USER’S GUIDE
®
DSCs

5.4 INTEGER

0x100 0x101 0x102 0X103
0x78 0x56 0x34 0x12
As another example, the long value of 0x12345678 is stored in registers w4 and w5:
w4 w5
0x5678 0x1234
Table 5-1 shows integer data types are supported in the compiler.
TABLE 5-1: INTEGER DATA TYPES
Type Bits Min Max
char, signed char 8-128127 unsigned char 80255 short, signed short 16 -32768 32767 unsigned short 16 0 65535 int, signed int 16 -32768 32767 unsigned int 16 0 65535 long, signed long 32 -2 unsigned long 32 0 2 long long**, signed long long** 64 -2 unsigned long long** 64 0 2
** ANSI-89 extension
31
63
231 - 1
32
- 1
263 - 1
64
- 1
2002-2011 Microchip Technology Inc. DS51284K-page 85
16-Bit C Compiler User’s Guide
For information on implementation-defined behavior of integers, see
Section A.7 “Integers”.

5.5 FLOATING POINT

The compiler uses the IEEE-754 format. Table 5-2 shows floating point data types are supported.
TABLE 5-2: FLOATING POINT DATA TYPES
Type Bits E Min E Max N Min N Max
float 32 -126 127 2 double* 32 -126 127 2 long double 64 -1022 1023 2
E = Exponent N = Normalized (approximate) * double is equivalent to long double if -fno-short-double is used.
For information on implementation-defined behavior of floating point numbers, see section Section A.8 “Floating Point”.

5.6 POINTERS

-126
-126
-1022
2 2
2
128 128
1024
All standard pointers are 16 bits wide. This is sufficient for full data space access (64 KB) and the small code model (32 Kwords of code.) In the large code model (>32 Kwords of code), pointers may resolve to “handles”; that is, the pointer is the address of a GOTO instruction which is located in the first 32 Kwords of program space.
A set of special purpose, 32-bit data pointers are also available. See Chapter 6. “Additional C Pointer Types” for more information.
DS51284K-page 86 2002-2011 Microchip Technology Inc.

Chapter 6. Additional C Pointer Types

6.1 INTRODUCTION

MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs (formerly MPLAB C30) offers some extended pointer modes to help access more of the unique features of Microchip’s 16-bit product architecture. Extended pointers and their use will be covered in this chapter.
• Managed PSV Pointers – for reading more data through the PSV
• PMP Pointers – for accessing data via the PMP peripheral (where available)
• External Pointers – for accessing external memory in a user-defined fashion
• Extended Data Space Pointers – for accessing variables declared in a variety of different memory spaces
Although the concentration will be on pointer access, defining variables and ensuring that the data is allocated in the correct region of the 16-bit architectures (bi-polar) memory is also covered.
This chapter will make use of concepts introduced in Chapter 2. “Differences
Between 16-Bit Device C and ANSI C”.
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC® DSCs
USER’S GUIDE

6.2 MANAGED PSV POINTERS

The dsPIC30F/33F and PIC24F/H families of processors contain hardware support for accessing data from within program Flash using a hardware feature that is commonly called Program Space Visibility (PSV). More detail about how PSV works can be found in device data sheets or family reference manuals. Also, see Section 4.14 “Program
Space Visibility (PSV) Usage” and Section 8.10 “PSV Usage with Interrup t Se r- vice Routines”.
Briefly, the architecture allows the mapping of one 32K page of Flash into the upper 32K of the data address space via the Special Function Register (SFR) PSVPAG. By default the compiler only supports direct access to one single PSV page, referred to as the auto_psv space. In this model, 16-bit data pointers can be used. However, on larger devices, this can make it difficult to manage large amounts of constant data stored in Flash.
The extensions presented here allow the definition of a variable as being a ‘managed’ PSV variable. This means that the compiler will manipulate both the offset (within a PSV page) and the page itself. As a consequence, data pointers must be 32 bits. The compiler will probably generate more instructions than the single PSV page model, but that is the price being paid to buy more flexibility and shorter coding time to access larger amounts of data in Flash.
6.2.1 Defining Data for Managed PSV Access
Chapter 2. “Differences Between 16-Bit Device C and ANSI C” introduces C exten-
sions which allows the identification of extra information for a variable or function. The compiler provides the space attribute to help place variables into different areas (spaces) of memory.
2002-2011 Microchip Technology Inc. DS51284K-page 87
16-Bit C Compiler User’s Guide
For example, to place a variable in the auto_psv space, which will cause storage to be allocated in Flas h in a conv enien t way to be acce ssed by a single PSVPAG setting, specify:
unsigned int FLASH_variable __attribute__((space(auto_psv)));
Other user spaces that relate to Flash are available:
space(psv) - a PSV space that the compiler does not access automatically
space(prog) - any location in Flash that the compiler do es not access aut omatically Note that both the psv and auto_psv spaces are appropriately blocked or aligned so
that a single PSVPAG setting is suitable for accessing the entire variable.
6.2.2 Managed PSV Access
Just placing something into Flash using the space attribute does not mean the compiler will be able to manage the access. The compiler requires that you identify variables in a special way. This is done because the managed PSV can be less efficient than man­aging the PSVPAG by hand (though far less complicated).
The compiler introduces several new qualifiers (CV-qualifiers for the language lawyers in the audien ce). Like const-volatile qualifier, the new qualifiers can be applied to pointers or objects. These are:
__psv__ for accessing objects that do not cross a PSV boundary, such as those allocated in space(auto_psv) or space(psv)
__prog__ for accessing objects that may cross a PSV boundary, specifically those allocated in space(prog), but it may be applied to any object in Flash
Typically there is no need to specify __psv__ or __prog__ for an object placed in space(auto_psv).
Moving the FLASH_variable from the previous section into a normal Flash space and requesting that the compiler manage the space is accomplished by:
__psv__ unsigned int FLASH_variable __attribute__((space(psv)));
Reading from the variable now will cause the compiler to generate code that adjusts the PSVPAG SFR as necessary to access the variable correctly. These qualifiers can equally decorate pointers:
__psv__ unsigned int *pFLASH;
produces a pointer to something in PSV, which can be assigned to a managed PSV object in the normal way. For example:
pFLASH = &FLASH_variable;
6.2.3 ISR Considerations
A data access using managed PSV pointers is definitely not atomic, meaning it can take several instructions to complete the access. Care should be taken if an access should not be interrupted.
Furthermore an interrupt service routine (ISR) never really knows what the current state of the PSVPAG register will be. Unfortunately the compiler is not really in any position to determine whether or not this is important in all cases.
The compiler will make the simplifying assumption that the writer of the interrupt service routine will know whether or not the automatic, compiler managed PSVPAG is required by the ISR. This is required to access any constant data in the auto_psv space or any string literals or constants when the default -mconst-in-code option is selected. When defining an interrupt service routine, it is best to specify whether or not it is nec­essary to assert the default setting of the PSVPAG SFR.
This is achieved by adding a further attribute to the interrupt function definition:
DS51284K-page 88 2002-2011 Microchip Technology Inc.
auto_psv - the compiler will set the PSVPAG register to the correct value for accessing the auto_psv space, ensuring that it is restored when exiting the ISR
no_auto_psv - the compiler will not set the PSVPAG register
For example:
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void) { IFS0bits.T1IF = 0; }
Current code (that does not assert the auto_psv attribute) may not execute proper ly unless recompiled. When recompiled, if no indication is made, the compiler will gener­ate a warning message and select the auto_psv model.
The choice is provided so that, if you are especially conscious of interrupt latency , you may select the best option. Saving and setting the PSVPAG will consume approxi­mately 3 cycles at the entry to the function and one further cycle to restore the setting upon exit from the function.
Note that boot or secure interrupt service routines will use a different setting of the PSVPAG register for their constant data.

6.3 PMP POINTERS

Some devices contain a Parallel Master Port (PMP) peripheral which allows the con­nection of various memory and non-memory devices directly to the device. Access to the peripheral is controlled via a selection of peripherals. More information about this peripheral can be found in the Family Reference Manual or device-specific data sheets.
Additional C Pointer Types
Note: PMP attributes are not supported on devices with EPMP. Use EDS.
PMP pointers are similar to managed PSV pointers as described in the previous sec­tion. These pointers make it easier to read or write data using the PMP.
The peripheral can require a substantial amount of configuration, depending upon the type and brand of memory device that is connected. This configuration is not done automatically by the compiler.
The extensions presented here allow the definition of a variable as PMP. This means that the compiler will communicate with the PMP peripheral in order to access the vari­able.
To use this feature:
• Initialize PMP - define the initialization function: void __init_PMP(void)
• Declare a New Memory Space
• Define Variables within PMP Space
6.3.1 Initialize PMP
The PMP peripheral requires initialization before any access can be properly pro­cessed. Consult the appropriate documentation for the device you are interfacing to and the data sheet for 16-bit device you are using.
The toolsuite, if PMP is used, will call void __init_PMP(void) during normal C run-time initialization. If a customized initialization is being used, please ensure that this function is called.
This function should make the necessary settings in the PMMODE and PMCON SFRs. In particular:
• The peripheral should not be configured to generate interrupts:
PMMODEbits.IRQM = 0
• The peripheral should not be configured to generate increments:
2002-2011 Microchip Technology Inc. DS51284K-page 89
16-Bit C Compiler User’s Guide
PMMODEbits.INCM = 0 The compiler will modify this setting during run-time as needed.
• The peripheral should be initialized to 16-bit mode:
PMMODEbits.MODE16 = 1
The compiler will modify this setting during run-time as needed.
• The peripheral should be configured for one of the MASTER modes: PMMODEbits.MODE = 2 or PMMODEbits.MODE = 3
• Set the wait-states PMMODEbits.WAITB, PMMODEbits.WAITM, and PMMODEbits.WAITE as appropriate for the device being connected.
• The PMCON SFR should be configured as appropriate making sure that the chip select function bits PMCONbits.CSF match the information communicated to the compiler when defining memory spaces.
A partial example might be:
void __init_PMP(void) { PMMODEbits.IRQM = 0; PMMODEbits.INCM = 0; PMMODEbits.MODE16 = 1; PMMODEbits.MODE = 3; /* device specific configuration of PMMODE and PMCCON follows */ }
6.3.2 Declare a New Memory Space
The compiler toolsuite requires information about each additional memory being attached via the PMP . In order for the 16-bit device linker to be able to properly assign memory, information about the size of memory available and the number of chip-selects needs to be provided.
In Chapter 2. “Differences Between 16-Bit Device C and ANSI C” the new pmp memory space was introduced. This attribute serves two purposes: declaring extended memory spaces and assigning C variable declarations to external memory (this will be covered in the next subsection).
Declaring an extended memory requires providing the size of the memory. You may optionally assign the memory to a particular chip-select pin; if none is assigned it will be assumed that chip-selects are not being used. These memory declarations look like normal external C declarations:
extern int external_PMP_memory
__attribute__((space(pmp(size(1024),cs(0)))));
Above we defined an external memory of size 1024 bytes and there are no chip-selects. The compiler only supports one PMP memory unless chip-selects are being used:
extern int PMP_bank1 __attribute__((space(pmp(size(1024),cs(1))))); extern int PMP_bank2
Above PMP_bank1 will be activated using chip-select pin 1 (address pin 14 will be asserted when accessing variables in this bank). PMP_bank2 will be activated using chip-select pin 2 (address pin 15 will be asserted).
Note that when using chip-selects, the largest amount of memory is 16 Kbytes per bank. It is recommended that these declaration appear in a common header file so that the declaration is available to all translation units.
__attribute__((space(pmp(size(2048),cs(2)))));
DS51284K-page 90 2002-2011 Microchip Technology Inc.
6.3.3 Define Variables within PMP Space
The pmp space attribute is also used to assign individual variables to the space. This requires that the memory space declaration to be present. Given the declarations in the previous subsection, the following variable declarations can be made:
__pmp__ int external_array[256]
external_array will be allocated in the previous declared memory external_PMP_memory. If there is only one PMP memory , and chip-selects are not
being used, it is possible to leave out the explicit reference to the memory. It is good practice, however, to always make the memory explicit which would lead to code that is more easily maintained.
Note that, like managed PSV pointers, we have qualified the variable with a new type qualifier __pmp__. When attached to a variable or pointer it instructs the compiler to generate the correct sequence for accessing via the PMP peripheral.
Now that a variable has been declared it may be accessed using normal C syntax. The compiler will generate code to correctly communicate with the PMP peripheral.
__attribute__((space(pmp(external_PMP_memory))));

6.4 EXTERNAL POINTERS

Not all of Microchip’s 16-bit devices have a PMP peripheral, or not all memories are suitabl e for attaching to a parallel port ( serial memories so ld by Microchip, fo r example). The toolsuite provides a more general interface to any external memory, although, as will be seen, the memory does not have to be external.
Like PMP memory space, the tool-chain needs to learn about external memories that are being attached. Unlike PMP, however, the compiler does not know how to access these mem orie s. A mec han ism is p rovid ed by w hic h an ap plic ati on c an spec ify how t o access such memories.
External pointers (and their addresses) consume 32 bits. The largest attachable mem­ory is 64K (16 bits); the other 16 bits is used to uniquely identify the memory. A total of 64K (16 bits) of these may be (theoretically) attached.
To use this feature:
• Declare a New Memory Space
• Define Variables within an External Space
• Define How to Access Memory Spaces As an example:
• An External Example
Additional C Pointer Types
6.4.1 Declare a New Memory Space
This is very similar to declaring a new memory space for PMP access. The 16-bit toolsuite requires information about each external memory. In order for
16-bit device linker to be able to properly assign memory, information about the size of memory available and, optionally the origin of the memory, needs to be provided.
In Chapter 2. “Differen c es Betwee n 16-Bit Device C and ANSI C” the new external memory space was introduced. This attribute serves two purposes: declar­ing extended memory spaces and assigning C variable declarations to external mem­ory (this will be covered in the next subsection).
Declaring an extended memory requires providing the size of the memory. You may optionally specify an origin for this memory; if none is specified 0x0000 will be assumed.
2002-2011 Microchip Technology Inc. DS51284K-page 91
16-Bit C Compiler User’s Guide
extern int external_memory
__attribute__((space(external(size(1024)))));
Above an external memory of size 1024 bytes is defined. This memory can be uniquely identified by its given name of external_memory.
6.4.2 Define Variables within an External Space
The external space attribute is also used to assign individual variables to the space. This requires that the memory space declaration to be present. Given the declarations in the previous subsection, the following variable declarations can be made:
__external__ int external_array[256]
external_array will be allocated in the previous declared memory external_memory.
Note that, like managed PSV pointers, we have qualified the variable with a new type qualifier __external__. When attached to a variable or pointer it instructs the com­piler to generate the correct sequence for accessing.
Now that a variable has been declared it may be accessed using normal C syntax. The compiler will generate code to access the variable via special helper functions that the programmer must define. These are covered in the next subsection.
__attribute__((space(external(external_memory))));
6.4.3 Define How to Access Memory Spaces
References to variables placed in external memories are controlled via the use of sev­eral helper functions. Up to five (5) functions may be defined for reading and five (5) for writing. One each of these is a generic function and will be called if any of the other four is not defined but is required. If none of the functions are defined, the compiler will gen­erate an error message. A brief example will be presented in the next subsection. Gen­erally defining the individual functions will result in more efficient code generation.
6.4.3.1 FUNCTIONS FOR READING
read_external
void __read_external(unsigned int address, unsigned int memory_space, void *buffer, unsigned int len)
This function is a generic Read function and will be called if one of the next functions are required but not defined. This function should perform the steps necessary to fill len bytes of memory in the buffer from the external memory named memory_space starting at address address.
read_external8
unsigned char __read_external8(unsigned int address, unsigned int memory_space)
Read 8 bits from external memory space memory_space starting from address address. The compiler would like to call this function if trying to access an 8-bit sized
object.
DS51284K-page 92 2002-2011 Microchip Technology Inc.
Additional C Pointer Types
read_external16
unsigned int __read_external16(unsigned int address, unsigned int memory_space)
Read 16 bits from external memory space memory_space starting from address address. The compiler would like to call this function if trying to access an 16-bit sized
object.
read_external32
unsigned long __read_external32(unsigned int address, unsigned int memory_space)
Read 32 bits from external memory space memory_space starting from address address. The compiler would like to call this function if trying to access a 32-bit sized object, such as a long or float type.
read_external64
unsigned long long __read_external64(unsigned int address, unsigned int memory_space)
Read 64 bits from external memory space memory_space starting from address address. The compiler would like to call this function if trying to access a 64-bit sized
object, such as a long long or long double type.
6.4.3.2 FUNCTIONS FOR WRITING
write_external
void __write_external(unsigned int address, unsigned int memory_space, void *buffer, unsigned int len)
This function is a generic Write function and will be called if one of the next functions are required but not defined. This function should perform the steps necessary to write len bytes of memory from the buffer to the external memory named memory_space starting at address address.
write_external8
void __write_external8(unsigned int address, unsigned int memory_space, unsigned char data)
Write 8 bits of data to external memory space memory_space starting from address address. The compiler would like to call this function if trying to write an 8-bit sized
object.
write_external16
void __write_external16(unsigned int address, unsigned int memory_space, unsigned int data)
Write 16 bit s of data to external memory space memory_space starting from address address. The compiler would like to call this function if trying to write an 16-bit sized
object.
2002-2011 Microchip Technology Inc. DS51284K-page 93
16-Bit C Compiler User’s Guide
write_external32
void __write_external32(unsigned int address, unsigned int memory_space, unsigned long data)
Write 32 bit s of data to external memory space memory_space starting from address address. The compiler would like to call this function if trying to write a 32-bit sized object, such as a long or float type.
write_external64
void __write_external64(unsigned int address, unsigned int memory_space, unsigned long long data)
Write 64 bit s of data to external memory space memory_space starting from address address. The compiler would like to call this function if trying to write a 64-bit sized object, such as a long long or long double type.
6.4.4 An External Example
The following snippets of example come from a working example (in the Examples folder.)
This example implements, using external memory, addressable bit memory. In this case each bit is stored in real data memory, not off chip. The code will define an external memory of 512 units and map accesses using the appropriate read and write function to one of 64 bytes in local data memory.
First the external memory is defined:
extern unsigned int bit_memory
__attribute__((space(external(size(512)))));
Next appropriate read and write functions are defined. These functions will make use of an array of memory that is reserved in the normal way.
static unsigned char real_bit_memory[64]; unsigned char __read_external8(unsigned int address, unsigned int memory_space) { if (memory_space == bit_memory) { /* an address within our bit memory */ unsigned int byte_offset, bit_offset; byte_offset = address / 8; bit_offset = address % 8; return (real_bit_memory[byte_offset] >> bit_offset) & 0x1; } else { fprintf(stderr,"I don't know how to access memory space: %d\n", memory_space); } return 0; } void __write_external8(unsigned int address, unsigned int memory_space, unsigned char data) { if (memory_space == bit_memory) { /* an address within our bit memory */ unsigned int byte_offset, bit_offset; byte_offset = address / 8; bit_offset = address % 8; real_bit_memory[byte_offset] &= (~(1 << bit_offset)); if (data & 0x1) real_bit_memory[byte_offset] |= (1 << bit_offset);
DS51284K-page 94 2002-2011 Microchip Technology Inc.
Additional C Pointer Types
} else { fprintf(stderr,"I don't know how to access memory space: %d\n", memory_space); } }
These functions work in a similar fashion:
• if accessing bit_memory, then
- determine the correct byte offset and bit offset
- read or write the appropriate place in the real_bit_memory
• otherwise access another memory (whose access is unknown) With the two major pieces of the puzzle in place, generate some variables and
accesses:
__external__ unsigned char bits[NUMBER_OF_BITS]
// inside main __external__ unsigned char *bit; bit = bits; for (i = 0; i < 512; i++) { printf("%d ",*bit++); }
Apart from the __external__ CV-qualifiers, ordinary C statements can be used to define and access variables in the external memory space.
__attribute__((space(external(bit_memory))));

6.5 EXTENDED DATA SPACE POINTERS

Extended data space pointers allow you to easily access variables that have been placed in a variety of different memory spaces. These include: space(data) (and its subsets), space(eds), space(eedata), space(prog), space(psv), space(auto_psv), and on some devices space(pmp). Not all devices support all memory spaces.
To use this feature:
• declare an object in an appropriate memory space
• qualify the object with the __eds__ qualifier For example:
__eds__ int var_a __attribute__((space(prog))); __eds__ int var_b [10] __attribute__((space(eds))); __eds__ int *var_c; __eds__ int *__eds__ *var_d __attribute__((space(psv)));
var_a - declares an int in Flash that is automatically accessed var_b - declares an array of ints, located in space(eds); the elements of the array
are automatically accessed var_c - declares a pointer to an int, where the destination may exist in any one of the
memory spaces supported by Extended Data Space pointers and will be automatically accessed upon dereference; the pointer itself must live in a normal data space
var_d - declares a pointer to an int, where the destination may exist in any one of the memory spaces supported by Extended Data Space pointers and will be automatically accessed upon dereference; the pointer value exists in Flash and is also automatically accessed.
2002-2011 Microchip Technology Inc. DS51284K-page 95
16-Bit C Compiler User’s Guide
The compiler will automatically assert the page attribute to scalar variable declarations; this allows the compiler to generate more efficient code when accessing larger data types. Remember, scalar variables do not include structures or arrays. T o force paging of a structure or array, please manually use the page attribute and the compiler w ill prevent the object from crossing a page boundary.
For read access to __eds__ qualified variables will automatically manipulate the PSVPAG or DSRPAG register (as appropriate). For devices that support extended data space memory, the compiler will also manipulate the DSWPAG register.
Note: Some devices use DSRPAG to represent extended read access to FLASH
or the extended data space (EDS)
DS51284K-page 96 2002-2011 Microchip Technology Inc.

Chapter 7. Device Support Files

7.1 INTRODUCTION

This section discusses device support files used in support of compilation using the MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs (formerly MPLAB C30).

7.2 HIGHLIGHTS

Items discussed in this chapter are:
• Processor Heade r Files
• Register Definition Files
•Using SFRs
• Using Macros
• Accessing EEDATA from C Code – PIC24F MCUS, dsPIC30F/33F DSCs only
MPLAB® C COMPILER FOR
PIC24 MCUs AND dsPIC® DSCs
USER’S GUIDE

7.3 PROCESSOR HEADER FILES

The processor header files are distributed with the language tools. These header files define the available Special Function Registers (SFRs) for each dsPIC DSC device. T o use a header file in C, use;
#include <p30fxxxx.h>
where xxxx corresponds to the device part number. The C header files are distributed in the support\h directory.
Inclusion of the header file is necessary in order to use SFR names (e.g., CORCONbits).
For example, the following module, compiled for the dsPIC30F2010 part, includes two functions: one for enabling the PSV window, and another for disabling the PSV window.
#include <p30f2010.h> void EnablePSV(void) { CORCONbits.PSV = 1; } void DisablePSV(void) { CORCONbits.PSV = 0; }
2002-2011 Microchip Technology Inc. DS51284K-page 97
16-Bit C Compiler User’s Guide
The convention in the processor header files is that each SFR is named, using the same name that appears in the data sheet for the part – for example, CORCON for the Core Control register. If the register has individual bits that might be of interest, then there will also be a structure defined for that SFR, and the name of the structure will be the same as the SFR name, with “bits” appended. For example, CORCONbits for the Core Control register. The individual bits (or bit fields) are named in the structure using the names in the data sheet – for example PSV for the PSV bit of the CORCON register. Here is the complete definition of CORCON (subject to change):
/* CORCON: CPU Mode control Register */ extern volatile unsigned int CORCON typedef struct tagCORCONBITS { unsigned IF :1; /* Integer/Fractional mode */ unsigned RND :1; /* Rounding mode */ unsigned PSV :1; /* Program Space Visibility enable */ unsigned IPL3 :1; unsigned ACCSAT :1; /* Acc saturation mode */ unsigned SATDW :1; /* Data space write saturation enable */ unsigned SATB :1; /* Acc B saturation enable */ unsigned SATA :1; /* Acc A saturation enable */ unsigned DL :3; /* DO loop nesting level status */ unsigned :4; } CORCONBITS; extern volatile CORCONBITS CORCONbits __attribute__((__near__));
__attribute__((__near__));
Note: The symbols CORCON and CORCONbits refer to the same register and will
resolve to the same address at link time.

7.4 REGISTER DEFINITION FILES

The processor header files described in Section 7.3 “Processor Header Files” name all SFRs for each part, but they do not define the addresses of the SFRs. A separate set of device-specific linker script files, one per part, is distributed in the support\gld directory. These linker script files define the SFR addresses. T o use one of these files, specify the linker command-line option:
-T p30fxxxx.gld
where xxxx corresponds to the device part number. For example, assuming that there exists a file named app2010.c, which contains an
application for the dsPIC30F2010 part, then it may be compiled and linked using the following command line:
pic30-gcc -o app2010.o -T p30f2010.gld app2010.c
The -o command-line option names the output COFF executable file, and the -T option gives the name for the dsPIC30F2010 part. If p30f2010.gld is not found in the current directory, the linker searches in its known library paths. For the default installation, the linker scripts are included in the PIC30_LIBRARAY_PATH. For reference see Section 3.6 “Environment Variables”.
DS51284K-page 98 2002-2011 Microchip Technology Inc.

7.5 USING SFRS

There are three steps to follow when using SFRs in an application.
1. Include the processor header file for the appropriate device. This provides the
2. Access SFRs like any other C variables. The source code can write to and/or
3. Link with the register definition file or linker script for the appropriate device. The
See “MPLAB User’s Guide” (DS51317) for more information on using linker scripts.
The following example is a sample real time clock. It uses several SFRs. Descriptions for these SFRs are found in the p30f6014.h file. This file would be linked with the device specific linker script which is p30f6014.gld.
Device Support File s
source code with the SFRs that are available for that device. For instance, the following statement includes the header files for the dsPIC30F6014 part:
#include <p30f6014.h>
read from the SFRs. For example, the following statement clears all the bits to zero in the special function register for Timer1.
TMR1 = 0;
This next statement represents the 15th bit in the T1CON register which is the “timer on” bit. It sets the bit named TON to 1 which starts the timer.
T1CONbits.TON = 1;
linker provides the addresses of the SFRs. (Remember the bit structure will have the same address as the SFR at link time.) Example 6.1 would use:
p30f6014.gld
®
Assembler, Linker and Utilities for PIC24 MCUs and dsPIC® DSCs
2002-2011 Microchip Technology Inc. DS51284K-page 99
16-Bit C Compiler User’s Guide
EXAMPLE 7-1: SAMPLE REAL-TIME CLOCK
/* ** Sample Real Time Clock for dsPIC ** ** Uses Timer1, TCY clock timer mode ** and interrupt on period match */
#include <p30f6014.h>
/* Timer1 period for 1 ms with FOSC = 20 MHz */ #define TMR1_PERIOD 0x1388
struct clockType { unsigned int timer; /* countdown timer, milliseconds */ unsigned int ticks; /* absolute time, milliseconds */ unsigned int seconds; /* absolute time, seconds */ } volatile RTclock;
void reset_clock(void) { RTclock.timer = 0; /* clear software registers */ RTclock.ticks = 0; RTclock.seconds = 0;
TMR1 = 0; /* clear timer1 register */ PR1 = TMR1_PERIOD; /* set period1 register */ T1CONbits.TCS = 0; /* set internal clock source */ IPC0bits.T1IP = 4; /* set priority level */ IFS0bits.T1IF = 0; /* clear interrupt flag */ IEC0bits.T1IE = 1; /* enable interrupts */
SRbits.IPL = 3; /* enable CPU priority levels 4-7*/ T1CONbits.TON = 1; /* start the timer*/ }
__attribute__((__interrupt__)) _T1Interrupt(void)
void { static int sticks=0;
if (RTclock.timer > 0) /* if countdown timer is active */ RTclock.timer -= 1; /* decrement it */ RTclock.ticks++; /* increment ticks counter */ if (sticks++ > 1000) { /* if time to rollover */ sticks = 0; /* clear seconds ticks */ RTclock.seconds++; /* and increment seconds */ }
IFS0bits.T1IF = 0; /* clear interrupt flag */ return; }
DS51284K-page 100 2002-2011 Microchip Technology Inc.
Loading...