How To Build A Simple Serial Bootloader For PIC32 GUIDE R1.1

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 5

How to build a simple serial bootloader for
PIC32
Diego Mendes (diego.mendes@ua.pt), Cristóvão Cruz (cac@ua.pt)
Department of Electronics, Telecommunications and Informatics /
Telecommunications Institute
University of Aveiro
Portugal
Version 1.1
1 Introduction
This guide is aimed for anyone looking to build a simple bootloader for a
generic development board based on the PIC32MX Family. Still, the guide itself
is oriented for the DETPIC32 from the University of Aveiro.
This guide is essentially a simplification of the application note AN1388 from
Ganapathi Ramachandra available on the Microchip website1.
2 Prerequisites
For this guide it is required that the user has a version of the MPLAB X
IDE and the XC32 1.20 compiler installed.
If this is not the case, the user can get the required installers as well as the
required installation instructions in:
http://ww1.microchip.com/downloads/mplab/X/index.html
3 Preparing the files and MPLAB project
1. Download the source code from:
ww1.microchip.com/downloads/en/AppNotes/AN1388_Source_Code_011112.
zip
2. Decompress the zip file and execute the Universal Bootloader. This step
requires Microsoft Windows or a windows emulator (e.g. wine for Linux
environments ) as the Universal Bootloader is distributed in the form of
an executable (“Universal Bootloader_011112.exe”);
3. The installation folder, defined by the user during step 2, contains two
different folders. One, called “Firmware”, contains the actual bootloader
code, executed by the PIC32 during the boot phase. The other one (“PC
1http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en554836
1
Application”) contains a Windows-based Graphical User Interface (GUI)
that shall be executed in the host PC whenever the user wants to upload
applications to the PIC32.
The supplied bootloader is adapted to the Microchip’s Explorer 16 board,
which has several communication interfaces (e.g. Ethernet, USB, SD
card). From these, the DETPIC32 board is only equipped with an UART
interface. For this reason, it necessary to execute the MPLABX IDE and
open the project “[INSTPATH]/Firmware/ Bootloader/MPLAB_X_Workspace/UART_Btl_Explorer16.X”,
where [INSTPATH] is the installation directory, defined at step 2;
4. In the project properties, change the compiler to the one you have in-
stalled, XC 1.20. The “Project properties” menu can be accessed e.g. by
right-clicking on the name of the project;
5. On Linux and MAC, change reference to “Bootloader.h” to “BootLoader.h”
(notice the capital L), in line 41 of “BootLoader.c”
6. On Linux and MAC, change “FrameWork” to “Framework” (notice the
capital W) in line 42 of “BootLoader.c”
7. On Linux and MAC, all the “\” in the include directives must be changed to
“/”. The affected lines are 39 to 42 of BootLoader.c, 39 to 42 of NVMem.c,
40 to 44 of Framework.c, 42 to 44 of Uart.c and 56 of BootLoader.h.
8. The provided linker script must be changed to work on XC32 1.20, so, in
line 57 of uart_btl_ex16.ld change
ex cep ti on_me m : ORIGIN = 0 x9F C01E00 , LE NGTH = 0x20 0
to
ex cep ti on_me m : ORIGIN = 0 x9F C01E00 , LE NGTH = 0xA0 0
9. After line 8 of the same file, add the following:
OPTIONAL("libmchp_peripheral .a")
OPTIONAL(" libmchp_peripheral_32MX795F512H . a")
4 Adapting the code to the DETPIC32 constraints
1. In the project properties menu, change the Device to PIC32MX795F512H
2. We want the application to be placed into the “User Application Code and
IVT” area2, which is placed between 0x9D000000 and 0x9D07FFFF. So
open the file “BootLoader.h” and at line 43 edit the values for the following
MACROS:
# define APP_F LA SH_ BA SE _A DD RES S 0 x 9D0000 00
# define APP_F LA SH _E ND _A DD RES S 0 x 9D07FF FF
# def ine US ER _A PP_R ESE T_AD DRES S (0 x9 D0 00 000 + 0 x 1000 + 0 x970 )
2AN1388 FIGURE 1, pag. 2
2
3. As mentioned above, the bootloader is adapted to the Explorer 16 board.
This board is equipped with a button that allows entering on the “Firmware
Upgrade Mode”. However, this switch is not present in the DETPIC32
board. Since the DETPIC32, by itself, does not contain any switch or
button, besides the reset one, it was decided to use only the time to con-
trol the process. When the bootloader starts (after power up or reset) it
tries to connect to the PC application during 1 second. After that time,
if no connection is established, the control is passed to the application
previously loaded (if any).
Additionally, the UART interface, by default, is configured to UART2.
However, in the DETPIC32 board, only UART1 has an external inter-
face, so, this aspect must also be changed.
4. Let’s start by the UART. For the DETPIC32 board we must configure the
bootloader to access the UART1, so open the header “Uart.h” and at line
29 change
# d ef ine Ux ( y) U2 ## y
to
# d ef ine Ux ( y) U1 ## y
5. Now for the main code I suggest the following.
INT m ai n ( void ) {
UINT p bClk ;
/* Setup configu r a t i o n */
pbClk = SYSTEMConfi g ( S Y S _FREQ , S YS_CFG _ W A I T_STAT E S | S Y S _CFG_PCAC H E ) ;
/* I n it i aliz e t he transport l a ye r - U ART / USB / E th er n et * /
TRANS_LAYER_Init(pbClk);
/* Stays in the firmware u p g r a d e mod e whil e no t i m e o u t
occurs or if no application is p r e s e n t o r if the GUI
is connected to the MCU */
while (( R eadCore Timer () < 0 x 1312D00 ) | | W ORKING () || ! V alid AppPresen t () ) {
/* E nter f i rm w are u pgrade m ode . * /
/* Be i n loop , looking for c o m m a n d s from PC */
TRANS_LAYER_Task(); /* R un T r a n s p ort layer tasks */
FRAMEWORK_FrameWorkTask(); /* Run frame work r e l a t e d
tasks ( H a n d l i n g Rx fram e , process f r a me a nd so on) */
}
/* C los e tras np o rt l ayer . * /
T R ANS_ LAYER _Clo se ( ) ;
/* No t r i g g e r + valid appli c a t i o n = run appl i c a t i o n . */
J umpT oA p p ( ) ;
return 0;
}
The “ReadCoreTimer() < 0x1312D00” condition forces the bootloader to
wait for 1 second before moving on to the application, if there is a valid
one. If you wish to have a different waiting time you only need to change
the value in this condition. Remember that the Core Timer counter is
incremented every two periods of the CPU clock3.
If only the above condition was used, after 1 second the firmware load-
ing process would be interrupted (the “while()” cycle would terminate),
even if a transfer was ongoing. To prevent this, a WORKING() function
is used to detect ongoing transfers. This function tests a flag that is set
3http://blog.flyingpic24.com/2009/04/02/using-the-32-bit-core-timer/
3
when a connection is established and reset when the connection termi-
nates. This way the bootloader leaves the loop only when it receives a
“JMP_TO_APP” command from the GUI or the PIC32 is reset.
To make this possible we must open the “Framework.c” file and add the
following global variable and function:
stati c BOOL Wor king = FALSE ;
BOOL WORKING ( void ){
return W orking ;
}
The next step consists in editing the “HandleCommand” function on the
same file. Start by editing the case “READ_BOOT_INFO”, in line 188,
(this request is sent every time the GUI tries to establish a connection to
the bootloader so we use this to our favor).
case READ_BOOT_INFO: // Read boot loader version info .
memcpy (& TxBuff . Data [1] , BootInfo ,2);
// Set the tr ansmit frame le ngth .
TxBuff . Len = 2 + 1; // Boot Info Fields + command
Working = TRUE ;
break ;
And finally in the “JMP_TO_APP” case, line 228,
case JMP_TO_AP P :
// Ex it firmware upgrade mode .
RunApplication = TRUE;
Working = FALSE ;
break ;
6. The bootloader is now ready.
5 Preparing the application’s linker
In order to create programs that can be booted by this bootloader, you must
use a custom linker script. This section explains the process of creating that
linker script.
1. Right click the project » New » Empty File and create a *.ld file with the
name you prefer(ex: linker.ld)
2. Copy the contents of “<XC32>\pic32mx\lib\ldscripts\elf32pic32mx.x” to
the newly created file. <XC32> is the compiler installation folder.
3. Copy the following lines of code and paste them after the PROVIDE
directives and before “SECTIONS”.
/*************************************************************************
* P roc essor - s p ec i fic o bject f ile . Contai ns S FR d efini ti o ns .
*************************************************************************/
INPUT (" processor . o")
/*************************************************************************
* For int e r r u p t v e c t or hand l i n g
*************************************************************************/
4
PROVIDE ( _ vector_ sp a cing = 0 x0 00 0000 1 );
/* _ebase _ a d d r ess value must be sam e as the ORIGIN value of exceptio n _ m e m
( see b elow ) * /
_ eb a se _a ddress = 0 x 9D 000000 ;
/*************************************************************************
* Memory Address Equates
*************************************************************************/
/* Equate _RESET_ADDR to the O R I G I N v a l u e of kseg1 _ b o o t_mem (see below ) */
_ RESET_ADD R = (0 x9D 00 0 000 + 0 x 1 00 0 + 0 x970 );
/* Map _BE V _ E X CPT_ADDR and _DBG_ E X C P T _ADDR in to kseg1_boot_ m e m ( s ee below ) */
/* Place _ BEV_EXC P T _ A D DR at an offset of 0x380 to _ R ESET_ADDR */
/* Place _ DBG_EXC P T _ A D DR at an offset of 0x480 to _ R ESET_ADDR */
_BEV _ E X C PT_ADDR = ( 0 x 9 D 0 0 0 0 0 0 + 0 x1000 + 0 x 9 70 + 0 x380 );
_DBG _ E X C PT_ADDR = ( 0 x 9 D 0 0 0 0 0 0 + 0 x1000 + 0 x 9 70 + 0 x480 );
_ DB G _C OD E_ADDR = 0 x BF C02000 ;
_DBG_CODE_SIZE = 0xFF0 ;
_ GEN_EX CPT_ADD R = _ eba se_addr es s + 0 x 180 ;
/*************************************************************************
* Memory R e g i o n s
*
* M emory r egions w ithout a ttri butes c annot be u se d f or o rphaned s ections .
* Only sections specific a l l y a s s i g n e d to the s e r e g i o n s can be allocated
* i nt o t hese r egions .
*************************************************************************/
MEMORY{
/* IVT is m a p p ed i n to t he e x c eption_me m . ORIGIN value of exce p t i o n _mem must
align with 4K address boundary . Keep the default v a l u e for the length */
excep t i o n _ mem : ORIGIN = 0 x9D000000 , L E N G T H = 0 x 1 0 0 0
/* P la ce k seg0 _boot_mem ad ja cent t o e xception_me m . K eep the d efault v alue
for the l e n g t h */
kseg 0 _ b o o t_mem : ORIGIN = (0 x 9 D000000 + 0x1000 ) , L E N G T H = 0 x 9 70
/* C Start - u p code is mapped into kseg1 _ b o o t _mem . Pla c e k s e g1_boot_ m e m
adjacent to
ks eg0_boot_m em . K eep the d efault v alue f or the l ength */
k seg1_b oot_mem : O R IG IN = ( 0 x9D000 00 0 + 0 x 1000 + 0 x 970 ), L EN G TH = 0 x490
/* All C files ( Text and Data ) are m a p p ed into k s e g 0_progr a m _ m em . P l a c e
kseg 0 _ p r ogram_ m e m a d j a c e n t to k s eg1_boot_ m e m . Change the l e n g t h of
k seg0_pro gram_me m as r equired . In this e xa mpl e , 5 12 KB F la sh s ize
is s hrunk as f ollows : */
k seg0_ progra m_mem ( rx ): ORIGIN = (0 x 9D000000 + 0 x1000 + 0 x970 + 0 x 490 ),
LENGTH = ( 0 x80000 - ( 0 x1000 + 0 x970 + 0 x490 ))
debu g _ e x e c_mem : ORIGIN = 0xBFC02000 , L E N G T H = 0 x F F0
config3 : ORIGIN = 0xBFC02FF 0 , L E N G T H = 0x4
config2 : ORIGIN = 0xBFC02FF 4 , L E N G T H = 0x4
config1 : ORIGIN = 0xBFC02FF 8 , L E N G T H = 0x4
config0 : ORIGIN = 0xBFC02FF C , L E N G T H = 0x4
kseg 1 _ d a t a_mem ( w!x) : O R I G I N = 0 x A 0000000 , LENGTH = 0 x20000
sfrs : ORIGIN = 0 xBF80 0 0 0 0 , LENGTH = 0x100000
configs f r s : O R I G I N = 0 x BFC02FF0 , L E N G T H = 0 x10
}
4. Remove the “INCLUDE procdefs.ld” directive.
5. Copy the content of the SECTIONS directive from <XC32>\lib\proc\
32MX795F512H\procdefs.ld and paste at the beginning of the existing
SECTIONS directory of the linker script.
6. *** VERY IMPORTANT *** For every application you want to load onto
the DETPIC32, you must add this linker to its project.
6 Closing remarks
By now you should have a functioning bootloader and the required linker
for your projects. If you wish to use these files in different development boards
the changes required are minimal so it should easy, still reading the AN1388 is
advised.
7 Changelog
2014-10-01
Pedro Fonseca and Paulo Pedreiras. Small text and code fixes.
5

Navigation menu