Pull to refresh

Comments 30

DMA надо использовать. Благо на чипах STM этого добра навалом.
А IRQ я откуда возьму?
Я не припомню, чтобы там был такой реквест.
Я полистал ref man, действительно в лоб не очень получается, но можно с использованием ETR одного из таймеров.
Ага, я думал о том, чтобы использовать таймерные кэпчур фичи, но т.к. при реальной работе придется все декодить адрес и режим доступа, и в соответствии с ними брать/класть значение в память, ДМА уже не поможет, поэтому я решил его не трогать.

Вот с SDшки в буфер читать им — это да, одно удовольствие.
Наверное можно сделать на комбинации нескольких таймеров и некольких каналов dma. И это уже будет отдельный квест:)
Как минимум, замените GPIOD->IDR на прямое обращение по адресу.
Современный 72МГц ARM не может совладать с архаичной 8МГц шиной. Чем же он занимается все это время? )
Можно подробнее описать куда такты тратятся? Т.е. 12 на вход в обработчик прерывания, а сколько на чтение порта?
Судя по осциллограмме — далеко не 12.
На осциллограмме я так понимаю там еще некоторое количество тактов затратилось на выставление уровня на ножке, т.е. войти в прерывание он вошел раньше чем мы увидели? Или ноги быстро дрыгаются?

Уж очень какой-то он неторопливый этот STM ))
Да, на выставление безусловно затратилось, но куда меньше, чем на вход в интеррапт.

GPIOB->BSRR=GPIO_Pin_2;
GPIOB->BRR=GPIO_Pin_2;
GPIOB->BSRR=GPIO_Pin_2;
GPIOB->BRR=GPIO_Pin_2;
GPIOB->BSRR=GPIO_Pin_2;

Вот это дает 20 МГц на ноге, 50 нс задержку. То есть на то, чтобы выставить уровень выходит 25 нс, около двух тактов.
Основное время занимает именно заход в этот интеррапт, и я не очень понимаю, почему — согласно документации он должен занимать 12 тактов + два такта на выставление уровня — 350 нс примерно. А занимает это все больше 500 нс.
Потрясающе. Только что вот решил для эксперимента поменять уровень оптимизации. Результат превзошел все ожидания — при оптимизации О1 вместо О3 система работает ровно так, как я и рассчитывал — 350 нс на вход и выставление пина. На О2 хуже, на О3 вообще ужасно.
Программа написана на С, а не на асме, да еще и с использованием Standard Peripheral Library. В результате там в ассемблерном коде адЪ и iзралилЪ. Не следует удивляться.
Нет, в интеррапте никакой SPL, вы же видите код.

void __attribute((naked))EXTI0_IRQHandler()
{
	GPIOB->BSRR=GPIO_Pin_2;
	Log[ptr]=GPIOD->IDR;
	ptr++;
	EXTI_ClearITPendingBit(EXTI_Line0);
	GPIOB->BRR=GPIO_Pin_2;
}


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

P.S.
Да, EXTI_ClearITPendingBit — это из SPL, но это уже после выставления флага, то есть на фронт не должно влиять.
Хотя, кстати, надо проверить — может оптимизатор пытается как раз этот вызов как-то переместить…
Если посмотреть на асм-код вот этого:
    GPIOB->BSRR=GPIO_Pin_2;
    Log[ptr]=GPIOD->IDR;
наверняка можно узнать много нового для себя :)
Это не объясняет, почему O3 дает худшие результаты, чем O1.
В O1 вполне все прозрачно,

0x08000390:   ldr r3, [pc, #36]     
0x08000392:   mov.w r2, #4
0x08000396:   str r2, [r3, #16]


В O3 компиллер местами меняет многие операции, видимо, пытаясь получить какой-то выигрыш, но на деле это наоборот сильно ударяет по производительности.
Ага, все, разобрался.
Не быстрее с O1, просто при O2, O3 компиллер начинает переставлять инструкции местами, и пин выставляется в 1 уже после того, как часть кода выполнилась. Поэтому если посмотреть на полную осциллограмму, то видно, что с О1 входит раньше (первой инструкцией реально выставляет 1), но зато выполняется дольше.

Жаль, кейл не установлен, интересно посмотреть, какой результат был бы с его компиллером.
Читал о ваших экспериментах и вспомнилась как раз статья которая тут недавно пролетала. Используйте volatile для переменных через которые работаете с регистрами и все будет ок.
Эти переменные объявлены внутри SPL, не я их объявлял, они от STMicroelectronics.
Кстати, а скорость ножек 50МГц, это же только когда ноги на выход работают, читать то их можно с любой скоростью? Или там в принципе получается что узкое место как раз эти 50МГц на ногах?
50 МГц это именно на выход. Но тут и 50 МГц не стало бы узким местом.
Познавательно и интересно.

В идеале хотелось бы, конечно, сделать эмулятор жесткого диска, работающий с SD-карточкой, но к этой цели будем идти постепенно.


Есть еще какие-то дальнейшие наработки? Когда ожидать продолжения?
Ну я статью написал через день после того, как получил эти результаты, так что информация в статье — все, что есть на текущий момент.
Насчет продолжения — пока не могу сказать, как будет время и желание.
Я бы в первую очередь посмотрел в сторону использования CompactFlash. Но тогда этого топика могло бы и не быть (:

CompactFlash IDE mode defines an interface that is smaller than, but electrically identical to, the ATA interface. The CF device contains an ATA controller and appears to the host device as if it were a hard disk.

Благодаря этому существуют переходники IDE-CF.
Дык это известная вещь, но это же не интересно)
> Потом подает команду 0x10, значение которой я так и не нашел
Recalibrate, сейчас это deprecated уже.
5.4.12 Recalibrate command
This command (command code 1xH, where xcan by any value from 0H
to FH) moves the read/write heads from anywhere on the disc to cylinder
0. Upon receipt of the command, the drive sets BSY and issues a seek
to cylinder zero. The drive then waits for the seek to complete before
updating status, clearing BSY and generating an interrupt.
If the drive cannot reach cylinder 0, a Track Not Found error is posted.
Drives with Power Managementfacilities that are in a low power state
when this command is received may signal completion of this command
without leaving the low power state.
Спасибо, дополнил статью.
Спасибо, испытал ностальгию. :) Хочу добавить, что в мою бытность радиолюбителя в наших журналах декодер называли дешифратором, а процесс получения сигнала CS — дешифрированием. Сам узел, формирующий CS из сигналов шины адреса и шины управления — дешифратором.

А ещё вы забыли при дешифрировании использовать сигнал AEN. Он активируется в процессе прямого доступа к памяти (DMA), который также использует линию IOR, при этом не обращаясь к портам. Если данный сигнал не учесть, у вас в регистрах могут (хотя и не обязательно) иногда появляться случайные данные.
Ну я просто на английский манер привык его называть, он даже на схемах как DC обозначается.

Насчет DMA — случайные-то данные вряд ли появятся, ведь читает то он все равно по этому адресу, из регистров ATA, то есть те данные, которые я все равно хотел бы монитором перехватить, разве нет?
Отличная статья. Сам системный программист поэтому как сказал человек в первом комментарии — прочитал на одном дыхании.
Как жаль, что нашел статью только сейчас, искал информацию на эту тему. Очень интересно читать.
Только вот мучает вопрос — почему бы не снять данные сразу со шлейфа IDE?
Sign up to leave a comment.

Articles