Ярлыки

_GetPixelIndex (1) _SetPixelIndex (1) 3-phase (1) 800x480 (1) АЦП (1) генератор (1) синхронный усилитель (2) структура (1) учебный курс (1) шаговый двигатель (1) ШИМ (2) accert (1) AD7608 (1) AD8429 (1) ADC (5) amplifer (1) arccos (1) arcsin (1) arctang (2) arctg (3) ARM (2) arm_sqrt_q15 (2) assembler (6) ASSERT (1) atan (2) bit (1) Bitband (1) boot (3) bootlloader (1) BUTTON (1) C (5) C# (1) CAN (2) CC2530 (5) CMSIS (4) command (1) Cordic (1) Core746I (1) CubeMX (4) DBGMCU (2) debug (2) debug.ini (1) delegate (1) Digital Potentiometers (1) DigitalPOT (1) Discovery (1) DMA (9) DMA2D (1) DSP (1) DSP library (1) DWT (1) EFM32 (5) EmWin (9) EXTI (1) FATFS (1) FMC (2) FreeRTOS (2) gl868-dual cmux (1) GPIO (4) GUI (2) GUIBuilder (1) GUIDRV_CompactColor_16 (1) HAL (3) HappyGecko (1) Hard Fault (2) heap (1) I2C (1) ID (1) ILI9320 (1) ILI9325 (1) Initialisation (1) InitLTDC (1) Instrumentithion (1) Interrupt (4) ITR (1) JTAG (1) Keil (5) LCDConf (2) lock-in (1) LTCD (1) LTDC (3) main (1) memory (1) MINI_STM32 Revision 01 (1) nBoot0 (1) NVIC (1) OnePulse (2) OSAL (4) pack (1) phase (1) printf (3) Pulse (1) PWM (12) RCC (2) RCR (1) Register (1) RESET (2) RS232 (3) RSS (1) RTC (3) RTOS-RTX (1) RTT (1) RTX-RTOS (1) SDCard (1) SDRAM (6) Segger (2) SPI (3) sqrt (3) SSD1298 (1) SSD1963 (1) Standart Peripherial Library (3) STANDBAY (1) startup (1) STemWin (8) stepper motor (1) STlink (2) STM32 (17) STM32429ZI (1) STM32Cube (1) STM32DBG.IN (1) STM32F (28) STM32F0 (4) STM32F1 (13) STM32F4 (10) STM32F4 Discovery (1) STM32F407ZG (1) STM32F429 (2) STM32F746 (1) STOP (1) string (1) struct (1) SWD (1) SWD JTAG (1) Synhronization (1) system_stm32f4xx.c (1) SystemInit (1) SysTick (1) task (4) telit (1) TIM (27) typedef (1) UART (1) USART (9) viewer (2) WM_PAINT (1) Z-stack (5) ZigBee (5)

четверг, 5 марта 2015 г.

Cortex STM32 memory (& bitband)


Код - эта область адресов используется для доступа к памяти, хранящей исполняемые коды.

Внутреннее ОЗУ - по этим адресам доступна внутренняя оперативная память.

Внутренняя периферия - по этим адресам доступны регистры управления внутренней периферией контроллера.

Внешнее ОЗУ - эта область адресов используется для доступа к внешней оперативной памяти.

Внешняя периферия - эта область адресов используется для доступа к внешней периферии.

Системная область - по этим адресам доступно управление самим ядром.


"Псевдонимизируемая" область памяти - перевод на русский язык выражение aliasing area. Смысл тут в том, что в зависимости от выбранного способа загрузки (выбирается сочетанием уровней сигналов на ногах boot0, boot1) эта область адресов может быть назначена псевдонимом flash-памяти или служебной области памяти. Соответственно, обращение по этим адресам реально будет приводить к обращению во flash или в служебную область памяти.

Например, если сочетанием ног boot0, boot1 выбрана загрузка с flash, то "псевдонимизируемая" область назначается псевдонимом flash-памяти, в результате чего flash-память становится доступна сразу по двум диапазонам адресов - начиная с 0x00000000 и начиная с 0x08000000. То есть теперь чтение/запись по адресу 0x00000000 приведёт к чтению/записи по адресу 0x08000000 (начало flash-памяти), чтение/запись по адресу 0x00000004 - к чтению/записи по адресу 0x08000004 и так далее.












Адреса, предназначенные для внутреннего ОЗУ и адреса, предназначенные для внутренней периферии. В каждой из этих областей есть диапазоны адресов, которые обозначены как "SRAM" и "регистры встроенной периферии контроллера", а есть диапазоны адресов, про которые сказано, что они "используются для доступа к отдельным битам" SRAM и регистров встроенной периферии, соответственно.
Это сделано для удобства операций с отдельными битами, которая называется bit-band. По сути она является всё той же псевдонимизацией, только теперь псевдоним по другому адресу появляется не у байта или слова, а у каждого отдельного бита.
Зачем это надо? Традиционный способ изменить пару-тройку бит в байте, расположенном по определённому адресу, выглядит так: мы считываем нужный байт (слово / двойное слово) в какой-нибудь регистр, меняем нужные биты (например, с помощью логических операций), а потом результат записываем из регистра назад, по тому же адресу. Этот способ называется "чтение-модификация-запись".
В методе bit-band для каждого бита из области хранения данных есть псевдоним, обращаясь к которому можно сразу изменить нужный бит (операции "чтение-модификация-запись" контроллер сделает автоматически, без нашего участия).
Область адресов, по которым данные доступны традиционным образом называется bit-band region (в русскоязычной терминологии - область хранения бит). Именно такие области и подписаны на карте памяти как "SRAM" и "регистры встроенной периферии контроллера". Область адресов, в которой расположены псевдонимы отдельных бит из области хранения, называется bit-band alias (псевдонимы области хранения). Про такие области, на карте памяти написано, что они используются для доступа к отдельным битам.
Можно заметить, что область псевдонимов для доступа к отдельным битам в 32 раза больше области хранения бит. Это объясняется тем, что в области псевдонимов значащими являются только младшие биты каждого 32-х битного слова (именно они и являются псевдонимами отдельного бита из области хранения). Почему именно так? Потому что контроллер-то у нас 32-х битный и оперировать мы всё равно будем 32-х битными словами, поэтому нужно, чтобы при изменении одного бита (а мы для этого будем писать в память целое 32-х битное слово) не затрагивались соседние биты.
Каким образом вычислить адрес 32-х битного слова из области псевдонимов, младший бит которого является псевдонимом нужного нам бита из области хранения? Делается это по следующей формуле:

AAW = SAR + OWBR * 0x20 + BN * 4 , где

AAW (Address of Alias World) - адрес слова, содержащего псевдоним нужного бита

SAR (Start of Alias Region) - начальный адрес области доступа к отдельным битам

OWBR (Offset of World in Bit-band Region) - смещение слова из области хранения, содержащего нужный бит, относительно начала области хранения

BN (Bit Number) - номер бита

Например, нам нужно установить в единицу 3-й бит в слове по адресу 0x20000008. Этот бит находится в SRAM, то есть начальный адрес области доступа к отдельным битам (SAR) у нас будет равен 0x22000000. Смещение слова из области хранения, содержащего нужный бит, относительно начала области хранения (OWBR) будет равно 0x20000008 - 0x20000000 = 8. Номер бита (BN), как мы уже сказали, равен 3.
Вычисляем адрес слова, которое содержит псевдоним нужного нам бита: AAW = 0x22000000 + 8 * 0x20 + 3 * 4 = 2200010C. Вот и всё, теперь записав по этому адресу любое слово, содержащее в младшем бите единицу, мы фактически получим установку в единицу третьего бита в слове по адресу 0x20000008. Старшие биты записываемого слова, как я уже говорил, значения не имеют. Если мы, наоборот, считываем слово из области доступа к отдельным битам, то старшие биты всегда читаются нулями.


У предшествующих ЦПУ ARM7 и ARM9 битовые операции в статическом ОЗУ можно
было выполнять только с помощью инструкций AND и OR. Для этого необходимо
выполнить последовательность ЧТЕНИЕ - МОДИФИКАЦИЯ - ЗАПИСЬ. Однако
использование этого метода приводит к чрезмерному расходованию количества циклов
на выполнение установки и сброса отдельных бит и увеличению результирующего кода
программы.
Преодолеть данное ограничение можно, если предусмотреть отдельные инструкции
сброса и установки бит или интегрировать полнофункциональный процессор битовой
обработки, однако это приведет к увеличению размеров и сложности ЦПУ. Вместо этого,
способ, называемый bit banding, позволяет напрямую воздействовать на биты в памяти
из областей УВВ и статического ОЗУ, не используя при этом каких-либо специальных
инструкций. Битноадресуемые области карты памяти Cortex разделены на две части:
область хранения бит (в нее входят до 1 Мбайт физической памяти или регистров УВВ)
и область доступа к битам, которая занимает до 32 Мбайт карты памяти. Получить
доступ к каждому отдельному биту из области хранения бит можно по соответствующему
адресу слова из области доступа к битам. Таким образом, если выполнять запись по
адресу в области доступа к битам на самом деле мы будем воздействовать на значение
определенного бита в физической памяти.
В итоге, мы можем воздействовать на значение отдельных бит, не прибегая, при этом,
к использованию специальных инструкций и сохраняя результирующие размеры ядра
Cortex на минимально возможном уровне. Чтобы использовать этот метод на практике,
необходимо вычислить адрес слова в области доступа к битам, который соответствует
заданной ячейки памяти из области УВВ или статического ОЗУ. Выполняется это по
следующей формуле:

Адрес в области доступа к битам = Базовый адрес области доступа к
битам + Смещение адреса слова доступа к биту,

где Смещение адреса слова доступа к биту = Смещение в байтах по
отношению базовому адресу области хранения бит х 0x20 + номер бита х 4

На самом деле все обстоит гораздо проще, чем может показаться на первый взгляд.
Рассмотрим практический пример. Необходимо выполнить запись в выходной регистр
порта ввода-вывода (ПВВ) для установки или сброса отдельных линий ввода-вывода.
Физический адрес выходного регистра порта В - 0x40010C0C. Предположим, что нужно
устанавливать и сбрасывать бит 8 этого регистра. Воспользуемся приведенной выше
формулой:

Адрес слова = 0x40010C0C
   Базовый адрес области хранения бит УВВ = 0x40000000
   Базовый адрес области доступа к битам УВВ = 0x42000000

Смещение в байтах по отношению базовому адресу области хранения бит
= 0x40010C0C - 0x40000000 = 10C0C

Смещение адреса слова доступа к биту
 = (0x10С0С x 0x20) +(8x4) = 0x2181A0

Адрес в области доступа к битам
= 0x42000000 + 0x2181A0 = 0x422181A0

Теперь мы можем создать указатель на этот адрес с помощью следующей Си-строки:

#define PortBbit8 (*((volatile unsigned long *) 0x422181A0 ))

После этого, этот указатель можно использовать для установки и сброса бит ПВВ:

PB8 = 1; //включаем светодиод

После компиляции будут сгенерированы следующие ассемблерные инструкции:

MOVS    r0,#0x01
LDR       r1,[pc,#104]
STR        r0,[r1,#0x00]

Для отключения светодиода используем строку:

PB8 = 0; // отключаем светодиод

Ей соответствуют следующие ассемблерные инструкции:

MOVS    r0,#0x00
LDR       r1,[pc,#88]
STR        r0,[r1,#0x00]


Таким образом, для установки или сброса бита необходимо выполнить три 16-битных
инструкции. Микроконтроллер STM32, работающий на частоте 72 МГц, выполнит их
за 80 нс. Альтернативно установку или сброс бита можно выполнить, если применить
логическую операцию "ИЛИ" или "И" ко всему слову из области хранения бит УВВ или
статического ОЗУ:

GPIOB->ODR |= 0x00000100; //Включение светодиода

LDR      r0,[pc,#68]
ADDS    r0,r0,#0x08
LDR      r0,[r0,#0x00]
ORR     r0,r0,#0x100
LDR     r1,[pc,#64]
STR     r0,[r1,#0xC0C]

GPIOB->ODR &=!0x00000100; //Отключение светодиода

LDR       r0,[pc,#40]
ADDS    r0,r0,#0x08
LDR      r0,[r0,#0x00]
MOVS  r0,#0x00
LDR     r1,[pc,#40]

STR      r0,[r1,#0xC0C]

Но в таком случае, одна операция установки/сброса потребует выполнения смеси 16- и 32 битных инструкций, которые займут минимум 14 байт и на той же тактовой частоте будут выполняться как минимум 180 нс. Таким образом, в программе, где используется установка сброс множества бит в регистрах УВВ, а также применяются семафоры и флаги в статическом ОЗУ, использование метода bit banding позволит существенно сэкономить, как размер кода программы, так и время его выполнения.

Адреса периферии STM32F1

                         AHB

0xA0000000       0xA0000FFF      FSMC   
0×50000000       0x5003FFFF      USB OTG FS
0×40030000       0x4FFFFFFF      reserv
0×40028000       0x40029FFF       Ethernet
0×40023400       0x40027FFF       reserv
0×40023000       0x400233FF       CRC
0×40022000       0x400223FF        flash-memory
0×40021400       0x40021FFF       reserv
0×40021000       0x400213FF       RCC
0×40020800       0x40020FFF       reserv
0×40020400       0x400207FF       DMA2
0×40020000       0x400203FF       DMA1
0×40018400       0x4001FFF         reserv
0×40018000       0x400183FF       SDIO

APB2

0×40015800       0x40017FFF       reserv
0×40015400       0x400157FF       TIM11
0×40015000       0x400153FF       TIM10
0x40014C00       0x40014FFF       TIM9
0×40014000       0x40014BFF      reserv
0x40013C00       0x40013FFF       ADC3
0×40013800       0x40013BFF      USART1
0×40013400       0x400137FF        TIM8
0×40013000       0x400133FF       SPI1
0x40012C00       0x40012FFF       TIM1
0×40012800       0x40012BFF      ADC2
0×40012400       0x400127FF       ADC1
0×40012000       0x400123FF       GPIOG
0x40011C00       0x40011FFF       GPIOF
0×40011800       0x40011BFF      GPIOE
0×40011400       0x400117FF       GPIOD
0×40011000       0x400113FF       GPIOC
0x40010C00       0x40010FFF       GPIOB
0×40010800       0x40010BFF      GPIOA
0×40010400       0x400107FF       EXTI
0×40010000       0x400103FF       AFIO

APB1

0×40007800       0x4000FFFF      reserv
0×40007400       0x400077FF       DAC
0×40007000       0x400073FF       PWR
0x40006C00       0x40006FFF       BKP
0×40006800       0x40006BFF      reserv
0×40006400       0x400067FF       bxCAN1
0×40006800       0x40006BFF      bxCAN2
0×40006000       0x400063FF        512 byte (USB/CAN)
0x40005C00       0x40005FFF       USB, registers FS
0×40005800       0x40005BFF      I2C2
0×40005400       0x400057FF       I2C1
0×40005000       0x400053FF       UART5
0x40004C00       0x40004FFF       UART4
0×40004800       0x40004BFF      USART3
0×40004400       0x400047FF       USART2
0×40004000       0x400043FF       reserv
0x40003C00       0x40003FFF       SPI3/I2S
0×40003800       0x40003BFF      SPI2/I2S
0×40003400       0x400037FF       reserv
0×40003000       0x400033FF       WDG
0x40002C00       0x40002FFF       WWDG
0×40002800       0x40002BFF      RTC
0×40002400       0x400027FF       reserv
0×40002000       0x400023FF        TIM14
0x40001C00       0x40001FFF       TIM13
0×40001800       0x40001BFF      TIM12
0×40001400       0x400017FF       TIM7
0×40001000       0x400013FF       TIM6
0x40000C00       0x40000FFF       TIM5
0×40000800       0x40000BFF      TIM4
0×40000400       0x400007FF       TIM3
0×40000000       0x400003FF       TIM2

Комментариев нет:

Отправить комментарий