#linker #arm #embedded #cortex-m #bit-banding
#компоновщик #рука #встроенный #cortex-m #кольцевание долот
Вопрос:
Есть ли способ разрешить компоновщику ARM RealView / Keil выбирать из более чем одного, но не из всех регионов?
Я могу использовать .ANY
спецификатор, чтобы предоставить компоновщику свободу действий, и я могу использовать *(section_name)
спецификатор для определения местоположения определенных объектов в одном регионе, но я хотел бы иметь возможность выбирать компоновщик из нескольких подходящих регионов.
Чтобы было понятно, почему это желательно, я использую микроконтроллер STM32F4xx с тремя отдельными, но смежными областями SRAM на отдельных шинах и еще одной областью памяти, связанной с ядром, которая не имеет битовой полосы пропускания или доступна через DMA. Я хочу использовать меньшую область SRAM для DMA, чтобы избежать конфликтов на шинах и улучшить производительность и детерминированное поведение. Эта область неудобно расположена между двумя более крупными областями, и я хочу иметь возможность использовать любую из более крупных областей для группирования битов, позволяя при этом свободно использовать память CCM для любых целей, отличных от DMA или группирования битов. В настоящее время регионы указаны следующим образом:
RW_IRAM0 CCM_START CCM_SIZE
{
.ANY ( RW ZI)
*(core_coupled_ram)
}
; SRAM1 112Kbytes (Buses: I, D, S, DMA)
RW_IRAM1 SRAM1_START SRAM1_SIZE
{
.ANY ( RW ZI)
}
; SRAM2 16Kbytes (Buses: S, DMA)
RW_IRAM2 SRAM2_START SRAM2_SIZE
{
*(dma_ram)
}
; SRAM3 64Kbytes (Buses: S, DMA)
RW_IRAM3 SRAM3_START SRAM3_SIZE
{
.ANY ( RW ZI)
}
Добавление *(bitbandable_ram)
к SRAM1 и SRAM3 отклоняется компоновщиком с помощью:
Error: L6223E: Ambiguous selectors found for ctransmissionschedulertask.o(bitbandable_ram) from Exec regions RW_IRAM1 and RW_IRAM3.
Аналогично, создание перекрывающейся области не работает:
; SRAM 192Kbytes
RW_IRAM_ALL SRAM_START (SRAM1_SIZE SRAM2_SIZE SRAM3_SIZE)
{
.ANY ( RW ZI)
*(bitbandable_ram)
}
отчетность:
Error: L6221E: Execution region RW_IRAM1 with Execution range [0x20000000,0x200045e0) overlaps with Execution region RW_IRAM_ALL with Execution range [0x20000000,0x20018608).
В настоящее время мои неидеальные решения:
- назначить только одну область для битового бэндинга,
- чтобы сделать всю непрерывную SRAM единой областью (позволяя выполнять операции DMA в любой памяти, что делает ее менее детерминированной), таким образом:
; SRAM 192Kbytes RW_IRAM_ALL SRAM_START (SRAM1_SIZE SRAM2_SIZE SRAM3_SIZE) { .ANY ( RW ZI) *(bitbandable_ram) *(dma_ram) }
- Удаление
.ANY
селектора из области CCM требует, чтобы объект был явно расположен там, используяcore_coupled_ram
именованный раздел.
Комментарии:
1. Согласен, макет оперативной памяти STM немного «особенный». Но вы действительно ожидаете серьезной проблемы с конфликтом шины? Просто поместите переменные стека и статические переменные в CCM и используйте системную SRAM как одну непрерывную область.
2. @Olaf: Я, вероятно, тоже сомневаюсь в требовании, но вопрос актуален, даже если в этом не было строгой необходимости; Конечно, у меня есть другие варианты. Это приложение для обработки сигналов; два сигнала от считываются со скоростью 48 кбит / с каждый из АЦП с использованием DMA, DMA также используется для SPI и USB. Опыт работы с несколькими целевыми объектами STM32 показал, что такое расположение является выгодным. Существуют и другие жесткие сроки в реальном времени, требующие детерминизма порядка нескольких десятков микросекунд. Одного места CCM недостаточно, и нет единого стека — это RTOS с запущенными потоками 15 или около того.
3. Я не хотел подразумевать, что это недействительно. И, не зная подробностей, я не скажу, что это не так. Просто это: я использую эти устройства с более чем 15 потоками, все стеки в CCM, это не проблема. (в этом есть еще одно преимущество: DMA не может повредить это пространство.) Хотя не совсем понятно, в чем проблема. Обычно из-за ограничений требуется вручную указать регион. В gcc / gnu-ld используются пользовательские разделы в исходном
_attribute__
коде. Я не уверен, что толку оставлять это компоновщику.4. @Olaf:
__attribute__
(armcc использовал синтаксис GNU) — это именно то, что я использую — имена разделов все равно должны быть определены в компоновщике, и компоновщик по-прежнему выполняет поиск —__attribute__(section))
это директива компоновщика. Что мне действительно нужно, так это атрибут, который говорит «найдите этот объект в любом регионе с указанной меткой» , а затем в файле scatter назначьте метки определенным регионам. Имя раздела может быть применено только к одному региону.5. Хм, возможно, я ошибаюсь, но у меня слабая память, по крайней мере, в GNU-ld (я не знаю инструментов Keil) есть возможность упомянуть раздел ввода в нескольких разделах вывода. Компоновщик поместит его в первую, в которую он вписывается. Как уже было сказано, я не уверен, что правильно помню, но, возможно, стоит попробовать. Альтернативой может быть создание управляющего файла из небольшой программы, например, Python.