adnega 10 15 февраля Опубликовано 15 февраля · Жалоба посмотрел v003 сильно отличается: CSR 0xBC0 - отсутствует; U режима нет совсем (mstatus.MPP=0b11, т.е. всегда в режиме M). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 15 февраля Опубликовано 15 февраля · Жалоба Почитал внимательно . ТС вызывает функции из функций )) Да, функции находятся в ОЗУ, но они могут использовать флешовые __riscv_save_0/__riscv_restore_0 Выглядит так: в начале функции 200000e0 <test_ram>: { 200000e0: 0c0002e7 jalr t0,192(zero) // 192=0xC0: <__riscv_save_0> 200000e4: 03000793 li a5,48 while(!(USART1->STATR & (1 << USART_STATR_TC))); ... и в конце 20000138: dfe5 beqz a5,20000130 <test_ram+0x50> test_foo(); 2000013a: 37b9 jal 20000088 <test_foo> - вызов вложенной ram-функции } 2000013c: 0ca00067 jr 202(zero) // 202=0xCA: <__riscv_restore_0> 000000c0 <__riscv_save_0>: c0: 1151 addi sp,sp,-12 c2: c026 sw s1,0(sp) c4: c222 sw s0,4(sp) c6: c406 sw ra,8(sp) c8: 8282 jr t0 000000ca <__riscv_restore_0>: ca: 4482 lw s1,0(sp) cc: 4412 lw s0,4(sp) ce: 40a2 lw ra,8(sp) d0: 0131 addi sp,sp,12 d2: 8082 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 9 15 февраля Опубликовано 15 февраля · Жалоба 14 minutes ago, adnega said: __riscv_save_0/__riscv_restore_0 У меня ничего подобного не наблюдается: WriteFlashPage64b: 2000014a: jalr t0,160(zero) # 0x0 <_start> 138 RAM_FLASH_Unlock_Fast () ; 2000014e: addi sp,sp,-4 20000150: mv s0,a1 20000152: mv s1,a0 20000154: jal 0x20000028 <RAM_FLASH_Unlock_Fast> 140 RAM_FLASH_ErasePage_Fast (Page_Address) ; 20000156: mv a0,s0 20000158: jal 0x20000046 <RAM_FLASH_ErasePage_Fast> 142 RAM_FLASH_BufReset () ; 2000015a: jal 0x2000007c <RAM_FLASH_BufReset> 143 for (uint8_t i=0 ; i<(FLASH_PAGESIZE/4) ; i++) 2000015c: li a5,0 145 RAM_FLASH_BufLoad (Page_Address+4*i, Buf64b[i]) ; 2000015e: add a4,s1,a5 20000162: lw a1,0(a4) 20000164: add a0,s0,a5 20000168: sw a5,0(sp) 2000016a: jal 0x200000a4 <RAM_FLASH_BufLoad> 2000016c: lw a5,0(sp) 2000016e: li a4,64 20000172: addi a5,a5,4 20000174: bne a5,a4,0x2000015e <WriteFlashPage64b+20> 148 RAM_FLASH_ProgramPage_Fast (Page_Address) ; 20000178: mv a0,s0 2000017a: jal 0x200000da <RAM_FLASH_ProgramPage_Fast> 150 RAM_FLASH_Lock_Fast () ; 2000017c: jal 0x2000010e <RAM_FLASH_Lock_Fast> 2000017e: addi sp,sp,4 20000180: jr 170(zero) # 0x0 <_start> RAM_FLASH_ErasePage_Fast: 20000046: lui a5,0xf8000 2000004a: add a5,a5,a0 2000004c: lui a4,0x4 2000004e: bgeu a5,a4,0x2000007a <RAM_FLASH_ErasePage_Fast+52> 20000052: lui a5,0x40022 20000056: lw a4,16(a5) 20000058: lui a3,0x20 2000005c: or a4,a4,a3 2000005e: sw a4,16(a5) 20000060: sw a0,20(a5) 20000062: lw a4,16(a5) 20000064: ori a4,a4,64 20000068: sw a4,16(a5) 2000006a: lw a4,12(a5) 2000006c: andi a4,a4,1 2000006e: bnez a4,0x2000006a <RAM_FLASH_ErasePage_Fast+36> 20000070: lw a4,16(a5) 20000072: lui a3,0xfffe0 20000074: addi a3,a3,-1 20000076: and a4,a4,a3 20000078: sw a4,16(a5) 2000007a: ret RAM_FLASH_BufReset: 2000007c: lui a5,0x40022 20000080: lw a4,16(a5) 20000082: lui a3,0x10 20000084: or a4,a4,a3 20000086: sw a4,16(a5) 20000088: lw a4,16(a5) 2000008a: lui a3,0x80 2000008e: or a4,a4,a3 20000090: sw a4,16(a5) 20000092: lw a4,12(a5) 20000094: andi a4,a4,1 20000096: bnez a4,0x20000092 <RAM_FLASH_BufReset+22> 20000098: lw a4,16(a5) 2000009a: lui a3,0xffff0 2000009c: addi a3,a3,-1 2000009e: and a4,a4,a3 200000a0: sw a4,16(a5) 200000a2: ret RAM_FLASH_BufLoad: 200000a4: lui a5,0xf8000 200000a8: add a5,a5,a0 200000aa: lui a4,0x4 200000ac: bgeu a5,a4,0x200000d8 <RAM_FLASH_BufLoad+52> 200000b0: lui a5,0x40022 200000b4: lw a4,16(a5) 200000b6: lui a3,0x10 200000b8: or a4,a4,a3 200000ba: sw a4,16(a5) 96 *(__IO uint32_t *)(Address) = Data0; 200000bc: sw a1,0(a0) 97 FLASH->CTLR |= CR_BUF_LOAD; 200000be: lw a4,16(a5) 200000c0: lui a3,0x40 200000c4: or a4,a4,a3 200000c6: sw a4,16(a5) 99 ; 200000c8: lw a4,12(a5) 200000ca: andi a4,a4,1 200000cc: bnez a4,0x200000c8 <RAM_FLASH_BufLoad+36> 100 FLASH->CTLR &= ~CR_PAGE_PG; 200000ce: lw a4,16(a5) 200000d0: lui a3,0xffff0 200000d2: addi a3,a3,-1 200000d4: and a4,a4,a3 200000d6: sw a4,16(a5) 200000d8: ret 106 if((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd)) RAM_FLASH_ProgramPage_Fast: 200000da: lui a5,0xf8000 200000de: add a5,a5,a0 200000e0: lui a4,0x4 200000e2: bgeu a5,a4,0x2000010c <RAM_FLASH_ProgramPage_Fast+50> 108 FLASH->CTLR |= CR_PAGE_PG; 200000e6: lui a5,0x40022 200000ea: lw a4,16(a5) 200000ec: lui a3,0x10 200000ee: or a4,a4,a3 200000f0: sw a4,16(a5) 109 FLASH->ADDR = Page_Address; 200000f2: sw a0,20(a5) 110 FLASH->CTLR |= CR_STRT_Set; 200000f4: lw a4,16(a5) 200000f6: ori a4,a4,64 200000fa: sw a4,16(a5) 112 ; 200000fc: lw a4,12(a5) 200000fe: andi a4,a4,1 20000100: bnez a4,0x200000fc <RAM_FLASH_ProgramPage_Fast+34> 100 FLASH->CTLR &= ~CR_PAGE_PG; 20000102: lw a4,16(a5) 20000104: lui a3,0xffff0 20000106: addi a3,a3,-1 20000108: and a4,a4,a3 2000010a: sw a4,16(a5) 2000010c: ret 119 FLASH->CTLR |= CR_LOCK_Set; RAM_FLASH_Lock_Fast: 2000010e: lui a4,0x40022 20000112: lw a5,16(a4) 20000114: ori a5,a5,128 20000118: sw a5,16(a4) 2000011a: ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 15 февраля Опубликовано 15 февраля · Жалоба 2000014a: jalr t0,160(zero) # 0x0 <_start> А это что? Что лежит по адресу 0xA0 ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 9 15 февраля Опубликовано 15 февраля · Жалоба 50 minutes ago, adnega said: Что лежит по адресу 0xA0 ? Но это не объясняет, почему контроллер зависает - в тесте я программирую последнюю не используемую страницу FLASH, т.е. не затираю ни одного байта полезного кода. Кроме того он виснет на этапе RAM_FLASH_ProgramPage_Fast -> RAM_FLASH_Lock_Fast. И конечно же вопрос как заставить MRS не использовать функции из FLASH в функциях выполняемых из RAM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
niXto 0 16 февраля Опубликовано 16 февраля · Жалоба Не увидел, где вы читаете флаги готовности флеш-контроллера. При исполнении из флеш это необязательно, потому что ядро подвисает, пока флеш не освободиться, а вот при исполнении из ОЗУ это обязательно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 9 16 февраля Опубликовано 16 февраля · Жалоба 1 hour ago, niXto said: Не увидел, где вы читаете флаги готовности флеш-контроллера. При исполнении из флеш это необязательно, потому что ядро подвисает, пока флеш не освободиться, а вот при исполнении из ОЗУ это обязательно. Я скопировал код из библиотеки SPL 1 в 1. Там только флаг SR_BSY проверяется. void RAM_FLASH_Unlock_Fast (void) { /* Authorize the FPEC of Bank1 Access */ FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; /* Fast program mode unlock */ FLASH->MODEKEYR = FLASH_KEY1; FLASH->MODEKEYR = FLASH_KEY2; } void RAM_FLASH_ErasePage_Fast (uint32_t Page_Address) { if((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd)) { FLASH->CTLR |= CR_PAGE_ER; FLASH->ADDR = Page_Address; FLASH->CTLR |= CR_STRT_Set; while(FLASH->STATR & SR_BSY) ; FLASH->CTLR &= ~CR_PAGE_ER; } } void RAM_FLASH_BufReset (void) { FLASH->CTLR |= CR_PAGE_PG; FLASH->CTLR |= CR_BUF_RST; while(FLASH->STATR & SR_BSY) ; FLASH->CTLR &= ~CR_PAGE_PG; } void RAM_FLASH_BufLoad (uint32_t Address, uint32_t Data0) { if((Address >= ValidAddrStart) && (Address < ValidAddrEnd)) { FLASH->CTLR |= CR_PAGE_PG; *(__IO uint32_t *)(Address) = Data0; FLASH->CTLR |= CR_BUF_LOAD; while(FLASH->STATR & SR_BSY) ; FLASH->CTLR &= ~CR_PAGE_PG; } } void RAM_FLASH_ProgramPage_Fast (uint32_t Page_Address) { if((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd)) { FLASH->CTLR |= CR_PAGE_PG; FLASH->ADDR = Page_Address; FLASH->CTLR |= CR_STRT_Set; while(FLASH->STATR & SR_BSY) ; FLASH->CTLR &= ~CR_PAGE_PG; } } void RAM_FLASH_Lock_Fast (void) { FLASH->CTLR |= CR_LOCK_Set; } Может быть стоит добавить задержку перед первой проверкой флага в while? Помню с PIC18 был прикол с UART, что там флаги статуса не сразу менялись и приходилось вставлять nop перед первым опросом флага. Может быть здесь такая же проблема?... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 16 февраля Опубликовано 16 февраля · Жалоба Чему равен Page_Address ? #define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF) - не много для 16кБ флешки? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 9 16 февраля Опубликовано 16 февраля · Жалоба 2 minutes ago, adnega said: Чему равен Page_Address ? 0x08003FC0 3 minutes ago, adnega said: #define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF) Все define скопированы из SPL ch32v00x_flash.c как есть, я ничего не менял. Я просто скопировал к себе код из фирменной ch32v00x_flash.c добавив в свой flash.h атрибуты для размещения в RAM, и добавил к названиям функций RAM_* чтобы они не перекликались с функциями из фирменной библиотеки. К тому же судя по коду фирменных функций FLASH_BANK1_END_ADDRESS нигде не используется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 16 февраля Опубликовано 16 февраля · Жалоба 13 часов назад, adnega сказал: 2000014a: jalr t0,160(zero) # 0x0 <_start> А это что? Что лежит по адресу 0xA0 ? Я тут уже неоднократно писал, пытаясь донести до ТС, что скорее всего у него где-то в коде есть обращение к флешь. И чтобы гарантированно исключить такую возможность, нужно весь код слинковать в ОЗУ. И убедиться по .map-файлу, что не используется ни одного адреса из региона FLASH. Но ТС похоже не понимает.... ТС похоже не понимает, что те префиксы, которые он пишет у функций, ничего не гарантируют (не гарантируют, что компилятор не решит какую-то часть кода функций или их const-данные расположить во флешь (раз она прописана в карте доступной для компоновки памяти)). От подобного гарантирует только префикс __ramfunc у IAR. Или подобный ему у других компиляторов. Если такого префикса нет, то и нет гарантии что часть кода или данных при очередной перекомпиляции не окажется во FLASH. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 9 16 февраля Опубликовано 16 февраля · Жалоба 4 minutes ago, jcxz said: весь код слинковать в ОЗУ Это Вы не понимаете, что ВЕСЬ код в 2КБ ОЗУ физически не помещается. Я уже писал Вам об этом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 16 февраля Опубликовано 16 февраля · Жалоба 6 минут назад, BSACPLD сказал: Это Вы не понимаете, что ВЕСЬ код в 2КБ ОЗУ физически не помещается. Зачем весь то его туда лепить??? Я вот этого не понимаю. Неужели так трудно догадаться, что достаточно написать необходимый набор функций и фиксированными точками входа в них, скомпилировать/скомпоновать это в бинарный образ по ОЗУ-адресам, прицепить этот образ в любое место исполняемого кода (во флешь), а перед вызовом любой функции из этого образа - просто сперва скопировать его в ОЗУ, а потом вызвать нужную функцию из ОЗУ уже. Или же каждую из функций (ф.стирания; ф.записи; etc.) - скомпилить как отдельные образы и все прицепить к флешевому образу и перед вызовом любой из этих функций - копировать нужный из них в ОЗУ. А 2КБ для простой функции записи флешь или стирания - этого более чем достаточно. Уже сто лет подобная практика используется при недостатке ОЗУ. И называется - "оверлеи". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 9 16 февраля Опубликовано 16 февраля · Жалоба Решил я проблему с зависанием при выполнении кода из ОЗУ. Было: while(FLASH->STATR & SR_BSY); FLASH->CTLR &= ~CR_PAGE_PG; Стало: while(FLASH->STATR & SR_BSY); for (uint8_t i=0 ; i<10 ; i++) __asm__("nop"); FLASH->CTLR &= ~CR_PAGE_PG; Как я и предполагал, между сбросом флага SR_BSY и записью в FLASH->CTLR должна быть некоторая задержка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться