Why write your own bootloader?
My first serial bootloader was a UART bootloader for Microchip PIC16 microcontrollers. I named it HyperBootloader_PIC16. I will explain why I chose this name below. Many friends may ask why you should write your own bootloader. If you search on Baidu, you will find many bootloaders that can be used directly after downloading. For example, ds30_Loader is very good, free, and supports many series of Microchip microcontrollers. That's right, but the bootloaders found online are written in C language, which are either unusable or not compiled with XC8 (Microchip's C compiler). Most of them are written in assembly language, including ds30_Loader. For me who don't use assembly language very much, I feel very headache. These bootloaders are also not easy to modify. For example, it is difficult to add a function that I need. So I decided to write a PIC16 serial bootloader in C language. I did it right away. I thought it would be a piece of cake. I didn't expect that writing a stable, easy-to-use and space-saving bootloader is not easy. This is a later story. Before I talk about how to implement your own PIC16 serial bootloader, I will first talk about the basics of serial bootloader. If you don't need to know, please skip this part.
The ABCs of Serial Bootloader
Serial bootloader is a very convenient and low-cost method for burning programs. Generally, every time we burn Microchip microcontrollers, we need to connect the burner PICKit3 or ICD3 to the target board, and then use Microchip IPE or MPLAB X on the computer to directly burn the Hex file to the target board. Using serial bootloader does not require plugging and unplugging the burner, which is very convenient for development engineers. Serial bootloader requires the serial port of the microcontroller, so the microcontroller side needs the following hardware circuit, in which the DB9 serial port is connected to the serial port of the computer.
The serial bootloader is burned into the program memory just like the application program. The serial bootloader and the application program need to be placed separately in the program memory. Therefore, there are generally two ways to place the serial bootloader, one is to place it at the head of the program memory, and the other is to place it at the bottom of the program memory, as shown in the figure below.
Serial bootloader can be burned to the target board using the burner PICkit3 or ICD3, and then the burner is not needed to update the application. The target board and the computer are connected through the serial port. A serial communication program is run on the computer to pass the Hex file of the application to the serial bootloader through the serial port. The serial bootloader then burns the received Hex data to the correct location of the program memory. Next, let's talk about today's protagonist HyperBootloader_PIC16 - the first PIC16 microcontroller C language serial bootloader I wrote by myself.
HyperBootloader_PIC16
HyperBootloader_PIC16 is an imitation of HI-TECH's PICC bootloader. Since I use the XC8 compiler, there are many changes. It is mentioned above that the bootloader is either at the head or at the bottom of the program memory, and HyperBootloader_PIC16 is at the bottom of the program memory. The serial communication program on the computer side that communicates with it is HyperTerminal. This is also the origin of its name.
Main code snippet
HyerBootloader_PIC16 is a serial bootloader written in C language that takes up very little space. Less than 0x200 program word space. The implementation logic is also very simple, the main code segment is as follows.
/* receive a hex file via the serial port and write it to program memory */ for(;;) // loop until end of file { typedef union { unsigned int word; unsigned char byte[2]; } wordbyte; static persistent unsigned char inx; static persistent BANKX wordbyte addr; while (comms_getch()!=':'); // wait for start of hex file line words2write = cksum = bytecount = getXbyte(); words2write >>= 1; // convert byte count to word count addr.byte[1] = getXbyte(); // get the high byte of address addr.byte[0] = getXbyte(); // get the low byte of the address addr.word >>= 1; // convert byte address to word address EEADR = addr.byte[0]; EEADRH = addr.byte[1]; if(addr.byte[1] == 0x21) // unless this case, EEPGD = 0; // when EEPROM should be selected else { EEPGD = 1; // else destination is flash memory // ignore code that overlaps loader or data such as CONF/IDLOC #ifdef _BANK_ALIGNED if( addr.byte[1] >= (BOOT_START>>8) ) { #else if( addr.word >= (BOOT_START) ){ #endif while (!TRMT); TXREG='\r'; while (!TRMT); TXREG='\n'; continue; } } rectype = getXbyte(); // get the record type inx=0; while(bytecount--) { databuff[inx++]=getXbyte(); // read all bytes in this record } checksum(); // test the checksum of this record if(rectype==1) { // if this was an END record: prepare to run new program comms_puts("\r\nDone\r\n"); #asm GOTO run_program #endasm } // else ... INHX8M data record ix=0; isStartup=0; // Initiate a write to memory - EEADR has already been loaded if (((tmpadrh=addr.byte[1])|(addr.byte[0] & 0xFC)) == 0) { // is this address < 0004h? EEADRH = BOOT_START >> 8; #ifndef _BANK_ALIGNED tmpadr=EEADR; EEADR = ((BOOT_START & 0xFF)); #endif isStartup=1; // Yes - this is the reset vector code of new app } #ifdef _WRITE_4_WORDS prewrite = EEADR & _FWMASK; EEADR &= ~_FWMASK; // to start of flash-write boundary do { if(prewrite){ prewrite--; RD=1; NOP(); NOP(); }else{ EEDATA=databuff[ix++]; EEDATH=databuff[ix++]; if ( words2write == 0 ) { prewrite=((~EEADR)&_FWMASK); } } #else do { EEDATA=databuff[ix++]; EEDATH=databuff[ix++]; #endif while(WR); WREN=1; // commit this word to flash EECON2=0x55; EECON2=0xAA; WR=1; //initiate the write NOP(); NOP(); while (WR); WREN=0; #ifdef _BANK_ALIGNED if(isStartup && (EEADR==3)){ #else if(isStartup && ((EEADR&3)==3)){ #endif isStartup = 0; EEADRH = tmpadrh; //swap back the address #ifndef _BANK_ALIGNED EEADR = (tmpadr|3); #endif } if(++EEADR == 0) EEADRH++; #ifdef _WRITE_4_WORDS }while((prewrite)||words2write--); #else }while(words2write--); #endif }
how to use
1. Use XC8 to compile HyperBootloader_PIC16. Since HyperBootloader_PIC16 will be placed at the bottom of the program memory, occupying 0x200 program words, before compiling, you need to set the Code Offset compilation parameter to the correct value. For example, the program memory space of a PIC16 microcontroller is 0x2000 program words, Code Offset = 0x2000 - 0x200 = 0x1E00, so you only need to set the Code offset to 1E00 and then compile.
2. Use pickit3 to burn the Hex file of HyperBootloader_PIC16 to the target board.
3. Unplug the pickit3 programmer, connect the target board to the PC’s serial port, open the HyperTerminal, and set it as follows: 9600-8-None-1-None, Line Delay-20ms.
4. Restart the target board and the word Booting... will appear in the HyperTerminal.
5. Within 6 seconds, if you press any key on the keyboard in the HyperTerminal window, ">" will appear (if no key is pressed within 6 seconds, it will automatically jump to the user's application).
6. Open the Send Text File dialog box, select the application hex file you want to burn, click OK, and HyperBootloader will transmit the received data back to the computer's hyperterminal and burn the data to the correct location of the target board's program memory.
7. After burning is completed, restart the target board again. After the hyperterminal displays Booting..., it will automatically jump to the application program, and the target board will start to run the application program normally.
Each time you update the app, just repeat steps 4 to 7.
Show results
The following is the result of me using HyperBootloader_PIC16 to burn the application program to PIC16F877A. HyperBootloader_PIC16 will send the received data back to the computer first, and then complete the burning. If there is a problem, this is very helpful for debugging.
Booting.... >
:100000000A128A1104283FFF0A128A11522EFF1B7E
:10001000112883137F1883170008840A0319FF0A25
:1000200008007F087F398A000408840A0319FF0A40
:1000300082003FFF3FFF3FFF3FFF3FFF3FFF3FFF8C
:10020000533465347434743469346E346734203450
:1002100054344D3452343034203474346F342034F8
:10022000753473346534203469346E347434653411
:1002300072346E3461346C34203469346E34733407
:100240007434723475346334743469346F346E3496
:1002500020346334793463346C346534203463344B
:100260006C346F3463346B342E342E342E342E348D
:100270002E342E34203400347534743469346C34A4
:1002800069347A346134743469346F346E342034B0
:100290006F346E3420344D346934633472346F34C7
:1002A0006334683469347034203438342D34623423
:1002B0006934743420346D34693464342D347234C8
:1002C00061346E346734653420344D3443345534EE
:1002D000203450344934433431343634463438349D
:1002E0003734373441340D340A3400341B345B3432
:1002F00031343B34343430343B34333431346D3482
:1003000020344E344F34543445341B345B34313450
:100310003B34343430343B34333434346D3420346F
:1003200043344F344C344F3452341B345B34313407
:100330003B34343430343B34333432346D34203451
:100340004334483441344E34473445341B345B34F1
:1003500030346D3420340D340A3400342D342D34CF
:100360002D342D342D342D342D342D342D342D3485
:100370002D342D342D342D342D342D342D342D3475
:100380002D342D342D342D342D342D342D342D3465
:100390002D342D342D342D342D342D342D342D3455
:1003A0002D342D342D342D342D342D342D342D3445
:1003B0002D342D342D342D342D342D342D342D3435
:1003C0002D342D340D340A340034543468346934F7
:1003D00073342034703472346F346734723461345F
:1003E0006D342034693473342034613420347334F0
:1003F00069346D3470346C34653420346534783449
:1004000061346D3470346C34653420346F34663448
:100410002034733465347234693461346C3420347C
.
.
.
:100CA000FE0A452E8313E830FD000530FE00F930C2
:100CB000FF00A03084000A128A11452683010A121F
:100CC0008A115C2D20308316980090308312980092
:100CD000673083169900181508008C1E00341A0816
:100CE000F0008C1208003FFF3FFF3FFF3FFF3FFF38
:02400E
:00000001FF
Done
Key Features
HyperBootloader_PIC16 has the following main features
1. Written in C, compiled by XC8 (only a little bit of assembly in it).
2. Very easy to transplant.
3. Support FLASH burning
4. Support EEPROM burning.
5. CONFIG BITS/IDLOC programming is not supported. Keep the Configuration Bits of the application consistent with the Bootloader.
Previous article:PIC microcontroller learning SPI operation digital tube
Next article:Write your own PIC18 serial bootloader in C
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Embedded System Basics: What is a Microcontroller MCU?
- Evaluation board quick test - based on TI Sitara Cortex-A9(3)
- Three-phase watt-hour meter transformer wiring
- How to export the sensor data on sensorile?
- Application of Doherty amplifier in 450W digital TV transmitter
- #Idle Market# is open, you sell your idle items and I'll give you gifts!
- Research on integrated navigation algorithm in case of GPS signal loss.pdf
- I want to build a data access platform for NB-IOT devices based on the COAP protocol. In addition to LIBCOAP, what other technologies are used?
- Beijing's first bicycle lane, 6.5 kilometers, 20 minutes, check-in successful
- Today at 10:00 AM, live broadcast with awards: Internet of Everything - Shijian Company and Microchip experts jointly discuss IoT solutions