非常茶花 发表于 2019-3-20 15:43:43

FLASH 使用__attribute__,於指定位置放入固定變數問題

想請教一下,目前使用STM32F051K6T7,這顆有32K的Flash空間,當我在程式裡面要增加一個Word值放在FLASH的0x7FFC的位置裡面,也就是FLASH最後面的位置 但是當我下下面的指令後int const IAP_End_Address__attribute__((at(0x08007FFC))) = 0x01234567; 卻出現下面的ERROR Warning: L6969W: Changing AT Section.ARM.__AT_0x08007800 type from RW to RO in ER_IROM1.Error: L6406E: No space in executionregions with .ANY selector matching __dczerorl2.o(.text).Error: L6407E: Sections of aggregate size0x58 bytes could not fit into .ANY selector(s). 但是當我放在0x08007FA4則可以使用,
使用Debug下去看,從0x08007FD8位置也都沒有放任何值,都是0xFF

請問為什麼我的值沒辦法放在FLASH最後的位置呢?

toofree 发表于 2019-3-20 17:59:33

看一下你的.map文件,以及生成的hex或bin文件,内有乾坤。
RW的数据会放在Flash的最后面。







非常茶花 发表于 2019-3-21 12:10:36

我早上在看MAP的時候也發現了這一點,.RW是不是就必須從最後面開始放,沒有其他解了呢?

toofree 发表于 2019-3-21 16:02:12

非常茶花 发表于 2019-3-21 12:10
我早上在看MAP的時候也發現了這一點,.RW是不是就必須從最後面開始放,沒有其他解了呢? ...

那你得研究一下链接文件怎么修改,keil下对应的是.sct文件。

wenyangzeng 发表于 2019-3-21 16:26:05

本帖最后由 wenyangzeng 于 2019-3-21 16:31 编辑

0x1234567应该是uint32_t 而非int呀
这个IAP_End_Address和__attribute_((at(0x08007ffc)))之间应该留一个空格才是;

赋值是否应该分2步:
uint32_t const IAP_End_Address __attribute_((at(0x08007ffc)));
IAP_End_Address = 0x1234567;


非常茶花 发表于 2019-3-21 17:03:47

wenyangzeng 发表于 2019-3-21 16:26
0x1234567应该是uint32_t 而非int呀
这个IAP_End_Address和__attribute_((at(0x08007ffc)))之间应该留一个 ...



1.這部分有空格沒錯,可能是複制上漏掉了

2.目前我只是把值寫進FLASH裡面,然後撈出來判斷是不是這個值而已,並沒有需要看到10進制的值,所以在寫入上int和uint32_t都可以使用,比較沒有注意這個部分

3.在賦值上若在main.c裡面是可以直接賦值的,如果把變數另外拉到 .h 做宣告,則需要兩段式賦值,這個部份我比較不了解為什麼,不過因為我需要值是直接寫在FLASH裡面的,讀的時候也是從FLASH裡面讀取,所以在宣告的時候就要一起賦值了,不然會因為FLASH的特性無法更改裡面的值,得整個Section Erase掉才可以重新改變Flash的值,且Eraseㄧ個Section目前至少須要0x1000的空間,所以需要這樣做。

4.然後我記得Const這個部分是寫在FLASH的,不會拉到RAM所以無法重新賦值給他,應該跟我第三項所說的一樣,FLASH有無法更改的特性,除非使用FLASH指令,但FLASH寫入只能由1改成0,若由0改成1還是得用Erase的功能才行。

edmundlee 发表于 2019-3-21 19:49:22

Options for the Target..->Linker--> 去勾Use Memory Layout.. --> Edit(Scatter File *.sct)

LR_IROM1 0x08000000 0x00004000{    ; load region size_region
ER_IROM1 0x08000000 0x00003400{; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
}
API_IROM1 0x08003400 0x00000C00{
        *.o(apiSection)
}

RW_IRAM1 0x20000000 0x00001000{; RW data
   .ANY (+RW +ZI)
}
}
加上红色部分

然后再
const u16 __attribute__((section("apiSection"))) CmdLengthList[]={....

非常茶花 发表于 2019-3-22 09:44:39

edmundlee 发表于 2019-3-21 19:49
Options for the Target..->Linker--> 去勾Use Memory Layout.. --> Edit(Scatter File *.sct)

LR_IROM1 0 ...

依照你的步驟設置完成後,發現他不會照著我要的位置放,這顆SIZE是0x40000,我要把值放在0x3FFFC裡面
LR_IROM1 0x08003000 0x0003CFFC{    ; load region size_region
ER_IROM1 0x08003000 0x0003CFFC{; load address = execution address
   *.o (RESET, +First)
   *(InRoot$Sections)
   .ANY (+RO)
}
    API_IROM1 0x0803FFFC 0x00000004{
      *.o(apiSection)
}
RW_IRAM1 0x200000BC 0x00007F44{; RW data
   .ANY (+RW +ZI)
}
}但是不管是使用

int const IAP_End_Address __attribute__((section("apiSection"))) = 0x12345678;

或是

int const IAP_End_Address __attribute__((at(0x0803FFFC))) = 0x12345678;

都不是放在我需要的位置,後來我在這邊增加IROM2,才能把我要的值放在最後面





在把.SCT擋叫出來看




static/image/hrline/1.gif


這邊我有先把User Memory Layout 勾勾取消,編輯後存檔,
但是怎麼樣就是無法放到0x083FFFC的位置,只能將IROM2打開分配另外ㄧ個空間才行
页: [1]
查看完整版本: FLASH 使用__attribute__,於指定位置放入固定變數問題