Цитата(aaarrr @ Oct 20 2015, 14:52)

У ARM7TDMI нет ни кэша ни буфера записи.
Ну я это подозревал. Тогда придется изложить, что же я наблюдаю.
Код такой
В *.h-файле:
Код
__no_init volatile unsigned long ForceReprogrammingSignature @ 0x40008000;
В *.cpp-файле функция:
Код
void ForceReprogramming(bool Monopoly)
{
ForceReprogrammingSignature = 0x085D0B75;
// asm("nop"); // маленькая задержка в пять ассемблерных команд - если раскомментировать, не помогает (возвращается старое значение)
// asm("nop");
// asm("nop");
// asm("nop");
// asm("nop");
// volatile unsigned long x = ForceReprogrammingSignature; // чтение (в ассемблере две команды) - если раскомментировать, помогает (сохраняется записанное значение)
// vTaskDelay(10/portTICK_RATE_MS); // большая задержка в 10 мс - если раскомментировать, помогает (сохраняется записанное значение)
if (Monopoly)
__disable_interrupt(); // при Monopoly == true запрещаем прерывания
PCLKSEL0_bit.PCLK_WDT = 1; // далее взводим WDT
WDTC = CCLK / 4 * 5; // на 5 секунд
WDMOD_bit.WDEN = 1;
WDMOD_bit.WDRESET = 1;
WDCLKSEL_bit.WDSEL = 1;
WDFEED = 0xAA;
WDFEED = 0x55;
if (Monopoly) // при Monopoly == true из функции не возвращаемся
while (1);
}
Так вот, изначально в ForceReprogrammingSignature некое значение, назовем его "старым значением". Далее разные варианты:
1. Вызываем ForceReprogramming(false), она записывает в ForceReprogrammingSignature сигнатуру 0x085D0B75, назовем это "записанное значение", запускает WDT, возвращается, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature
"записанное значение", все ок, вопросов нет.
2. Вызываем ForceReprogramming(
true), она записывает в ForceReprogrammingSignature сигнатуру,
без задержки запрещает прерывания (тем самым в частности останавливает планировщик FreeRTOS), запускает WDT,
виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature
"старое значение", офигеваем.
3. Вызываем ForceReprogramming(true) с
раскомментированной задержкой на 10 мс, она записывает в ForceReprogrammingSignature сигнатуру,
через 10 мс запрещает прерывания, запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature
"сохраненное значение".
4. Вызываем ForceReprogramming(true) с
закомментированной задержкой на 10 мс, но с
раскомментированным чтением, она записывает в ForceReprogrammingSignature сигнатуру, тут же
считывает ее (две ассемблерные команды), запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature
"сохраненное значение".
5. Вызываем ForceReprogramming(true) с
закомментированными задержкой на 10 мс и чтением, но с
раскомментированной задержкой из пяти nop'ов, она записывает в ForceReprogrammingSignature сигнатуру,
выполняет 5 пустых команд, запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature
"старое значение".
Вот и создается такое впечатление, как будто оператор
Код
ForceReprogrammingSignature = 0x085D0B75;
пишет физически в кэш, и если после этого сразу отключить прерывания, то значение из кэша не успевает сброситься в "настоящий" RAM, поэтому после перезагрузки по WDT снова читаем оттуда старое значение. Звучит бредово, поэтому ищу другую версию )
Сообщение отредактировал murug - Oct 20 2015, 12:56