某些目标中的加载功能中的引导加载程序问题

问题描述 投票:0回答:0

我在(Atmega16a)中调用函数时在引导加载程序应用程序中遇到问题,他运行良好的引导加载程序但将此目标更改为 ATmega128 函数 bootloaderDriver 无法加载到程序内存中

这是什么问题 我在 Atmega16 中设置引导加载程序大小为 256 字,而 Atmega128 为 512 字 ATmega16 中的字节地址是 0x3E00 和 ATmega128 中的 0x1FC00

#ifndef APP_H
#define APP_H
#define  CALL_POINT         (0)
#define  ROOM_POINT         (1)
#define  DISPLAY_POINT      (2)
#define  SAVE_POINT         (3)

#define  DEVICE_TYPE                   (DISPLAY_POINT)
#define __FLASH_RECOVER    (0)
#define  F_CPU            11059200UL     
//#include <xc.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <math.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/boot.h>
#include "macros.h"
#include "types.h"

#if DEVICE_TYPE == CALL_POINT
#include "../../../../Nurse System/Nurse Call Point/SW/Call Point V1/CallPoint.X/inc/boardinfo.h"
#elif DEVICE_TYPE == ROOM_POINT
#include "../../../../Nurse System/Nurse Room/SW/Room Sw V1/NurseRoom.X/inc/boardinfo.h"
#elif DEVICE_TYPE == DISPLAY_POINT
#include "../../../../Nurse System/Nurse Display/SW/Display Sw V1/NurseDisplay.X/inc/boardinfo.h"
#elif DEVICE_TYPE == SAVE_POINT
#include "../../../../Nurse System/Nurse Master/SW/Master SW V1/NurseMaster.X/inc/boardinfo.h"
#endif

#ifdef __HAS_ELPM__

typedef unsigned long MyAddressType;
#else
typedef unsigned int MyAddressType;

#endif


static const uint8_t FlashboardInfoBackup[SPM_PAGESIZE] __attribute__((section(".varaddress"))) = {0};
static const uint8_t FlashboardInfo[SPM_PAGESIZE] __attribute__((section(".varaddress"))) = {0};
#define MIN_ADDREES        (0)    
#if   defined(__AVR_ATmega128A__) || defined (__AVR_ATmega128__)
#define BOOTSECTORSIZE     0x400 // 512 word * 2 = 1024 Byte    
#elif   defined(__AVR_ATmega16__)|| defined(__AVR_ATmega16A__) 
#define BOOTSECTORSIZE      0x200 // 256 word * 2 = 512 Byte 
#endif
#define ADR_FLASH_BUFFER       (MyAddressType)(FlashboardInfoBackup) // get page address from byte  
#define MAX_ADDRESS    FLASHEND-BOOTSECTORSIZE

#define FLASH_BUFFER_FULL_ID  0xAA

#define  APP_START      asm("JMP 0x0000")


#if __FLASH_RECOVER


typedef struct {
    uint16_t pageNumber; /*0x0000*/
    uint8_t status; /*0x0002*/
} stFlashBackup_t;
stFlashBackup_t EEMEM FlashBackup = {0};
#endif

                                                                   
static inline uint8_t _FlashAddressCheck(MyAddressType flashAdr);
static inline void WriteBufToFlash(MyAddressType flashStartAdr);
static inline void ReadModifyStoredTempPageBuf(MyAddressType flashAddr, uint8_t data);
#if __FLASH_RECOVER
static inline void RecoverFlash();
#endif
static inline uint8_t WriteFlashPage(MyAddressType flashStartAdr, uint8_t *dataPage);
static inline uint8_t WriteFlashByte(MyAddressType flashAddr, uint8_t data);
static inline uint8_t ReadFlashPage(MyAddressType flashStartAdr, uint8_t *dataPage);
static inline uint8_t ReadFlashByte(MyAddressType flashStartAdr);
static inline uint8_t ReadFlashByte(MyAddressType flashStartAdr);

static inline uint8_t _FlashAddressCheck(MyAddressType flashAdr) {
#if  __FLASH_RECOVER
    if (
            (flashAdr >= MIN_ADDREES) && /*address large than or equals start application address*/
            (flashAdr <= MAX_ADDRESS) && /*address less than or equals end application address*/
            (flashAdr != ADR_FLASH_BUFFER) &&/*address != Page 0 (information of the recovery mode*/
            !(flashAdr & (SPM_PAGESIZE - 1))) { /*address fill into page */
        return (1);
    } else {
        return (0);
    }
#else
    if (
            (flashAdr >= MIN_ADDREES) && /*address large than or equals start application address*/
            (flashAdr <= MAX_ADDRESS) && /*address less than or equals end application address*/
            !(flashAdr & (SPM_PAGESIZE - 1))) { /*address fill into page */
        return (1);
    } else {
        return (0);
    }
#endif
}
static inline void WriteBufToFlash(MyAddressType flashStartAdr)__attribute__((unused));

static inline void WriteBufToFlash(MyAddressType flashStartAdr) {
#ifdef __HAS_RAMPZ__ /*AVR uses the RAMPZ to access constant data above the 64K-byte boundary 
    https://imagecraft.com/help/ICCV8AVR/iccavr/6-programmingavr/accessing_memory_outside_of_the_64k_range.htm
    */
    flashStartAdr = (uint8_t) (flashStartAdr >> 16);
#endif
    boot_page_erase(flashStartAdr); /*erase page*/
    boot_spm_busy_wait(); /*wait for flash erase operation completed*/
    boot_page_write(flashStartAdr); /*store data Into Flash*/
    boot_spm_busy_wait(); /*wait for flash write operation completed*/
    boot_rww_enable(); /*enable read while write */
}


static inline void ReadModifyStoredTempPageBuf(MyAddressType flashAddr, uint8_t data) {
    /*
     *
     < Z-register 
      -------------------------------------
      | PCPAGE : Page address in the flash
      | PCWORD : address with in page
     */
    uint16_t byteWrite; /*R21,R2*/
    uint8_t oddByte; /*odd address indicator 0 when even and 1 when address is odd*/
    uint16_t pcWord; /* program counter word count in page The content of PCWORD in the Z-register is used to address the data in the temporary buffer*/
    MyAddressType pageAdr; /*first address of the Page  `*/
    oddByte = (uint8_t) (flashAddr & 1); /* 0bxxxxxxx1 is defined odd number and 0bxxxxxxx0 is even numbers (0bxxxxxxx1 &00000001) = 1 and (0bxxxxxxx0 & 0x00000001 = 0)  */
    /*
     < @note SPM_PAGESIZE = number of byte in page 
     * for example system has 32 word  0 to 31 words  = (0 to 31*2 Bytes)
     * to get address of the word from address of the byte
     * to get address word of current byte address (byte address & 62) 
     */
    pcWord = ((uint16_t) flashAddr & (SPM_PAGESIZE - 2)); /*start byte address in word*/
    /* < page  is 8 Byte size 
     * the last  byte address is 7 for any address is & ~7 ((remove is first 3 bit is zero))   
     * 00 to 07 is 00 start address of the page page 0
     * 08 to 15 is 08 start page 1
     * 16 to 23 is 16 start page 2
     * 24 to 31 is 24 start page 3
     */
    /*
     < @note SPM_PAGESIZE = number of byte in page 
     * for example system has 64 byte per page     = (0 to 63 Bytes)
     * to get page address is 0 or 1 or 2 or ......... of the current byte adderss
     * get last address byte (~63) and & with this value 
     */

    pageAdr = flashAddr & (~(SPM_PAGESIZE - 1)); // get page address from byte address into page
    for (uint16_t index = 0; (index < SPM_PAGESIZE); index += 2) { /*Increment by 2 because the index indicate two byte (word (Instruction))*/
        if (index == pcWord) { /*index reach current address access in the page*/
            /* <
             * flash address & ~1 fill same address odd with even
             * 0 1 word 1  (byte 0 stored in LSB in address (word count) 1 and  byte 1 stored in MSB in the same address)
             * 2 3 word 2  (byte 0 stored in LSB in address (word count) 2 and  byte 1 stored in MSB in the same address)
             * 4 5 word 3  (byte 0 stored in LSB in address (word count) 3 and  byte 1 stored in MSB in the same address)
             * 6 7 word 4  (byte 0 stored in LSB in address (word count) 4 and  byte 1 stored in MSB in the same address)
             * from table LSB strored in even and MSB stored into odd
             */
            if (oddByte) { /*current address is odd address*/
                /* current index is 6 and current address is 7
                 * get data from even address of the current Odd address (7&~1) = 6 7 is current odd address , 6 even address result 
                 * and set this data in LSB  and stored current data in MSB 
                 */
                /*
                 * get even address data and or with current data 
                 */
                byteWrite = (pgm_read_word(index + pageAdr) & 0x00FF) | ((uint16_t) (data << 8));
            } else {
                /* current index is 6 and current address is 6
                 * get data from odd address of the current even number and stored into MSB and stored 
                 * current address in LSB
                 */
                byteWrite = (pgm_read_word(index + pageAdr) & 0xFF00) | ((uint16_t) (data));
                // bootFillPage(byteWrite, index); // Write even byte in temporary buffer
            }
        } else { /*current index not equals current word count */
            /*store other data of the page into temp buffer*/
            byteWrite = pgm_read_word(index + pageAdr);
        }
        boot_page_fill(index, byteWrite);
    }
}
#if __FLASH_RECOVER

static inline void RecoverFlash() {
    uint16_t index;
    if (FlashBackup.status == FLASH_BUFFER_FULL_ID) { /*check recover page contians data or not*/
        for (index = 0; index < SPM_PAGESIZE; index += 2) { // Writes to Flash write buffer
            boot_page_fill(index, pgm_read_word(ADR_FLASH_BUFFER + index)); /*write Page 0 in temp page buffer*/
        }
        WriteBufToFlash((MyAddressType) (FlashBackup.pageNumber * SPM_PAGESIZE)); /*write data into fill buffer to recover*/
        FlashBackup.status = 0;
        eeprom_busy_wait(); /*wait free eeprom*/
        return;
    }
    return;
}
#endif

static inline uint8_t WriteFlashPage(MyAddressType flashStartAdr, uint8_t *dataPage) {
    uint16_t index;
    uint8_t eepromInterruptSettings;
    if (_FlashAddressCheck(flashStartAdr)) { /*check the address valid or not*/
        eepromInterruptSettings = EECR & (_BV(EERIE)); /*save Interrupt state of the eeprom*/
        EECR &= ~_BV(EERIE); /*Disable EEPROM Interrupt*/
        eeprom_busy_wait(); /*wait eeprom is ready*/
#if __FLASH_RECOVER /*before write data save cureent page write to Page 0 (recovery Buffer)*/
        FlashBackup.status = 0; /*reset recovery mode (recovery buffer is empty)*/
        eeprom_busy_wait(); /*status write into eeprom wait for write operation is done*/
        for (index = 0; index < SPM_PAGESIZE; index += 2) { /*Fills Flash write buffer*/
            boot_page_fill(index, (uint16_t) dataPage[index]+((uint16_t) dataPage[index + 1] << 8)); /*fill even and odd byte or fill odd and even byte in word address*/
        }
        WriteBufToFlash(ADR_FLASH_BUFFER); // Writes to Flash recovery buffer
        FlashBackup.pageNumber = (uint16_t) (flashStartAdr / SPM_PAGESIZE); /*page number from current address and page size*/
        FlashBackup.status = FLASH_BUFFER_FULL_ID; // Indicates that Flash recovery buffer
        eeprom_busy_wait(); /*wait eeprom is ready because the FlashBackup stored in eeprom*/

#endif
        /*save Page into buffer*/
        for (index = 0; index < SPM_PAGESIZE; index += 2) { // Fills Flash write buffer
            boot_page_fill(index, (uint16_t) dataPage[index]+((uint16_t) dataPage[index + 1] << 8)); /*fill even and odd byte or fill odd and even byte in word address*/
        }
        WriteBufToFlash(flashStartAdr); // Writes Page to Flash
#if __FLASH_RECOVER
        FlashBackup.status = 0; /* indicate that Flash buffer does  not contain data for writing*/
        eeprom_busy_wait(); /*wait eeprom is ready because the FlashBackup stored in eeprom*/
#endif
        EECR |= eepromInterruptSettings; // Restore EEPROM interrupt state
        return (1); /*write page operation is done*/
    }
    return (0); /*address valid and no write page*/
}
static inline uint8_t WriteFlashByte(MyAddressType flashAddr, uint8_t data) {
    MyAddressType pageAdr;
    uint8_t eepromInterruptSettings;
    uint8_t state;
    state = SREG;
    cli();
    if (_FlashAddressCheck(flashAddr & ~(SPM_PAGESIZE - 1))) { /*start address of the Page of the current address */
        eepromInterruptSettings = EECR & (1 << EERIE); /* save EEPROM interrupt state*/
        EECR &= ~(1 << EERIE); /* Disable EEPROM interrupt */
        eeprom_busy_wait(); /*wait for eeprom is ready to stored recovery state*/
        pageAdr = flashAddr & (~(SPM_PAGESIZE - 1)); /* start address of the Page of the current address*/
#if __FLASH_RECOVER
        FlashBackup.status = 0; /* Indicate Recovery buffer is empty*/
        eeprom_busy_wait(); /*wait for eeprom is ready to stored recovery state*/
        ReadModifyStoredTempPageBuf(flashAddr, data); /*Fills Flash write buffer*/
        WriteBufToFlash(ADR_FLASH_BUFFER); /* Writes to Flash recovery buffer*/
        FlashBackup.pageNumber = (unsigned int) (pageAdr / SPM_PAGESIZE); /*get Page number*/
        FlashBackup.status = FLASH_BUFFER_FULL_ID; /*Indicates that Flash recovery buffer is Full*/
        eeprom_busy_wait(); /*wait for eeprom is ready to stored recovery state and page number*/
#endif
        ReadModifyStoredTempPageBuf(flashAddr, data); /* Fills Flash write buffer*/
        WriteBufToFlash(pageAdr); /* Writes to Flash with word address*/
#if __FLASH_RECOVER
        FlashBackup.status = 0; // Indicates that Flash recovery buffer
        eeprom_busy_wait(); /*wait for eeprom is ready to stored recovery state */
#endif
        EECR |= eepromInterruptSettings; // Restore EEPROM interrupt state
        SREG = state;
        return (1); /* return 1 if address valid for writing*/
    }
    return (0); /*return 0 if address not valid for writing*/
}

static inline uint8_t ReadFlashByte(MyAddressType flashStartAdr) {
    return (uint8_t) (pgm_read_byte(flashStartAdr)); /*return data stored into flash address*/
}


static inline uint8_t ReadFlashPage(MyAddressType flashStartAdr, uint8_t *dataPage) {
    uint16_t index;
    if (!(flashStartAdr & (SPM_PAGESIZE - 1))) { /*  input address is a page address*/
        for (index = 0; index < SPM_PAGESIZE; index++) {
            dataPage[index] = ReadFlashByte(flashStartAdr + index); /*get data from address and stored into buffer*/
        }
        return 1; /* return 1 if valid page address*/
    } else {
        return 0; /* return 0 if not valid page address*/
    }
}






static  inline void bootloaderDriver() {
    /*check the state of the Ram */
    volatile boardinfo_t *BoardInfo;
    uint8_t buf[SPM_PAGESIZE];
    for (uint8_t i = 0; i < SPM_PAGESIZE; i++) {
        buf[i] = 0x00;
    }
    BoardInfo = (boardinfo_t *) (BoardInfoAddress);
    uint8_t *BoradInfoBytes = (uint8_t *) BoardInfo;

    if (BoardInfo->State == 1) {
        for (uint8_t i = 0; i< sizeof (boardinfo_t); i++) {
            buf[i] = BoradInfoBytes[i + 1];
        }
        WriteFlashPage((MyAddressType) (FlashboardInfo), buf);
        BoardInfo->State = 0;
    }
#if __FLASH_RECOVER
    RecoverFlash();   
#endif
    for (uint8_t i = 0; i< sizeof (boardinfo_t) + 1; i++) {
        BoradInfoBytes[i + 1] = pgm_read_byte(FlashboardInfo + i);
    }

    APP_START;
}

#endif /* APP_H */

主要功能是


#include "../inc/app.h"

__attribute__((naked)) __attribute__((section(".ctors"))) void boot(void) {
    asm volatile("clr r1");
    pgm_read_byte(&FlashboardInfoBackup[0]); /*init the backup to 0*/
    while (1) {
        bootloaderDriver();
   }
}

bootloader avr-gcc atmega16
© www.soinside.com 2019 - 2024. All rights reserved.