Поиск по сайту:

 


По базе:  

микроэлектроника, микросхема, микроконтроллер, память, msp430, MSP430, Atmel, Maxim, LCD, hd44780, t6963, sed1335, SED1335, mega128, avr, mega128  
  Главная страница > Статьи > Средства разработки

реклама

 




Мероприятия:




LMA и VMA

В этом примере рассмотрим работу с секцией инициализированных данных. Организация этой секции важна для связывания модулей написанных на языках высокого уровня. На рисунке 3 представлено, как располагаются секции, когда требуется задать секцию инициализированных данных. Необходимость определения инициализированных данных можно обойти, создав необходимые константы, которые будут размещены в ROM, а затем в программе будут копироваться в область неинициализированных данных (секцию .bss). Но для поддержки языков высокого уровня требуется другая методика.


Рисунок 3

Секцию .data размещают в ROM, а затем, её содержимое переносится в RAM . Таким образом, перед выполнением прикладной программы, нужно выполнить некоторый код инициализации, а так же задать соответственные команды в скрипте линковки. Каждый символ в секции .data будет иметь два различных адреса. Один адрес в области ROM - LMA (Load Memory Address). А другой адрес в RAM - VMA (Virtual Memory Address).

Конечная программа будет работать с адресами VMA.

Скрипт компоновщика приведён ниже:

	
MEMORY {  ROM (RX) : ORIGIN = 0x0 LENGTH = 128K
          RAM (RW) : ORIGIN = 0x020000000 LENGTH = 8K 
       }
SECTIONS { .text  :      {
            * (.text);   } > ROM
          .rodata :      {
            * (.rodata);
            flash_sd = .; } > ROM
          .bss :      {
            * (.bss); } > RAM
          .data  : AT (flash_sd) {
              ram_sd = . ; 
            * (.data);
              ram_ed = . ;       } > RAM 
          d_size = SIZEOF(.data) ; }
	 

Первыми идут секции кода. В стандарте языка линкера, предусмотрена возможность задания программистом символов хранящих адреса и константы. Значения этих символов доступны из программного кода. В скрипте определяется символ flash_sd , он хранит адрес конца секции констант и начало области, где будут размещаться символы секции .data в ROM. Символы ram_sd и ram_ed , содержат адреса начала и конца секции .data в RAM. Символ d_size хранит размер секции .data . Для определения размера секции .data использовалась стандартная функция SIZEOF . В коде инициализации, значения этих символов будут использоваться для копирования секции .data из ROM в RAM. Ключевое слово AT определяет адрес загрузки секции в ROM. Линковщик расположит её за секцией .rodata в ROM, в то время как адреса символов принадлежащих этой секции, будут соответствовать расположению в RAM. Чтобы всё стыковалось, и программа нормально работала, содержимое секции из ROM нужно скопировать в RAM программным кодом инициализации. Текст на ассемблере приведён ниже.

	
@ example 3
    .syntax unified
    .cpu cortex-m3
    .thumb
 .equ  STACKINIT, 0x20002000 
  .section .text
   .type start , %function
   .type _nmi_handler , %function
   .type _hard_fault , %function
   .type _memory_fault , %function
   .type _bus_fault , %function
   .type _usage_fault , %function
     .word STACKINIT        @ stack pointer value 
     .word start            @ reset
     .word _nmi_handler
     .word _hard_fault
     .word _memory_fault
     .word _bus_fault
     .word _usage_fault
 start:		            
   ldr r0, =flash_sd  @ copy section data
   ldr r1, =ram_sd
   ldr r2, =d_size
 copy:
   ldrb r4, [r0], #1
   strb r4, [r1], #1
   subs r2, r2, #1
   bne copy          @ end copy section data

   ldr r0, =var1
   ldr r1, =var2

  ldr r2, [r0]
  ldr r3, [r1]
  add r4, r2, r3
  ldr r0, =res
  str r4, [r0]
      stop:   b stop    @ trap
  _dummy:               @ handlers
  _nmi_handler:
  _hard_fault:
  _memory_fault:
  _bus_fault:
  _usage_fault:   add r0, 1
                  add r1, 1
                  b _dummy
 .section .rodata       
   .word 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA
 .section .data
      var1 :    .word 11
      var2 :    .word 22
      res :     .word 0
 .section .bss
      buf :    .skip 32 * 4
 .end
	

В этом примере используется директива .type . В данном случае она применяется для задания типа метки программного кода. При использовании этой директивы, необходимость в увеличении на единицу значения адреса, как в предыдущих примерах, отпадает.

В начале программы команды, выполняющие копирование секции инициализированных данных, а затем простейший код, выполняющий суммирование значений 2-х переменных.

Реальные значения символов определённых в скрипте линкера, можно узнать, воспользовавшись утилитой arm-none-eabi-nm, из инструментария.

Для контроля результатов компоновки, выполняем команду:

	
     arm-none-eabi-objdump -h ./ex3.elf
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000068  00000000  00000000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .rodata       00000010  00000068  00000068  00008068  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .bss          00000080  20000000  20000000  00010000  2**0
                  ALLOC
  3 .data         0000000c  20000080  00000078  00008080  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  4 .ARM.attributes 00000021  00000000  00000000  0000808c  2**0
                  CONTENTS, READONLY
  5 .debug_line   0000004e  00000000  00000000  000080ad  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_info   00000042  00000000  00000000  000080fb  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_abbrev 00000014  00000000  00000000  0000813d  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_aranges 00000020  00000000  00000000  00008158  2**3
                  CONTENTS, READONLY, DEBUGGING
		 

Кроме размеров секций, дамп вывода содержит VMA и LMA адреса начала секций. У секции .data , VMA и LMA адреса не совпадают. Дополнительно, эта утилита выводит информацию об атрибутах секций. Атрибут LOAD (loadable section) - содержимое секции будет загружено в память целевой системы. Атрибут ALLOC (allocatable section) - секция будет занимать место в адресном пространстве во время выполнения. Секция bss не имеет данных для загрузки в память целевой системы, но имеет размер. Поэтому она имеет только атрибут ALLOC. Секция ARM.attributes - выполняет служебные функции и не имеет данных для размещения в памяти целевой системы, поэтому не имеет атрибутов ALLOC и LOAD. Секции отладки так же не размещаются в памяти целевой системы, эти секции использует отладчик. Значения остальных атрибутов очевидны.

<-- Предыдущая страница Оглавление Следующая страница -->





 
Впервые? | Реклама на сайте | О проекте | Карта портала
тел. редакции: +7 (995) 900 6254. e-mail:info@eust.ru
©1998-2023 Рынок Микроэлектроники