
I present to your attention a new compact
Bootloader for AVR Tiny 45/85 . This autoloader is distributed under the GNU GPL license, as required by the V-USB license. The basis for this autoloader was ATtiny85 USB Boot Loader from Embedded Creations and its descendant micronucleus-t85, used by Digispark boards.
Like the aforementioned, TinyHID Loader is based on the V-USB library.
Key features:
- Works under ATtiny45 and ATtiny85
- Compact (2kb with basic functions)
- Expanding (there are a number of additional functions, the inclusion of which will increase the size)
- No need for drivers (which is especially important for newer versions of Windows)
- Does not work with AVRdude, uses cross-platform C # API instead.
- Able to update himself
Why AVR Tiny 85?
The economy should be economical, gentlemen. And with AVR Tiny x5, you save twice and even in two questions. The first is the question of price: "Tinky" is cheaper than "Meg." But personally, the Tiny x5 has a PLL generator, which also allows you to drop the quartz resonator. So we save on it and on two capacitors. In addition, there is also the issue of space on the board. In the QNF body cockroach size 2.5 by 2.5 mm. And again, we do not need a resonator. The whole scheme can easily fit on a ridiculous 12x5 mm. As a summary, the use of AVR Tiny 85 is always appropriate, and especially for USB devices until you need functionality that this cockroach does not support (for example, when many IO ports are needed)
Why special autoloader?
AVR Mega autoloaders are a dime a dozen, but with the Tiny 85 it's not that easy. To understand these difficulties, I present the algorithm of the classics:
')
- If the configuration bit BOOTRST is set to 0, then after restarting the controller starts execution not from the zero address, but from the Boot Reset Address (specific to different models and can be configured).
- According to the Boot Reset Address, the autoloader itself is located, which first of all moves the interrupt table to the Boot Reset Address.
- The autoloader determines whether it needs to boot itself or not. If necessary, it runs as a regular firmware, although it is not located in the zero address.
- If you do not need to load the autoloader, it will move the interrupt table back to the zero address, and transfer control there, thereby loading the application firmware.
- While writing data to Flash, the autoloader continues to work with the USB protocol, responding to host requests.
- Also, the autoloader's memory area is not writable, which prevents the autoloader from damaging itself.
And now the nuances of the 85th Tiny:
- ATtiny is always loaded from the zero address, it cannot be configured to another address.
- Interrupt vectors are also not transferred anywhere.
- During recording, the controller pauses for 4.5 ms and cannot respond to anything.
- Well, the autoloader has no hardware protection against self-recording either.
And workarounds.
- The cleared memory is filled with units that are interpreted by the controller as NOP. This means that after a reset, control will reach the autoloader. Though before this, one and a half thousand NOPs will be performed.
- But for the functioning of the USB protocol, this is still not enough. You also need a response to the PCINT0 interrupt. The interrupt vector table cannot be moved, but the autoloader addresses can be written to this table. Therefore, immediately after the first boot, the autoloader writes down the address vectors of its handlers to RESET and PCINT0.
- While writing the application firmware, the autoloader also replaces the RESET and PCINT0 vectors.
- The initial RESET and PCINT application firmware autoloader writes to addresses directly in front of the autoloader.
- Completion of the V-USB PCINT0 handler so that it can call the PCINT0 application firmware handler. The condition for the autoloader handler to work is TCCR1 == 0 && TCNT1 == 0xff. Otherwise, run the application handler.
- Delay before recording or purging memory. At this time, the controller manages to inform the host of the success of the operation, and the host does not lose it.
- After performing a clear memory operation, the autoloader always records its RESET and PCINT0 vectors.
- Before writing the application firmware, the autoloader clears the FLASH from end to beginning. This cleaning direction ensures that even if the cleaning / writing process is interrupted by an unexpected power outage, the autoloader will remain in working condition. Either the first page of FLASH is not yet erased / already written down, and the control to the autoloader will go over the vector. Either the entire memory is cleared, and the control will pass to the autoloader through a chain of NOPs.
- A software check is performed on the write to the autoloader instead of the hardware one.
For more information about the features of the autoloader on AVR Tiny 85, you can read on the
Embedded Creations website in English
Why reinvent the wheel?
Using classic MEGA autoloaders on AVR tiny is not possible for the reasons described in the previous chapter. But even without them, there are 2 autoloader implementations: ATtiny85 USB Boot Loader and micronucleus-t85, and both emulate the once popular USBasp programmer. And the aforementioned programmer works on the host through the libusb library. This is a wonderful and versatile library, and its use on Mac OS or Linux is as simple as 2x2. And if you are going to use your creations yourself, then TinyHID Loader can only be liked by a more compact size. But under Windows 8.1 x64, installing the libusb driver is no longer a trivial task. Deep-deep in the settings there is an item that allows one-time restart of the computer with disabled driver's electronic signature verification. And woe to those who will explain this method to a typical user. Therefore, the main idea was to create an autoloader capable of working through the HID Feature Report. For all HID devices, standard OS drivers are used, and there is no need to install additional ones. It also turned out that the refusal of avrdude support brings an opportunity to reduce the weight of the loader. When you disable all the options except for writing / cleaning FLASH and software output to the application firmware, the autoloader weighs 2k, which is less than the competition.
How to use?
First you need to configure the firmware. To do this, you need to adjust the firmware / usbloader / usbloader.h file for your scheme and your needs:
// ATtiny, USB D- #define USB_CFG_DMINUS_BIT 2 // ATtiny, USB D+ #define USB_CFG_DPLUS_BIT 1 // ATtiny, // ( , ) // #define LED_PIN 4 // ATtiny, ( ) // ( ) #define START_JUMPER_PIN 0 // 1, EEPROM ( ) #define CAN_ERASE_EEPROM 0 // 1, FLASH ( ) #define CAN_READ_FLASH 0 // 0, ( ) #define CAN_LEAVE_LOADER 1
You do not need to take care that the USB_CFG_DPLUS_BIT gets on INT0 foot, since the autoloader uses the PCINT0 interrupt, which can be configured on any leg.
In the above variant, the bootloader fits into 2kb, albeit back to back. The inclusion of any additional options will bring it beyond these limits, and you will have to change its location in memory at the same time. This is done differently depending on whether you use AtmelStudio or Makefile.
Atmel studio
Make sure the Release configuration is selected.
Open the project properties, go to the Toolchain tab, and in the “AVR / GNU Linker / Memory Settings” section, decrease the value “.text = 0xc00”. You can reduce only portions of 32 words. That is, 0xbe0, 0xbc0, 0xba0. 0xba0 is enough for the operation of all available options, no further reduction is necessary. In addition, you must also reduce the value of the constant BOOTLOADER_WADDRESS. This can be done on the "AVR / GNU C Compiler / Symbols" page. The value must be equal to the value ".text =".
After configuration, you need to compile the project (F7) and you can upload it to the controller with an external programmer.
Makefile
Open the Makefile, and reduce the constant BOOTLOADER_ADDRESS to the desired value. It can be reduced only by portions of 64 bytes (AtmelStudio uses words, and Makefiles use bytes). That is, 17c0, 1780, 1740. 1740 is enough for the operation of all available options, no further reduction is necessary.
After configuration, you need to compile the project by typing make in the command line and you can upload it to the controller with an external programmer.
Done, the external programmer of your circuit is no longer needed, go to the software on the computer.
Software
The utility flooding the firmware on the controller is written in C #, the project was developed in VisualStudio 2012, but it can be opened in Xamarin for further work with MONO. To communicate with HID, the HidSharp cross-platform library is used, which will make your MONO project truly cross-platform.
The download utility is extremely easy to use:
TinyLoaderCmd.exe firmware.hex
And after 3 seconds the cockroach is stitched and ready to go. If the firmware was created with the default configuration, then running the utility will not only flash the controller, but also, when ready, launch the recorded firmware.
In addition, you can use the TinyHID Loader API from your C # project:
void UploadNewFirmware(string file) { HexFile file = new HexFile(args[0]); Loader ldr = Loader.TryGetLoader(40); byte[] programm = new byte[Loader.LOADERSTART]; for (int i = 0; i < programm.Length; i++) programm[i] = 0xff; file.Fill(programm); ldr.WriteFlash(programm, 0); ldr.LeaveBootloader(); }
And if in your firmware add the function of loading the autoloader:
void runBootloader() { cli(); TCCR1 = 0; TCNT1 = 0xff; asm volatile ("rjmp __vectors"); }
That flashing will turn for the user into pressing one button. And your project at that time:
- Tell your firmware to load the autoloader.
- It will wait (Loader.TryGetLoader) for the moment when the system picks up the autoloader.
- Will write a new firmware.
- Tell the autoloader to load the firmware.
- Wait for the moment when the system picks up your new firmware.
And if you needed a different set of options?
Put a full set of options and the new firmware now does not fit? Or do you regret not adding the ability to read memory? Well, or does TinyHID Loader not suit you at all, and life is not sweet without avrdude? But the microcontroller is not only flashed, but also sealed. And I do not want to drink it at all. No question - TinyHID Loader can rewrite itself!
The self-flashing algorithm is as follows:
- From the command line, the user is using TinyLoaderCmd.exe reload bootloader.hex (as an option, no one enters anything, and you implement the process via an API from your software on the host)
- The utility creates a firmware for reloading. It includes the image of the new autoloader, a summary of it (the target address in FLASH and CRC16), as well as a special update utility (reloader).
- The firmware is poured onto the microcontroller in the usual way, like any other firmware.
- The device reboots (maybe programmatically, if this option is not disabled), and the control is transferred to reloader.
- Reloader checks the correctness of the new autoloader by checking the CRC16 and its dimensions and ability to fit on the device.
- If all checks succeed, the reloader clears the first page of memory. From this moment there is no turning back. And if the power is turned off, control will not be transferred to the old bootloader.
- The main step is to copy the new autoloader from the image to real addresses, and also to clean the page directly in front of the autoloader (since all autoloaders use it)
- And in the final - the transition on the vector RESET of the new autoloader - while the autoloader re-initiates the FLASH and starts working
Security guarantees for reloader are the CRC check and the process logic that will start again in the event of an unexpected completion. But incorrect new firmware will turn a cockroach into a brick, and only a programmer can resurrect it. Therefore, be careful - check the correctness of the settings.
Also with the help of reloader, you can flash TinyHID Loader on a device with another programmer. That is to replace any AVR Tiny 85 autoloader with any other.
Special thanks:
- The Atmel V-USB library for Atmel microcontrollers for the ability to work with USB
- ATtiny85 USB Boot Loader by Embedded Creations for describing the details of autoloader creation for AVR Tiny 85
- autoloader micronucleus-t85 for the very idea of ​​reducing the volume.
- BootloaderHID for the idea that the transition to HID only seems expensive in terms of weight. Avoid compatibility with avrdude allows you to win more.
- Rasso German FunkUsb for the idea to change osccal.c to osctune.h, which significantly reduces the weight of the code