| /* Copyright (c) 2007, Atmel Corporation |
| All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in |
| the documentation and/or other materials provided with the |
| distribution. |
| |
| * Neither the name of the copyright holders nor the names of |
| contributors may be used to endorse or promote products derived |
| from this software without specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. */ |
| |
| /* $Id: lock.h 1692 2008-04-29 18:07:36Z arcanum $ */ |
| |
| /* avr/lock.h - Lock Bits API */ |
| |
| #ifndef _AVR_LOCK_H_ |
| #define _AVR_LOCK_H_ 1 |
| |
| |
| /** \file */ |
| /** \defgroup avr_lock <avr/lock.h>: Lockbit Support |
| |
| \par Introduction |
| |
| The Lockbit API allows a user to specify the lockbit settings for the |
| specific AVR device they are compiling for. These lockbit settings will be |
| placed in a special section in the ELF output file, after linking. |
| |
| Programming tools can take advantage of the lockbit information embedded in |
| the ELF file, by extracting this information and determining if the lockbits |
| need to be programmed after programming the Flash and EEPROM memories. |
| This also allows a single ELF file to contain all the |
| information needed to program an AVR. |
| |
| To use the Lockbit API, include the <avr/io.h> header file, which in turn |
| automatically includes the individual I/O header file and the <avr/lock.h> |
| file. These other two files provides everything necessary to set the AVR |
| lockbits. |
| |
| \par Lockbit API |
| |
| Each I/O header file may define up to 3 macros that controls what kinds |
| of lockbits are available to the user. |
| |
| If __LOCK_BITS_EXIST is defined, then two lock bits are available to the |
| user and 3 mode settings are defined for these two bits. |
| |
| If __BOOT_LOCK_BITS_0_EXIST is defined, then the two BLB0 lock bits are |
| available to the user and 4 mode settings are defined for these two bits. |
| |
| If __BOOT_LOCK_BITS_1_EXIST is defined, then the two BLB1 lock bits are |
| available to the user and 4 mode settings are defined for these two bits. |
| |
| If __BOOT_LOCK_APPLICATION_TABLE_BITS_EXIST is defined then two lock bits |
| are available to set the locking mode for the Application Table Section |
| (which is used in the XMEGA family). |
| |
| If __BOOT_LOCK_APPLICATION_BITS_EXIST is defined then two lock bits are |
| available to set the locking mode for the Application Section (which is used |
| in the XMEGA family). |
| |
| If __BOOT_LOCK_BOOT_BITS_EXIST is defined then two lock bits are available |
| to set the locking mode for the Boot Loader Section (which is used in the |
| XMEGA family). |
| |
| The AVR lockbit modes have inverted values, logical 1 for an unprogrammed |
| (disabled) bit and logical 0 for a programmed (enabled) bit. The defined |
| macros for each individual lock bit represent this in their definition by a |
| bit-wise inversion of a mask. For example, the LB_MODE_3 macro is defined |
| as: |
| \code |
| #define LB_MODE_3 (0xFC) |
| ` \endcode |
| |
| To combine the lockbit mode macros together to represent a whole byte, |
| use the bitwise AND operator, like so: |
| \code |
| (LB_MODE_3 & BLB0_MODE_2) |
| \endcode |
| |
| <avr/lock.h> also defines a macro that provides a default lockbit value: |
| LOCKBITS_DEFAULT which is defined to be 0xFF. |
| |
| See the AVR device specific datasheet for more details about these |
| lock bits and the available mode settings. |
| |
| A convenience macro, LOCKMEM, is defined as a GCC attribute for a |
| custom-named section of ".lock". |
| |
| A convenience macro, LOCKBITS, is defined that declares a variable, __lock, |
| of type unsigned char with the attribute defined by LOCKMEM. This variable |
| allows the end user to easily set the lockbit data. |
| |
| \note If a device-specific I/O header file has previously defined LOCKMEM, |
| then LOCKMEM is not redefined. If a device-specific I/O header file has |
| previously defined LOCKBITS, then LOCKBITS is not redefined. LOCKBITS is |
| currently known to be defined in the I/O header files for the XMEGA devices. |
| |
| \par API Usage Example |
| |
| Putting all of this together is easy: |
| |
| \code |
| #include <avr/io.h> |
| |
| LOCKBITS = (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4); |
| |
| int main(void) |
| { |
| return 0; |
| } |
| \endcode |
| |
| Or: |
| |
| \code |
| #include <avr/io.h> |
| |
| unsigned char __lock __attribute__((section (".lock"))) = |
| (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4); |
| |
| int main(void) |
| { |
| return 0; |
| } |
| \endcode |
| |
| |
| |
| However there are a number of caveats that you need to be aware of to |
| use this API properly. |
| |
| Be sure to include <avr/io.h> to get all of the definitions for the API. |
| The LOCKBITS macro defines a global variable to store the lockbit data. This |
| variable is assigned to its own linker section. Assign the desired lockbit |
| values immediately in the variable initialization. |
| |
| The .lock section in the ELF file will get its values from the initial |
| variable assignment ONLY. This means that you can NOT assign values to |
| this variable in functions and the new values will not be put into the |
| ELF .lock section. |
| |
| The global variable is declared in the LOCKBITS macro has two leading |
| underscores, which means that it is reserved for the "implementation", |
| meaning the library, so it will not conflict with a user-named variable. |
| |
| You must initialize the lockbit variable to some meaningful value, even |
| if it is the default value. This is because the lockbits default to a |
| logical 1, meaning unprogrammed. Normal uninitialized data defaults to all |
| locgial zeros. So it is vital that all lockbits are initialized, even with |
| default data. If they are not, then the lockbits may not programmed to the |
| desired settings and can possibly put your device into an unrecoverable |
| state. |
| |
| Be sure to have the -mmcu=<em>device</em> flag in your compile command line and |
| your linker command line to have the correct device selected and to have |
| the correct I/O header file included when you include <avr/io.h>. |
| |
| You can print out the contents of the .lock section in the ELF file by |
| using this command line: |
| \code |
| avr-objdump -s -j .lock <ELF file> |
| \endcode |
| |
| */ |
| |
| |
| #ifndef __ASSEMBLER__ |
| |
| #ifndef LOCKMEM |
| #define LOCKMEM __attribute__((section (".lock"))) |
| #endif |
| |
| #ifndef LOCKBITS |
| #define LOCKBITS unsigned char __lock LOCKMEM |
| #endif |
| |
| #endif /* !__ASSEMBLER */ |
| |
| |
| /* Lock Bit Modes */ |
| #if defined(__LOCK_BITS_EXIST) |
| #define LB_MODE_1 (0xFF) |
| #define LB_MODE_2 (0xFE) |
| #define LB_MODE_3 (0xFC) |
| #endif |
| |
| #if defined(__BOOT_LOCK_BITS_0_EXIST) |
| #define BLB0_MODE_1 (0xFF) |
| #define BLB0_MODE_2 (0xFB) |
| #define BLB0_MODE_3 (0xF3) |
| #define BLB0_MODE_4 (0xF7) |
| #endif |
| |
| #if defined(__BOOT_LOCK_BITS_1_EXIST) |
| #define BLB1_MODE_1 (0xFF) |
| #define BLB1_MODE_2 (0xEF) |
| #define BLB1_MODE_3 (0xCF) |
| #define BLB1_MODE_4 (0xDF) |
| #endif |
| |
| #if defined(__BOOT_LOCK_APPLICATION_TABLE_BITS_EXIST) |
| #define BLBAT0 ~_BV(2) |
| #define BLBAT1 ~_BV(3) |
| #endif |
| |
| #if defined(__BOOT_LOCK_APPLICATION_BITS_EXIST) |
| #define BLBA0 ~_BV(4) |
| #define BLBA1 ~_BV(5) |
| #endif |
| |
| #if defined(__BOOT_LOCK_BOOT_BITS_EXIST) |
| #define BLBB0 ~_BV(6) |
| #define BLBB1 ~_BV(7) |
| #endif |
| |
| |
| #define LOCKBITS_DEFAULT (0xFF) |
| |
| #endif /* _AVR_LOCK_H_ */ |