2014年11月2日 星期日

作業系統之前的程式 for stm32f4discovery (9) - CCM

我最近 (201410) 才從 datasheet 知道 ccm 這東西。stm32f4discovery 有 192k sram, 不過是這樣分佈的:

sram1: 112k
sram2: 16k
ccm (core coupled memory): 64k

sram1, sram2 從 0x2000 0000 開始的 128k
ccm 從 0x1000 0000 開始的 64K

192k 的位址並不連續, 而且 ccm 只能存資料, 無法存指令, 那麼該怎麼運用這塊記憶體呢? 我把他用在 stack 上, 有 64k 的 stack, 在這嵌入式平台上真是奢侈。

修改 linker script 加入一個 .ccm section, 以及在程式碼使用 __attribute__((section(".ccm"))), 將某個變數存放到 .ccm section。

stm32.ld
 1 /*
 2 MEMORY
 3 {
 4   FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K
 5   SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
 6 }
 7 */
 8 
 9 /* Specify the memory areas */
10 /* form: STM32F4-Discovery_FW_V1.1.0/Project/Peripheral_Examples/IO_Toggle/TrueSTUDIO/IO_Toggle/stm32_flash.ld */
11 MEMORY
12 {
13   FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
14   CCM (rw)        : ORIGIN = 0x10000000, LENGTH = 64K /* 0x1000_0000 ~ 0x1000_FFFF. */
15   SRAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 128K
16   MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
17 }
18 
19 
20 SECTIONS
21 {
22   .text :
23   {
24     KEEP(*(.isr_vector .isr_vector.*))
25     *(.text .text.*)
26     *(.rodata .rodata*)
27     _etext = .;
28   } > FLASH
29 
30   .ccm(NOLOAD):
31   {
32     . = ALIGN(8);
33     *(.ccm)
34     . = ALIGN(8);
35   } > CCM
36 
37   .data : AT (_etext)
38   {
39     _data = .;
40     *(.data .data.*)
41     _edata = .;
42   } > SRAM
43   .bss(NOLOAD) :
44   {
45     _bss = .;
46     *(.bss .bss.*)
47     *(COMMON)
48     . = ALIGN(4);
49     _ebss = .;
50   } > SRAM
51 
52   . = ALIGN(4);
53   _end = .;
54 }

ex:
#define STACK_SIZE 0xffff

__attribute__((section(".ccm")))
static u8 stack[STACK_SIZE];

stm32.h
  1 #ifndef STM32_H
  2 #define STM32_H
  3 
  4 #include "lib_mygpio_led.h"
  5 
  6 #define STACK_SIZE 0xffff
  7 extern unsigned long _etext;
  8 extern unsigned long _data;
  9 extern unsigned long _edata;
 10 extern unsigned long _bss;
 11 extern unsigned long _ebss;
 12 
 13 extern "C"
 14 {
 15   int mymain();
 16 }
 17 
 18 void ResetISR(void)
 19 {
 20   unsigned long *pulSrc, *pulDest;
 21 
 22   pulSrc = &_etext;
 23   for (pulDest = &_data; pulDest < &_edata;)
 24     *pulDest++ = *pulSrc++;
 25   for (pulDest = &_bss; pulDest < &_ebss;)
 26     *pulDest++ = 0;
 27 
 28   mymain();
 29 }

 94  __attribute__((section(".ccm")))
 95 static u8 stack[STACK_SIZE];
 98 __attribute__((section(".isr_vector")))
 99 pfnISR VectorTable[]=
100 {
101   (pfnISR)((unsigned long)stack + STACK_SIZE),
102   ResetISR, // 1
103   int_isr,
104   int_isr,
105   int_isr,
106   int_isr,
107   int_isr,
108   int_isr,
109   int_isr,
110   int_isr,
111   int_isr,
112   svc_isr,    // 11
113   int_isr,
114   int_isr,
115   pendsv_isr, // 14
116   systick_isr, // 15
117 
128 };
129 
130 #endif

以下是根據 stm32.ld 編譯出來的 bin 檔。

hexdump -C myur.bin
00000000 ff ff 00 10 41 00 00 08 35 01 00 08 35 01 00 08

前四個 byte 是 sp 的位址, 已經指到 ccm 區域。不過我用 gdb step 時, sp 的值是 0x1000fffc, 這是個疑問??是 alignment 的問題, 改成

#define STACK_SIZE 0xfff0, sp 就是 0x1000fff0。

完整範例:
https://github.com/descent/stm32f4_prog/tree/master/float

ref: http://wiki.csie.ncku.edu.tw/embedded/Flash

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。