Перейти к содержанию
    

AT32F437: эффективность работы команд под WS0

Всем доброго времени!
Занялся переносом программ с STM32F745 на AT32F437 и наткнулся на вещи, не совместимые с документацией.... Также для меня было новостью, что если используешь кварц 25 МГц, то выстроить 288 МГц не получится. А если взять иной кварц, то не получится с CLKOUT выдать 25/50 МГц для работы ETH PHY. Печалька, но придется использовать кварц 16 МГц, разгонять до 288 МГц, а для ETH использовать свой собственный кварц или генератор.

Но дело даже не в этом.

Я вижу, что некоторые ассемблерные команды исполняются где-то за 6-7 нс, но некоторые - аж за 28-36 нс!

Что я сделал.
Я разогнал AT до 288 МГц. Проверил на таймере - действительно, это так: таймер TMR2 проходит ровно за 1 секунду 144000 такта.

Я в С описал PF10 как выход, а в asm использовал команды для быстрой SET/CLR:

; код установки бита
                LDR R5, GPIO_DBG_ptr    ;; GPIO_DBG_ptr содержит GPIOF_BASE + смещение регистра SCR
                LDR R5, [R5]                     ; Грузим адрес GPIOF->SCR
                MOVS R4, #DBG_SET_BSRR ; R4 <= 1<<10
                STR R4, [R5] ; Сохраняем 4 команда

; код сброса бита
                LDR R5, GPIO_DBG_ptr     ; 5 команда
                LDR R5, [R5]                     ; Грузим адрес GPIOF->SCR
                MOVS R4, #DBG_CLR_BSRR ; R4 <= 1<<(10+16)
                STR R4, [R5] ; Сохраняем 8 команда

Код разместил в FLASH, вся программа целиком (включая эти команды) влезла чуть более чем 16 кБ, загружена начиная с 0x08000000, т.е. она 100% попала в область NWS (WS=0).
Если просто запустить эти 8 команд, то при помощи осциллографа можно поймать импульс длиной аж в 70 нс! (картинка 2)

Идем дальше. Если убрать команды 5-6, то импульс резко сокращается до 7 нс. (картинка 1)
Опытным путем выяснил, сколько исполняются каждая из команд:

                LDR R5, GPIO_DBG_ptr    ; 36 нс! (это по сути команда LDR R5, [PC + 60], PC смотрит на Flash NWS (0 WS))
                LDR R5, [R5]                     ; 24 нс!
                MOVS R4, #DBG_SET_BSRR ; эта и следующая - около 7 нс.
                STR R4, [R5] ;

Получается, что взять значение из периферии дольше, чем туда положить....

Кто-нибудь имеет такой опыт? Может ли подсказать, как нивелировать разницу? Или что я не учёл, когда рассчитывал, что все команды будут исполняться где-то за 1-2-4 такта. А 1 такт это около 3,5 нс.

IMG_20230808_205856_.jpg

IMG_20230808_205942_.jpg

Изменено пользователем dmitrykhom

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, dmitrykhom сказал:

 Печалька, но придется использовать кварц 16 МГц, разгонять до 288 МГц, а для ETH использовать свой собственный кварц или генератор.

А какой PHY? Неужто он не умеет сам выдавать REF_CLK_OUT?
 

Цитата

Или что я не учёл, когда рассчитывал, что все команды будут исполняться где-то за 1-2-4 такта.

Что кроме этого теста из 8 команд запущено на МК параллельно? Прерывания, DMA, все что угодно другое - отключено? Дальше - измеряйте разницу времени правильно - с помощью DWT-счетчика. Так виднее будет, куда копать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, Arlleex сказал:

А какой PHY? Неужто он не умеет сам выдавать REF_CLK_OUT?

Если контроллер его не тактирует, то и PHY ничего не выдаст)))  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, mantech сказал:

Если контроллер его не тактирует, то и PHY ничего не выдаст)))  

Не, не так. В разных PHY система тактирования разная. У меня вот коммутатор стоит, у него свой кварц, а нога REF_CLK_OUT идет на RMII_REF_CLK МК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Arlleex сказал:

у него свой кварц, а нога REF_CLK_OUT идет на RMII_REF_CLK МК.

Ну все правильно, ТС так и написал, свой кварц у PHY, а на МК идет уже с него...

16 часов назад, dmitrykhom сказал:

для ETH использовать свой собственный кварц или генератор.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, mantech сказал:

Ну все правильно, ТС так и написал, свой кварц у PHY, а на МК идет уже с него...

Вообще-то он написал наоборот: источник тактирования - МК.  У вас там где-то лишний инвертор в глазном нерве затесался. Читайте внимательнее или выкусите инвертор.   :biggrin: 

 

PS: Вот интересно, а учёл ли автор требования о максимальном джиттере для чипа PHY? Когда строил таким образом систему тактирования....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, jcxz сказал:

У вас там где-то лишний инвертор в глазном нерве затесался.

 

Вообще-то он написал наоборот: источник тактирования - МК. 

У вас что-ли??

"А если взять иной кварц, то не получится с CLKOUT выдать 25/50 МГц для работы ETH PHY. Печалька, но придется использовать кварц 16 МГц, разгонять до 288 МГц, а для ETH использовать свой собственный кварц или генератор."

Еще вопросы?

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, mantech сказал:

"А если взять иной кварц, то не получится с CLKOUT выдать 25/50 МГц для работы ETH PHY. Печалька, но придется использовать кварц 16 МГц, разгонять до 288 МГц, а для ETH использовать свой собственный кварц или генератор."

Еще вопросы?

И...?

Вопрос тот же самый: Где вы узрели там:

7 часов назад, mantech сказал:

ТС так и написал, свой кварц у PHY, а на МК идет уже с него...

???

PS: Некоторые и в самом деле - как будто через кривое зеркало читают..... :sarcastic:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 часов назад, jcxz сказал:

Некоторые и в самом деле - как будто через кривое зеркало читают.

И правда)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 08.08.2023 в 22:58, Arlleex сказал:

А какой PHY? Неужто он не умеет сам выдавать REF_CLK_OUT?
 

Что кроме этого теста из 8 команд запущено на МК параллельно? Прерывания, DMA, все что угодно другое - отключено? Дальше - измеряйте разницу времени правильно - с помощью DWT-счетчика. Так виднее будет, куда копать.

PHY можно взять например KSZ8041 и повесить ему кварц или генератор.

Паралельно точно ничего не запущено! Процесс запущен в единственном прерывании, которое срабатывает от EXINT по спаду на ноге PC9 раз в 10 мкс . Нет ни DMA, ни чего-то еще. Я запустил протестировать самые критические процедуры, поэтому я грузанул весь проект, но ничего не инициализировал. Код получился большой, потому что я загружал ассемблерный код, а он не оптимизируется.

image.png.816ac569b28ba5971e21196a640f10b4.png

Это чтоль DWT-счетчик?

 

19 часов назад, jcxz сказал:

PS: Вот интересно, а учёл ли автор требования о максимальном джиттере для чипа PHY? Когда строил таким образом систему тактирования....

Спасибо, что обратили мое внимание на джиттер! Буду наперед интересоваться такими вещами. Но могу сказать, что у меня очень много устройств на ETH PHY, тактируемых от STM MCO1, и обмен отличный, связь всегда есть. Про AT32F437 - буду использовать отдельный источник.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 часа назад, vladec сказал:

Может другой аналог контроллера попробовать, например, GD32F450.

Думал над этим. Но это тот же cortex-M4, возможно, чуть более лучший, чем AT32F437. Но GD он ввел санкции, в отличие от AT, поэтому я уж лучше останусь на STM, потому что там cortex-M7, и скорость адекватная.

То самое прерывание, которое запускается раз в 10 мкс, на STM отрабатывает за 1..1,2 мкс (т.е. загрузка ресурсов 10..12%), а на AT оно же работает 2,7..3 мкс (загрузка 27..30%). Я понимаю, что на AT стоит Cortex-M4. Но всё же было заявление с исполнением команд без задержек. Ну даже допустим 2 мкс было бы, но 3 - это чересчур..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, dmitrykhom сказал:

Паралельно точно ничего не запущено! Процесс запущен в единственном прерывании, которое срабатывает от EXINT по спаду на ноге PC9 раз в 10 мкс .

Про DMA понял, про прерывания - не понял. Вам нужно отключить вообще любые прерывания и в main() в бесконечном цикле линейно разместить блок из нескольких подряд дерганий ногой GPIO.
 

1 час назад, dmitrykhom сказал:

Но всё же было заявление с исполнением команд без задержек.

Все-таки, я пока что предполагаю, что где-то что-то недонастроено, либо все-таки кто-то перебивает доступ CPU к шине.

Я бы, интереса ради (не знаю, как у Вас щас) скачал оригинальный стартап + конфиг тактирования и повторил эксперименты.

И, повторюсь, GPIO-шкой смотреть время выполнения команд не совсем честно. Все-таки таймером DWT правильнее. На скрине да, Вы верно его нашли.

P.S. Еще вопрос. Каково состояние бита NZW_BST у Вас, посмотрите отладчиком?

P.S.2. Еще вопрос. Вы говорите

В 08.08.2023 в 21:20, dmitrykhom сказал:

Код разместил в FLASH, вся программа целиком (включая эти команды) влезла чуть более чем 16 кБ, загружена начиная с 0x08000000, т.е. она 100% попала в область NWS (WS=0).

А Вы уверены, что это именно так и работает? У меня есть подозрение, что проект должен линковаться не с 0x08000000, а с 0x0. Иначе контроллеру как-то надо знать (читай - задавать руками), область какого банка Flash "кэшируется" (копируется) в быструю SRAM для реализации zero-wait-execution. Попробуйте слинковать программу с адреса 0x0.

P.S.3. Кстати, Вы и эксперимент с GPIO и осциллографом тоже под отладчиком проводили? Или в МК уже была зашита прошивка, а программатор вовсе не подцеплен?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/10/2023 at 4:06 PM, Arlleex said:

А Вы уверены, что это именно так и работает? У меня есть подозрение, что проект должен линковаться не с 0x08000000, а с 0x0. Иначе контроллеру как-то надо знать (читай - задавать руками), область какого банка Flash "кэшируется" (копируется) в быструю SRAM для реализации zero-wait-execution. Попробуйте слинковать программу с адреса 0x0.

Для STM32 в скрипте компоновщика GCC у меня так прописано

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      		: ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw)      	: ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx)      	: ORIGIN = 0x08000000, LENGTH = 128K
APP (rx)      		: ORIGIN = 0x08020000, LENGTH = 128K
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, dimka76 сказал:

Для STM32 в скрипте компоновщика GCC у меня так прописано

Это STM32, а у ТС - другой, китайский, МК. На текущий момент я нашел кое-какую доку, в которой объяснено, как кэшируется Flash в SRAM (для имитации zero-wait), и, вопреки моим предположениям, исполнение с 0x08000000, скорее всего, должно быть zero-wait по умолчанию.

А вот если бы этого явно не было описано, то мое предположение имело бы место, т.к. при загрузке контроллеру так или иначе нужно было бы знать, из какой области Flash грузить теневую SRAM исполняемым кодом. И раз в документации вообще не описан процесс загрузки МК, то сей процесс определения запросто мог быть заведен на логику ремапа BOOT0/1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...