1
我目前正在開發基於Atmel的at91sam7s256 MCU的器件功能。該功能是具有預設值的計數器,在某些點上會減少。 我的想法是在內部閃存中實現此計數器,因爲大部分閃存空間都未使用。在內部寫入at91sam7s256閃存
我在ld腳本中添加了一個單獨的鏈接器部分,並在此部分包含了一個變量。鏈接描述:當計數器減
/*
FLASH is reserved for internal settings
*/
MEMORY
{
CODE (rx) : ORIGIN = 0x00100000, LENGTH = 252k
FLASH (rx) : ORIGIN = 0x0013F000, LENGTH = 4k
DATA (rwx) : ORIGIN = 0x00200000, LENGTH = 64k
}
__FIRST_IN_RAM = ORIGIN(DATA);
__TOP_STACK = ORIGIN(DATA) + LENGTH(DATA);
/* Section Definitions */
SECTIONS
{
/* first section is .text which is used for code */
. = ORIGIN(CODE);
.text :
{
KEEP(*(.vectorg))
. = ALIGN(4);
KEEP(*(.init))
*(.text .text.*) /* remaining code */
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.gcc_except_table)
*(.rodata) /* read-only data (constants) */
*(.rodata.*)
*(.gnu.linkonce.r.*)
. = ALIGN(4);
} >CODE
. = ALIGN(4);
/* .ctors .dtors are used for c++ constructors/destructors */
.ctors :
{
PROVIDE(__ctors_start__ = .);
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
PROVIDE(__ctors_end__ = .);
} >CODE
.dtors :
{
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
} >CODE
. = ALIGN(4);
_etext = . ;
PROVIDE (etext = .);
/* .data section which is used for initialized data */
.data : AT (_etext)
{
_data = . ;
KEEP(*(.vectmapped))
. = ALIGN(4);
*(.fastrun .fastrun.*)
. = ALIGN(4);
SORT(CONSTRUCTORS)
. = ALIGN(4);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(4);
} >DATA
. = ALIGN(4);
_edata = . ;
PROVIDE (edata = .);
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
__bss_start = . ;
__bss_start__ = . ;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >DATA
. = ALIGN(4);
__bss_end__ = . ;
.flash :
{
. = ORIGIN(FLASH);
*(.flash*)
. = ALIGN(4);
} >FLASH
_end = .;
PROVIDE (end = .);
}
以下例程用於:
#define INTERNAL_FLASH __attribute__((section(".flash")))
#define AT91C_MC_WRITE_KEY ((unsigned)0x5A << 24) // Magic number
INTERNAL_FLASH uint32_t Counter = 30; // The section .flash begins at 0x0013F000
void prepaid_decrement(void)
{
if(Counter > 0) {
// write into buffer
Counter = Counter - 1;
volatile AT91PS_MC mc = AT91C_BASE_MC;
// set flash mode (timing)
mc->MC_FMR = AT91C_MC_FWS_1FWS | ((1 + (((MCK * 15)/10000000))) << 16);
uint32_t page = ((uint32_t)&Counter - (uint32_t)AT91C_IFLASH)/(uint32_t)AT91C_IFLASH_PAGE_SIZE;
// start writing
mc->MC_FCR = AT91C_MC_WRITE_KEY | AT91C_MC_FCMD_START_PROG | (page << 8);
if(0 != (mc->MC_FSR & AT91C_MC_PROGE)) {TRACE("error!");}
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
}
}
但代碼掛在 mc->MC_FCR = AT91C_MC_WRITE_KEY | AT91C_MC_FCMD_START_PROG | (page << 8);
。下面的行永遠不會到達,因爲MCU跳轉到異常循環(向量表中的地址0x60)。
無論如何,數據似乎被正確寫入,因爲重置後計數器變量減少了一個。
誰能告訴我我做錯了什麼?代碼沒有被打斷。
「計數器=計數器-1」嘗試寫入閃存中的地址,該地址最可能是隻讀區域。你沒有粘貼你的鏈接腳本。 – mkmk88
該變量鏈接到該部分開頭的固定地址。這意味着(buffer-)變量是可寫的,也可以通過調用寫入命令寫入閃存。但不知何故,它掛在這個命令,雖然閃光燈已經寫好。 – eeucalyptus
我沒有使用這個特定的MCU,但根據文檔:http://www.atmel.com/Images/doc6175.pdf內部閃存介於0x00100000和0x001FFFFF之間。您的代碼指示將變量「counter」放入「.flash」部分。源代碼中的註釋指出,「.flash」在0x0013F000處,這實際上是內部閃存。本節最可能是隻讀的。沒有看到你的鏈接腳本,我不能幫助更多。 – mkmk88