
Комментарии 10
Как интересно, счетчик сделали 64-битным, а атомарное 64-битное чтение не завезли?
Неужто инструкция LD неатомарная?
В микроконтроллерах обычно предусмотрен аппаратный механизм, обеспечивающий “атомарность” при чтении таких регистров. Одна часть читается напрямую, а вторая через промежуточный регистр-защелку. При чтении младшей части, старшая защелкивается в промежуточном регистре (а может наоборот). Надо просто соблюдать последовательность чтения младший-старший.
В этом контроллере что-то нестандартно сделано. Надо документацию посмотреть. Или может это ранняя ревизия, инженерный образец.
Нет, на QingKe V4 (RV32IMAC) не завезли. STK_CNTL и STK_CNTH читаются двумя отдельными LW
Только запрет прерываний для этой комманды не поможет. Нужно использовать специальную обертку:
```
static uint64_t __riscv_get_cycle64(void)
{
#if __riscv_xlen == 64
uint64_t val;
asm volatile(
"rdcycle %0"
: "=r"(val));
return val;
#else
uint32_t hi1, hi2, low;
do
{
asm volatile(
"rdcycleh %0\n"
"rdcycle %1\n"
"rdcycleh %2"
: "=r"(hi1), "=r"(low), "=r"(hi2));
} while (hi1 != hi2);
return ((uint64_t)hi1 << 32) | low;
#endif
}
```
Я бы завернул в цикл просто вместо одиночного if. И даже без запрета прерываний оно бы в итоге смогло считать корректное значение.
Впрочем, и без цикла запрет прерываний не так уж нужен. Не исполняются обработчики прерываний десятки секунд. А если исполняются, то у нас уже всё сломалось.
Это реальная задача из собеса в яндекс. Как прочитать 64-битный каунтер 32-битными операциями.
Нельзя просто взять и прочитать 64-битный SysTick на CH32V203