~ubuntu-branches/ubuntu/raring/avr-libc/raring-proposed

« back to all changes in this revision

Viewing changes to doc/api/pgmspace.dox

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-08-10 09:59:16 UTC
  • mfrom: (1.2.1 upstream) (8 intrepid)
  • mto: (4.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20080810095916-7ku06pjsfia3hz16
Added build-depends on texlive-extra-utils (closes: #493454)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2007  Eric B. Weddington
 
2
   All rights reserved.
 
3
 
 
4
   Redistribution and use in source and binary forms, with or without
 
5
   modification, are permitted provided that the following conditions are met:
 
6
 
 
7
   * Redistributions of source code must retain the above copyright
 
8
     notice, this list of conditions and the following disclaimer.
 
9
   * Redistributions in binary form must reproduce the above copyright
 
10
     notice, this list of conditions and the following disclaimer in
 
11
     the documentation and/or other materials provided with the
 
12
     distribution.
 
13
   * Neither the name of the copyright holders nor the names of
 
14
     contributors may be used to endorse or promote products derived
 
15
     from this software without specific prior written permission.
 
16
 
 
17
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
18
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
21
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
27
  POSSIBILITY OF SUCH DAMAGE. */
 
28
 
 
29
/* $Id: pgmspace.dox,v 1.3 2007/10/02 13:48:37 arcanum Exp $ */
 
30
 
 
31
/** 
 
32
 
 
33
\page pgmspace Data in Program Space
 
34
 
 
35
\section pgmspace_introduction Introduction
 
36
 
 
37
So you have some constant data and you're running out of room to store it?
 
38
Many AVRs have limited amount of RAM in which to store data, but may have
 
39
more Flash space available. The AVR is a Harvard architecture processor,
 
40
where Flash is used for the program, RAM is used for data, and they each
 
41
have separate address spaces. It is a challenge to get constant data to be
 
42
stored in the Program Space, and to retrieve that data to use it in the
 
43
AVR application.
 
44
 
 
45
The problem is exacerbated by the fact that the C Language was not designed
 
46
for Harvard architectures, it was designed for Von Neumann architectures where
 
47
code and data exist in the same address space. This means that any compiler
 
48
for a Harvard architecture processor, like the AVR, has to use other means to 
 
49
operate with separate address spaces.
 
50
 
 
51
Some compilers use non-standard C language keywords, or they extend the standard
 
52
syntax in ways that are non-standard. The AVR toolset takes a different 
 
53
approach. 
 
54
 
 
55
GCC has a special keyword, \c __attribute__ that is used to attach
 
56
different attributes to things such as function declarations, variables, and
 
57
types. This keyword is followed by an attribute specification in double
 
58
parentheses. In AVR GCC, there is a special attribute called \c progmem. This
 
59
attribute is use on data declarations, and tells the compiler to place
 
60
the data in the Program Memory (Flash).
 
61
 
 
62
AVR-Libc provides a simple macro \c PROGMEM that is defined as the attribute
 
63
syntax of GCC with the \c progmem attribute. This macro was created as a
 
64
convenience to the end user, as we will see below. The \c PROGMEM macro is
 
65
defined in the \c <avr/pgmspace.h> system header file.
 
66
 
 
67
It is difficult to modify GCC to create new extensions to the C language syntax, 
 
68
so instead, avr-libc has created macros to retrieve the data from the Program
 
69
Space. These macros are also found in the \c <avr/pgmspace.h> system header 
 
70
file.
 
71
 
 
72
 
 
73
\section pgmspace_const A Note On const
 
74
 
 
75
Many users bring up the idea of using C's keyword \c const as a means of
 
76
declaring data to be in Program Space. Doing this would be an abuse of
 
77
the intended meaning of the \c const keyword.
 
78
 
 
79
\c const is used to tell the compiler that the data is to be "read-only". It
 
80
is used to help make it easier for the compiler to make certain transformations,
 
81
or to help the compiler check for incorrect usage of those variables.
 
82
 
 
83
For example, the const keyword is commonly used in many functions as a modifier 
 
84
on the parameter type. This tells the compiler that the function will only use 
 
85
the parameter as read-only and will not modify the contents of the parameter 
 
86
variable.
 
87
 
 
88
\c const was intended for uses such as this, not as a means to identify where 
 
89
the data should be stored. If it were used as a means to define data storage, 
 
90
then it loses its correct meaning (changes its semantics) in other situations 
 
91
such as in the function parameter example.
 
92
 
 
93
 
 
94
\section pgmspace_data Storing and Retrieving Data in the Program Space
 
95
 
 
96
 
 
97
Let's say you have some global data:
 
98
 
 
99
\code
 
100
unsigned char mydata[11][10] =
 
101
{
 
102
        {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09},
 
103
        {0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13},
 
104
        {0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D},
 
105
        {0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27},
 
106
        {0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31},
 
107
        {0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B},
 
108
        {0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45},
 
109
        {0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F},
 
110
        {0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59},
 
111
        {0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63},
 
112
        {0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D}
 
113
};
 
114
\endcode
 
115
 
 
116
and later in your code you access this data in a function and store a single
 
117
byte into a variable like so:
 
118
 
 
119
\code
 
120
byte = mydata[i][j];
 
121
\endcode
 
122
 
 
123
Now you want to store your data in Program Memory. Use the \c PROGMEM macro 
 
124
found in \c <avr/pgmspace.h> and put it after the declaration of the variable, 
 
125
but before the initializer, like so:
 
126
 
 
127
\code
 
128
#include <avr/pgmspace.h>
 
129
.
 
130
.
 
131
.
 
132
unsigned char mydata[11][10] PROGMEM =
 
133
{
 
134
        {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09},
 
135
        {0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13},
 
136
        {0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D},
 
137
        {0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27},
 
138
        {0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31},
 
139
        {0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B},
 
140
        {0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45},
 
141
        {0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F},
 
142
        {0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59},
 
143
        {0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63},
 
144
        {0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D}
 
145
};
 
146
\endcode
 
147
 
 
148
That's it! Now your data is in the Program Space. You can compile, link, and 
 
149
check the map file to verify that \c mydata is placed in the correct section.
 
150
 
 
151
Now that your data resides in the Program Space, your code to access (read)
 
152
the data will no longer work. The code that gets generated will retrieve the
 
153
data that is located at the address of the \c mydata array, plus offsets 
 
154
indexed by the \c i and \c j variables. However, the final address that is
 
155
calculated where to the retrieve the data points to the Data Space! Not the
 
156
Program Space where the data is actually located. It is likely that you will 
 
157
be retrieving some garbage. The problem is that AVR GCC does not intrinsically
 
158
know that the data resides in the Program Space.
 
159
 
 
160
The solution is fairly simple. The "rule of thumb" for accessing data stored
 
161
in the Program Space is to access the data as you normally would (as if the
 
162
variable is stored in Data Space), like so:
 
163
 
 
164
\code
 
165
byte = mydata[i][j];
 
166
\endcode
 
167
 
 
168
then take the address of the data:
 
169
 
 
170
\code
 
171
byte = &(mydata[i][j]);
 
172
\endcode
 
173
 
 
174
then use the appropriate \c pgm_read_* macro, and the address of your data
 
175
becomes the parameter to that macro:
 
176
 
 
177
\code
 
178
byte = pgm_read_byte(&(mydata[i][j]));
 
179
\endcode
 
180
 
 
181
The \c pgm_read_* macros take an address that points to the Program Space, and
 
182
retrieves the data that is stored at that address. This is why you take the 
 
183
address of the offset into the array. This address becomes the parameter to the 
 
184
macro so it can generate the correct code to retrieve the data from the Program
 
185
Space. There are different \c pgm_read_* macros to read different sizes of data 
 
186
at the address given. 
 
187
 
 
188
 
 
189
\section pgmspace_strings Storing and Retrieving Strings in the Program Space
 
190
 
 
191
Now that you can successfully store and retrieve simple data from Program Space
 
192
you want to store and retrive strings from Program Space. And specifically
 
193
you want to store and array of strings to Program Space. So you start off
 
194
with your array, like so:
 
195
 
 
196
\code
 
197
char *string_table[] = 
 
198
{
 
199
    "String 1",
 
200
    "String 2",
 
201
    "String 3",
 
202
    "String 4",
 
203
    "String 5"
 
204
};
 
205
\endcode
 
206
 
 
207
and then you add your PROGMEM macro to the end of the declaration:
 
208
 
 
209
\code
 
210
char *string_table[] PROGMEM = 
 
211
{
 
212
    "String 1",
 
213
    "String 2",
 
214
    "String 3",
 
215
    "String 4",
 
216
    "String 5"
 
217
};
 
218
\endcode
 
219
 
 
220
Right? WRONG!
 
221
 
 
222
Unfortunately, with GCC attributes, they affect only the declaration that they
 
223
are attached to. So in this case, we successfully put the \c string_table 
 
224
variable, the array itself, in the Program Space. This DOES NOT put the actual
 
225
strings themselves into Program Space. At this point, the strings are still
 
226
in the Data Space, which is probably not what you want.
 
227
 
 
228
In order to put the strings in Program Space, you have to have explicit 
 
229
declarations for each string, and put each string in Program Space:
 
230
 
 
231
\code
 
232
char string_1[] PROGMEM = "String 1";
 
233
char string_2[] PROGMEM = "String 2";
 
234
char string_3[] PROGMEM = "String 3";
 
235
char string_4[] PROGMEM = "String 4";
 
236
char string_5[] PROGMEM = "String 5";
 
237
\endcode
 
238
 
 
239
Then use the new symbols in your table, like so:
 
240
 
 
241
\code
 
242
PGM_P string_table[] PROGMEM = 
 
243
{
 
244
    string_1,
 
245
    string_2,
 
246
    string_3,
 
247
    string_4,
 
248
    string_5
 
249
};
 
250
\endcode
 
251
 
 
252
Now this has the effect of putting \c string_table in Program Space, where
 
253
\c string_table is an array of pointers to characters (strings), where each
 
254
pointer is a pointer to the Program Space, where each string is also stored.
 
255
 
 
256
The \c PGM_P type above is also a macro that defined as a pointer to a 
 
257
character in the Program Space.
 
258
 
 
259
Retrieving the strings are a different matter. You probably don't want to pull
 
260
the string out of Program Space, byte by byte, using the \c pgm_read_byte() 
 
261
macro. There are other functions declared in the <avr/pgmspace.h> header file
 
262
that work with strings that are stored in the Program Space.
 
263
 
 
264
For example if you want to copy the string from Program Space to a buffer in
 
265
RAM (like an automatic variable inside a function, that is allocated on the 
 
266
stack), you can do this:
 
267
 
 
268
\code
 
269
void foo(void)
 
270
{
 
271
    char buffer[10];
 
272
    
 
273
    for (unsigned char i = 0; i < 5; i++)
 
274
    {
 
275
        strcpy_P(buffer, (PGM_P)pgm_read_word(&(string_table[i])));
 
276
        
 
277
        // Display buffer on LCD.
 
278
    }
 
279
    return;
 
280
}
 
281
\endcode
 
282
 
 
283
Here, the \c string_table array is stored in Program Space, so
 
284
we access it normally, as if were stored in Data Space, then take the address
 
285
of the location we want to access, and use the address as a parameter to
 
286
\c pgm_read_word. We use the \c pgm_read_word macro to read the string pointer 
 
287
out of the \c string_table array. Remember that a pointer is 16-bits, or word 
 
288
size. The \c pgm_read_word macro will return a 16-bit unsigned integer. We then
 
289
have to typecast it as a true pointer to program memory, \c PGM_P. This pointer 
 
290
is an address in Program Space pointing to the string that we want to 
 
291
copy. This pointer is then used as a parameter to the function \c strcpy_P. The 
 
292
function \c strcpy_P is just like the regular \c strcpy function, except that 
 
293
it copies a string from Program Space (the second parameter) to a buffer in the 
 
294
Data Space (the first parameter).
 
295
 
 
296
There are many string functions available that work with strings located in
 
297
Program Space. All of these special string functions have a suffix of \c _P in
 
298
the function name, and are declared in the <avr/pgmspace.h> header file.
 
299
 
 
300
 
 
301
\section pgmspace_caveats Caveats
 
302
 
 
303
The macros and functions used to retrieve data from the Program Space have
 
304
to generate some extra code in order to actually load the data from the
 
305
Program Space. This incurs some extra overhead in terms of code space (extra 
 
306
opcodes) and execution time. Usually, both the space and time overhead is 
 
307
minimal compared to the space savings of putting data in Program Space. But you 
 
308
should be aware of this so you can minimize the number of calls within a single 
 
309
function that gets the same piece of data from Program Space. It is always
 
310
instructive to look at the resulting disassembly from the compiler.
 
311
 
 
312
 
 
313
 
 
314
*/