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

CH32V003 удалённое обновление прошивки

посмотрел v003 сильно отличается: CSR 0xBC0 - отсутствует; U режима нет совсем (mstatus.MPP=0b11, т.е. всегда в режиме M).

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


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

Почитал внимательно .

ТС вызывает функции из функций ))

Да, функции находятся в ОЗУ, но они могут использовать флешовые __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
  

 

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


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

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

 

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


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

50 minutes ago, adnega said:

Что лежит по адресу 0xA0 ?

Но это не объясняет, почему контроллер зависает - в тесте я программирую последнюю не используемую страницу FLASH, т.е. не затираю ни одного байта полезного кода.

Кроме того он виснет на этапе RAM_FLASH_ProgramPage_Fast -> RAM_FLASH_Lock_Fast.

И конечно же вопрос как заставить MRS не использовать функции из FLASH в функциях выполняемых из RAM.

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


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

Не увидел, где вы читаете флаги готовности флеш-контроллера. При исполнении из флеш это необязательно, потому что ядро подвисает, пока флеш не освободиться, а вот при исполнении из ОЗУ это обязательно.

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


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

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 перед первым опросом флага.

Может быть здесь такая же проблема?...

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


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

Чему равен Page_Address ?

#define FLASH_BANK1_END_ADDRESS    ((uint32_t)0x807FFFF)

- не много для 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 нигде не используется.

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


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

13 часов назад, adnega сказал:
2000014a:   jalr    t0,160(zero) # 0x0 <_start>

А это что?

Что лежит по адресу 0xA0 ?

Я тут уже неоднократно писал, пытаясь донести до ТС, что скорее всего у него где-то в коде есть обращение к флешь. И чтобы гарантированно исключить такую возможность, нужно весь код слинковать в ОЗУ. И убедиться по .map-файлу, что не используется ни одного адреса из региона FLASH. Но ТС похоже не понимает.... :unknw:

ТС похоже не понимает, что те префиксы, которые он пишет у функций, ничего не гарантируют (не гарантируют, что компилятор не решит какую-то часть кода функций или их const-данные расположить во флешь (раз она прописана в карте доступной для компоновки памяти)). От подобного гарантирует только префикс __ramfunc у IAR. Или подобный ему у других компиляторов. Если такого префикса нет, то и нет гарантии что часть кода или данных при очередной перекомпиляции не окажется во FLASH.

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


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

4 minutes ago, jcxz said:

весь код слинковать в ОЗУ

Это Вы не понимаете, что ВЕСЬ код в 2КБ ОЗУ физически не помещается.

Я уже писал Вам об этом.

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


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

6 минут назад, BSACPLD сказал:

Это Вы не понимаете, что ВЕСЬ код в 2КБ ОЗУ физически не помещается.

Зачем весь то его туда лепить??? Я вот этого не понимаю.  :unknw:

Неужели так трудно догадаться, что достаточно написать необходимый набор функций и фиксированными точками входа в них, скомпилировать/скомпоновать это в бинарный образ по ОЗУ-адресам, прицепить этот образ в любое место исполняемого кода (во флешь), а перед вызовом любой функции из этого образа - просто сперва скопировать его в ОЗУ, а потом вызвать нужную функцию из ОЗУ уже.

Или же каждую из функций (ф.стирания; ф.записи; etc.) - скомпилить как отдельные образы и все прицепить к флешевому образу и перед вызовом любой из этих функций - копировать нужный из них в ОЗУ.

А 2КБ для простой функции записи флешь или стирания - этого более чем достаточно.

 

Уже сто лет подобная практика используется при недостатке ОЗУ. И называется - "оверлеи".

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


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

Решил я проблему с зависанием при выполнении кода из ОЗУ.

Было:

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 должна быть некоторая задержка.

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


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

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

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

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

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

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

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

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

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

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