首页 > 代码库 > atmega128 bootloader程序在IAR-AVR下 linker文件的配置及原因
atmega128 bootloader程序在IAR-AVR下 linker文件的配置及原因
第一步:atmega128的片内flash分区描述
在atmega128 datasheet的275页中有分区描述
对应的在284页中,有具体的应用区与boot区的大小设置
注意:Byte address = word address * 2
这里的BOOT区首地址,$F000 = 0x1E000
根据手册中的描述,我们使用JTAG MKII 烧写器通过软件 Avr Studio 4,配置熔丝位 BOOTSZ为00
注意:这里面的4096 words = 8K bytes
第二步:说明一下linker(.xcl)文件的作用
好了,怎么让我们的程序烧写到flash中是在指定的0x1E000处呢?这就需要在link文件中指定CODE区的位置了。
适用于atmega128 bootloader程序的.xcl文件如下:
/* - lnkm128.xcl - * * XLINK command file for the ICCAVR C-compiler using the --cpu=m128, -ms * options. Segments are defined for an ATmega128 whithout external * memory. It is also possible to "add" external SRAM, EPROM and EEPROM. * * Usage: xlink your_file(s) -f lnkm128 * * File version: $Name: $ *//*========================================================================*//* NOTE: This file has been modified to be used with the code example in: *//* AVR106: C functions for reading and writing to Flash memory *//* Se comments further down in this file, and the application note for *//* more information. *//*========================================================================*//*====================================================*//* * Constants used down below, * Do not change these lines, * if it is not stated otherwise *//* Code (flash) segments */-D_..X_INTVEC_SIZE=8C /* 4 bytes * 35 vectors */-D_..X_FLASH_TEND=FF /* End of tiny flash memory */-D_..X_FLASH_NEND=FFFF /* End of near flash memory */-D_..X_FLASH_END=1FFFF /* End of flash memory *//* Internal data memory *//* * Change the two lines below to 60(BASE) and FF(TEND) * if you are running in "mega103 mode" */-D_..X_SRAM_BASE=100 /* Start of ram memory */-D_..X_SRAM_TEND=100 /* End of tiny ram memory */-D_..X_SRAM_END=10FF /* End of ram memory *//* Internal EEPROM */-D_..X_EEPROM_END=FFF /* End of eeprom memory *//*====================================================*//* * Modify the lines below to alter the size of the RSTACK, CSTACK and HEAP * segments. These need to be fine tuned to suit your specific application. * The ‘_..X_‘ prefix is used by C-SPY as an indication that the label should * not be displayed in the dissassembly window. */ //-D_..X_CSTACK_SIZE=200 /* 512 bytes for auto variables and saved registers. *///-D_..X_RSTACK_SIZE=40 /* 64 bytes for return addresses, equivalent to 32 */ /* levels of calls, including interrupts. *///-D_..X_HEAP_SIZE=100 /* 256 bytes of heap. */-D_..X_CSTACK_SIZE=300 /* 512 bytes for auto variables and saved registers. */-D_..X_RSTACK_SIZE=40 /* 64 bytes for return addresses, equivalent to 32 */ /* levels of calls, including interrupts. */-D_..X_HEAP_SIZE=100 /* 256 bytes of heap. *//* * Modify these lines if you have an external SRAM connected to the system. * * Note: Remember to turn on the external data and address busses in * __low_level_init if external memory is used. */-D_..X_EXT_SRAM_BASE=_..X_SRAM_BASE-D_..X_EXT_SRAM_END=_..X_SRAM_END/* * Modify these lines if you have an external EPROM connected to the system. * * Note: Remember to turn on the external data and address busses in * __low_level_init if external memory is used. */-D_..X_EXT_EPROM_BASE=_..X_SRAM_BASE-D_..X_EXT_EPROM_END=_..X_SRAM_END/* * Modify these lines if you have an external EEPROM connected to the system. * * Note: Remember to turn on the external data and address busses in * __low_level_init if external memory is used. */-D_..X_EXT_EEPROM_BASE=_..X_SRAM_BASE-D_..X_EXT_EEPROM_END=_..X_SRAM_END/* * The following segments are located in the internal memory of * the ATmega128. Do not change these lines. *//* Define CPU */-ca90/*========================================================================*//* How to move the complete project and interrupt table to a Boot Sector. *//*========================================================================*//* This method can be used on any device with boot sectors. *//* It presumes these defines are predefined: *//* _..X_INTVEC_SIZE, _..X_FLASH_TEND, *//* _..X_FLASH_NEND, _..X_FLASH_END *//*========================================================================*//* -1- Find and remove (/comment out) the following section from the *//* original XCL file. *//*========================================================================*//* Code memory *///-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)/* Fill unused interrupt vector‘s with RETI *//*-H1895-h(CODE)0-_..X_INTVEC_SIZE-Z(CODE)TINY_F=_..X_INTVEC_SIZE-_..X_FLASH_TEND-Z(CODE)NEAR_F,SWITCH,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_NEND-Z(CODE)CODE=_..X_INTVEC_SIZE-_..X_FLASH_END-Z(FARCODE)FAR_F=_..X_INTVEC_SIZE-_..X_FLASH_END-Z(CODE)HUGE_F,INITTAB=_..X_INTVEC_SIZE-_..X_FLASH_END-Z(CODE)TINY_ID,NEAR_ID,CHECKSUM=_..X_INTVEC_SIZE-_..X_FLASH_END*//*========================================================================*//* -2- Paste in the following section as a replacement. *//* -3- Remove the comment marking on the used Boot Sector Size *//*========================================================================*//* Boot Sector Size */-D_..X_BOOTSEC_SIZE=2000 /* 4096 words *///-D_..X_BOOTSEC_SIZE=1000 /* 2048 words *///-D_..X_BOOTSEC_SIZE= 800 /* 1024 words *///-D_..X_BOOTSEC_SIZE= 400 /* 512 words *///-D_..X_BOOTSEC_SIZE= 200 /* 256 words *///-D_..X_BOOTSEC_SIZE= 100 /* 128 words */-D_..X_DEFSEC_POS=1000/* Code memory */-Z(CODE)INTVEC=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+1)-(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE) -Z(CODE)DEFSEC=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+1+_..X_DEFSEC_POS)-_..X_FLASH_END/* Fill unused interrupt vector‘s with RETI */-H1895-h(CODE)(_..X_FLASH_END-_..X_BOOTSEC_SIZE+1)-(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE) /*========================================================================*//* -4- If the flash size is 32kB or less then; *//* - Remove the comment marking on following line: *//*========================================================================*///-Z(CODE)NEAR_F,SWITCH,DIFUNCT=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE+1)-_..X_FLASH_NEND/*========================================================================*//* -5- If the flash size is 32kB or less then; *//* - Remove the SWITCH segment from the following line: *//*========================================================================*/-Z(CODE)CODE,SWITCH=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE+1)-_..X_FLASH_END-Z(FARCODE)FAR_F=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE+1)-_..X_FLASH_END-Z(CODE)HUGE_F,INITTAB=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE+1)-_..X_FLASH_END-Z(CODE)TINY_ID,NEAR_ID,CHECKSUM=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE+1)-_..X_FLASH_END/*========================================================================*//*========================================================================*//* Internal data memory */-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_BASE-_..X_SRAM_TEND-Z(DATA)NEAR_I,NEAR_Z=_..X_SRAM_BASE-_..X_SRAM_END,_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END/* * If external SRAM is available it is possible to place the stacks there. * However, the external memory is slower than the internal so moving the * stacks to the external memory will degrade the system performance. */-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END /* ,_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END */-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END /* ,_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END *//* * If external SRAM is available it might be a good idea to move the * heap segment there, i.e. remove the _..X_SRAM_BASE-_..X_SRAM_END range. */-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END,_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END/* Internal eeprom memory */-Z(XDATA)EEPROM_I,EEPROM_N=0-_..X_EEPROM_END/* * The following segment definitions are only used if external memory is * connected to the AVR controller. *//* External EPROM */-Z(CONST)NEAR_C=_..X_EXT_EPROM_BASE-_..X_EXT_EPROM_END/* External EEPROM */-Z(DATA)NEAR_N=_..X_EXT_EEPROM_BASE-_..X_EXT_EEPROM_END/* Select reduced "printf" support to reduce library size. See configuration section in manual concerning printf/sprintf. *//*Dlib*/-e_Printf_1=_Printf/*Clib*/-e_small_write=_formatted_write-e_small_write_P=_formatted_write_P/* Disable floating-point support in "scanf" to reduce library size. See configuration section in manual concerning scanf/sscanf *//*Dlib*/-e_Scanf_1=_Scanf/*Clib*/-e_medium_read=_formatted_read-e_medium_read_P=_formatted_read_P/* Suppress one warning which is not relevant for this processor */-w29/* Code will now reside in file aout.a90 or aout.d90, unless -o is specified *//* .d90 is the default if debug system is linked (option -r) *//* .a90 is the default without debugging. Default format is -Fmotorola */
其中
-D_..X_BOOTSEC_SIZE=2000 /* 4096 words */
确定了BOOT区的大小为4096字,与我们设置的BOOTSZ = 00正好吻合。
然后
-Z(CODE)INTVEC=(_..X_FLASH_END-_..X_BOOTSEC_SIZE+1)-(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE)-h(CODE)(_..X_FLASH_END-_..X_BOOTSEC_SIZE+1)-(_..X_FLASH_END-_..X_BOOTSEC_SIZE+_..X_INTVEC_SIZE)
表示中断向量区的范围从0x1E000 ~ 0x1E08B,并将其填充
具体参数项,可以参考AVR的帮助文档 Linker and library Tools reference guide.
参考:ATMEL的官方应用文档的AVR106号应用笔记
http://www.atmel.com/dyn/products/app_notes.asp?family_id=607
第三步:bootloader程序,linker文件加载
1)将以上代码保存为lnkm128.xcl,并放于工程目录下
2)通过配置工程 Linker->Config->Override default将该文件加载进来
第四步:验证生成的hex文件是否将代码编译到了片内flash的0x1E000地址处
021000 -> 确定偏移段地址为0x1000
10E000 -> 确定段内地址从 0xE000开始
经计算实际地址为 0x10000 + 0xE000 = 0x1E000
atmega128 bootloader程序在IAR-AVR下 linker文件的配置及原因