Я розглядаю розробку програмного забезпечення, що працює на батареях, за допомогою контролерів EFM Gekko (http://energymicro.com/), і хотів би спати контролер, коли нічого корисного для цього не робити. Для цього використовується інструкція WFI (Wait For Interrupt); він переведе процесор у режим сну, поки не відбудеться переривання.
Якщо уві сні спати, зберігаючи щось десь, можна використовувати ексклюзивні / магазинні ексклюзивні операції, щоб зробити щось на кшталт:
// dont_sleep завантажується з 2 будь-коли, коли щось трапляється // повинен змусити головну петлю провести цикл хоча б один раз. Якщо перерва // відбувається, що призводить до його скидання до 2 під час наступного твердження, // поведінка буде так, ніби перерва сталася після неї. store_exclusive (load_exclusive (dont_sleep) >> 1); поки (! dont_sleep) { // Якщо відбувається переривання між наступним оператором і store_exclusive, не спите load_exclusive (SLEEP_TRIGGER); if (! dont_sleep) store_exclusive (SLEEP_TRIGGER); }
Якщо між операціями load_exclusive і store_exclusive відбудеться переривання, ефектом було б пропустити store_exclusive, тим самим змусивши систему ще раз пробігти цикл (щоб побачити, чи встановив переривання dont_sleep). На жаль, Gekko використовує інструкцію WFI, а не адресу запису для запуску режиму сну; написання коду, як
if (! dont_sleep) WFI ();
ризикує виникнути перерва між 'if' і 'wfi' та встановити dont_sleep, але wfi продовжуватиметься та виконуватиметься все одно. Яка найкраща модель для запобігання цьому? Встановіть PRIMASK на 1, щоб запобігти перериванню процесора безпосередньо перед виконанням WFI, і очистити його відразу після? Або є якийсь кращий трюк?
EDIT
Мене цікавить біт Події. За загальним описом, хотілося б, що він призначений для підтримки декількох процесорів, але цікаво, чи може працювати щось подібне:
якщо (dont_sleep) SEV (); / * Зробимо чіткий прапор події WFE, але не сплю * / WFE ();
Кожне переривання, яке встановлює don_sleep, також повинно виконувати інструкцію SEV, тому якщо переривання відбудеться після тесту "якщо", WFE очистить прапор події, але не перейде до сну. Це звучить як добра парадигма?