ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
2 мая
1425756
il-2 (12.04.2024 18:08 - 18:23, просмотров: 1110)
Тут где-то на просторах LightElf жаловался на Flash-память микроконтроллера WCH. Я жаловаться не стану, но от этой истории думаю многие тут офигеют задумаются. 

Я сейчас плотно работаю с RISC-V CH582, думаю это касается всей линейки CH57x,CH58x,CH59x.

У этой серии в ассемблерном стартапе по адресу 0x14 (в таблице векторов) помещается некая магическая константа - 0xF5F9BDA9. Поначалу я на это не обращал внимания, при освоении нового МК и без того есть на что глядеть. Но вот я наконец углядел в отладчике, что вместо нее там прошивается 0xFFFFFFFF. Странность, конечно, но в новом МК все кажется странным. И вот недавно, когда отпустило, решил я подразобраться с этой конкретной странностью.

Первое, что я нарыл тупым поиском по исходникам, что в их оригинальной peripheral library в функции UserOptionByteConfig (как ясно из названия - задание OptionByte) этот адрес 0x14 и эта константа проверяются, выполняется программирование OptionByte, а затем выполняется запись во Flash по адресу 0x14, чтоб (наверное) эту константу порушить и добиться таким образом однократного программирования OptionByte.

Ну и в описании функции есть такой текст: "To use this function, you must use the officially provided startup .S file". Но в любом случае, я этой функцией не пользуюсь (в скобках - она вообще неработоспособна).

По наитию я решил наставить этих магических констант 0xF5F9BDA9 по разным адресам, и офигел!!! До определенного адреса (я не выяснял до какого) константа заменяется на 0xFFFFFFFF, а на более высоких адресах - прошивается нормально. Причем это все реально прошиваемые значения, они программой тоже читаются.

Ну и а подвожу к концу - я задал вопрос в поддержку, и вот что мне ответили:

Q:

In CodeFlash area at address 0x14 placed value 0xF5F9BDA9 (this defined in startup .S file). But after downloading i see in debugger 0xFFFFFFFF instead 0xF5F9BDA9.

I place 0xF5F9BDA9 value at various adresses, and at low addresses i have 0xFFFFFFFF, and (for example) at address 0x25378 this value correct.

I guess that this done by bootloader for unknown reasons?

In what address area is the replacement performed? This question has implications for firmware checksum self-test.

A:

When reading the value in CodeFlash through the LINK debugger, the debugger will determine whether the data is 0xF5F9BDA9. If so, it will be replaced with 0xFFFFFFFF. Because in the previous version of CH583's CodeFlash, 0xFFFFFFFF would be encrypted into 0xF5F9BDA9. So the debugger will replace 0xF5F9BDA9 with 0xFFFFFFFF. The debugger has not been updated with the features of the latest chips. The above problems will not affect the verification of the chip. The CodeFlash data read through FLASH_ROM_READ() is definitely correct. The debugger communicates directly with the chip core, while the bootloader is just a piece of code that operates the flash. The two work in different ways. In the production process, debuggers will not be used to download and verify programs. Generally, USB or serial port is used to download and verify the program through Bootloader.


Я понял проблему так - у меня какой-то относительно новый чип (который я мучаю почти год), с которым отладчик работает "по старому". В результате я после прошивки отладчиком имею во флешь памяти совсем не то. Он в ответе этот момент пробросил, что это как будто ПРИ ЧТЕНИИ отладчик подсовывает не то. Но на самом деле отладчик делает замену ПРИ ЗАПИСИ, да еще до определенного адреса. И я эту замену вижу в своей фирмвари, и контрольная сумма моей прошивки у меня не будет биться. И его хваленая функция FLASH_ROM_READ() тоже читает 0xFFFFFFFF.

Но его утверждение, что при загрузке прошивки ИХ боотлоадером все будет нормально - я не проверял. Вполне возможно, что это так.


Чтобы развить тему, я приведу еще один раунд переписки:

Q:

I use ISP Tool for program DataFlash area at 0x70000...0x700FF (256 bytes page). I use EEPROM_READ(0, buf, 256) macro for access to DataFlash area and this work fine. But, when i use direct read DataFlash area i have wrong results.

For example:

uint32_t data = *(uint32_t *)0x70000;

This direct access return wrong data. I need to have direct access to my data, without EEPROM_READ.

I look memory dump in debugger and i see "encrypted" data:

0x00000000 encrypted as 0x2C064216

0xFFFFFFFF encrypted as 0xF3F9BDA9

and etc...

This is possible to disable this encryption? Or how to program DataFlash with "reverse encrypted" data?

A:

The DataFlash of CH583 will be encrypted by hardware. The correct value cannot be read through the absolute address (uint32_t data = *(uint32_t *)0x70000). Currently no anti-encryption interface is provided. The data in DataFlash can only be read through EEPROM_READ


Я здесь подвожу к тому, что для работы в CodeFlash и DataFlash есть библиотечные функции (без исходников):

Для DataFlash - EEPROM_ERASE, EEPROM_WRITE, EEPROM_READ. Чтобы записанное и считанное совпадало, надо пользоваться только ими. Никаких регистров, никаких прямых обращений в память.

Для CodeFlash - FLASH_ROM_ERASE и FLASH_ROM_WRITE. Пресловутая FLASH_ROM_READ представляет собой обычную процедуру чтения блока, с исходным кодом.