2013-12-06 5 views
0

Я хочу создать приложение малой мощности с mbed (LPC1768) и следовали учебник Джимом Хамблена по адресу: https://mbed.org/cookbook/Power-Management, а также http://mbed.org/users/no2chem/notebook/mbed-power-controlconsumption/mbed не спать с RTOS

я смог разбудить mbed из спящего режима() прерыванием GPIO, прерыванием UART и тикером. Я использую библиотеку PowerControl.

Вот мой код:

#include "mbed.h" 
#include "PowerControl/PowerControl.h" 
#include "PowerControl/EthernetPowerControl.h" 
// Need PowerControl *.h files from this URL 
// http://mbed.org/users/no2chem/notebook/mbed-power-controlconsumption/ 

// Function to power down magic USB interface chip with new firmware 
#define USR_POWERDOWN (0x104) 
int semihost_powerdown() { 
    uint32_t arg; 
    return __semihost(USR_POWERDOWN, &arg); 
} 

DigitalOut myled1(LED1); 
DigitalOut myled2(LED2); 
DigitalOut myled3(LED3); 
DigitalOut myled4(LED4); 

bool rx_uart_irq = false; 

Serial device(p28, p27); // tx, rx 
InterruptIn button(p5); 

// Circular buffers for serial TX and RX data - used by interrupt routines 
const int buffer_size = 255; 
// might need to increase buffer size for high baud rates 
char tx_buffer[buffer_size]; 
char rx_buffer[buffer_size]; 
// Circular buffer pointers 
// volatile makes read-modify-write atomic 
volatile int tx_in=0; 
volatile int tx_out=0; 
volatile int rx_in=0; 
volatile int rx_out=0; 
// Line buffers for sprintf and sscanf 
char tx_line[80]; 
char rx_line[80]; 

void Rx_interrupt(); 

void blink() { 
    myled2 = !myled2; 
} 


int main() { 
    //int result; 

    device.baud(9600); 
    device.attach(&Rx_interrupt, Serial::RxIrq); 
// Normal mbed power level for this setup is around 690mW 
// assuming 5V used on Vin pin 
// If you don't need networking... 
// Power down Ethernet interface - saves around 175mW 
// Also need to unplug network cable - just a cable sucks power 
    PHY_PowerDown(); 
    myled2 = 0; 
// If you don't need the PC host USB interface.... 
// Power down magic USB interface chip - saves around 150mW 
// Needs new firmware (URL below) and USB cable not connected 
// http://mbed.org/users/simon/notebook/interface-powerdown/ 
// Supply power to mbed using Vin pin 
    //result = semihost_powerdown(); 
// Power consumption is now around half 

// Turn off clock enables on unused I/O Peripherals (UARTs, Timers, PWM, SPI, CAN, I2C, A/D...) 
// To save just a tiny bit more power - most are already off by default in this short code example 
// See PowerControl.h for I/O device bit assignments 
// Don't turn off GPIO - it is needed to blink the LEDs 
    Peripheral_PowerDown(~(LPC1768_PCONP_PCUART0 | 
          LPC1768_PCONP_PCUART2 | 
          0)); 

// use Ticker interrupt and Sleep instead of a wait for time delay - saves up to 70mW 
// Sleep halts and waits for an interrupt instead of executing instructions 
// power is saved by not constantly fetching and decoding instructions 
// Exact power level reduction depends on the amount of time spent in Sleep mode 
    //blinker.attach(&blink, 0.05); 
    //button.rise(&blink); 
    while (1) { 
     myled1 = 0; 
     printf("bye\n"); 
     Sleep(); 
     if(rx_uart_irq == true) { 
      printf("wake from uart irq\n"); 
     } 
     myled1 = 1; 
    } 
} 

// Interupt Routine to read in data from serial port 
void Rx_interrupt() { 
    myled2 = !myled2; 
    rx_uart_irq = true; 
     uint32_t IRR0= LPC_UART2->IIR; 
    while ((device.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { 
     rx_buffer[rx_in] = LPC_UART2->RBR; 
     rx_in = (rx_in + 1) % buffer_size; 
    } 
} 

Вот проблема: Sleep() не ставит mbed спать, когда добавляется библиотека mbed-RTOS. Даже если я не использую никаких вызовов функций из библиотеки rtos, функция Sleep() не работает.

Мое объяснение: Возможно, у rtos есть таймер, работающий в фоновом режиме, и он периодически создает прерывание. (Но это своего рода не имеет смысла, потому что я не использовать какую-либо функцию или объект из библиотеки RTOS)

Мой вопрос:

Есть ли какой один из засыпания() функцию работы с ОСРВ? если да, пожалуйста, укажите мне правильное направление или если у вас есть решение, пожалуйста, поделитесь.

+0

Вы пробовали Thread :: сна() функцию вместо этого? –

ответ

0

Каждый rtos имеет таймер, который прерывает прерывание. Это используется для переключения задач. Вы можете остановить этот таймер, когда вы вызываете метод сна, пока вы убедитесь, что он будет перезапущен на вашем собственном прерывании.

1

Я не уверен, что функция Sleep() предназначена для использования RTOS, но я сомневаюсь. Кто-то с лучшими знаниями в mbed-rtos, вероятно, мог бы точно сказать, но я подозреваю, что обработка IRQ в RTOS может вызвать проблему. Если Sleep() полагается на WFE, тогда MCU будет спать, если флаг ожидающего прерывания отсутствует. В конструкции супер-цикла вам (должен) быть полный контроль над этим; с RTOS вы этого не делаете.

Я предлагаю вместо этого использовать Thread :: wait(), который должен иметь полное представление о том, что делает RTOS. Не могу сказать, вызывает ли это сон, но я ожидаю не меньше.

+0

Эрик прав. Thread :: Wait будет служить цели здесь. –