// ACM "Automat" Edition :) // Based on MCU: STM32L151CB or STM32L151CB-A // STM32L151CB, ROM 128K, RAM 16K: // Flash Memory Begins from 0x08000000 // Flash Memory Ends at 0x0801FFFF // RAM Memory begins from 0x20000000 // RAM Memory ends at 0x20003FFF // STM32L151CB-A, ROM 128K, RAM 32K: // Flash Memory Begins from 0x08000000 // Flash Memory Ends at 0x0801FFFF // RAM Memory begins from 0x20000000 // RAM Memory ends at 0x20007FFF // Relative addresses of ROM: // Base address: 0x08000000 // // Static firmware: Bootloader program + Vector table + Priveleged section // Bootloader fw. total: 32KiB - 256 priveleged bytes - 256 intvec bytes // 0x00000 0x00100 0x07F00 0x07FFF // | | | | // +-----------------+----------------------------------+---------------------+ // | Interrupt | Bootloader program | Priveleged | // | Table | | section | // | Bootloader | 32,256 bytes | 256 bytes | // | .intvec | | | // +-----------------+----------------------------------+---------------------+ // |<- sizeIntVect ->|<--------- sizeBootloader ------->|<- sizePriveleged ->| // | | // |<------------------------- sizeFixedFirmware ---------------------------->| // Dynamic firmware: Application program + Vector table + Progversion section // Application total: 96KiB - 256 program version bytes - 256 intvec bytes // 0x80000 0x81000 0x1FF00 0x1FFFF // | | | | // +-----------------+----------------------------------+---------------------+ // | Interrupt | Application | Program | // | Table | program | version | // | Application | | section | // | .intvec | 97,792 bytes | .progversion * | // +-----------------+----------------------------------+---------------------+ // |<- sizeIntVect ->|<--------- sizeApplication ------>|<- sizeProgversion ->| // | | // |<-------------------------- sizeDynamicFirmware ------------------------->| // // *Note: Program version section includes CRC32 (4 bytes) section for checksum. // // // Relative addresses of RAM: // Base address: 0x20000000 // RAM (Application), STM32L151CB and STM32L151CB-A // // Bootloader: // 0x00000 0x00C00 0x00C10 0x03FFF // | | | | // +---------------+------------+------------------------------------------+ // | | Service | | // | CSTACK | BOOTSIGN | Common RAM | // | 3KiB | section | | // | | .bootsign | 13,296 bytes | // +---------------+------------+------------------------------------------+ // |<- sizeStack ->|<- ****** ->|<------------- sizeCommonRam ------------>| // / \ // sizeRamBootsign // Application: // 0x00000 0x00C00 0x00C10 0x01C10 0x03FFF // | | | | | // +---------------+------------+--------------+---------------------------+ // | | Service | | | // | CSTACK | BOOTSIGN | HEAP | Common RAM | // | 3KiB | section | .heap | | // | | .bootsign | 4KiB | 9,200 bytes | // +---------------+------------+--------------+---------------------------+ // |<- sizeStack ->|<- ****** ->|<- sizeHeap ->|<----- sizeCommonRam ----->| // / \ // sizeRamBootsign // Relative addresses of RAM: // Base address: 0x20000000 // RAM (Application), STM32L151CB-A only // // Bootloader and Application: // 0x04000 0x07FFF // | | // +-------------------------------------------------------------------+ // | | // | Common RAM | // | | // | 16 KiB | // +-------------------------------------------------------------------+ // |<------------------------- +++sizeCommonRam ---------------------->| // BOOTSIGN - service region of RAM dedicated for storing the application/bootloader flags // Common - general purpose application RAM region // HEAP - application dynamic memory region (Application only) // CSTACK - main thread stack // ======================== Symbols and Sizes ================================= // Check for wheither symbol 'BOOTLOADER' is defined if(!isdefinedsymbol(BOOTLOADER)) { // this is app, BOOTLOADER is not defined define symbol BOOTLOADER = 0; } if( !isdefinedsymbol(STM32L151CBA) ) { define symbol STM32L151CBA = 0; } // Check for wheither symbol 'APPIMGINBOOT' is defined if(!isdefinedsymbol(APPIMGINBOOT)) { // by default, APPIMGINBOOT = 0, that means // no application image is placed in bootloader project define symbol APPIMGINBOOT = 0; } // Define memory size: define memory mem with size = 4G; // Base hard-addresses: define symbol baseROM = 0x08000000; // @baseROM: Chip-ROM define symbol baseRAM = 0x20000000; // @baseRAM: Chip-RAM // Region sizes: define symbol sizeChipRom = 0x20000; // @sizeChipRom: Whole Chip-ROM size define symbol sizeFixedFirmware = 0x04000; // @sizeFixedFirmware: Fixed Firmware Size, aka "Bootloader" + some constant data // @sizeDynamicFirmware: Size of re-writable firmware and data define symbol sizeDynamicFirmware = sizeChipRom - sizeFixedFirmware; define symbol sizeIntVect = 0x00100; // @sizeIntVect: size of interrupt vector table if( STM32L151CBA ) { // Region sizes: define symbol sizeChipRam = 0x08000; // @sizeChipRam: Whole Chip-RAM size, 32KiB for STM32L151CBA } else { // Region sizes: define symbol sizeChipRam = 0x04000; // @sizeChipRam: Whole Chip-RAM size, 16KiB for STM32L151CB } // ---------------------------------------------------------------------------------------------------- define exported symbol sizeRamBootsign = 0x00010; // @sizeRamBootsign: size of service RAM-region (app-->boot flags) define exported symbol sizePriveleged = 0x00100; // @sizePriveleged: Priveleged section: contains constant device data define exported symbol sizeProgversion = 0x00100; // @sizeProgversion: Program Version Sector size define exported symbol sizeProgverCRC = 0x00004; // @sizeProgverCRC: Program Version Checksumm size // @sizeProgverData: Program Version Data size define exported symbol sizeProgverData = sizeProgversion - sizeProgverCRC; // @sizeBootloader: Bootloader program ROM size define exported symbol sizeBootloader = sizeFixedFirmware - sizePriveleged; // @sizeApplication: Application program ROM size define exported symbol sizeApplication = sizeDynamicFirmware - sizeProgversion; if( BOOTLOADER ) { // For Bootloader: define symbol sizeStack = 0x01000; // @sizeStack: CStack size (RAM) define symbol sizeHeap = 0x00000; // @sizeHeap: Heap size (RAM) - NO HEAP in bootloader define symbol sizeUsbBuffRam = 0x01000; // @sizeUsbBuffRam: logical sector for USB-Buffers } else { // For Application: define symbol sizeStack = 0x01000; // @sizeStack: CStack size (RAM) define symbol sizeHeap = 0x01000; // @sizeHeap: Heap size (RAM) define symbol sizeUsbBuffRam = 0x01000; // @sizeUsbBuffRam: logical sector for USB-Buffers } // @sizeCommonRam: common readwrite memory // The readwrite memory is reserved for CSTACK (@sizeStack), // Service RAM-region (@sizeRamBootsign) and HEAP(@sizeHeap). // The rest part of the chip RAM is common readwrite memory. define symbol sizeCommonRam = sizeChipRam - sizeRamBootsign - sizeStack - sizeHeap; // Predefined IAR-symbol '__ICFEDIT_size_cstack__' must be defined: define symbol __ICFEDIT_size_cstack__ = sizeStack; // Predefined IAR-symbol '__ICFEDIT_size_heap__' must be defined: define symbol __ICFEDIT_size_heap__ = sizeHeap; // Absolute ranges (Region edjes): // 1) Fixed Firmware Region: // begins since the start of ROM and takes @sizeFixedFirmware bytes: define symbol addrFixedFirmware = baseROM; define symbol addrFixedFirmwareEnd = baseROM + sizeFixedFirmware - 1; // 1.1) Bootloader's Interrupt Vector Table: // table begins at @addrFixedFirmware and takes @sizeIntVect bytes: define exported symbol addrIntVectBoot = addrFixedFirmware; // Note: 'addrIntVectBoot' is referred by bootloader program define symbol addrIntVectBootEnd = addrIntVectBoot + sizeIntVect - 1; // 1.2) Bootloader's program: // follows the bootloader's interrupt vector table and takes @sizeBootloader: define symbol addrBootloader = addrIntVectBootEnd + 1; define symbol addrBootloaderEnd = addrBootloader + sizeBootloader - 1; // 1.3) Priveleged section: // the end of the fixed firmware region: define exported symbol addrPriveleged = addrFixedFirmwareEnd - sizePriveleged + 1; define symbol addrPrivelegedEnd = addrFixedFirmwareEnd; // 2) Dynamic firmware: // follows the fixed one - the rest part of the chip's ROM define symbol addrDynamicFirmware = addrFixedFirmwareEnd + 1; define symbol addrDynamicFirmwareEnd = addrDynamicFirmware + sizeDynamicFirmware - 1; // 2.1) Application's Interrupt Vector Table: // table begins at @addrDynamicFirmware and takes @sizeIntVect bytes: define exported symbol addrIntVectApp = addrDynamicFirmware; // Note: 'addrIntVectApp' is referred by bootloader program define symbol addrIntVectAppEnd = addrIntVectApp + sizeIntVect - 1; // 2.2) Application program: // follows the application's interrupt vector table and takes @sizeApplication: define symbol addrApplication = addrIntVectAppEnd + 1; define symbol addrApplicationEnd = addrApplication + sizeApplication - 1; // 2.3) Program Version Sector: // located in the tail of the dynamic firmware sector: define symbol addrProgversion = addrDynamicFirmwareEnd - sizeProgversion + 1; define symbol addrProgversionEnd = addrDynamicFirmwareEnd; // 2.3.1) Program Version Sector Data region // located at the beginning of the progversion section: define symbol addrProgverData = addrProgversion; define symbol addrProgverDataEnd = addrProgversionEnd - sizeProgverCRC; // 2.3.2) Program Version Sector Checksumm region // located at the end of the progversion section: define symbol addrProgverCRC = addrProgversionEnd - sizeProgverCRC + 1; define symbol addrProgverCRCEnd = addrProgversionEnd; // Note: 'symChecksum' will be used by 'ielftool.exe' to reference start address of checksum section. define exported symbol symChecksum = addrProgverCRC; // Note: 'symProgVers' is used by application to place the PROGVERSION structure using '@' define exported symbol symProgVers = addrProgversion; if( BOOTLOADER ) { // Interrupt Vector Table: global definition for bootloader define exported symbol addrIntVect = addrIntVectBoot; define symbol addrIntVectEnd = addrIntVectBootEnd; define symbol addrProgram = addrBootloader; define symbol addrProgramEnd = addrBootloaderEnd; } else { // Interrupt Vector Table: global definition for application define exported symbol addrIntVect = addrIntVectApp; define symbol addrIntVectEnd = addrIntVectAppEnd; define symbol addrProgram = addrApplication; define symbol addrProgramEnd = addrApplicationEnd; } // CSTACK RAM-region: // Takes the first @sizeStack bytes from @baseRAM. // If overflows, it does not damage any other data. define symbol addrStackStart = baseRAM; define symbol addrStackEnd = addrStackStart + sizeStack - 1; // Service RAM-region: // Follows the CSTACK RAM-region and takes @sizeRamBootsign bytes define symbol addrSvcRamStart = addrStackEnd + 1; define symbol addrSvcRamEnd = addrSvcRamStart + sizeRamBootsign - 1; // Heap RAM-region: // Follows the Service RAM-region and takes @sizeHeap bytes define symbol addrHeapStart = addrSvcRamEnd + 1; define symbol addrHeapEnd = addrHeapStart + sizeHeap - 1; // Common RAM-region: // Follows the Heap RAM-region and takes @sizeCommonRam bytes define symbol addrRamStart = addrHeapEnd + 1; define symbol addrRamEnd = addrRamStart + sizeCommonRam - 1; // ============================= REGIONS ====================================== // ------------------------------------------------------------------------------ // Bootloader/Application Interrupt Vector Table (current project): define region regionIntVec = mem:[ from addrIntVect to addrIntVectEnd ]; // Bootloader/Application program region (current project execution ROM): define region regionReadonly = mem:[ from addrProgram to addrProgramEnd ]; // ------------------------------------------------------------------------------ // Service RAM region: define region regionSvcRAM = mem:[ from addrSvcRamStart to addrSvcRamEnd ]; // Common RAM region: define region regionRAM = mem:[ from addrRamStart to addrRamEnd ]; if( sizeHeap > 0) { // HEAP RAM region: define region regionHeap = mem:[ from addrHeapStart to addrHeapEnd ]; } // CSTACK RAM region: define region regionStack = mem:[ from addrStackStart to addrStackEnd ]; // Program Version ROM-region (data only, no checksum): define region regionProgversion = mem:[ from addrProgverData to addrProgverDataEnd ]; // Program Version Checksumm ROM-region (only checksum): define region regionProgverCRC = mem:[ from addrProgverCRC to addrProgverCRCEnd ]; if( !BOOTLOADER ) { // Bootloader-image region define region regionBootImg = mem:[ from addrFixedFirmware to addrFixedFirmwareEnd ]; } else { // Application-image region define region regionAppImg = mem:[ from addrDynamicFirmware to addrDynamicFirmwareEnd ]; } // ============================= BLOCKS ====================================== // Defining blocks: // Main stack: define block CSTACK with alignment = 8, size = sizeStack { section .cstack }; if( sizeHeap > 0 ) { // Dynamic memory (Heap): define block HEAP with alignment = 8, size = sizeHeap { }; } // Bootloader signature (App-->Boot data exchange) define block BOOTSIGN with alignment = 8, size = sizeRamBootsign { readwrite data section .bootsign }; // USB-Buffers (logical block) define block USBBUF with alignment = 8, size = sizeUsbBuffRam { section .usbbuf }; if( !BOOTLOADER ) { // For Application: // Bootloader-image block: contains full fixed firmware image define block BOOTIMG with alignment = 4, size = sizeFixedFirmware { readonly data section .bootimg }; // Application program version sector define block PROGVERSION with alignment = 4, size = sizeProgverData { section .progver }; define block PROGVERCRC with alignment = 4, size = sizeProgverCRC { section .progvercrc }; } else { // For Bootloader: if( APPIMGINBOOT ) { // Application-image block: contains full dynamic firmware image define block APPIMG with alignment = 4, size = sizeDynamicFirmware { section .appimg }; } } // ========================= Initializers ==================================== // Initializers: initialize by copy { readwrite }; do not initialize { section .noinit }; do not initialize { section .bootsign }; // =========================== Placement ===================================== // Current project Interrupt Vector Table: place in regionIntVec { readonly section .intvec }; // Current project executable readonly memory: place in regionReadonly { readonly }; // Current project common readwrite memory (non-marked + marked): place in regionRAM { readwrite, section .flashram, section .grombuf, last block USBBUF }; // Service RAM-region: BOOTSIGN block place in regionSvcRAM { first block BOOTSIGN }; if( sizeHeap > 0 ) { // Heap RAM-region place in regionHeap { first block HEAP }; } // CSTACK region: place in regionStack { first block CSTACK }; if( !BOOTLOADER ) { // For Application: place in regionBootImg { first block BOOTIMG }; place in regionProgversion { first block PROGVERSION }; place in regionProgverCRC { first block PROGVERCRC }; keep { section .bootimg, block BOOTIMG , section .progver, section .progvercrc }; } else { // For Bootloader: if( APPIMGINBOOT ) { place in regionAppImg { first block APPIMG }; keep { section .appimg }; } } keep { section .intvec, section .bootsign, block BOOTSIGN };