Oi Habr.
A vantagem exclusiva tradicional da plataforma Arduino foi chamada (e agora ela é chamada às vezes, embora isso já esteja errado - e falaremos por que) diminuindo o limiar de entrada no desenvolvimento de microcontroladores para o nível de conhecimento básico de C / C ++ e eletrônica na escala "conecte o LED na polaridade correta".
Pergunte a qualquer suporte ativo do Arduino, e eles explicarão rapidamente o que você pode, é claro, escrever sob STM32 ou nRF52, mas não há benefício real, mas noites sem dormir esperam por você em centenas de páginas de folhas de dados e infinitas folhas de funções com nomes obscuros longos.
É realmente difícil superestimar os méritos do Arduino ao diminuir o limite de entrada - essa plataforma nasceu no meio dos zero anos e, após 2010, ganhou grande popularidade entre os amadores. Naquela época, não havia alternativas especiais - os processadores baseados nos núcleos Cortex-M apareceram; em comparação com o AVR, eles eram bastante complicados, mesmo para desenvolvedores profissionais, e as placas de depuração para a maioria dos fornecedores custam centenas de dólares ou mais (e, em geral, o preço da indústria) por depurar em um controlador de US $ 5 a US $ 500, não fiquei muito surpreso com ninguém).
No entanto, o grande problema do Arduino é que seu desenvolvimento nos últimos 10 anos se assemelha mais a alguns modelos AvtoVAZ:
Como pretendo fazer uma longa introdução agora, para que você possa imaginar qual será a parte prática, darei o texto
completo do programa, incluindo a inicialização do processador STM32 e o piscar do LED. O programa foi escrito para o ARM Mbed OS:
#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 « » :
- MinGW, arm-none-eabi-gcc GNU make ( Windows 10 , Ubuntu)
- RIOT
- cd RIOT/examples/hello-world
- make BOARD=nucleo-l152re
- 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 ! ?