Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Глюки оптимизации
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Sagittarius
Цитата(VslavX @ May 16 2012, 08:02) *
по моим криптографическим тестам (ЭЦП и поточное шифрование).


если не секрет то за какое время выполняется подпись ключом 2048bit? У меня F207 и на либах из PolarSSL получилось 2.7с без оптимизации и 1.5 с полной оптимизацией (IAR). Но при полной оптимизации дохнет драйвер ethernet от ST :-)
scifi
Цитата(Sagittarius @ May 16 2012, 10:27) *
Но при полной оптимизации дохнет драйвер ethernet от ST :-)

Можно, конечно, снижать оптимизацию выборочно. Но по-хорошему такой драйвер надо оторвать и выбросить.
Кстати, когда я ваял свой драйвер ethernet для STM32 (uIP), то подивился, насколько просто это оказалось. Всего 200 строчек:
CODE
/**
* @file stm32eth.h
* @brief Драйвер Ethernet для STM32
*/

#include "stm32eth.h"
#include "stm32f2regs.h"
#include "timer.h"
#include "net/uip.h"
#include <string.h>

#define SMI_TMPL 0x00000004 /* sets SMI clock range and PHY address */
#define RX_BUF_SIZE 256
#define RX_RING_SIZE 32

static bool link, act;
/* the only TX descriptor used in this program */
static uint32_t volatile tx_desc[4] = { 0, 0, (uint32_t)uip_buf, 0 };
static uint32_t volatile rx_desc[RX_RING_SIZE][4];
static uint8_t volatile rx_buf[RX_RING_SIZE][RX_BUF_SIZE];
/* first descriptor in frame, next descriptor to check */
static unsigned int rx_first, rx_cur;

static bool
smi_busy(void)
{
return (ETH_MACMIIAR & 1) != 0;
}

static void
smi_write(int reg, int val)
{
ETH_MACMIIDR = val;
ETH_MACMIIAR = (reg << 6) | SMI_TMPL | 3;
while (smi_busy())
{
/* wait */
}
}

static void
smi_start_read(int reg)
{
ETH_MACMIIAR = (reg << 6) | SMI_TMPL | 1;
}

static int
smi_read_data(void)
{
return ETH_MACMIIDR;
}

static void
phy_init(void)
{
smi_write(0, 0x1100);
smi_write(4, 0x0021);/* auto-negotiate 10Mb half-duplex only */
}

static void
fill_rx_desc(void)
{
int i;
for (i = 0; i < RX_RING_SIZE; i++)
{
rx_desc[i][0] = (1u << 31); /* OWN bit */
rx_desc[i][1] = RX_BUF_SIZE;
rx_desc[i][2] = (uint32_t)&rx_buf[i];
}
rx_desc[RX_RING_SIZE - 1][1] |= (1 << 15); /* end of ring */
}

void
stm32eth_init(void)
{
/* enable clocking of MAC core, ports A, B, C */
RCC_AHB1ENR |= 0x1E000007;
fill_rx_desc();
GPIOA_AFRL |= 0xB000BBBB;
GPIOB_AFRL |= 0x000000BB;
GPIOB_AFRH |= 0x00BBBB0B;
GPIOC_AFRL |= 0x00BBBBB0;
GPIOA_MODER |= 0x000080AA;
GPIOB_MODER |= 0x0AA2000A;
GPIOC_MODER |= 0x00000AA8;
timer_delay(TIMER_TPS / 1000);
ETH_DMATDLAR = (uint32_t)&tx_desc;
ETH_DMARDLAR = (uint32_t)&rx_desc;
ETH_MACCR = (1 << 16) /* disable carrier sense */
| (1 << 3) /* enable transmitter */
| (1 << 2);/* enable receiver */
ETH_DMAOMR = (1 << 21) /* transmit store and forward */
| (1 << 13) /* start transmission */
| (1 << 1);/* start reception */
phy_init();
smi_start_read(1);
}

void
stm32eth_setmac(const uint8_t mac[6])
{
ETH_MACA0LR = *(uint32_t*)mac;
ETH_MACA0HR = *(uint16_t*)(mac + 4);
}

static void
collect_frame(void)
{
int i, remlen;
uint8_t *dst = uip_buf;
remlen = (rx_desc[rx_cur & (RX_RING_SIZE - 1)][0] & 0x3FFF0000) >> 16;
uip_len = remlen;
for (i = rx_first; i <= rx_cur; i++)
{
int len;
len = (i != rx_cur) ? RX_BUF_SIZE : remlen;
memcpy(dst, (void*)rx_buf[i & (RX_RING_SIZE - 1)], len);
dst += len;
remlen -= len;
}
}

static void
reinit_rx_desc(void)
{
unsigned int i;
for (i = rx_cur; i != (rx_first - 1); i--)
{
rx_desc[i & (RX_RING_SIZE - 1)][0] = 1u << 31; /* OWN bit */
}
}

static void
rx_poll(void)
{
uint32_t status;
status = rx_desc[rx_cur & (RX_RING_SIZE - 1)][0];
if (status & (1u << 31)) /* OWN bit */
{
return;
}
if (status & (1 << 9)) /* first segment */
{
rx_first = rx_cur;
}
if (status & (1 << 8)) /* last segment */
{
if ((status & 0x4000F89F) == 0) /* error bits */
{
collect_frame();
}
reinit_rx_desc();
}
rx_cur++;
}

void
stm32eth_poll(void)
{
static timer_value prev;
timer_value now;
now = timer_getval();
if (timer_ticksbetween(prev, now) > TIMER_TPS / 100)
{
link = !!(smi_read_data() & 4);
smi_start_read(1);
prev = now;
}
rx_poll();
}

void
stm32eth_send(void)
{
tx_desc[1] = uip_len;
tx_desc[0] = (1u << 31) /* OWN bit */
| (1 << 29) /* last segment */
| (1 << 28) /* first segment */
| (1 << 21);/* end of ring */
ETH_DMATPDR = 0; /* start transmission */
while (tx_desc[0] & (1u << 31))
{
/* wait until TX descriptor is released */
}
}

bool
stm32eth_link(void)
{
return link;
}

bool
stm32eth_act(void)
{
bool ret;
ret = act;
act = false;
return ret;
}
VslavX
Цитата(Sagittarius @ May 16 2012, 09:27) *
если не секрет то за какое время выполняется подпись ключом 2048bit?

Я пока до RSA не добрался. Есть "советский" 34.310/34.311, украинский 4145-2002, и беларусский 1176.2.
34.310 и 1176.2 тоже на модульной арифметике основаны, поэтому результаты подобные RSA будут - то же самое модульное возведение в степень.
1176.2 при длине 2462 бита дает 680мс на выработку подписи.

Цитата(Sagittarius @ May 16 2012, 09:27) *
У меня F207 и на либах из PolarSSL получилось 2.7с без оптимизации и 1.5 с полной оптимизацией (IAR). Но при полной оптимизации дохнет драйвер ethernet от ST :-)

IAR начиная с 6.2x глючит при оптимизации, никак они не исправят, откатитесь на 5.x.
PolarSSL - хорошо и аккуратно написан и структурирован код. Но с точки зрения ресурсов/скорости - имхо, скорее середнячок.
jcxz
Цитата(VslavX @ May 16 2012, 13:02) *
IAR начиная с 6.2x глючит при оптимизации, никак они не исправят, откатитесь на 5.x.
PolarSSL - хорошо и аккуратно написан и структурирован код. Но с точки зрения ресурсов/скорости - имхо, скорее середнячок.

Не замечал. У меня с Cortex-M3 всё ок. В чём именно глюк?
Если что-то не работает при оптимизации - в первую очередь надо обратить внимание на свой код и в последнюю - на компилятор. имхо
VslavX
Цитата(jcxz @ May 16 2012, 13:36) *
Не замечал. У меня с Cortex-M3 всё ок. В чём именно глюк?
Если что-то не работает при оптимизации - в первую очередь надо обратить внимание на свой код и в последнюю - на компилятор. имхо

Угу - в этой теме проблема описана
SII
Корректный оптимизатор ни при каких условиях не должен давать неработоспособный код. Так что, если без оптимизации всё работает, а с ней -- нет, то дело в оптимизаторе, а не исходном коде.
Сергей Борщ
QUOTE (SII @ May 16 2012, 13:50) *
Так что, если без оптимизации всё работает, а с ней -- нет, то дело в оптимизаторе, а не исходном коде.
Ага, конечно. Поищите по форуму ключевое слово volatile и темы про задержки на пустых циклах.
KRS
Цитата(Сергей Борщ @ May 16 2012, 15:36) *
Ага, конечно. Поищите по форуму ключевое слово volatile и темы про задержки на пустых циклах.

+1
у IAR оптимизатор очень любит циклы выкидывать, обращения к данным...
так что в циклы надо __no_operation вставлять, а у данных volatile

Ошибки в оптимизаторе появляются, но обычно все таки проблема именно в коде и в том что многие привыкли к тому что другие компиляторы сами "додумывают" где volatile и пустые циклы не убирают...
scifi
Цитата(SII @ May 16 2012, 14:50) *
Корректный оптимизатор ни при каких условиях не должен давать неработоспособный код.

Это просто неверное утверждение. Если в исходниках накосячено, то в зависимости от настроек компилятора, дня недели и погоды за окном код может генериться как рабочий, так и нерабочий.
RCray
а можно ли где-то найти что-то подобие release notes / mail list со списком исправленных или известных багов?
release notes начиная с 5.40 такой информации, судя по всему, не содержат.
_Артём_
Цитата(RCray @ May 18 2012, 09:18) *
а можно ли где-то найти что-то подобие release notes / mail list со списком исправленных или известных багов?
release notes начиная с 5.40 такой информации, судя по всему, не содержат.

Смотрите в Release notes for individual components.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.