И еще раз здравствуйте! Вот и добрался я до своего любимого ассемблера Интересует технический вопрос: Как это делается ? можно ли непосредственно в сишный код вставлять? если можно то как? если нельзя то как это оформить? В конце концов, посодействуйте авторитетной ссылочкой
Использую GCC, и там собственно говоря никаких особенностей нет и ничем не отличается кроме команд от AVR и x86. Набираешь в поисковике "gcc arm assembly" или "gcc STM32 assembly" и радуешься.
Только ASM редко нужен. Память, как на дешевых AVR смысла нет экономить. Time Critical места встречаются очень редко. Да и для большинства Time Critical есть своя периферия.
coredumped, спасибо! с первого взгляда возникла мысль: "что это за ахинея?? как то это рвет шаблон...", но пройдя по ссылке все приобрело смысл
balmer писал(а):
Память, как на дешевых AVR смысла нет экономить
ну это понятно. Больше быстродействие интересует. глянул, какой код генерит компилятор и присел на 120мгц опрос внешнего ацп с занесением в буфер работает с частотой 3 Мгц. То есть 40тактов на цикл... и это хваленый риск
Код:
for (j=0;j<256;j++) { GPIOB->BSRRL |= 1<<12; for (i=0;i<1;i++){}; buff[j] = GPIOB->ODR; GPIOB->BSRRH |= 1<<12; }
дизасмом посмотрел что творит компилятор.. не сказать что офигел, но был немного разочарован... Кстати, вопрос в продолжение: я, конечно, слабо себе представляю архитектуру АРМа. Но догадываюсь что шина не позволяет за такт произвести операцию чтения и записи в память (например инкремент ячейки памяти). Я прав?
По мне так вполне прилично. Естественно for (int i=0;i<1;i++){}; выкинуто полностью, ибо оптимизатор видит что цикл нафиг не нужен.
Хотя да, ногодрыг - это одно из мест, где имело бы смысл на ASM точную задержку выставить. Правда мне такой подход не нравится. Меняешь частоту процессора - будь добр переписать код, неее я уж какнить DMA с Таймерами настрою на этот случай, будет надежнее.
Карма: 3
Рейтинг сообщений: 43
Зарегистрирован: Вт апр 12, 2011 18:38:19 Сообщений: 838 Откуда: с Земли
Рейтинг сообщения:0
Скажем, DMA с внешним "параллельным" АЦП связать не просто - единственный вариант FSMC (поправьте меня, если я не прав). Да и смысла особого нет, при передаче 1 слова за итерацию. Тут бы проектик целиком увидеть. Таймер - да, нужная вещь, но с прерываниями надо быть внимательным - посмотрите какой код генерирует компилятор при входе - выходе из ISR. Если период таймера небольшой, то использование таймера может стать неэффективным, если нужно выжать из процессора все ресурсы. Что касается вставки ассемблерного кода и кода, генерируемого компилятором. Нужно было мне забирать данные с FPGA, порядка 10 Мбайт в секунду, блоками по 1К, обрабатывать и отправлять в эзернет. FSMC применить не получалось, ввиду не совсем удачного распределения GPIO. В общем - ногодрыг, задержки __nop() итп. Думал написать процедуру на ассемблере, чтоб выжать из процессора все, а когда посмотрел листинг компиллятора, понял, что лучшше я не сделаю пожалуй. Я это к тому, что компиляторы С довольно умные стали, главное код правильно написать. А методов оптимизации море - раскручивание циклов, работа с указателями с учетом архитектуры итп. Лучший оптимизатор - моск
_________________ Все будет только лучше, в крайнем случае - хуже.
А вот почему буфер читается с ODR а не с IDR так же не понятно
Предельно понятно - описка...
С ДМА я практически не разбирался(особенно с генерацией запросов) Поэтому не представляю, каким образом это на ДМА вообще можно сделать? 2 канала запускать? : 1 на клок (тут можно еще и управление усилителем запихать ) и 1 на данные)? А синхронизировать разными фронтами одного события? Так возможно?
В идеале, конечно, надо плис подпаивать и хоть 200 МГц цифруй по четырем каналам параллельно
Карма: 3
Рейтинг сообщений: 43
Зарегистрирован: Вт апр 12, 2011 18:38:19 Сообщений: 838 Откуда: с Земли
Рейтинг сообщения:0
dosikus писал(а):
Конечно не прав. GPIO та же периферия . Конечно при работе с DMA много не выжмешь , зато будет аппаратно...
Ну да, ну да... А строб данных как сформировать (шина данных 16-битная)? Варианты?
2 FPGAlover: В Вашем случае с DMA выигрыш не получить - передача 1 байта(слова). В моем - да, было бы хорошо, если бы можно было сформировать клок на FPGA + еще несколько сигналов. Использовать втрой канал ПДП - не вариант при пакетной передаче с подтверждением. FSMC - да, но платы уже готовы, а в 100-ногом корпусе расположение пинов таково(+ еще Ethernet, I2C), что нет вариантов замапить. Одеяльце коротковато В связке с ПЛИС можно поиграться с FIFO на ПЛИС + FSMC на ARM. Тут DMA очень даже выручит. Перекладываете работу с АЦП на стейтмашину, данные в FIFO, а дальше уж - куда Вам их надо По ходу можно еще фильтрануть, если надо - пики/выбросы отсеять, огибающую посчитать - да что угодно!
_________________ Все будет только лучше, в крайнем случае - хуже.
поигрался с оптимизацией, получил достаточно приемлемый (6.5 мгц) с точки зрения компилятора результат. Выигрыш идет за счет того, что ссылки на регистры периферии сидят в регистрах процессора. Однако такой подход опасен... вот добавятся еще переменные - регистров на все не хватит, а компилятор втихоря в памяти значение хранить начнет и временная диаграмма поплывет ...
Код:
uint16_t buff[256]; uint32_t i = 0; uint32_t* SetReg ; uint32_t* ResetReg ; uint32_t* DataReg ; SetReg = (uint32_t*)&GPIOB->BSRRL; ResetReg = (uint32_t*)&GPIOB->BSRRH; DataReg = (uint32_t*)&GPIOB->IDR; while(1){ uint32_t j=0; do { *SetReg = 1<<12; //set bit i=0; //пауза.. АЦП быстродействующее, вполне хватает buff[j++] = *DataReg; *ResetReg = 1<<12; //set bit } while (j<256);
2 coredumped: На самом деле, в моем случае отношение времени сбора и обработки информации весьма мало. т.е. Мне важно с хорошей частотой собрать в буфер, а потом хоть по усарту выкачивать
_________________ Шоб я польку танцевал..
Последний раз редактировалось FPGAlover Пт дек 13, 2013 11:05:28, всего редактировалось 1 раз.
почему то в хардфаулт уходит... Сейчас выясним. Выяснил : bp = buff; перед главным циклом стоит Выигрыша в скорости на глаз не видно.
и кстати, я в си не силен, но... компиляторы отродясь такое понимали? bp = buff; это выглядил логичнее, но компилятор не понимает: bp = &buff; а с этим все в порядке... bp = &buff[0];
и еще непонятны предпосылки к генерации кода на while(j--):
Код:
MOVS R6,R5 SUBS R5,R6,1 CMP R6,#0 BNE.N ??Main_1
в системе команд отсутствует декремент регистра и флаг "зеро"?
Карма: 3
Рейтинг сообщений: 43
Зарегистрирован: Вт апр 12, 2011 18:38:19 Сообщений: 838 Откуда: с Земли
Рейтинг сообщения:0
А компайлер какой? Вариант bp = buff; и bp = &buff[0]; одно и то же. Команды декремента нет, есть SUBS - который должен влиять на флаг Z (Z флаг имеется), не понятно зачем компилятор всунул CMP Я Кейлом пользуюсь, у меня все норм. Мой вариант должен работать чуть быстрее, хотя очень сильно зависит от компилятора. Посмотри ассемблерные листинги и сравни.
_________________ Все будет только лучше, в крайнем случае - хуже.
листинги не сходятся ну вообще... У меня цикл с I стоически генерит код, несмотря на полную оптимизацию. а если честно, как то ваш листинг, в моем нубском мозгу(смысл половины команд пока непонятен), слабо коррелируется с исходником... Какие то непонятные L9 и push. а где же pop?.
кстати, давно интересовал вопрос: "4FF48051 mov r1, #4096" откуда берется константа 4096? в "4FF48051" ее ни слухом ни духом
"4FF48051 mov r1, #4096" откуда берется константа 4096?
СпойлерFlexible second operand Many general data processing instructions have a flexible second operand. This is shown as operand2 in the descriptions of the syntax of each instruction. Operand2 can be a: ● Constant ● Register with optional shift Constant You specify an operand2 constant in the form #constant, where constant can be: ● Any constant that can be produced by shifting an 8-bit value left by any number of bits within a 32-bit word. ● Any constant of the form 0x00XY00XY ● Any constant of the form 0xXY00XY00 ● Any constant of the form 0xXYXYXYXY In the constants shown above, X and Y are hexadecimal digits.
Это случай by shifting an 8-bit value left by any number of bits within a 32-bit word.
Карма: 3
Рейтинг сообщений: 43
Зарегистрирован: Вт апр 12, 2011 18:38:19 Сообщений: 838 Откуда: с Земли
Рейтинг сообщения:0
Это еще 16-битный набор команд thumb - слегка "урезанный". Посмотрите что можно в режиме ARM (32-битном) http://www.gaw.ru/html.cgi/txt/doc/micr ... g_data.htm Правда в Cortex-M (к которым пренадлежит семейство stm32) набор ARM отсутствует, только THUMB
_________________ Все будет только лучше, в крайнем случае - хуже.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения