Chapter 6: Under The Hood - Programming 16-bit

advertisement
Chapter 6
Under the Hood
Checklist
The following tools will be used in this lesson:


MPLAB X, Integrated Development Environment
(v1.8 or later, free)
MPLAB XC16, C compiler (v1.11 or later, free)
The following pieces of documentation will be used during this
lesson:

PIC24FJ128GA010 Datasheet –DS39747 (latest rev.)
Make sure they are available and/or installed and ready to use on
your computer.
You can download them from Microchip web site at:
http://www.microchip.com/mplabx
And
http://www.microchip.com/xc16
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Characters and Strings

The declaration of a variable containing a single
character:
char c;


An 8-bit integer (character), that is treated as a signed
value (-128..+127) by default.
We can declare and initialize it with a numerical value:
char c = 0x41;

Or, we can declare and initialize it with an ASCII value:
char c = ’a’;



Note: use single quotes for ASCII character constants
Note: characters are numbers!
We can declare and initialize a string as an array of 8-bit
integers (characters):
char s[5] = { ’H’, ’E’, ’L’, ’L’, ’O’};
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Strings Proper

For short use:
char s[5] = "HELLO";

Or let the C compiler determine the number
of characters required to store the string:
char s[] = "HELLO";
Note: This automatically adds a termination
character (zero).
 The example above is, in truth, equivalent to
the following declaration:

char s[6] = { ’H’, ’E’, ’L’, ’L’, ’O’, ’\0’ };
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Assigning a value to a char

Assigning a value to a char (8-bit integer)
variable and performing arithmetic upon it is
no different to performing the same operation
on any integer type:
char c;
c = ’a’;
table
c++;
// declare c as an 8-bit signed integer
// assign value ’a’ from the ASCII
// increment, c == ’b’ now!
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Assigning a value to a String
char s[15];

// declare s as an array of 15 char
A string can be initialized during definition
but cannot be assigned a value at run time
using the same notation:
s = ”Hello!”; // Error! This does not work!
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Using string.h
By including the string.h, gain access to
numerous useful functions to:
 copy the content of a string into another...

strcpy( s, "HELLO");

// s : "HELLO"
append (or concatenate) two strings...
strcat( s, " WORLD"); // s : "HELLO WORLD"

determine the length of a string...
i = strlen( s);

// i : 11
and many more …
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Memory Space Allocation

Every time a string variable is declared and initialized
as in:
char s[] = "Flying with the PIC24";

1.
2.
3.
Three things happen:
The MPLAB XC linker reserves a contiguous set of
(22) memory locations in RAM (data space).
This space is part of the ndata (near) data section
The MPLAB XC linker stores the initialization value
in a 22 byte long table (in program memory). This
space is part of the init code section.
The MPLAB XC compiler creates a small routine
that will be called before the main program (part of
the crt0 code) to copy the values, thereby initializing
the variable.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Constant Strings

If a string is not supposed to be manipulated
during the program, but is only used “as is”,
consider declaring the string as a constant. This
will save RAM space and initialization code/time:
const char s[] = ”Flying with the PIC24”;


The XC linker will only allocate space in program
memory, in the const code section, (it will be
accessible via the Program Space Visibility
window)
The string will be treated by the XC compiler as a
direct pointer into program memory and, as a
consequence, there will be no RAM space used.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Program Space Visibility
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Notes for the PIC MCU Experts



Notice that the PIC24 uses a 24-bit wide program
memory bus, but operates only on a 16-bit wide data
bus.
The PSV connects only the lower 16-bits of the
program memory bus to the data memory bus. The
upper portion (8-bit) of each program memory word
is not accessible using the PSV window.
However, when using the table access instructions,
all parts of the program memory word become
accessible, but at the cost of having to differentiate
the manipulation of data in RAM (using direct
addressing) from the manipulation of data in
program memory (using the special table access
instructions).
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Notes for PIC Experts

Since the PIC24 program memory is
implemented using single supply Flash
technology:



it is possible to design boot-loaders which are applications
that automatically update part or all of their own code.
It is also possible to utilize sections of the Flash program
memory as a Non Volatile Memory storage area,
To write to the Flash program memory:



Memory can only be written in complete rows
(64 words at a time)
Must be first erased in blocks of 8 rows (512 words) each.
NOTE: This can make frequent updates impractical if
single words or, as is more usual, small data structures are
being managed.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Notes for the PIC MCU Experts


The PIC24 programmer can therefore choose
between the more convenient, but relatively memory
inefficient, method for transferring data between the
two buses of the PSV, or the more memory efficient,
but less transparent, solution offered by the table
access instructions.
The designers of the MPLAB XC compiler considered
the trade offs and chose to use both mechanisms
albeit using them to solve different problems at
different times:


The PSV is used to manage constant arrays (numeric and
strings) so that a single type of pointer (to the data memory bus)
can be used uniformly for constants and variables.
The table access mechanism is used to perform the variable
initializations (limited to the crt0 segment) for maximum
compactness and efficiency.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Investigating Memory Allocation
/*
** Strings
*/
#include <config.h>
#include <string.h>
// 1. variable declarations
const char a[] = "Learn to fly with the PIC24";
char b[100] = ””;
// 2. main program
main()
{
strcpy( b, "MPLAB C compiler"); // assign new content to b
} //main
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Watches
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Before and After strcpy()
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Looking at the .map
section
------.text
.const
.dinit
.text
.isr
address length (PC units) length (bytes) (dec)
------- ----------------- -------------------0x200
0x90
0xd8 (216)
0x290
0x38
0x54 (84)
0x2c8
0x4c
0x72 (114)
0x314
0x16
0x21 (33)
0x32a
0x2
0x3 (3)
Total program memory used (bytes):
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
0x1c2 (450) <1%
Sections of the .map





Most section names are pretty intuitive, other are
historical:
.text section - is where all the code generated
by the MPLAB XC compiler from your source
files will be placed
.const section - is where the constants (integers
and strings) will be placed for access via the
PSV
.dinit section - is where RAM variable's
initialization data (used by the crt0 code) will be
found
.isr - is where the Interrupt Service Routine (in
this case a default one) will be found
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Embedded Memory Editor
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Data Memory Usage Section
section
address
alignment gaps
-------------------------.icd
0x800
0x50
.ndata
0x850
0
Total data memory used (bytes):
a small area of 80 bytes reserved for the
In Circuit Debugger use starting at address
0x800, the first location available in the PIC24
RAM.
.ndata, containing only one variable: b for
which 100 bytes are reserved immediately
following .icd
 .icd,

total length (dec)
------------------0x50 (80)
0x64 (100)
0xb4 (180) 2%
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Pointers

Sequential access to an array of integers:
int *pi;
int
i;
int a[10];
// define a pointer to an integer
// index/counter
// an array of integers
// 1. sequential access using array indexing
for( i=0; i<10; i++)
a[ i] = i;
// 2. sequential access using a pointer
pi = a;
for( i=0; i<10; i++)
{
*pi = i;
pi++;
}
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Pointer (cont)

The previous code is more often reduced to
the following:
// 2. sequential access to array using pointers
for( i=0, pi=a; i<10; i++)
*pi++ = i;

Note: an “empty” pointer,, is assigned a
special value NULL, which is implementation
specific and defined in stddef.h.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
The Heap
The heap is an area of data memory reserved
for dynamic use
 The standard C library stdlib.h , provide the
tools to allocate and free the memory blocks.


void *malloc(size_t size);


Takes a block of memory of requested size from
the heap, and returns a pointer to it.
void free(void *ptr);

Returns the block of memory pointed to by ptr to
the heap.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
PIC24 NEAR and FAR space



The PIC24 architecture allows for a very efficient
(compact) instruction encoding for all operations
performed on data memory within the first 8k
byte of addressing space. This is referred to as
the “near” memory.
Access to memory beyond the 8k byte limit,
“far”, requires the use of indirect addressing
methods (pointers).
The stack (and with it all the local variables used
by C functions) and the heap (used for dynamic
memory allocation) are naturally accessed via
pointers and are correspondingly ideal
candidates to be placed in the far RAM space.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
MPLAB XC Data Memory Models

Small Data Model:


Large Data model:



The linker will attempt to place all the global variables defined in a
project in the near memory space for maximum efficiency. If a
variable cannot be placed within the near memory space it has to be
“manually” declared with a far attribute, so that the compiler will
generate the appropriate access code.
Each variable is assumed to be far unless the near attribute is
manually specified.
In practice, while using the PIC24FJ128GA010, you will
use almost uniquely the default Small Memory Model and
in rare occasions you will find it necessary to identify a
variable with the far attribute.
Since access to elements of an array (explicitly via
pointers or by indexing) is performed via indirect
addressing anyway, there is typically no performance or
code size penalty in declaring an array far.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
MPLAB XC Program Memory Models
Similarly the PIC24 architecture allows for
maximum efficiency when functions are
called within a +/-32K byte (near) range.
 Small Program model:



MPLAB XC attempts to place all functions compiled in
a module within the near range (+/-32K).
Large Program model:

All functions are considered as far unless manually
specified otherwise
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Notes for C Experts



The const attribute is normally used in C language
together with most other variable types only to assist
the compiler in catching common parameters usage
errors.
When a parameter is passed to a function as a const
or a variable is declared as a const, the compiler can
in fact help flag any following attempt to modify it.
The MPLAB XC extends the const semantic in a very
natural way by ensuring that the variable is placed in
Flash memory space.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Notes for the Assembly Experts


The string.h library contains many useful block
manipulation functions that can be useful, via the
use of pointers, to perform operations on any type of
data array, not just strings, like memcpy(),
memcmp(), memset() and memmove().
The ctype.h library, on the other hand, contains
functions that help discriminate individual characters
according to their position in the ASCII table, to
discriminate lower case from upper case, and or
convert between the two cases.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Tips and Tricks

Copying zero terminated strings can be dangerous:
void mycpy( char *dest, char * src)
{
while( *dest++ = *src++);
}

Problems:
There
is no limit to how many characters could be copied.
There is no check as to whether the dest pointer is pointing to a buffer that is large enough
What would happen should the src string be missing the termination character?
It would be very easy for this code to continue beyond the allocated variable spaces and to corrupt the
entire contents of the data RAM including the all precious SFRs.

To Do:
Try
at least to verify that pointers passed to your functions have been initialized before use.
Compare them with the NULL value (declared in stdlib.h and/or stddef.h) to catch the error.
Add a limit to the number of bytes to be copied.
If you don’t know the size of the strings/arrays used, use the sizeof() operator.

A better implementation of mycpy() could be the following:
void mycpy( char *dest, char *src, int max)
{
if ((dest != NULL) && ( src != NULL))
while (( max-- > 0) && ( *src))
*dest++ = *src++;
}
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Suggested Excercises
1.
2.
3.
Search for a string in an array of strings
sequentially
Implement a Binary search
Develop a simple Hash Table management library
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Recommended Readings

Wirth, N. (1976), Algorithms + Data Structures =
Programs, Prentice-Hall, Englewood Cliffs, NJ.

With un-paralleled simplicity Wirth (the father of the Pascal
programming language) takes you from the basics of
programming all the way up to writing your own compiler.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Online Resources

http://en.wikipedia.org/wiki/Pointers#Support_in_vari
ous_programming_languages
Learn more about pointers and see how they are
managed in various programming languages.
Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)
Download