avr_lock(3avr)

πŸ’… avr_lock β€” welcome to the lockbit support party bestie

okay so this is avr_lock(3avr), and it's literally the whole <avr/lock.h> situation β€” Lockbit Support, no cap. grab a strawberry πŸ“ and let's get into it.


✨ NAME ✨

avr_lock β€” <avr/lock.h>: Lockbit Support

✨ SYNOPSIS ✨

Detailed Description

🌸 Introduction 🌸

so the Lockbit API is the thing that lets you, the user, tell AVR exactly what lockbit settings you want for the specific AVR device you're compiling for. those settings get tucked into a special little section in the ELF output file, and this happens after linking, just so we're clear.

now the programming tools can be absolute besties about this: they take that lockbit info embedded in the ELF file, extract it, and figure out whether the lockbits still need to be programmed after the Flash and EEPROM memories get programmed. the glow-up here is that a single ELF file can carry literally all the info you need to program an AVR. one file, everything, iconic. πŸ‘‘

to actually use the Lockbit API you include <avr/io.h>, which β€” plot twist β€” automatically includes the individual I/O header file and the <avr/lock.h> file. those other two files are the ones serving up everything necessary to set the AVR lockbits. πŸ’–

πŸ” Lockbit API πŸ”

each I/O header file may define up to 3 macros that control what kinds of lockbits are available to you. here's the lineup:

  • if __LOCK_BITS_EXIST is defined, then two lock bits are available to you 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 you 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 you 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 (this one 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 (also 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 (XMEGA family again 🫢).

now here's the spicy part β€” AVR lockbit modes have inverted values. logical 1 = an unprogrammed (disabled) bit, logical 0 = a programmed (enabled) bit. the macros defined for each individual lock bit show this off by doing a bit-wise inversion of a mask in their definition. for example, the LB_MODE_3 macro is defined as:

#define LB_MODE_3  (0xFC)

to combine lockbit mode macros together so they represent a whole byte, you use the bitwise AND operator, like so:

(LB_MODE_3 & BLB0_MODE_2)

<avr/lock.h> also defines a macro that gives you a default lockbit value: LOCKBITS_DEFAULT, which is defined to be 0xFF.

and bestie, go read the AVR device specific datasheet for more deets 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".

another convenience macro, LOCKBITS, is defined that declares a variable, __lock, of type unsigned char with the attribute defined by LOCKMEM. this variable is the whole point β€” it lets you set the lockbit data super easily. 🌈

πŸ“Œ 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. iykyk.

🧚 API Usage Example 🧚

putting all of this together is easy, fr fr:

#include <avr/io.h>

LOCKBITS = (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4);

int main(void)
{
    return 0;
}

or, if you're feeling extra:

#include <avr/io.h>

unsigned char __lock __attribute__((section (".lock"))) =
    (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4);

int main(void)
{
    return 0;
}

however 😭 there are a number of caveats you genuinely need to be aware of to use this API properly, so buckle up:

  • 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 you can NOT assign values to this variable in functions and expect the new values to be put into the ELF .lock section. it just won't happen, periodt. πŸ’€
  • the global variable declared in the LOCKBITS macro has two leading underscores, which means it's reserved for the "implementation" β€” meaning the library β€” so it will not conflict with a user-named variable. she's built different.
  • you must initialize the lockbit variable to some meaningful value, even if that value is the default one. this is because the lockbits default to a logical 1, meaning unprogrammed. normal uninitialized data defaults to all logical 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. 🚨 not a vibe. do not skip this.
  • be sure to have the -mmcu=device flag in your compile command line and your linker command line, so you have the correct device selected and the correct I/O header file included when you include <avr/io.h>. both lines, no skipping. ✨
  • you can print out the contents of the .lock section in the ELF file by using this command line:
avr-objdump -s -j .lock <ELF file>

πŸ’œ Author πŸ’œ

Generated automatically by Doxygen for AVR-LibC from the source code.


and that's the whole page, bestie! πŸŽ€ this little beauty came from AVR-LibC, Version 2.2.1, and yeah, it's avr_lock(3avr) β€” go forth and initialize your lockbits, i'm obsessed with you. πŸ’–πŸ‘‘πŸ¦‹

πŸ“¦ where this page comes from