Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Влияние библиотеки STDPeriph на скорость

Ср фев 22, 2017 18:33:11

Просветите меня пожалуйста. Я может пока ещё многого не понимаю, но подскажите.

Вот этот кусок кода выполняется за 82 мкс
Код:
int i;
GPIO_InitTypeDef KEY;
RCC_APB2PeriphClockCmd(KEYB_PORT_KEY_CMD, ENABLE);
for(i = 0; i < ROWS; i++){
KEY.GPIO_Mode = GPIO_Mode_Out_OD;
KEY.GPIO_Speed = GPIO_Speed_10MHz;
KEY.GPIO_Pin = row_pin[i];
GPIO_Init(row_port[i], &KEY);
GPIO_SetBits(row_port[i], row_pin[i]);
}


А вот тоже самое, только на CMSIS

Код:
GPIOB->CRL |= (GPIO_CRL_MODE5_0 | GPIO_CRL_CNF5_0); // Pin 5 Output mode, Speed 10mHz, Open Drain
GPIOB->CRL |= (GPIO_CRL_MODE6_0 | GPIO_CRL_CNF6_0); // Pin 6 Output mode, Speed 10mHz, Open Drain
GPIOB->CRL |= (GPIO_CRL_MODE7_0 | GPIO_CRL_CNF7_0); // Pin 7 Output mode, Speed 10mHz, Open Drain
GPIOB->CRH |= (GPIO_CRH_MODE8_0 | GPIO_CRH_CNF8_0); // Pin 8 Output mode, Speed 10mHz, Open Drain
GPIOB->BSRR = (GPIO_BSRR_BS5 | GPIO_BSRR_BS6 | GPIO_BSRR_BS7 | GPIO_BSRR_BS8);

Это выполняется за 5 мкс.

Вопрос. Зачем писать на std periph, если оно заметно тормозит дело. Я понимаю что счёт на микросекунды это ерунда, но хочется понять идеальные условия. Время замерял, включив отладку в Keil и шагая по коду построчно.

Re: Влияние библиотеки STDPeriph на скорость

Ср фев 22, 2017 19:42:40

supercelt писал(а):Вот этот кусок кода выполняется за 82 мкс
Уровень оптимизации?

supercelt писал(а):А вот тоже самое, только на CMSIS
Где цикл, где массив? Где в коде включается тактирование портов и прочая инициализация?
Почему не обеспечены равные условия? :facepalm:

supercelt писал(а):Зачем писать на std periph, если оно заметно тормозит дело.
Не используйте SPL или вас кто-то заставляет? :)))

Re: Влияние библиотеки STDPeriph на скорость

Ср фев 22, 2017 23:04:09

оптимизация - level0

в том то и дело что как я сделаю циклом, если надо заранее знать CRL или CRH. то есть как я сделаю подстановку то в эту строку?

не использовать это значит это значит писать всё в ручную типа во так: GPIOB->BSRR = 0x0043 ?

Re: Влияние библиотеки STDPeriph на скорость

Чт фев 23, 2017 10:23:17

Мы так и не поняли в чём проблема открыть и посмотреть реализацию скажем GPIO_Init чтобы убедится что она будет выполняться явно дольше
GPIOB->CRL |= (GPIO_CRL_MODE5_0 | GPIO_CRL_CNF5_0);
Хотя бы потому что в ней много всякого понаписано.
Плюс к этому работа со стеком, массивы, циклы.

За удобство надо платить ресурсами.

Re: Влияние библиотеки STDPeriph на скорость

Чт фев 23, 2017 13:30:11

Тогда я задам вопрос, который напрашивается сам собой):
Как тогда в цикле сделать инициализацию пинов 5,6,7,8 в таком стиле GPIOB->CRL |= (GPIO_CRL_MODE5_0 | GPIO_CRL_CNF5_0); И что самое забавное, учесть, что пины могут быть на разных портах))

Re: Влияние библиотеки STDPeriph на скорость

Чт фев 23, 2017 17:38:23

Получить универсальную запись в явном виде нельзя.
Но это можно сделать через работу с указателями на регистры портов, чем собственно и занимаются функции внутри stdperiph gpio.
Если посмотреть на карту памяти чипов и карту регистров, то можно увидеть что:
1. Блоки портов находятся по фиксированным для данного устройства адресам.
2. Блоки имеют одинаковое смещение друг относительно друга.
3. Биты в конфигурационных регистрах идентичны и имеют одинаковые смещения.
Благодаря этому можно построить достаточно простой алгоритм конфигурации, который можно перебирать в цикле.
Например обращение к конфигурационным регистрам портов по номерам:

portNumber=0;
*(GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE)*portNumber + 0)= something1; // CRL
*(GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE)*portNumber + 4)= something2; // CRH

Но я не знаю зачем это может так сильно понадобится. Ведь конфигурация портов определяется схемой и печатной платой устройства, что изменяются довольно редко. Следовательно, хранить конфигурацию в виде массива не всегда оправдано, а с точки зрения быстродейсвия даже вредно.

Re: Влияние библиотеки STDPeriph на скорость

Чт фев 23, 2017 21:31:00

supercelt писал(а):Как тогда в цикле сделать инициализацию пинов...самое забавное, учесть, что пины могут быть на разных портах

вот примерчик отсюда:
http://en.radzio.dxp.pl/stm32f429idisco ... oller.html
Спойлер
Код:
static const GPIO_TypeDef * const GPIOInitTable[] = {
  GPIOC, GPIOB, GPIOA, GPIOA, GPIOB, GPIOG,
  GPIOA, GPIOG, GPIOB, GPIOB, GPIOC, GPIOD,
  GPIOD, GPIOG, GPIOG, GPIOA, GPIOB, GPIOB,
  GPIOA, GPIOC, GPIOF, GPIOG,
  0};

static uint8_t const PINInitTable[] = {
  10, 0, 11, 12, 1, 6,
  6, 10, 10, 11, 7, 3,
  6, 11, 12, 3, 8, 9,
  4, 6, 10, 7,
  0};

static uint8_t const AFInitTable[] = {
  14, 9, 14, 14, 9, 14,
  14, 9, 14, 14, 14, 14,
  14, 14, 9, 14, 14, 14,
  14, 14, 14, 14,
  0};

Код:
  uint8_t i = 0;
  /* GPIO pin configuration */
  while(GPIOInitTable[i] != 0){
    gpio_conf(GPIOInitTable[i], PINInitTable[i], MODE_AF, TYPE_PUSHPULL, SPEED_100MHz, PULLUP_NONE,     AFInitTable[i]);
    i++;
  }

Re: Влияние библиотеки STDPeriph на скорость

Чт фев 23, 2017 23:28:20

Я сделал с помощью макроса

Код:
#define GPIO_INI_PIN(PORT, PIN, MODE) (PIN > 7) ? \
      (PORT->CRH = (PORT->CRH & (~((uint32_t)0x0F << (((PIN) & 0x07) << 2)))) | (((uint32_t)(MODE) & 0x0F) << (((PIN) & 0x07) << 2))) : \
      (PORT->CRL = (PORT->CRL & (~((uint32_t)0x0F << (((PIN) & 0x07) << 2)))) | (((uint32_t)(MODE) & 0x0F) << (((PIN) & 0x07) << 2)))   


но сам вызов я не стал зацикливать, а расписал 4 строками, потому что если в цикле, выполняется за 25 мкс, а если просто расписать 4 строками, то 5 мкс))
Ответить