sasamy 1 25 сентября, 2023 Опубликовано 25 сентября, 2023 · Жалоба On 9/23/2023 at 11:44 AM, sasamy said: вдруг мне тоже потом надо барьер памяти делать похоже что в freertos обработка прерываний корректно работает без барьера. Написал тестовый драйвер для Linux msgbox и проверил прерывания - соединил два gpio, один на выход с меандром а второй на вход прерываний, число пульсов совпадает с числом прерываний #define GPIO_IN GPIO_PIN(PORTD, 12) #define GPIO_OUT GPIO_PIN(PORTD, 13) int interrupts = 0; void vTaskMain(void *pvParameters) { (void)pvParameters; int i = 1000; gpio_init(GPIO_OUT, GPIO_OUTPUT); gpio_set_value(GPIO_OUT, 1); gpio_init(GPIO_IN, GPIO_PERIPH_MUX14); gpio_set_pull(GPIO_IN, GPIO_PULL_UP); eint_init(GPIO_IN, EINT_NEGATIVE_EDGE); eint_ctl(GPIO_IN, EINT_ENABLE); dsp_msgbox_init(NULL); intc_init(NULL); printf("DSP uart\n"); msgbox_channel_send_data(3, 0x12345678); printf("pulses %d\n", i); while (i--) { gpio_set_value(GPIO_OUT, 0); vTaskDelay(1); gpio_set_value(GPIO_OUT, 1); vTaskDelay(1); } printf("interrupts %d\n", interrupts); while (1) { vTaskDelay(1000); } } обработчик extern int interrupts; static int intc_isr(int dummy, void *args) { (void)dummy; (void)args; uint32_t val; ++interrupts; val = read32(0x02000000 + 0x274); write32(0x02000000 + 0x274, val); val = read32(SUNXI_R_INTC_PBASE + INTC_PENDING1); write32(SUNXI_R_INTC_PBASE + INTC_PENDING1, val); return 0; } результат Quote # echo -n dsp.elf > /sys/class/remoteproc/remoteproc0/firmware # echo start > /sys/class/remoteproc/remoteproc0/state [ 233.242474] remoteproc remoteproc0: powering up 1700000.dsp [ 233.248299] remoteproc remoteproc0: Booting fw image dsp.elf, size 97904 [ 233.255121] remoteproc remoteproc0: No resource table in elf [ 233.260805] remoteproc remoteproc0: map memory: 0x00400000+20000 to 0xc8780000 [ 233.268091] remoteproc remoteproc0: map memory: 0x47f00000+100000 to 0xc8800000 [ 233.275424] remoteproc remoteproc0: Loading phdr 0 from 0x00400000 to 0xc8780000 (284 bytes) [ 233.283879] remoteproc remoteproc0: Loading phdr 1 from 0x00401000 to 0xc8781000 (364 bytes) [ 233.292329] remoteproc remoteproc0: Loading phdr 2 from 0x00401178 to 0xc8781178 (16 bytes) [ 233.300675] remoteproc remoteproc0: Loading phdr 3 from 0x00401198 to 0xc8781198 (16 bytes) [ 233.309035] remoteproc remoteproc0: Loading phdr 4 from 0x004011b8 to 0xc87811b8 (16 bytes) [ 233.317401] remoteproc remoteproc0: Loading phdr 5 from 0x004011d8 to 0xc87811d8 (16 bytes) [ 233.325765] remoteproc remoteproc0: Loading phdr 6 from 0x004011f8 to 0xc87811f8 (16 bytes) [ 233.334129] remoteproc remoteproc0: Loading phdr 7 from 0x00401218 to 0xc8781218 (16 bytes) [ 233.342491] remoteproc remoteproc0: Loading phdr 8 from 0x00401238 to 0xc8781238 (16 bytes) [ 233.350836] remoteproc remoteproc0: Loading phdr 9 from 0x37f00000 to 0xc8800000 (38428 bytes) [ 233.359646] remoteproc remoteproc0: remote processor 1700000.dsp is now up DSP uart pulses 1000 [ 233.368530] test-msgbox 3003000.mailbox: 0x12345678 interrupts 1000 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 25 сентября, 2023 Опубликовано 25 сентября, 2023 · Жалоба 33 minutes ago, sasamy said: похоже что в freertos обработка прерываний корректно работает без барьера. Написал тестовый драйвер для Linux msgbox и проверил прерывания - соединил два gpio, один на выход с меандром а второй на вход прерываний, число пульсов совпадает с числом прерываний Очевидно, роль барьера взял на себя вот этот фрагмент кода: 33 minutes ago, sasamy said: val = read32(SUNXI_R_INTC_PBASE + INTC_PENDING1); write32(SUNXI_R_INTC_PBASE + INTC_PENDING1, val); Проверил. Действительно, если сделать чтение-запись регистра GPIO раньше, чем чтение-запись INTC, то работает нормально. И барьер не нужен: void GPIOC_Handler(void) { u32 val; UART_putc('c'); val=PC_EINT_STATUS; PC_EINT_STATUS=val; val=pintc_regs->pending1; pintc_regs->pending1=val; } Так тоже работает нормально без барьера: void GPIOC_Handler(void) { UART_putc('c'); PC_EINT_STATUS=PC_EINT_STATUS; pintc_regs->pending1=pintc_regs->pending1; } А вот так уже не работает нормально - без барьера будет второй заход в прерывание: void GPIOC_Handler(void) { UART_putc('c'); //buggy... pintc_regs->pending1=pintc_regs->pending1; PC_EINT_STATUS=PC_EINT_STATUS; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 1 25 сентября, 2023 Опубликовано 25 сентября, 2023 · Жалоба On 9/25/2023 at 10:39 AM, repstosw said: А вот так уже не работает нормально - без барьера будет второй заход в прерывание: проверил - в freertos перестановка пендингов мествами не влияет, код работает корректно без дополнительных барьеров static inline __attribute__((__always_inline__)) void write32(virtual_addr_t addr, uint32_t value) { *((volatile uint32_t *)(addr)) = value; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 25 сентября, 2023 Опубликовано 25 сентября, 2023 (изменено) · Жалоба 16 minutes ago, sasamy said: проверил - в freertos перестановка пендингов мествами не влияет, код работает корректно без дополнительных барьеров Значит в коде freertos есть фрагмент, который вносит задержку после чтения-записи регистра, выполняющий роль барьера ))) Что там идёт после вашего сишного обработчика? Простыня из контекстов восстановлений? ))) Чем не барьер? https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/master/kernel/portable/xtensa_vectors.S#L617 https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/blob/master/kernel/portable/xtensa_vectors.S#L1051 Слишком дофига всего: /* Save rest of interrupt context and enter RTOS. */ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ /* !! We are now on the RTOS system stack !! */ /* Set up PS for C, enable interrupts above this level and clear EXCM. */ #ifdef __XTENSA_CALL0_ABI__ movi a0, PS_INTLEVEL(1) | PS_UM #else movi a0, PS_INTLEVEL(1) | PS_UM | PS_WOE #endif wsr a0, PS rsync /* OK to call C code at this point, dispatch user ISRs */ dispatch_c_isr 1 XCHAL_INTLEVEL1_MASK /* Done handling interrupts, transfer control to OS */ call0 XT_RTOS_INT_EXIT /* does not return directly here */ На голом железе обработчик намного быстрее и понятнее ))) Kernel: addi sp,sp,-64 s32i a0,sp,0 s32i a2,sp,4 s32i a3,sp,8 s32i a4,sp,12 s32i a5,sp,16 s32i a6,sp,20 s32i a7,sp,24 s32i a8,sp,28 s32i a9,sp,32 s32i a10,sp,36 s32i a11,sp,40 s32i a12,sp,44 s32i a13,sp,48 s32i a14,sp,52 s32i a15,sp,56 movi a2,PS_INTLEVEL(1) //mask interrupts to prevent stack corrupt in C/C++ calls wsr.ps a2 rsync rsr.exccause a2 beqi a2,EXCCAUSE_LEVEL1,IntLevel1 j . //catch rest interrupts .align 4 IntLevel1: movi a2,INTC_VECTOR memw l32i a2,a2,0 l32i a2,a2,0 callx0 a2 l32i a15,sp,56 l32i a14,sp,52 l32i a13,sp,48 l32i a12,sp,44 l32i a11,sp,40 l32i a10,sp,36 l32i a9,sp,32 l32i a8,sp,28 l32i a7,sp,24 l32i a6,sp,20 l32i a5,sp,16 l32i a4,sp,12 l32i a3,sp,8 l32i a2,sp,4 l32i a0,sp,0 addi sp,sp,64 rfi 1 Изменено 25 сентября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 48 25 сентября, 2023 Опубликовано 25 сентября, 2023 · Жалоба Коллеги, вопрос к вам и модераторам, может вынесем тему про DSP Allwinner в отдельную, тут уже много всего по нему, потом мало ли что искать будет удобнее, как считаете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 25 сентября, 2023 Опубликовано 25 сентября, 2023 · Жалоба Пытаюсь поднять C++ окружение. Создаю конструкторы: //C constructor __attribute__((constructor(101))) void init101() { UART_puts("init101"); } //C++ constructor IClass ic(2,5); //делаем экземпляр класса - уже на момент создания класса, С++ рантайм должен сработать TestClass tc(ic); int main(void) { //... В линкере описываю нужные секции: .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } > ROM .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } > ROM .fini_array : { _fini = . ; PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } > ROM .ctors : { KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors*)) } > ROM .dtors : { KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors*)) } > ROM А в сишном стартапе пишу: extern void (*__preinit_array_start []) (void) __attribute__((weak)); extern void (*__preinit_array_end []) (void) __attribute__((weak)); extern void (*__init_array_start []) (void) __attribute__((weak)); extern void (*__init_array_end []) (void) __attribute__((weak)); extern void (*__fini_array_start []) (void) __attribute__((weak)); extern void (*__fini_array_end []) (void) __attribute__((weak)); void _fini(void); void _exit(int return_code) __attribute__((noreturn)); static void __libc_init_array(void) { size_t count,i; count=__preinit_array_end-__preinit_array_start; for(i=0;i<count;i++)__preinit_array_start[i](); count=__init_array_end-__init_array_start; for(i=0;i<count;i++)__init_array_start[i](); } static void __libc_fini_array(void) { int count,i; count=__preinit_array_end-__preinit_array_start; for(i=count-1;i>=0;i--)__fini_array_start[i](); _fini(); } void exit(int return_code) { __libc_fini_array(); _exit(return_code); } void libc_init(void) { // memcpy(&_sdata,&_sidata,&_edata-&_sdata); //copy LMA to VMA memset(&_sbss,0,&_ebss-&_sbss); //clear BSS __libc_init_array(); //constructor init (C++) } В итоге конструкторы не работают! Если их вызвать в main(), то они работают. Вариант выше работает в ARM GCC, но не работает в DSP GCC. Ассемблер показал следующее: c18028a4 <.text.__libc_init_array>: c18028a4: e0c112 addi a1, a1, -32 c18028a7: 7109 s32i.n a0, a1, 28 c18028a9: fff631 l32r a3, 0xc1802884 c18028ac: fff621 l32r a2, 0xc1802884 c18028af: c02320 sub a2, a3, a2 c18028b2: 212220 srai a2, a2, 2 c18028b5: 1129 s32i.n a2, a1, 4 c18028b7: 020c movi.n a2, 0 c18028b9: 0129 s32i.n a2, a1, 0 c18028bb: 0005c6 j 0xc18028d6 c18028be: 000000 ill c18028c1: fff031 l32r a3, 0xc1802884 c18028c4: 0128 l32i.n a2, a1, 0 c18028c6: 1122e0 slli a2, a2, 2 c18028c9: 232a add.n a2, a3, a2 c18028cb: 0228 l32i.n a2, a2, 0 c18028cd: 0002c0 callx0 a2 Тоесть он почему-то считает что __preinit_array_end = __preinit_array_start = 0xc1802884. Тоесть в этой секции дырка от бублика, а не указатели, которые надо вызвать: count=__preinit_array_end-__preinit_array_start; for(i=0;i<count;i++)__preinit_array_start[i](); Вопрос, как побороть это? Может в данном GCC это не preinit_array, а как-то по-другому называется? map-файл тоже пишет, что секция не занята. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 26 сентября, 2023 Опубликовано 26 сентября, 2023 (изменено) · Жалоба 13 hours ago, repstosw said: Вопрос, как побороть это? Может в данном GCC это не preinit_array, а как-то по-другому называется? map-файл тоже пишет, что секция не занята. Заработали конструкторы и статические объявления классов в С++. Тулчейн размещает конструкторы в секцию .ctors, а не в .init / .init_array. Следовательно стартап для С++ с рабочими конструкторами выглядит так: extern char _sidata,_sdata,_edata; extern char _sbss,_ebss; extern char _ctors_start,_ctors_end; static void cxx_invoke_constructors(void) { typedef void (*ctor_func_t)(void); ctor_func_t *func=(ctor_func_t*)&_ctors_start; for(;func!=(ctor_func_t*)&_ctors_end; func++)(*func)(); } void libc_init(void) { // memcpy(&_sdata,&_sidata,&_edata-&_sdata); //copy LMA to VMA memset(&_sbss,0,&_ebss-&_sbss); //clear BSS cxx_invoke_constructors(); //constructor init (C++) } Для линкера: .ctors : { PROVIDE_HIDDEN (_ctors_start = .); KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors*)) PROVIDE_HIDDEN (_ctors_end = .); } > ROM Работают нормально как сишные конструкторы, так и статически объявленные C++ классы с инициализацией: #include "klass.h" void init101(void) __attribute__((constructor)); void init102(void) __attribute__((used,constructor)); void init101(void) { UART_puts("init101\n"); } void init102(void) { UART_puts("init102\n"); } IClass ic(2,5); //делаем экземпляр класса - уже на момент создания класса, С++ рантайм должен вывести строку TestClass tc(ic); int main(void) { UART_init(); printf("\nHiFi4 C++ Class Example\n"); while(1); return 0; } вывод: init101 init102 Hi! I'm Constructor ;) HiFi4 C++ Class Example Изменено 26 сентября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 27 сентября, 2023 Опубликовано 27 сентября, 2023 · Жалоба On 9/25/2023 at 7:39 PM, mantech said: Коллеги, вопрос к вам и модераторам, может вынесем тему про DSP Allwinner в отдельную, тут уже много всего по нему, потом мало ли что искать будет удобнее, как считаете? Добрый день! Не совсем понял, что Вы предлагаете? Что-то выделить из этой темы в отдельную? Если да, то я поглядел всю тему бегло, считаю, что это сделать сложно без потери целостности изложения материала. Или прицепить, т.е. закрепить, эту всю тему в шапке текущей ветки (TI,Allwinner, GigaDevice, Nordic, Espressif, etc.)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 48 27 сентября, 2023 Опубликовано 27 сентября, 2023 · Жалоба 5 часов назад, haker_fox сказал: Что-то выделить из этой темы в отдельную? Это было б хорошо, но если сложно, то что поделаешь, можно закрепить, тут много чего полезного для тех, кто захочет освоить данный DSP, ИМХО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 27 сентября, 2023 Опубликовано 27 сентября, 2023 (изменено) · Жалоба Пожалуй переименование и закреп здорово помогут. Мне кстати на начальных этапах именно данная тема здорово помогла в разбирательствах с allwinner Изменено 27 сентября, 2023 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 27 сентября, 2023 Опубликовано 27 сентября, 2023 · Жалоба 6 minutes ago, GenaSPB said: Пожалуй переименование и закреп здорово помогут. Модератор: Закрепил. Предлагайте новые имена темы. Я в данной теме микроконтроллеров не очень компетентен. Чтобы не засорять тему, я предлагаю писать мне личные сообщения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 27 сентября, 2023 Опубликовано 27 сентября, 2023 (изменено) · Жалоба 9 hours ago, haker_fox said: Что-то выделить из этой темы в отдельную? Если да, то я поглядел всю тему бегло, считаю, что это сделать сложно без потери целостности изложения материала. Совершенно верно. Я как автор темы, против разбиения этой темы. 3 hours ago, GenaSPB said: Пожалуй переименование и закреп здорово помогут. Мне кстати на начальных этапах именно данная тема здорово помогла в разбирательствах с allwinner 3 hours ago, haker_fox said: Модератор: Закрепил. Предлагайте новые имена темы. Я в данной теме микроконтроллеров не очень компетентен. Чтобы не засорять тему, я предлагаю писать мне личные сообщения. Allwinner T113-s3 уделал HiFi4 DSP. Смеяться или плакать? Доделал настройку тулчейна и SDK для C++. Портировал ещё один мега-проектище, поддерживающий музыкальные форматы различных игровых систем: https://github.com/mmontag/game-music-emu Game_Music_Emu is a collection of video game music file emulators that support the following formats and systems: AY ZX Spectrum/Amstrad CPC GBS Nintendo Game Boy GYM Sega Genesis/Mega Drive HES NEC TurboGrafx-16/PC Engine KSS MSX Home Computer/other Z80 systems (doesn't support FM sound) NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound) SAP Atari systems using POKEY sound chip SPC Super Nintendo/Super Famicom VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro Как раз там один жёсткий С++ с классами. Из особенностей, можно отметить следующее: 1. Линковать с -lstdc++. Иначе многое будет не определено. 2. Пришлось сделать свою реализацию __ieee754_remainder(): // IEEERemainder Remainder operator // 3 / 2 = -1 1 // 4 / 2 = 0 0 // 10 / 3 = 1 1 // 11 / 3 = -1 2 // 27 / 4 = -1 3 // 28 / 5 = -2 3 // 17.8 / 4 = 1.8 1.8 // 17.8 / 4.1 = 1.4 1.4 // -16.3 / 4.1 = 0.0999999999999979 -4 // 17.8 / -4.1 = 1.4 1.4 // -17.8 / -4.1 = -1.4 -1.4 /* Remainder = (Math.Abs(dividend) - (Math.Abs(divisor) * (Math.Floor(Math.Abs(dividend) / Math.Abs(divisor))))) * Math.Sign(dividend) IEEERemainder = dividend - (divisor * Math.Round(dividend / divisor)) */ double __ieee754_remainder(double x,double y) { return x-(y*round(x/y)); } 3. Функции-пустышки. Не вызываются. Но из-за -lstdc++ должны быть определены: Spoiler #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wreturn-type" void _exit(void) { printf("_exit\n"); } int _getpid_r(struct _reent *r) { printf("_getpid_r\n"); } int _kill_r(struct _reent *r,int a,int b) { printf("_kill_r\n"); } int _fstat_r(struct _reent *r,int a,struct stat *s) { printf("_fstat_r\n"); } _ssize_t _read_r(struct _reent *r,int a,void *p,size_t s) { printf("_read_r\n"); } _off_t _lseek_r(struct _reent *r,int a,_off_t o,int b) { printf("_lseek_r\n"); } _ssize_t _write_r(struct _reent *r,int a,const void *p,size_t s) { printf("_write_r\n"); } int _close_r(struct _reent *r,int a) { printf("_close_r\n"); } #pragma GCC diagnostic pop 4. Компиляция с флагами: -Ofast -DNDEBUG -fmax-errors=1 -ftree-vectorize -fno-math-errno -ffast-math -fno-rtti -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fomit-frame-pointer -fno-threadsafe-statics -ffunction-sections -fdata-sections 5. Линковка: -nostartfiles -nostdlib -nodefaultlibs -ffreestanding -Wl,--gc-sections -Wl,--static -Wl,--strip-all -lstdc++ -lhal Постарался всё лишнее вырезать. Работы над SDK для HiFi4 завершены. Всё что хотел, получил. Изменено 27 сентября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vasily_ 54 27 сентября, 2023 Опубликовано 27 сентября, 2023 · Жалоба 4 часа назад, repstosw сказал: Я как автор темы, против разбиения этой темы. Это как так? Потрудитесь объяснить. В 11.06.2020 в 11:54, __inline__ сказал: Раскурил Allwinner A13 SoC на уровне голого железа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 27 сентября, 2023 Опубликовано 27 сентября, 2023 (изменено) · Жалоба Потерялся логин давно... Изменено 27 сентября, 2023 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 217 30 сентября, 2023 Опубликовано 30 сентября, 2023 · Жалоба По просьбе ТС поменял название темы на "Allwinner T113-s3 уделал HiFi4 DSP. Смеяться или плакать?". Во избежание ненужных проблем тему разделения этой темы на несколько предлагаю далее исключить из обсуждения и если интересно обсуждать какие-то частные вопросы - создавать отдельные темы. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться