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

Allwinner T113-s3 уделал HiFi4 DSP. Смеяться или плакать?

57 минут назад, sasamy сказал:

сто раз в секнду стандартного шедулера

Разве не 1000 раз в сек? Или это в винде)))

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


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

On 9/13/2023 at 10:47 PM, mantech said:

Разве не 1000 раз в сек? Или это в винде)))

дефолтный конфиг разный у разных процессоров, у т113 в майнстримном ядре с дефолтным конфигом для allwinner 100

Quote

linux-custom$ grep "CONFIG_HZ" .config
# CONFIG_HZ_PERIODIC is not set
CONFIG_HZ_FIXED=0
CONFIG_HZ_100=y
# CONFIG_HZ_200 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_500 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100

 

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


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

Просветите начинающего... а если прерывания ждёт тред с приоритетом более высоким чем у остальных - после прерывания reschedule не происходит? Обязательно таймера ждут?

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


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

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

Просветите начинающего... а если прерывания ждёт тред с приоритетом более высоким чем у остальных - после прерывания reschedule не происходит? Обязательно таймера ждут?

Это вопрос вообще или конкретно к кому-то?

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


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

8 hours ago, sasamy said:

внешними прерываниями от периферии нет планов разобраться? без этого всё выглядит малопригодным.

Не стоит недооценивать обработку системных исключений в этой архитектуре. Без "оконных разливов" (window spill) программа будет очень ограничена:

🥇 в уровне вложенности функций

🥈 в количестве используемых локальных переменных

🥉 про сишный lib.c можно забыть (он весь простроен на вложенных вызовах, подтягивая ещё и проверки на повторную входимость).

Ещё раз.  Это не ARM, где можно начать работу вообще без никаких прерываний-исключений.  Здесь регистрово-оконная архитектура, диктующая инные требования к обработке исключений, которые нельзя игнорировать.

Лишь только после как сделан этот уровень, можно работать...

8 hours ago, sasamy said:

с внешними прерываниями от периферии

 

6 hours ago, sasamy said:

для бареметал сойдёт и так - там всё равно процессору больше нечего делать кроме поллинга 🙂 

Собственно, мне и нужен BareMetal.  Я не пишу под Линукс в МК.

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

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


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

4 hours ago, Arlleex said:

вопрос вообще или конкретно к кому-то?

Вопрос вообще. То, что говорилось тут про отсутствие tickless планировщика в rtos немного удивило меня.

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


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

Задействовал кеширование для HiFi4 DSP. Функция board_init( ) из файла board-init.c.  Пришлось подключать либу из FreeRTOS: libhal.a, потому что исходников на неё я пока не искал.

Ну что же сказать... Мои ожидания оправдались - даёт ощутимый прирост после вызова board_init( ).  Так что старший ниббл в адресе с двойки ( 0x2******* ) - это ещё не всё! :biggrin:

Протестировал несколько регионов с включением board_init( )  и без неё.

Код на котором проверялось быстродействие (оптимизация компилятора специально была выключена: -O0 ) :

void delay(volatile u64 d)
{
 while(d--);
}

extern void board_init(void);
u32 t;

int main(void)
{
 board_init();

 Loop:
  AVS_CNT0_REG=0; //Замер времени
  delay(50000);
  t=AVS_CNT0_REG;
  printf("%d\n",t);
 goto Loop;
//...

 

Код функции delay( ).    30 инструкций за 13000 тактов 6 МГц-таймера. В процедуре 50 000 итераций. 

Грубый расчёт по времени:  (6000000/13000)*30*50000 = 692307692.  Похоже, что и вправду 600 МГц :bomb:

Spoiler
20028ce8 <delay>:
20028ce8:	006136                      	entry	a1, 48
20028ceb:	017d                          	mov.n	a7, a1
20028ced:	0020c0                      	memw
20028cf0:	0729                          	s32i.n	a2, a7, 0
20028cf2:	0020c0                      	memw
20028cf5:	1739                          	s32i.n	a3, a7, 4
20028cf7:	f03d                          	nop.n
20028cf9:	0020c0                      	memw
20028cfc:	0728                          	l32i.n	a2, a7, 0
20028cfe:	0020c0                      	memw
20028d01:	1738                          	l32i.n	a3, a7, 4
20028d03:	fcde81                      	l32r	a8, 2002807c <Literal+0x78>
20028d06:	fcdd91                      	l32r	a9, 2002807c <Literal+0x78>
20028d09:	428a                          	add.n	a4, a2, a8
20028d0b:	160c                          	movi.n	a6, 1
20028d0d:	013427                      	bltu	a4, a2, 20028d12 <delay+0x2a>
20028d10:	060c                          	movi.n	a6, 0
20028d12:	539a                          	add.n	a5, a3, a9
20028d14:	665a                          	add.n	a6, a6, a5
20028d16:	065d                          	mov.n	a5, a6
20028d18:	0020c0                      	memw
20028d1b:	0749                          	s32i.n	a4, a7, 0
20028d1d:	0020c0                      	memw
20028d20:	1759                          	s32i.n	a5, a7, 4
20028d22:	024d                          	mov.n	a4, a2
20028d24:	204430                      	or	a4, a4, a3
20028d27:	fce456                      	bnez	a4, 20028cf9 <delay+0x11>
20028d2a:	f03d                          	nop.n
20028d2c:	f03d                          	nop.n
20028d2e:	f01d                          	retw.n

 

 

Результаты следующие:

0x40000000 .. 0x7FFFFFFF (не кеширован, только буферизован):
	без board_init() : 385000 тактов
	с   board_init() : 385000 тактов
      
0xC0000000 .. 0xFFFFFFFF (кеширован, буферизован):
	без board_init() : 385700 тактов
	с   board_init() : 13000 тактов - самый быстрый!
      
0x20000000 .. 0x3FFFFFFF (кеширован, буферизован):
	без board_init() : 595000 тактов
	с   board_init() : 13000 тактов - самый быстрый!

0x00000000 .. 0x1FFFFFFF (не кеширован, только буферизован):
	без board_init() : 595000 тактов
	с   board_init() : 595000 тактов

 

Тоесть, делаю выводы, что с кешированными регионами выходит быстрее: в 29 .. 45 раз! :yes:

При этом T113-s3 грузит код по следующим адресам:

0x41800000 или  0xC1800000 (что одно и то же) - для DDR.

0x00028000 - для DSP0 IRAM/DRAM

 

Очевидно, что адреса, куда грузит T113-s3  программу для DSP не влияют на кеширование.

Влияет значение регистра DSP_ALT_RESET_VEC_REG + на какие адреса слинкована программа для DSP его компилятором + включение функции board_init().

 

Во всех замерах - такты таймера 6 МГц,  его 6000000 тактов - 1 секунда.

Что касается библиотеки libhal.a - её придётся использовать как есть или декомпилировать. Много интересых вещей находится именно в ней. :dance4:

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

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


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

On 9/14/2023 at 1:32 AM, repstosw said:

Ещё раз.  Это не ARM, где можно начать работу вообще без никаких прерываний-исключений.  Здесь регистрово-оконная архитектура, диктующая инные требования к обработке исключений, которые нельзя игнорировать.

Лишь только после как сделан этот уровень, можно работать...

в freertos всё это работает из коробки - мне прерывания от периферии в DSP нужны

 

On 9/14/2023 at 6:23 AM, repstosw said:

Пришлось подключать либу из FreeRTOS: libhal.a, потому что исходников на неё я пока не искал.

исходников от неё наверно и нет в свободном доступе - китаец накидал проприетарных либ из тулзов cadence, некоторые ф-ции libc тоже оттуда берутся а не из тулчейна, отсюда и варнинги при сборке freertos

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


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

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

Тоесть, делаю выводы, что с кешированными регионами выходит быстрее: в 29 .. 45 раз!

Да уж, я-то думал, что выделенная статика для DSP  IRAM-DRAM по сути и есть кэш с 1-тактовым доступом, типа TCM в СТМ МК, а тут вон оно что...

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

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


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

25 minutes ago, mantech said:

Да уж, я-то думал, что выделенная статика для DSP  IRAM-DRAM по сути и есть кэш с 1-тактовым доступом, типа TCM в СТМ МК, а тут вон оно что...

A1 SRAM у T113-s3 без кеширования тоже тормозная.

А у C6745 память L1/L2 на частоте ядра и кастомно можно задавать сколько тратить её на кеши и на обычные буфера, доступные программисту.  Да и там доступ ко всей памяти кеша есть: можно даже случайно наехать...

 

Проверил соответствие адресных линий DDR для DSP и T113-s3. 

Проверяемый фрагмент памяти 40 МБ  заполнялся псевдо-рэндомом со стороны DSP. Спустя какое-то время T113-s3 начинал проверять эту область памяти. Тестирование успешно. Свопинга адресных линий (интерлив адресов) для DDR к счастью нет.

Про свопинг вопрос подымался здесь:

 

2 hours ago, sasamy said:

мне прерывания от периферии в DSP нужны

И мне нужны! :ok:

2 hours ago, sasamy said:

исходников от неё наверно и нет в свободном доступе - китаец накидал проприетарных либ из тулзов cadence, некоторые ф-ции libc тоже оттуда берутся а не из тулчейна, отсюда и варнинги при сборке freertos

Пока использую её.  Будет настроение - попытаюсь декомпилировать её в C-код через дизасм, как это делал с кодом инита DDR.

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

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


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

Сделал Messagebox. От CPU к DSP. И от DSP к CPU.  По прерываниям. Использовал только прерывания по приёму данных. Прерывания передачи данных не использовал (мне не нужно).

В FreeRTOS нет примера как работать с messagebox.

Как всегда, ничего просто не бывает, пришлось разбираться. Намудрили с базовыми адресами - было не понятно, кому какой принадлежит в случае если передавать туда и обратно.

Базовые адреса в рабочем примере распределены следующим образом:

//Со стороны DSP:
SUNXI_MSGBOX_ARM_BASE - посылка сообщения к CPU
SUNXI_MSGBOX_DSP_BASE - инициализация, обработчик прерывания по приёму данных от CPU
  
//Со стороны CPU:
SUNXI_MSGBOX_DSP_BASE - посылка сообщения к DSP
SUNXI_MSGBOX_ARM_BASE - инициализация, обработчик прерывания по приёму данных от DSP

Вот таким мудрёным образом.

При этом все смещения в адресах регистров (0x100*N), N=0 - обмен сообщениями работает в обе стороны .  С N=1 не работает ни в одну сторону.

Смещения (P*4) работают при P=0..3 - все 4 канала работают.

Cо стороны DSP прерывания по приёму данных от CPU и передача данных - прерывания уровня 3, также как и прерывание от таймера. Необходима сепарация, в случае, если одновременно использовать прерывания таймера и messagebox.  Смещение от начала таблицы векторов прерываний: +0x19C.   Бит номер 3 регистра intenable - включает прерывание приёма данных от CPU, бит 4 этого же регистра - прерывание передачи данных к CPU.

Со стороны CPU прерывание по приёму данных от DSP - номер 32. Номер прерывания передачи данных к DSP - номер 117. GIC.

Данные передаются через FIFO буферы  8 4-байтных слов.  Длина сообщения должна быть кратна 4. Придётся передавать нули в конце 1..3 штуки, если длина не кратна 4.

image.png.e91d4949084fa8b435ccbcf7388ba33c.png

 

 

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


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

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

Со стороны CPU прерывание по приёму данных от DSP - номер 32. Номер прерывания передачи данных к DSP - номер 117. GIC.

Данные передаются через FIFO буферы  8 4-байтных слов.  Длина сообщения должна быть кратна 4. Придётся передавать нули в конце 1..3 штуки, если длина не кратна 4.

 

А зачем эти мутарства с ФИФО, есть же общая память? Давнул прерывание процу, что ДСП что-то сделал, а данные забираешь из общей памяти и наоборот, не??

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


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

5 hours ago, mantech said:

А зачем эти мутарства с ФИФО, есть же общая память? Давнул прерывание процу, что ДСП что-то сделал, а данные забираешь из общей памяти и наоборот, не??

Прерывания происходят по порогу срабатывания FIFO: он настраивается: 1/2/4/8.

На счёт общей памяти согласен - большие массивы данных только так и давать-забирать. 

FIFO относительно медленный по сравнению с памятью, и к тому же, если он заполнен (тоесть кто-то ещё данные не прочёл) то передача приостанавливается. Тоесть максимум 32 байта отправил, и надо ждать пока как минимум 4 байта не прочтётся. 

"Первый вошёл, первым и вышел"...  Поэтому обязательно как минимум: кто-то пишет И кто-то читает. Но с прерываниями - это не проблема.

Можно заполнять память и давать 4 байта в Msgbox. Прерывание будет. И времени много не займёт 🙂

 

Quote

Давнул прерывание процу, что ДСП что-то сделал,

Расскажите, как ?  Как c-инициировать искуственно аппаратное прерывание?  🙂

Cкорее всего, линии IRQ программисту недоступны.

image.png.886489850652b72edb949cb21d84c258.png

 

Однако меня беспокоит другой вопрос.  Сейчас прерывание Msgbox висит на том же векторе, что и прерывание Таймера. А именно - IntLevel3. Пока не разобрался с определением источника прерывания, чтобы сделать селектор.  Сделал только селектор для исключений (там проще).

Есть ли возможность отмапить источники прерываний  на другой вектор?  Их куча свободных: IntLevel 2,4,5.

IntLevel 1- занят - на нём висят исключения

IntLevel 3 - Timer.

В C6745 можно любой источник прерывания повешать на любой вектор.

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

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


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

Обнаружил, что компилятор xtensa-hifi4-elf-gcc для DSP не выравнивает константные строки, если задан уровень оптимизации -Os (по размеру).

Конкретно вот здесь:

dsp_msgbox_channel_send_2CPU(MSGBOX_CHANNEL,(u32*)"Hello, T113-s3 CPU! I'm HiFi4 DSP :) I have receive your message!\n\n",67);

Несмотря на то, что в прототипе функции явно указан указатель на 4-байтный тип:

void dsp_msgbox_channel_send_2CPU(u32 ch,const u32 *bf,u32 len);

Строка выводится с артефактами.

Если же сделать так:

u8 tmp[]="Hello, T113-s3 CPU! I'm HiFi4 DSP :) I have receive your message!\n\n";
dsp_msgbox_channel_send_2CPU(MSGBOX_CHANNEL,(u32*)tmp,67);

Или так:

 static /*const*/ u8 tmp[]="Hello, T113-s3 CPU! I'm HiFi4 DSP :) I have receive your message!\n\n";
 dsp_msgbox_channel_send_2CPU(MSGBOX_CHANNEL,(u32*)tmp,67);

То всё работает нормально.

Проверил адреса указателей:  в случае когда строка сразу загоняется в функцию - её адрес не кратен 4-м: 0x0003877B.

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

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


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

On 9/16/2023 at 4:06 AM, repstosw said:

Есть ли возможность отмапить источники прерываний  на другой вектор?  Их куча свободных: IntLevel 2,4,5.

уровни для каждого прерывания прописаны в конфиге так что врядли такое возможно

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/164696d952116d20100daefd7a475d2ede828eb0/include/xtensa/config/core-isa.h#L467

но есть возможность любое внешнее прерывание смапить на NMI а у него level 5, правда как это делать не знаю - в freertos NMI не используется

Ещё теоретически должен быть коммутатор с выбором какое прерывание периферии на какое прерывание DSP подключить и в таком случае периферийные прерывания можно раскидать на разные уровни, но это сейчас главная загадка 🙂

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

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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