ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
29 апреля
1584246 Топик полностью
Nikolay_Po (Сегодня, 00:06, просмотров: 15) ответил Nikolay_Po на RISC-V, QingKeV2 (CH32V006). По мере роста размера кода (4кБ сейчас), начал сваливаться в хардфолт. Компилятор GCC15 для WCH от Mounriver (из дистрибутива MRS2).
В общем, казалось бы, победил, поправив ключи компилятора. Но нет: стал опять падать. Причём, в зависимости от кода (использовал IQmath_RV32 или float - пробовал и то, и другое) получал целый ряд причин отказа mcause - от 4й до 7й (interrupt = 0): 


Проблема появлялась на оптимизациях -O3 и -Ofast, не появлялась с -Og и могла не проявляться с -Os. Решил, что так жить нельзя, стал копать дальше.

С указанием на инструкцию, вызвавшую ошибку, проблем не было. Как показала практика, регистр mpec чётко показывает на адрес сбойной инструкции. Тут без сюрпризов, никакого "проскальзывания кэша" (у этого МК кэша нет, максимум - prefetch или вообще ничего).


- Собрав некоторую статистику, выяснил, что проблема с инструкциями, использующими косвенную адресацию.

- Пробовал сдвигать данные, к которым обращались команды. Не помогало.

- Пробовал сдвигать код. Не помогало. Ситуация не менялась вообще.

- Пробовал, после сбоя, заглянуть в регистры, по адресам из которых шло обращение с отказом. Хмм... Значения вообще не адекватные. Значит, их что-то портит!

- Убрал со всех прерываний в системе атрибут прерывания "WCH-Interrupt-fast". Проблема ушла.


Кстати, IQmath_RV32 - рабочая штука. Считаю квадратные корни. До 385 тактов занимает взять 32-разрядное целое и получить из него 16-бит корень. Для сравнения, lroundf(sqrtf()), занимают 6140 такта, а без округления, только корень - 5752 такта примерно. Но это уже не точно - долгие вычисления прерываются.