Перейти к содержанию
    

Как зарезервировать страницу памяти в середине кода

On 2/29/2024 at 10:11 AM, makc said:

Здесь нет озвученной ТС фиксации адреса блока параметров. Он может меняться.

Я эту идею вообще не понял )))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, Ivan. сказал:

Все определено:

Да, точно, я не посмотрел на карту всей памяти, т.к. сам никогда не бью регионы таким образом. У меня карта регионов отражает физическую структуру памяти МК, а не логическое распределение.

Только что, dimka76 сказал:

Я эту идею вообще не понял )))

Его идея у вас уже реализована. Так что в принципе есть консенсус. 🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока так и сделал.

Жаль, что нельзя сделать так:
 

2 часа назад, Ivan. сказал:

.text :
  {
.....
  } >FLASH1, FLASH2

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 2/29/2024 at 10:22 AM, Ivan. said:

Пока так и сделал.

Жаль, что нельзя сделать так:

Если вы хотите кружануть и по максимому использовать первую секцию памяти, то можно указать куда линковать 

конкретные объектные файлы или даже отдельные функции. 

Например так в коде

void SysTick_Handler(void) __attribute__((section(".isr_vector")));

Или так в LD файле

.isr_vector :
  {
    . = ALIGN(8);
    _image_start = ABSOLUTE(.);
    KEEP(*(.isr_vector)) /* Startup code */
      
      stm32f30x_it.o(*) /* размещаем объектный файл в секции isr_vector */
      
    . = ALIGN(8);
  } >ISR_FLASH  

Сам не пробовал, взял из AN4296 Application note от STM

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Ivan. сказал:

заполнить его еще чем нибудь вручную, например: Initialized data и постоянно за этим следить

Так и сделал

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Ivan. сказал:

И в Вашем и в моем случае разрыв будет. По этому я и ищу способ не выбрасывать ~16К на выравнивание. вектора занимают 400Б и init 40Б, а остальное на выравнивание.
Я хочу, чтобы линковщик по максимуму разместил данные в первом секторе, а потом перескочил на третий.

GNU LD не умеет работать с регионами в которых есть "дырки". На это тикет уже лет 10 висит, разработчикам похер. Либо заполняйте вручную либо будет потеряно место.

IAR - умеет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Покажу, как это сделано у меня.

STM32F4. Раскладка флэша:

16К - векторы;

32К (16К+16К) - байт-код программы пользователя;

16К - параметры програграммы пользователя по умолчанию;

64К - резерв;

всё остальное программа МК.

Скрипт линковщика:

Spoiler
/**
 ******************************************************************************
 * @file      LinkerScript.ld
 * @author    Auto-generated by STM32CubeIDE
 *  Abstract    : Linker script for Discovery-F446xx Board embedding STM32F446xx
 *                device from stm32f4 series
 
                512Kbytes FLASH
 *              128Kbytes RAM
 *
 *            Set heap size, stack size and stack location according
 *            to application requirements.
 *
 *            Set memory bank area and size if external memory is used
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);    /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x800;   /* required amount of heap  */
_Min_Stack_Size = 2K;   /* required amount of stack */

/* Memories definition */
MEMORY
{
    RAM                 (xrw)   : ORIGIN = 0x20000000, LENGTH = 128K
    BKPSRAM             (xrw)   : ORIGIN = 0x40024000, LENGTH = 4K
    
    SECTOR_0            (rx)    : ORIGIN = 0x08000000, LENGTH = 16K
    SECTOR_1_2          (rx)    : ORIGIN = 0x08004000, LENGTH = 32K
    SECTOR_3            (rx)    : ORIGIN = 0x0800C000, LENGTH = 16K  
    SECTOR_4            (rx)    : ORIGIN = 0x08010000, LENGTH = 64K /* Reserved */  
    SECTOR_5_7          (rx)    : ORIGIN = 0x08020000, LENGTH = 384K  
}

/* Sections */
SECTIONS
{
  .bkpsram :
  {
    . = ALIGN(1);
    KEEP(*(.bkpsram))
    . = ALIGN(4);
  } >BKPSRAM

  /* The startup code into "FLASH" Rom type memory */
  .isr_vector_FLASH :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector_FLASH)) /* Startup code */
    . = ALIGN(4);
  } >SECTOR_0

  .plc_params :
  {
    . = ALIGN(2);
    
    KEEP (*(.plc_params))
                    
    /*. = ALIGN(2);*/
  } >SECTOR_1_2
  
  .plc_prog :
  {
    /*. = ALIGN(2);*/
    KEEP (*(.plc_prog))
                    
    . = ALIGN(2);
  } >SECTOR_1_2
     
  .plc_D8xxx :
  {
    . = ALIGN(2);
    
    KEEP (*(.plc_D8xxx))
                    
    . = ALIGN(2);
  } >SECTOR_1_2
        
  .plc_data_regs :
  {
    . = ALIGN(2);
    
    KEEP (*(.plc_data_regs))
                    
    . = ALIGN(2);
  } >SECTOR_3
        
  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >SECTOR_5_7

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >SECTOR_5_7

  .ARM.extab   : { 
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >SECTOR_5_7
  
  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >SECTOR_5_7

  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >SECTOR_5_7
  
  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >SECTOR_5_7
  
  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >SECTOR_5_7
  
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM" Ram type memory */
  .isr_vector_RAM :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector_RAM))
    PROVIDE_HIDDEN ( __isr_vector_RAM = .);
    . = ALIGN(4);
  } >RAM

  
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
    
  } >RAM AT> SECTOR_5_7

  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough "RAM" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM

  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

 

Размещение данных по этим областям:

Spoiler
.....

const uint8 __PLC_params[ SIZE_BYTE_PARAMS ] \
    __attribute__ ( (section( ".plc_params" ), used ) ) =
{
    //MAX_STEP / 1000, 0x00,  // 00 0x0000 -- SIZE IN STEP 16000
    0x02, 0x00,  // 00 0x0000 -- SIZE IN STEP 16000
    0x00, 0x00,             // 02        --
    0x00, 0x00,             // 04        --
    0x00, 0x00,             // 06        --

    0x20, 0x20,             // 08 0x0008 -- PASSWORD 0
    0x20, 0x20,             // 10        -- PASSWORD 1
    0x20, 0x20,             // 12        -- PASSWORD 2
    0x20, 0x20,             // 14        -- PASSWORD 3

    'S', 'K',               // 16 0x0010 -- PLC NAME 0
    '2', 'N',               // 18        -- PLC NAME 1
    '-', 'F',               // 20        -- PLC NAME 2
    '4', '6',               // 22        -- PLC NAME 3
    '6',   0,               // 24        -- PLC NAME 4
      0,   0,               // 26        -- PLC NAME 5
      0,   0,               // 28        -- PLC NAME 6
      0,   0,               // 30        -- PLC NAME 7
      0,   0,               // 32        -- PLC NAME 8
      0,   0,               // 34        -- PLC NAME 9
      0,   0,               // 36        -- PLC NAME A
      0,   0,               // 38        -- PLC NAME B
      0,   0,               // 40        -- PLC NAME C
      0,   0,               // 42        -- PLC NAME D
      0,   0,               // 44        -- PLC NAME E
      0,   0,               // 46        -- PLC NAME F

    0x00,0x08,              // 48 0x0030 -- M   Latch Start 0
    0xFF,0x0B,              // 50        -- M   Latch End   1023
    0x00,0x00,              // 52        -- S   Latch Start 0
    0xE7,0x03,              // 54        -- S   Latch End   999
    0x00,0x0E,              // 56        -- C16 Latch Start /
    0xC7,0x0E,              // 58        -- C16 Latch End   /
    0xC8,0x0E,              // 60        -- C32 Latch Start /
    0xFF,0x0E,              // 62        -- C32 Latch End   /

    0x00,0x00,              // 64 0x0040 -- D   Latch Start /
    0xFE,0x03,              // 66        -- D   Latch End   /
    0x00,0x00,              // 68        --
    0x00,0x00,              // 70        --
    0x00,0x00,              // 72        -- File register address
    0x00,0x00,              // 74        -- File register capaity blocks
    0x00,0x00,              // 76        -- Comments address
    0x00,0x00,              // 78        -- Comments capaity blocks

    0x00,0x00,              // 80 0x0050 -- 0x80 ( RUN X007 -- X000 ) 0x40 -- PLC system 1/2
    0x00,0x00,              // 82        --
    0x00,0x00,              // 84        --
    0x00,0x00,              // 86        --
    0x00,0x00,              // 88        --
    0x00,0x00,              // 90        --
};
const uint16 __PLC_prog[ 16000 ] \
    __attribute__ ( (section( ".plc_prog" ), used ) ) =
{
    0x2800, 0xC801, 0x001C, // -|M0|-(M1)-
    0xFFFF,                 // ----[FEND]-
    0x000F                  // -----[END]-
};

const uint16 __PLC_simple_programm[] \
 =
{
    0x2800, 0xC801, 0x001C, // -|M0|-(M1)-
    0xFFFF,                 // ----[FEND]-
    0x000F                  // -----[END]-
};

.....

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, Ivan. сказал:

а потом указать, что секцию .text разместить в этих 2 регионах
  .text :
  {
.....
  } >FLASH1, FLASH2

Зачем? Какой смысл? У вас уже код так вырос, что нет места во флешь? Тогда лучше просто включить оптимизацию по размеру. Это даст гораздо бОльший выигрыш, чем жалкие 16КБ.

Размазывание .text по нескольким несвязанным регионам в общем случае снижает эффективность кода (снижает скорость его выполнения). А скорость выполнения более важный фактор, чем размер кода (в наше время). Поэтому лучше оставить младший сектор полупустым. Ну или разместить в нём какие-то const-данные большого размера (если таковые имеются). Так же часто первый(-ые) сектор(-а) оставляют для bootloader-а (даже если пока у вас его нет).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 минут назад, jcxz сказал:

Размазывание .text по нескольким несвязанным регионам в общем случае снижает эффективность кода (снижает скорость его выполнения).

Данное измышление необходимо обосновать. Пока оно выглядит высосанным из пальца даже если приплести влияние ART акселератора. В большой программе функции как правило лежат не в порядке их вызова при исполнении так что в любом случае будет обращение не в линейном порядке адресов.

 

Цитата

А скорость выполнения более важный фактор, чем размер кода (в наше время).

Это кому как.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 минуты назад, jcxz сказал:

Зачем? Какой смысл? У вас уже код так вырос, что нет места во флешь?

Да на самом деле нет, просто хотел идеальный вариант. Вообще к концу разработки в первый сектор ляжет Boot, а App уже куда угодно.

 

12 минут назад, _3m сказал:

А скорость выполнения более важный фактор, чем размер кода (в наше время).

Приоритет:
1. Надежность
2. Читаемость исходника
3. Скорость / объем (на выбор)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, _3m сказал:

Данное измышление необходимо обосновать. Пока оно выглядит высосанным из пальца даже если приплести влияние ART акселератора.

Если вы не знакомы с системой команд ARM, то что-то обосновывать вам бесполезно. А если знакомы - то обосновывать не нужно, так как и сами понимаете причину.

 

PS: Дальность переходов в системе команд ограничена разрядностью смещений (в соответствующих инструкциях CPU). Чем дальше переходы - тем более тяжёлые команды переходов будут использованы. А в некоторых случаях даже переходы будут осуществляться через специальные промежуточные вставки кода (когда расстояний перехода не хватает). Соответственно такой код будет выполняться медленнее и будет тяжелее.

Это во-первых, во-вторых: дальность адресации .const-данных, адресуемых через PC (в ARM-коде таких данных много), тоже ограничена разрядностью смещений в коде команд. Чем данные дальше от PC, тем (в среднем) больше и более тяжёлых команд нужно для их адресации.

А при указании .text {  } >FLASH1, FLASH2 как компоновщик раскидает код - неизвестно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

+ вызов функций из другого региона памяти, как правило, будет идти через виниры, и нафига оно надо?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 минут назад, Arlleex сказал:

+ вызов функций из другого региона памяти, как правило, будет идти через виниры, и нафига оно надо?

Я об этом писал:

2 часа назад, jcxz сказал:

А в некоторых случаях даже переходы будут осуществляться через специальные промежуточные вставки кода (когда расстояний перехода не хватает)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 часов назад, Ivan. сказал:

Первые страницы могут иметь маленький размер, а последние по 128 или 256 кБ.

Простите, что со своим самоваром встреваю, но в первой странице-двух  располагаю загрузчик, позволяющий передавать заказчику зашифрованный образ обновленной прошивки и заливать его через имеющийся интерфейс (а не тот, который решили использовать ST), далее еще один маленький сектор на настройки и все остальное под рабочую программу, ей уже все равно, какого размера сектора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...