Миро Самек "Использование режимов малого энергопотребления в простых программных архитектурах" (перевод)


8051

Архитектура MCS-51 поддерживает два режима низкого потребления (ожидание - "idle" и выключение - "power down"). Эти режимы активируются битами "IDL" и "PD" в регистре управления питанием "PCON", расположенном по адресу 0x87. Запись единицы в какой-либо бит немедленно останавливает процессор и должна проводиться при разрешённых прерываниях, в противном случае контроллер останется в режиме малого потребления [* до выключения питания или сброса]. Это означает, что атомарный переход в какой-либо из режимов сна невозможен, так как любое немаскированное событие сможет перехватить управление у фонового процесса после разрешения прерываний, но до перехода в режим сна. Таким образом, для MCS-51 требуется техника, отличающаяся от обсуждавшихся до настоящего момента.

Такой техникой будет отмена перехода в режим сна в каждом прерывании [* похожая техника - возвращение из режима сна - применяется в случае MSP430]. Таким образом, если прерывание перехватывает управление у фонового цикла непосредственно перед переходом в режим малого потребления, обработчик прерывания отменит переход и после возврата управления фоновый цикл не войдёт в режим сна.

Одним из путей реализации такой техники в MCS-51 будет создание теневой копии регистра "PCON", в битовом адресном пространстве памяти (bdata) [* не обязательно в битовом (0x20..0x2F) - достаточно в прямоадресуемом из диапазона 0x00..0x7F]. Назовём эту копию "PCON_shadow". В листинге 8 (компилятор Keil C51) показано использование переменной "PCON_shadow" фоновым циклом.

Листинг 8. Использование переменной PCON_shadow в фоновом цикле (компилятор Keil C51)

    unsigned char bdata PCON_shadow;    /*  Размещаем PCON_shadow в ..      */
                                        /*  .. прямоадресуемой памяти       */
    ...
    EA = 0;                             /*  Запрещаем прерывания            */
    if (idle_condition()) {             /*  Состояние простоя ?             */
        PCON_shadow = PCON | 0x01;      /*  Да: устанавливаем бит "IDL"     */
        EA = 1;                         /*  Разрешаем прерывания            */
        PCON = PCON_shadow;             /*  Переходим в режим малого ..     */
                                        /*  .. потребления инструкцией: ..  */
                                        /*  .. "MOV 87H,20H"                */
    }
    else {
        EA = 1;                         /*  Нет: разрешаем прерывания       */    
    }

				

 

Фоновый процесс устанавливает бит "IDL" только в теневой копии регистра при запрещённых прерываниях. Затем прерывания разрешаются и регистр "PCON" восстанавливается из копии. Очень важно, чтобы восстановление регистра производилось одной машинной инструкцией (атомарно). Как оказалось [* СЮРПРИЗ!], присваивание значения переменной из битового адресного пространства [* прямоадресуемой памяти] регистру специальных функций такому, как "PCON", может быть выполнено одной инструкцией - "MOV 87H,20H".

Состояние "PCON_shadow" должно корректироваться в соответствии с листингом 9 в каждом обработчике прерываний, который добавляет работы фоновому циклу. Отметим, что биты "IDL" и "PD" в регистре "PCON" перед входом в прерывание обнуляются автоматически, таким образом они будут гарантированно сброшены и в теневой копии после того, как обработчик скопирует в неё значение "PCON" (см. листинг 9).

Листинг 9. PCON_shadow должна обновляться в каждой ISR, в которой могут появиться данные, требующие обработки в фоновом цикле

    void my_ISR(void) interrupt xx {
        ...
        PCON_shadow = PCON;     /*  Обновляем состояние PCON_shadow */    
    }

				

 

В такой программной конструкции прерывание может произойти на любой машинной инструкции между резрешением прерываний и восстановлением "PCON" из теневой копии. Любое прерывание сбросит биты "IDL" и "PD" в "PCON_shadow" и они не доживут до момента, когда фоновый цикл восстановит регистр из копии. Отсюда, любое прерывание, перехватывающее управление у фонового процесса запрещает режим сна, выполняя задачу безопасного, с точки зрения обработки внешних событий, перехода в режим ожидания (idle).

ПредпросмотрAttachmentSize
low_power_modes_in_background.zip27.87 КБ