SDCC Compiler User Guide

SDCC Compiler User Guide

Chapter 4

Notes on supported Processors

4.1

MCS51 variants

MCS51 processors are available from many vendors and come in many different flavours. While they might differ considerably in respect to Special Function Registers the core MCS51 is usually not modified or is kept compatible.

4.1.1

pdata access by SFR

With the upcome of devices with internal xdata and flash memory devices using port P2 as dedicated I/O port is becoming more popular. Switching the high byte for pdata access which was formerly done by port P2 is then achieved by a Special Function Register. In well-established MCS51 tradition the address of this sfr is where the chip designers decided to put it. Needless to say that they didn’t agree on a common name either. So that the startup code can correctly initialize xdata variables, you should define an sfr with the name _XPAGE at the appropriate location if the default, port P2, is not used for this. Some examples are: sfr at 0x92 _XPAGE; /* Cypress EZ-USB family */ sfr at 0xaf _XPAGE; /* some Silicon Labs (Cygnal) chips */ sfr at 0xaa _XPAGE; /* some Silicon Labs (Cygnal) chips */

For more exotic implementations further customizations may be needed. See section

3.11

for other possibilities.

4.1.2

Other Features available by SFR

Some MCS51 variants offer features like Double DPTR, multiple DPTR, decrementing DPTR, 16x16 Multiply.

These are currently not used for the MCS51 port. If you absolutely need them you can fall back to inline assembly or submit a patch to SDCC.

4.2

DS400 port

The DS80C400 microcontroller has a rich set of peripherals. In its built-in ROM library it includes functions to access some of the features, among them is a TCP stack with IP4 and IP6 support. Library headers (currently in beta status) and other files are provided at ftp://ftp.dalsemi.com/pub/tini/ds80c400/c_libraries/sdcc/index.html

.

4.3

The Z80 and gbz80 port

SDCC can target both the Zilog and the Nintendo Gameboy’s Z80-like gbz80. The Z80 port is passed through the same regressions tests as the MCS51 and DS390 ports, so floating point support, support for long variables and bitfield support is fine. See mailing lists and forums about interrupt routines.

As always, the code is the authoritative reference - see z80/ralloc.c and z80/gen.c. The stack frame is similar to that generated by the IAR Z80 compiler. IX is used as the base pointer, HL and IY are used as a temporary registers, and BC and DE are available for holding variables. Return values for the Z80 port are stored in L (one byte), HL (two bytes), or DEHL (four bytes). The gbz80 port use the same set of registers for the return values, but in a different order of significance: E (one byte), DE (two bytes), or HLDE (four bytes).

48

4.4. THE HC08 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

4.4

The HC08 port

The port to the Motorola HC08 family has been added in October 2003, and is still undergoing some basic development. The code generator is complete, but the register allocation is still quite unoptimized. Some of the

SDCC’s standard C library functions have embedded non-HC08 inline assembly and so are not yet usable.

4.5

The PIC14 port

The 14bit PIC port still requires a major effort from the development community. However it can work for very simple code.

4.5.1

C code and 14bit PIC code page and RAM banks

The linker organizes allocation for the code page and RAM banks. It does not have intimate knowledge of the code flow. It will put all the code section of a single asm file into a single code page. In order to make use of multiple code pages, separate asm files must be used. The compiler treats all functions of a single C file as being in the same code page unless it is non static. The compiler treats all local variables of a single C file as being in the same

RAM bank unless it is an extern.

To get the best follow these guide lines:

1. make local functions static, as non static functions require code page selection overhead.

2. Make local variables static as extern variables require RAM bank selection overhead.

3. For devices that have multiple code pages it is more efficient to use the same number of files as pages, i.e. for the 16F877 use 4 separate files and i.e. for the 16F874 use 2 separate files. This way the linker can put the code for each file into different code pages and the compiler can allocate reusable variables more efficiently and there’s less page selection overhead. And as for any 8 bit micro (especially for PIC 14 as they have a very simple instruction set) use ’unsigned char’ whereever possible instead of ’int’.

4.5.2

Creating a device include file

For generating a device include file use the support perl script inc2h.pl kept in directory support/script.

4.5.3

Interrupt code

For the interrupt function, use the keyword ’interrupt’ with level number of 0 (PIC14 only has 1 interrupt so this number is only there to avoid a syntax error - it ought to be fixed). E.g.: void Intr(void) interrupt 0

{

T0IF = 0; /* Clear timer interrupt */

}

4.5.4

Linking and assembling

For assembling you can use either GPUTILS’ gpasm.exe or MPLAB’s mpasmwin.exe. GPUTILS is available from http://sourceforge.net/projects/gputils

. For linking you can use either GPUTIL’s gplink or MPLAB’s mplink.exe. If you use MPLAB and an interrupt function then the linker script file vectors section will need to be enlarged to link with mplink.

Here is a Makefile using GPUTILS:

49

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

.c.o: sdcc -S -V -mpic14 -p16F877 $< gpasm -c $*.asm

$(PRJ).hex: $(OBJS) gplink -m -s $(PRJ).lkr -o $(PRJ).hex $(OBJS) libsdcc.lib

Here is a Makefile using MPLAB:

.c.o: sdcc -S -V -mpic14 -p16F877 $< mpasmwin /q /o $*.asm

$(PRJ).hex: $(OBJS) mplink /v $(PRJ).lkr /m $(PRJ).map /o $(PRJ).hex $(OBJS) libsdcc.lib

Please note that indentations within a Makefile have to be done with a tabulator character.

4.5.5

Command-line options

Besides the switches common to all SDCC backends, the PIC14 port accepts the following options (for an updated list see sdcc --help):

--debug-extra emit debug info in assembly output

--no-pcode-opt disable (slightly faulty) optimization on pCode

4.5.6

The library

4.5.6.1

error: missing definition for symbol ”__gptrget1”

The PIC14 port uses library routines to provide more complex operations like multiplication, division/modulus and (generic) pointer dereferencing. In order to add these routines to your project, you must link with PIC14’s libsdcc.lib

.

For single source file projects this is done automatically, more complex projects must add libsdcc.lib

to the linker’s arguments. Make sure you also add an include path for the library (using the -I switch to the linker)!

4.5.6.2

Processor mismatch in file ”XXX”.

This warning can usually be ignored due to the very good compatibility amongst 14 bit PIC devices.

You might also consider recompiling the library for your specific device by changing the ARCH=p16f877

(default target) entry in device/lib/pic/Makefile.in and device/lib/pic/Makefile to reflect your device.

This might even improve performance for smaller devices as unneccesary BANKSELs migth be removed.

4.5.7

Known bugs

4.5.7.1

initialized data

Currently, data can only be initialized if it resides in the source file together with main(). Data in other source files will silently not be initialized.

4.6

The PIC16 port

The PIC16 port is the portion of SDCC that is responsible to produce code for the Microchip(TM) microcontrollers with 16 bit core. Currently this family of microcontrollers contains the PIC18Fxxx and PIC18Fxxxx. Currently supported devices are:

50

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

18F242 18F248 18F252 18F258 18F442 18F448

18F452 18F458 18F1220 18F2220 18F2550 18F4331

18F4455 18F6520 18F6620 18F6680 18F6720 18F8520

18F8620 18F8680 18F8720

4.6.1

Global Options

PIC16 port supports the standard command line arguments as supposed, with the exception of certain cases that will be mentioned in the following list:

--callee-saves See --all-callee-saves

--all-callee-saves All function arguments are passed on stack by default. There is no need to specify this in the

command line.

--fommit-frame-pointer Frame pointer will be omitted when the function uses no local variables.

4.6.2

Port Specific Options

The port specific options appear after the global options in the sdcc –help output.

4.6.2.1

General Options

General options enable certain port features and optimizations.

--stack-model=[model] Used in conjuction with the command above. Defines the stack model to be used, valid stack models are :

small large

Selects small stack model. 8 bit stack and frame pointers. Supports 256 bytes stack size.

Selects large stack model. 16 bit stack and frame pointers. Supports 65536 bytes stack size.

--preplace-udata-with=[kword] Replaces the default udata keyword for allocating unitialized data variables with

[kword]. Valid keywords are: "udata_acs", "udata_shr", "udata_ovr".

--ivt-loc <nnnn> positions the Interrupt Vector Table at location <nnnn>. Useful for bootloaders.

--asm= sets the full path and name of an external assembler to call.

--link= sets the full path and name of an external linker to call.

--mplab-comp MPLAB compatibility option. Currently only suppresses special gpasm directives.

4.6.2.2

Optimization Options

--optimize-goto Try to use (conditional) BRA instead of GOTO

--optimize-cmp Try to optimize some compares.

--optimize-df Analyze the dataflow of the generated code and improve it.

--obanksel=nn Set optimization level for inserting BANKSELs.

0

1

2 no optimization checks previous used register and if it is the same then does not emit BANKSEL, accounts only for labels.

tries to check the location of (even different) symbols and removes BANKSELs if they are in the same bank.

Important: There might be problems if the linker script has data sections across bank borders!

51

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

4.6.2.3

Linking Options

--nodefaultlibs do not link default libraries when linking

--no-crt Don’t link the default run-time modules

--use-crt= Use a custom run-time module instead of the defaults.

4.6.2.4

Debugging Options

Debugging options enable extra debugging information in the output files.

--debug-xtra Similar to --debug, but dumps more information.

--debug-ralloc Force register allocator to dump <source>.d file with debugging information. <source> is the name of the file compiled.

--pcode-verbose Enable pcode debugging information in translation.

--denable-peeps Force the usage of peepholes. Use with care.

--gstack Trace push/pops for stack pointer overflow

--call-tree dump call tree in .calltree file

4.6.3

Enviromental Variables

There is a number of enviromental variables that can be used when running SDCC to enable certain optimizations or force a specific program behaviour. these variables are primarily for debugging purposes so they can be enabled/disabled at will.

Currently there is only two such variables available:

OPTIMIZE_BITFIELD_POINTER_GET when this variable exists reading of structure bitfields is optimized by directly loading FSR0 with the address of the bitfield structure. Normally SDCC will cast the bitfield structure to a bitfield pointer and then load FSR0. This step saves data ram and code space for functions that perform heavy use of bitfields. (ie. 80 bytes of code space are saved when compiling malloc.c

with this option).

NO_REG_OPT do not perform pCode registers optimization. This should be used for debugging purposes. In some where bugs in the pcode optimizer are found, users can benefit from temporarily disabling the optimizer until the bug is fixed.

4.6.4

Preprocessor Macros

PIC16 port defines the following preprocessor macros while translating a source.

Macro

SDCC_pic16

__pic16 pic18fxxxx

__18Fxxxx

STACK_MODEL_nnn

Description

Port identification

Port identification (same as above)

MCU Identification. xxxx is the microcontrol identification number, i.e. 452, 6620, etc

MCU Identification (same as above) nnn = SMALL or LARGE respectively according to the stack model used

In addition the following macros are defined when calling assembler:

Macro Description

__18Fxxxx MCU Identification. xxxx is the microcontrol identification number, i.e. 452, 6620, etc

SDCC_MODEL_nnn nnn = SMALL or LARGE respectively according to the memory model used for SDCC

STACK_MODEL_nnn nnn = SMALL or LARGE respectively according to the stack model used

52

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

4.6.5

Directories

PIC16 port uses the following directories for searching header files and libraries.

Directory Description Target

PREFIX/sdcc/include/pic16 PIC16 specific headers Compiler

PREFIX/sdcc/lib/pic16 PIC16 specific libraries Linker

Command prefix

-I

-L

4.6.6

Pragmas

PIC16 port currently supports the following pragmas: stack pragma stack forces the code generator to initialize the stack & frame pointers at a specific address.

This is an adhoc solution for cases where no STACK directive is available in the linker script or gplink is not instructed to create a stack section.

The stack pragma should be used only once in a project. Multiple pragmas may result in indeterminate

behaviour of the program.

1

The format is as follows:

#pragma stack bottom_address [stack_size]

bottom_address is the lower bound of the stack section.

The stack pointer initially will point at address

(bottom_address+stack_size-1).

Example:

/* initializes stack of 100 bytes at RAM address 0x200 */

#pragma stack 0x200 100

If the stack_size field is omitted then a stack is created with the default size of 64. This size might be enough for most programs, but its not enough for operations with deep function nesting or excessive stack usage.

wparam

This pragma is deprecated. Its use will cause a warning message to be issued.

code place a function symbol at static FLASH address

Example:

/* place function test_func at 0x4000 */

#pragma code test_func 0x4000 library instructs the linker to use a library module.

Usage:

#pragma library module_name

module_name can be any library or object file (including its path). Note that there are four reserved keywords which have special meaning. These are:

Keyword Description Module to link

ignore

ignore all library pragmas

c

link the C library

math io

link the Math libarary link the I/O library

(none)

libc18f.lib

libm18f.lib

libio18f*.lib

debug

link the debug library libdebug.lib

* is the device number, i.e. 452 for PIC18F452 MCU.

This feature allows for linking with specific libraries withoug having to explicit name them in the command line. Note that the

IGNORE keyword will reject all modules specified by the library pragma.

1

The old format (ie. #pragma stack 0x5ff) is deprecated and will cause the stack pointer to cross page boundaries (or even exceed the available data RAM) and crash the program. Make sure that stack does not cross page boundaries when using the SMALL stack model.

53

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS udata pragma udata instructs the compiler to emit code so that linker will place a variable at a specific memory bank

Example:

/* places variable foo at bank2 */

#pragma udata bank2 foo char foo;

In order for this pragma to work extra SECTION directives should be added in the .lkr script. In the following example a sample .lkr file is shown:

// Sample linker script for the PIC18F452 processor

LIBPATH .

CODEPAGE NAME=vectors

CODEPAGE NAME=page

START=0x0

START=0x2A

END=0x29

END=0x7FFF

CODEPAGE NAME=idlocs

CODEPAGE NAME=config

CODEPAGE NAME=devid

CODEPAGE NAME=eedata

START=0x200000

START=0x300000

START=0x3FFFFE

START=0xF00000

END=0x200007

END=0x30000D

END=0x3FFFFF

END=0xF000FF

ACCESSBANK NAME=accessram START=0x0

DATABANK NAME=gpr0 START=0x80

DATABANK NAME=gpr1

DATABANK NAME=gpr2

START=0x100

START=0x200

DATABANK NAME=gpr3

DATABANK NAME=gpr4

START=0x300

START=0x400

DATABANK NAME=gpr5 START=0x500

ACCESSBANK NAME=accesssfr START=0xF80

END=0x7F

END=0xFF

END=0x1FF

END=0x2FF

END=0x3FF

END=0x4FF

END=0x5FF

END=0xFFF

SECTION

SECTION

SECTION

SECTION

SECTION

SECTION

SECTION

NAME=CONFIG

NAME=bank0

NAME=bank1

NAME=bank2

NAME=bank3

NAME=bank4

NAME=bank5

ROM=config

RAM=gpr0

RAM=gpr1

RAM=gpr2

RAM=gpr3

RAM=gpr4

RAM=gpr5

PROTECTED

PROTECTED

PROTECTED

PROTECTED

PROTECTED

PROTECTED

# these SECTION directives

# should be added to link

# section name ’bank?’ with

# a specific DATABANK name

The linker will recognise the section name set in the pragma statement and will position the variable at the memory bank set with the RAM field at the SECTION line in the linker script file.

4.6.7

Header Files

There is one main header file that can be included to the source files using the pic16 port. That file is the

pic18fregs.h. This header file contains the definitions for the processor special registers, so it is necessary if the source accesses them. It can be included by adding the following line in the beginning of the file:

#include <pic18fregs.h>

The specific microcontroller is selected within the pic18fregs.h automatically, so the same source can be used with a variety of devices.

4.6.8

Libraries

The libraries that PIC16 port depends on are the microcontroller device libraries which contain the symbol definitions for the microcontroller special function registers. These libraries have the format pic18fxxxx.lib, where xxxx is the microcontroller identification number. The specific library is selected automatically by the compiler at link stage according to the selected device.

Libraries are created with gplib which is part of the gputils package http://sourceforge.net/projects/ gputils

.

54

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

Building the libraries

Before using SDCC/pic16 there are some libraries that need to be compiled. This process is not done automatically by SDCC since not all users use SDCC for pic16 projects. So each user should compile the libraries separately.

The steps to compile the pic16 libraries under Linux are: cd device/lib/pic16

./configure make cd ..

make model-pic16 su -c ’make install’ # install the libraries, you need the root password

If you need to install the headers too, do: cd device/include su -c ’make install’ # install the headers, you need the root password

There exist a special target to build the I/O libraries. This target is not automatically build because it will build the

I/O library for every supported device. This way building will take quite a lot of time. Users are advised to edit the

device/lib/pic16/pics.build file and then execute: make lib-io

4.6.9

Memory Models

The following memory models are supported by the PIC16 port:

• small model

• large model

Memory model affects the default size of pointers within the source. The sizes are shown in the next table:

Pointer sizes according to memory model small model large model code pointers data pointers

16-bits

16-bits

24-bits

16-bits

It is advisable that all sources within a project are compiled with the same memory model. If one wants to override the default memory model, this can be done by declaring a pointer as far or near. Far selects large memory model’s pointers, while near selects small memory model’s pointers.

The standard device libraries (see

4.6.7

) contain no reference to pointers, so they can be used with both memory

models.

4.6.10

Stack

The stack implementation for the PIC16 port uses two indirect registers, FSR1 and FSR2.

FSR1

FSR2 is assigned as stack pointer is assigned as frame pointer

The following stack models are supported by the PIC16 port

SMALL model

LARGE model

S

MALL model means that only the FSRxL byte is used to access stack and frame, while

LARGE uses both FSRxL and FSRxH registers. The following table shows the stack/frame pointers sizes according to stack model and the maximum space they can address:

55

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

Stack & Frame pointer sizes according to stack model small large

Stack pointer FSR1

Frame pointer FSR2

8-bits

8-bits

16-bits

16-bits

L

ARGE stack model is currently not working properly throughout the code generator. So its use is not advised.

Also there are some other points that need special care:

1. Do not create stack sections with size more than one physical bank (that is 256 bytes)

2. Stack sections should no cross physical bank limits (i.e. #pragma stack 0x50 0x100)

These limitations are caused by the fact that only FSRxL is modified when using SMALL stack model, so no more than 256 bytes of stack can be used. This problem will disappear after LARGE model is fully implemented.

4.6.11

Functions

In addition to the standard SDCC function keywords, PIC16 port makes available two more: wparam Use the WREG to pass one byte of the first function argument. This improves speed but you may not use this for functions with arguments that are called via function pointers, otherwise the first byte of the first parameter will get lost. Usage: void func_wparam(int a) wparam

{

/* WREG hold the lower part of a */

/* the high part of a is stored in FSR2+2 (or +3 for large stack model) */

...

}

This keyword replaces the deprecated wparam pragma.

shadowregs When entering/exiting an ISR, it is possible to take advantage of the PIC18F hardware shadow registers which hold the values of WREG, STATUS and BSR registers. This can be done by adding the keyword

shadowregs before the interrupt keyword in the function’s header.

void isr_shadow(void) shadowregs interrupt 1

{

...

}

shadowregs instructs the code generator not to store/restore WREG, STATUS, BSR when entering/exiting the ISR.

4.6.12

Function return values

Return values from functions are placed to the appropriate registers following a modified Microchip policy optimized for SDCC. The following table shows these registers: size destination register

8 bits

16 bits

24 bits

32 bits

WREG

PRODL:WREG

PRODH:PRODL:WREG

FSR0L:PRODH:PRODL:WREG

>32 bits on stack, FSR0 points to the beginning

56

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

4.6.13

Interrupts

An interrupt servive routine (ISR) is declared using the interrupt keyword.

void isr(void) interrupt

n

{

...

}

n is the interrupt number, which for PIC18F devices can be:

n

Interrupt Vector

0 RESET vector

1 HIGH priority interrupts

2 LOW priority interrupts

Interrupt Vector Address

0x000000

0x000008

0x000018

When generating assembly code for ISR the code generator places a

GOTO instruction at the Interrupt Vector

Address which points at the genetated ISR. This single GOTO instruction is part of an automatically generated

interrupt entry point function. The actuall ISR code is placed as normally would in the code space. Upon interrupt request, the GOTO instruction is executed which jumps to the ISR code. When declaring interrupt functions as

_naked this GOTO instruction is not generated. The whole interrupt functions is therefore placed at the Interrupt

Vector Address of the specific interrupt. This is not a problem for the LOW priority interrupts, but it is a problem for the RESET and the HIGH priority interrupts because code may be written at the next interruptt’s vector address

and cause undeterminate program behaviour if that interrupt is raised.

2

n is possible to be omitted. This way a function is generated similar to an ISR, but it is not assigned to any interrupt.

When entering an interrupt, currently the PIC16 port automatically saves the following registers:

• WREG

• STATUS

• BSR

• PROD (PRODL and PRODH)

• FSR0 (FSR0L and FSR0H)

These registers are restored upon return from the interrupt routine.

3

4.6.14

Generic Pointers

Generic pointers are implemented in PIC16 port as 3-byte (24-bit) types. There are 3 types of generic pointers currently implemented data, code and eeprom pointers. They are differentiated by the value of the 7th and 6th bits of the upper byte: pointer type data code eeprom

(unimplemented)

7th bit 6th bit

0

1

1

0

0

0

1

1 rest of the pointer descrption uuuuuu uuuuxxxx xxxxxxxx a 12-bit data pointer in data RAM memory uxxxxx xxxxxxxx xxxxxxxx a 21-bit code pointer in FLASH memory uuuuuu uuuuuuxx xxxxxxxx a 10-bit eeprom pointer in EEPROM memory xxxxxx xxxxxxxx xxxxxxxx unimplemented pointer type

Generic pointer are read and written with a set of library functions which read/write 1, 2, 3, 4 bytes.

2

This is not a problem when

1. this is a HIGH interrupt ISR and LOW interrupts are disabled or not used.

2. when the ISR is small enough not to reach the next interruptt’s vector address.

3

NOTE that when the _naked attribute is specified for an interrupt routine, then NO registers are stored or restored.

57

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

4.6.15

PIC16 C Libraries

4.6.15.1

Standard I/O Streams

In the stdio.h the type FILE is defined as: typedef char * FILE;

This type is the stream type implemented I/O in the PIC18F devices. Also the standard input and output streams are declared in stdio.h: extern FILE * stdin; extern FILE * stdout;

The FILE type is actually a generic pointer which defines one more type of generic pointers, the stream pointer.

This new type has the format: pointer type <7:6> <5> <4> <3:0> stream 00 1 0 nnnn rest of the pointer uuuuuuuu uuuuuuuu descrption upper byte high nubble is 0x2n, the rest are zeroes

Currently implemented there are 3 types of streams defined: stream type value module description

STREAM_USART

0x200000UL

USART Writes/Reads characters via the USART peripheral

STREAM_MSSP

0x210000UL

MSSP Writes/Reads characters via the MSSP peripheral

STREAM_USER

0x2f0000UL

(none) Writes/Reads characters via used defined functions

The stream identifiers are declared as macros in the stdio.h header.

In the libc library there exist the functions that are used to write to each of the above streams. These are

__stream_usart_putchar writes a character at the USART stream

__stream_mssp_putchar writes a character at the MSSP stream putchar dummy function. This writes a character to a user specified manner.

In order to increase performance putchar is declared in stdio.h as having its parameter in WREG (it has the wparam keyword). In stdio.h exists the macro PUTCHAR(arg) that defines the putchar function in a user-friendly way. arg is the name of the variable that holds the character to print. An example follows:

#include <pic18fregs.h>

#include <stdio.h>

PUTCHAR( c )

{

PORTA = c;

}

/* dump character c to PORTA */ void main(void)

{ stdout = STREAM_USER; /* this is not necessery, since stdout points

* by default to STREAM_USER */

}

58

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

4.6.15.2

Printing functions

PIC16 contains an implementation of the printf-family of functions. There exist the following functions: extern unsigned int sprintf(char *buf, char *fmt, ...); extern unsigned int vsprintf(char *buf, char *fmt, va_list ap); extern unsigned int printf(char *fmt, ...); extern unsigned int vprintf(char *fmt, va_lista ap); extern unsigned int fprintf(FILE *fp, char *fmt, ...); extern unsigned int vfprintf(FILE *fp, char *fmt, va_list ap);

For sprintf and vsprintf buf should normally be a data pointer where the resulting string will be placed. No range checking is done so the user should allocate the necessery buffer. For fprintf and vfprintf fp should be a stream pointer (i.e. stdout, STREAM_MSSP, etc...).

4.6.15.3

Signals

The PIC18F family of microcontrollers supports a number of interrupt sources. A list of these interrupts is shown in the following table: signal name description

SIG_RB

SIG_INT0

SIG_INT1

SIG_INT2

SIG_CCP1

SIG_CCP2

SIG_TMR0

SIG_TMR1

PORTB change interrupt

INT0 external interrupt

INT1 external interrupt

INT2 external interrupt

CCP1 module interrupt

CCP2 module interrupt

TMR0 overflow interrupt

TMR1 overflow interrupt

SIG_TMR2 TMR2 matches PR2 interrupt

SIG_TMR3 TMR3 overflow interrupt signal name

SIG_EE

SIG_BCOL

SIG_LVD

SIG_PSP

SIG_AD

SIG_RC

SIG_TX

SIG_MSSP

The prototypes for these names are defined in the header file signal.h .

In order to simplify signal handling, a number of macros is provided: descritpion

EEPROM/FLASH write complete interrupt

Bus collision interrupt

Low voltage detect interrupt

Parallel slave port interrupt

AD convertion complete interrupt

USART receive interrupt

USART transmit interrupt

SSP receive/transmit interrupt

DEF_INTHIGH(name) begin the definition of the interrupt dispatch table for high priority interrupts. name is the function name to use.

DEF_INTLOW(name) begin the definition of the interrupt dispatch table fo low priority interrupt. name is the function name to use.

DEF_HANDLER(sig,handler) define a handler for signal sig.

END_DEF end the declaration of the dispatch table.

Additionally there are two more macros to simplify the declaration of the signal handler:

SIGHANDLER(handler) this declares the function prototype for the handler function.

SIGHANDLERNAKED(handler) same as SIGHANDLER() but declares a naked function.

An example of using the macros above is shown below:

#include <pic18fregs.h>

#include <signal.h>

DEF_INTHIGH(high_int)

DEF_HANDLER(SIG_TMR0, _tmr0_handler)

DEF_HANDLER(SIG_BCOL, _bcol_handler)

END_DEF

59

4.6. THE PIC16 PORT CHAPTER 4. NOTES ON SUPPORTED PROCESSORS

SIGHANDLER(_tmr0_handler)

{

/* action to be taken when timer 0 overflows */

}

SIGHANDLERNAKED(_bcol_handler)

{

_asm

/* action to be taken when bus collision occurs */

} retfie

_endasm;

NOTES: Special care should be taken when using the above scheme:

• do not place a colon (;) at the end of the DEF_* and END_DEF macros.

• when declaring SIGHANDLERNAKED handler never forget to use retfie for proper returning.

4.6.16

PIC16 Port – Tips

Here you can find some general tips for compiling programs with SDCC/pic16.

4.6.16.1

Stack size

The default stack size (that is 64 bytes) probably is enough for many programs. One must take care that when there are many levels of function nesting, or there is excessive usage of stack, its size should be extended. An example of such a case is the printf/sprintf family of functions. If you encounter problems like not being able to print integers, then you need to set the stack size around the maximum (256 for small stack model). The following diagram shows what happens when calling printf to print an integer: printf () --> ltoa () --> ultoa () --> divschar ()

It is should be understood that stack is easily consumed when calling complicated functions. Using command line arguments like --fommit-frame-pointer might reduce stack usage by not creating unnecessery stack frames. Other ways to reduce stack usage may exist.

60

Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement

Table of contents