Inicio rápido con ARM Mbed: desarrollo en microcontroladores modernos para principiantes

Hola Habr

Se llamó a la ventaja única tradicional de la plataforma Arduino (y ahora a veces se llama, aunque esto ya está mal, y hablaremos de por qué) reducir el umbral para ingresar al desarrollo de microcontroladores al nivel de conocimiento básico de C / C ++ y electrónica en la escala "conectar el LED en la polaridad correcta".

Pregúntele a cualquier partidario activo de Arduino, y le explicarán rápidamente lo que puede, por supuesto, escribir bajo STM32 o nRF52, pero no hay ningún beneficio real, pero las noches sin dormir lo esperan en cientos de páginas de hojas de datos y hojas interminables de funciones con nombres largos y oscuros.

Es realmente difícil sobreestimar los méritos de Arduino en la reducción del umbral de entrada: esta plataforma nació a mediados de los años cero, y después de 2010 ganó una gran popularidad entre los aficionados. No había alternativas especiales en ese momento: los procesadores basados ​​en núcleos Cortex-M recién estaban surgiendo, en comparación con AVR, eran bastante complicados incluso para desarrolladores profesionales, y las placas de depuración para la mayoría de los proveedores cuestan cientos de dólares o más (y, en general, el precio en la industria por depurar en un controlador de $ 5 a $ 500, nadie me sorprendió mucho).

Sin embargo, el gran problema con Arduino es que su desarrollo en los últimos 10 años se parece más a algunos modelos de AvtoVAZ:


Como planeo una larga introducción adicional, ahora, para que pueda imaginar cuál será la parte práctica, le daré el texto completo del programa, incluida la inicialización del procesador STM32 y el parpadeo del LED. El programa está escrito para el sistema operativo ARM Mbed:

#include "mbed.h"
DigitalOut myled(LED1);

int main() {
    while(1) {
        myled = 1; // LED is ON
        wait(0.2); // 200 ms
        myled = 0; // LED is OFF
        wait(1.0); // 1 sec
    }
}

? ? ? ? , .

, 2010 … . AVR, 8- , — 2017 12 % ( Aspencore), : AVR, PIC STM8. , — , ..

ATMega 12 % — 32- Cortex-M / (STM32F030 16-64 4-8 30-50 ). , - .


64- — , , Cortex-A

. , , Cortex-M ? ( , — ), . AVR , STM32F1 STM32L1 , - Infineon NXP…

, — , STMicro : SPL, HAL LL. , , , .

.

, . , — , , , . , (, , , loop(), , - — , - , - ).


— , « », :

  • HAL — . . , -, (, , - STM32L072, STM32L151 STM32L451 — , ), -, ( , , , STM32, , ). — , RIOT API SAUL, ; , - .
  • — , , - . , , .
  • — , . , . , , , . , .
  • IPC — . , , , , , , , , , - - (, , : , , , , ).
  • — API , , . , , , , , , , API .
  • — « » .

, — API POSIX.

, . , :

  • FreeRTOS — , , . — . ( , )
  • Contiki OS — , , , 6LoWPAN. , (, ). Contiki NG — , .
  • RIOT OS — , Contiki. ( ATMega) . . C. , , . , , .
  • ARM Mbed — ( , Apache 2.0) ARM Holdings. 2.0, 5.x. C++ API. , . , Mbed.
  • TI-RTOS — Texas Instruments, , TI - , , . , API .

- , arm-none-eabi-gcc. , RIOT Makefile', Visual Studio, . ARM Mbed (mbed-cli), PlatformIO, mbed-cli Keil uVision Makefiles.

— , Arduino. , gdb JTAG/SWD-.


, ? , ?

. . , .

, RIOT OS « » :

  1. MinGW, arm-none-eabi-gcc GNU make ( Windows 10 , Ubuntu)
  2. RIOT
  3. cd RIOT/examples/hello-world
  4. make BOARD=nucleo-l152re
  5. HEX- Nucleo ( ST-Link )

, main.c, :

#include <stdio.h>

int main(void)
{
    puts("Hello World!");

    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);

    return 0;
}

? , ? SPL? , ?

.

, . — ARM Mbed .


( , , b2b-, Nucleo-L152RE BME280 OPT3001)



1) mbed.com.

2) «Compiler» - . , . , «Add board» Nucleo, ( L152RE, , Nucleo, ). , Nucleo .



3) New → New Program. Mbed - , Nucleo-L152 . , , 5.9.5, — «Empty program».

— -, mbed, -, - main.cpp. #include, mbed-os.

:

  • «Import», «Click here to import from URL», ( , Mbed, )
  • «Library»
  • «Import»



→ «New file» → main.cpp. :

#include "mbed.h"

DigitalOut led(LED1);

int main()
{
    printf("Hello World !\n");

    while(1) {
        wait(1); // 1 second
        led = !led; // Toggle LED
    }
}

(LED1 — Nucleo )

4) Ctrl-D ( «Compile»), -, . Nucleo USB- ( : Nucleo mini-USB, ), 540 «Node_L152RE». MBED.HTM, , .

, , BIN- HEX- , Mbed , .

. Nucleo , — LED1.

5) BME280, ? , «Import Library» (, , , — ). , Library, («Target path»).



, , .

6) , :

#include "mbed.h"
#include "BME280.h"

DigitalOut led(LED1);
BME280 sensor_bme(D14, D15);

int main()
{
    while(1) {
        wait(1); // 1 second
        led = !led; // Toggle LED
        printf("%2.2f degC, %04.2f hPa, %2.2f %%\r\n", sensor_bme.getTemperature(), sensor_bme.getPressure(), sensor_bme.getHumidity());
    }
}

, , , Nucleo I2C-. , .. SDA SCL ( STM32L1 I2C, ), , , I2C_SDA I2C_SCL . .

7) . — +3,3 , , SDA, SCL. STM32, 3,3-, .



8) «Compile», BIN- Nucleo.

8) ??????

( — Termite, , Nucleo; COM-. 9600 /)

9) PROFIT!!!



. , , « , », , .

— , . -, , while(1) 1- — , 1 , 1 , .

-, 9600 / — - , 2018 , 115200.

: Serial, , .

Serial pc(SERIAL_TX, SERIAL_RX);
pc.baud(115200);

while(1) , , . Mbed , (EventQueue), ( call) ( call_every), .

:

#include "mbed.h"
#include "BME280.h"

DigitalOut led(LED1);
BME280 sensor_bme(D14, D15);
EventQueue eventQueue(/* event count */ 50 * EVENTS_EVENT_SIZE);

void printTemperature(void)
{
    printf("%2.2f degC, %04.2f hPa, %2.2f %%\r\n", sensor_bme.getTemperature(), sensor_bme.getPressure(), sensor_bme.getHumidity());
    led = !led; // Toggle LED
}

int main()
{
    eventQueue.call_every(1000, printTemperature); // run every 1000 ms
    eventQueue.dispatch_forever();
    
    return 0;
}

, . , ( ), — , - . eventQueue ( — , 50 ), , , , .

?

, while(1) , .

, OPT3001. , …

OPT3001 — ( , ), TSL2561 , Mbed . , ( ), — https://github.com/ashok-rao/mbed-OPT3001.

Import, «Click here to import from URL», URL , «Library» — «Import».

. .

, . , « OPT3001.cpp, », ( , OPT3001).

: Import → Click here to import from URL → github.com/olegart/mbed_opt3001 → Library → Target Path = → Import.

:

#include "mbed.h"
#include "BME280.h"
#include "OPT3001.h"

DigitalOut led(LED1);
BME280 sensor_bme(D14, D15);
OPT3001 sensor_opt(D14, D15);
EventQueue eventQueue(/* event count */ 50 * EVENTS_EVENT_SIZE);
Serial pc(SERIAL_TX, SERIAL_RX);

void printTemperature(void)
{
    pc.printf("%2.2f degC, %04.2f hPa, %2.2f %%\r\n", sensor_bme.getTemperature(), sensor_bme.getPressure(), sensor_bme.getHumidity());
    
    pc.printf("%ld lux\r\n", sensor_opt.readSensor());
    
    led = !led; // Toggle LED
}

int main()
{
    pc.baud(115200);
    
    eventQueue.call_every(1000, printTemperature); // run every 1000 ms
    eventQueue.dispatch_forever();
    
    return 0;
}

Compile, , Nucleo, 115200…



PROFIT!!!

:


, , , — , .

, , , . , , .

Nucleo «IDD», , , ( , — , ).



L152 10 , - LED1, ( 2-3 ). - , , ?..

, . , , , — , , eventQueue.call_every , . STM32L151 , — , RTC ( L151CB-A , RTC_SSR), — .

, dispatch_forever(), — , , , , .

, ? , , — ?

LowPowerTicker, RTC, — . LowPowerTicker, sleep() — ( , , , — , , - , , ).

: , - — , ( OPT3001, , 100 ). printf — , . , , .

, while(1), — . , while(1) ?

, EventQueue, .

#include "mbed.h"
#include "BME280.h"
#include "OPT3001.h"

DigitalOut led(LED1);
BME280 sensor_bme(D14, D15);
OPT3001 sensor_opt(D14, D15);
EventQueue eventQueue(/* event count */ 50 * EVENTS_EVENT_SIZE);
Serial pc(SERIAL_TX, SERIAL_RX);
LowPowerTicker lpTicker;

void printTemperature(void)
{
    pc.printf("%2.2f degC, %04.2f hPa, %2.2f %%\r\n", sensor_bme.getTemperature(), sensor_bme.getPressure(), sensor_bme.getHumidity());
    pc.printf("%ld lux\r\n", sensor_opt.readSensor());        
    led = !led; // Toggle LED
}

void tickerIRQ (void)
{
    eventQueue.call(printTemperature);
}

int main()
{
    pc.baud(115200);
    
    lpTicker.attach(tickerIRQ, 1); // every second
    
    while(1)
    {
        eventQueue.dispatch(0);
        sleep();
    }
}

? : Low Power Ticker, . , eventQueue.call, ( , .. , — call ). .call , while(1), — dispatch , , sleep(), .

.

→ → → call → → dispatch → → sleep() .

PROFIT???



PROFIT!!!

( , 0,57 — , . Mbed, , STM32L1: Digital In , Analog In , - - . , Nucleo JTAG -)

- . , « RTOS» , , .

— 55,1 9,2 ( , «Build details» ), — , 2- STM32F103CB 128 20 . , , STM32F030F4P6 16 4 — RIOT OS .

, , float printf . — , . malloc , malloc .

P.S. —  Mbed.

P.P.S. : Nucleo-L152RE ( Nucleo / Discovery , , — , , ), BME280 (: , , , BMP280, ). OPT3001 — , TI .


, RTOS , — Mbed , , - , RIOT 2018.07 ( ), .

, Arduino « », — , , , - ( , , ).

, , . , , , — , . , « », — , , , , 2018 , , , , - .

, — , . , , . .

, , . - , AVR.

…



?!

, 2018 ! ?

Source: https://habr.com/ru/post/es420435/


All Articles