/** * @file avr/lock.h * * @brief Lock Bits API * \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 header file, which in turn * automatically includes the individual I/O header file and the * 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 * * 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 * * LOCKBITS = (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4); * * int main(void) * { * return 0; * } * \endcode * * Or: * * \code * #include * * 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 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=device 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 . * * 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 * \endcode */ /* * 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. */ #ifndef _AVR_LOCK_H_ #define _AVR_LOCK_H_ 1 /** * @defgroup avr_lock Lockbit Support * * @ingroup avr */ /**@{*/ #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_ */