Mbed OS: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
|||
Riadok 689: | Riadok 689: | ||
</source></tab> | </source></tab> | ||
</tabs> | </tabs> | ||
[[Category:ARM]] |
Aktuálna revízia z 09:55, 4. august 2023
mbed je jednak počítačová platforma na báze procesorov ARM Cortex-M a jednak rovnomenný operačný systém určený pre túto platformu. Operační systém mbed je napísaný v kombinácii C a C++ a je uvolnený pod licenciou Apache License. Jeho vývoj koordinuje firma ARM Holdings, ktorá celú platformu inzeruje ako základ pre tvorbu aplikácií pre IoT.
Medzi podporný software napísaný priamo pre mbed patrí integrované vývojové prostredie implementované ako webová aplikácia, ktorá běží priamo v prehliadači. Okrem toho pre túto platformu existujú aj iné vývojové prostredia a kompilátory, napr. Eclipse doplnené o príslušnú variantu GCC alebo Yotta.
- https://os.mbed.com/mbed-os/ Main page
- https://en.wikipedia.org/wiki/Mbed Overview
- https://www.arm.com/products/development-tools/embedded-and-software/mbed-os ARM product page
- https://youtu.be/BsV-5IFaOLg What is Mbed OS? (video)
- https://os.mbed.com/docs/mbed-os/v6.15/apis/security-concepts.html Mbed security concepts
Iny OS pre ARM je Zephyros: https://www.zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-1-gpio/
Všeobecný text o tom, čo je to Embedded OS spolu s prehladom (FreeRTOS, mbedOS, Embedded Linux, Windows...) je tuto
https://community.element14.com/learn/learning-center/essentials/w/documents/4762/embedded-software-i-embedded-os?ICID=essentials-embedsoftware2-doc?param=prev
Hardware
- https://os.mbed.com/handbook/mbed-Microcontrollers Mbed official microcontroller boards
- micro:bit
- STM Nucleo boards
- RPi pico - experimental support: https://github.com/arduino/ArduinoCore-mbed/releases/tag/2.0.0
- List of supported HW: https://os.mbed.com/platforms/
- Pozor na fake chipy:
Simulátor
NOTE: The hosted Mbed simulator will stop running from December 2022. You can continue to use the simulator locally or host your own version by following these instructions: https://github.com/ARMmbed/mbed-simulator#readme
Courses & Tutorials
- https://courses.edx.org/courses/course-v1:ArmEducation+EDARMXES1.6x+3T2020/7c46ec78a5b640ecb721b9ca5bc285f9/
- https://os.mbed.com/blog/entry/introducing-mbed-simulator/
Príklady
Zoznam príkladov a návodov, ktoré by sa dali využiť a testovať na micro:bit alebo iný vhodný dev Kit.
Velmi dobry zoznam k nejakemu kurzu je tu: https://os.mbed.com/teams/TVZ-Mechatronics-Team/wiki/Homepage
- Course notes aj so slajdami https://os.mbed.com/cookbook/Course-Notes
- Kucharska kniha: https://os.mbed.com/cookbook/Homepage
- https://os.mbed.com/users/4180_1/notebook/cc-io-register-names/
- https://os.mbed.com/users/4180_1/notebook/using-the-hc-sr04-sonar-sensor/ (zaroven aj Timer!)
- Analog In https://os.mbed.com/docs/mbed-os/v5.15/apis/analogin.html (a asi aj serial printf?)
- Serial https://os.mbed.com/handbook/Serial (software serial?)
- Blocking and non-blocking Serial input https://os.mbed.com/questions/80004/How-to-read-and-write-serial-data/
micro:bit specific
- https://os.mbed.com/platforms/Microbit/#micro-bit-device-abstraction-layer-dal
- https://lancaster-university.github.io/microbit-docs/ubit/io/
/* Zakladne blikanie LEDkou na micro:bite
*
* Prvy sposob nevyzaduje specialnu micro:bit kniznicu, staci mbed.h a vybrany prislusny hardware. Z neho je uz jasne,
* ako sa ma co prelozit, len treba pouzivat originalne nazvy pinov P0_x
*
* Druhy sposob vyzaduje MicroBit.h a je tam zjednodusene volanie, ale zasa sa asi nedostaneme az priamo ku HW.
* Podstatne je, ze oba sposoby funguju ALE! nesmu sa kombinovat, potom mi tam nieco preblikava naviac.
* 4.2.2022
*
* Kompletna dokumentacia k MicroBit.h je tu https://lancaster-university.github.io/microbit-docs/ubit/io/
*/
#include "mbed.h"
#include "MicroBit.h"
#define Row2 P0_14
#define Col3 P0_6
/* len mbed.h */
DigitalOut row2(P0_14); // priama definicia
DigitalOut col(Col3); // detto s vyuzitim pseudopremennej Col3
/* len MicroBit.h */
MicroBit uBit;
int main()
{
while(1) {
/* len mbed.h */
/* row2 = 1;
col = 0;
wait(0.25);
row2 = 0;
col = 0;
wait(0.25);
*/
/* len MicroBit.h */
uBit.display.image.setPixelValue(2,2,127); // treti parameter <0-255>
wait(0.25);
uBit.display.image.setPixelValue(2,2,0);
wait(0.25);
}
}
No a toto je priklad, ktory som nasiel na disku pod nazvom armCourse02, ale uz si nepamatam ci to fungovalo a co to malo robit, treba to preverit
#include "mbed.h"
#define BUTTON_1 p5
#define BUTTON_2 p6
#define BUTTON_3 p7
#define BUTTON_4 p8
#define RED_LED p9
#define YEL_LED p10
#define BLU_LED p11
K tomuto poznamka pre micro:bit (ostatne platformy by mali byt ovela jasnejsie vraj):
//#defines for each edge connector pin
#define MICROBIT_PIN_P0 P0_3 //P0 is the left most pad (ANALOG/DIGITAL) used to be P0_3 on green board
#define MICROBIT_PIN_P1 P0_2 //P1 is the middle pad (ANALOG/DIGITAL)
#define MICROBIT_PIN_P2 P0_1 //P2 is the right most pad (ANALOG/DIGITAL) used to be P0_1 on green board
#define MICROBIT_PIN_P3 P0_4 //COL1 (ANALOG/DIGITAL)
#define MICROBIT_PIN_P4 P0_5 //COL2 (ANALOG/DIGITAL)
#define MICROBIT_PIN_P5 P0_17 //BTN_A
#define MICROBIT_PIN_P6 P0_12 //COL9
#define MICROBIT_PIN_P7 P0_11 //COL8
#define MICROBIT_PIN_P8 P0_18 //PIN 18
#define MICROBIT_PIN_P9 P0_10 //COL7
#define MICROBIT_PIN_P10 P0_6 //COL3 (ANALOG/DIGITAL)
#define MICROBIT_PIN_P11 P0_26 //BTN_B
#define MICROBIT_PIN_P12 P0_20 //PIN 20
#define MICROBIT_PIN_P13 P0_23 //SCK
#define MICROBIT_PIN_P14 P0_22 //MISO
#define MICROBIT_PIN_P15 P0_21 //MOSI
#define MICROBIT_PIN_P16 P0_16 //PIN 16
#define MICROBIT_PIN_P19 P0_0 //SCL
#define MICROBIT_PIN_P20 P0_30 //SDA
DigitalIn b1(BUTTON_1);
DigitalIn b2(BUTTON_2);
DigitalIn b3(BUTTON_3);
DigitalIn b4(BUTTON_4);
DigitalOut rled(RED_LED);
DigitalOut yled(YEL_LED);
DigitalOut bled(BLU_LED);
BusIn buttonbus(BUTTON_1,BUTTON_2,BUTTON_3,BUTTON_4);
BusOut ledsbus (RED_LED,YEL_LED,BLU_LED);
void ControlLED_DigitalIO ();
void ControlLED_BusIO ();
int main()
{
while(1)
{
// ControlLED_DigitalIO ();
ControlLED_BusIO ();
wait(0.25);
}
}
void ControlLED_DigitalIO ()
{
rled = !b4&&b3;
yled = 1;
bled = b4;
}
void ControlLED_BusIO ()
{
switch(buttonbus)
{
case 0 ... 3:
ledsbus = 0b0100;
break;
case 4 ... 14:
ledsbus = 0b0111;
break;
case 15:
ledsbus = 0b0000;
break;
default:
break;
}
}
Priklad na radio RX a TX cez mBed, ale je tam aj dolezity konfiguracny subor mbed_app.json
https://stackoverflow.com/questions/47580207/using-config-json-file-with-bbc-microbit-mbed-online-compiler
i2c na micro:bit
- API: https://os.mbed.com/docs/mbed-os/v6.15/apis/i2c.html
- Handbook: https://os.mbed.com/handbook/I2C
- Nazvy pinov tu: https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/PinNames.h
Tento kod je jednoduchy i2c scanner, ukazuje aj tie moznosti, ktore nefunguju
/* Note: only te microbit v1.3 is oficially supported, both v1.5 and v2.0 require offline tools */
#include <mbed.h>
// I2C i2c(I2C_SDA0, I2C_SCL0); // toto nie je dobre, lebo bud nie su definovane, alebo je tam zle cislo...
I2C i2c(P20, P19); // SDA pin, SCL pin ani toto nie je dobre, najde 127 zariadeni, odvsadial pride odozva
// I2C i2c(P0_20, P0_19); // SDA pin, SCL pin atoto je skoro OK, ale hlasi ich nejako nahodne.
// Co je ale cudne, ze v pinnames.h je to zadefinovane takto:
// I2C_SDA0 = P0_30
// I2C_SCL0 = P0_0 //SCL (SERIAL CLOCK LINE)
Serial pc(USBTX, USBRX);
// DigitalOut col0(P0_4, 0);
// DigitalOut myled(P0_13);
int main()
{
pc.baud(115200);
i2c.frequency(100000);
wait_ms(2000);
pc.printf("i2c scanner start!\n");
int count = 0;
/* method 4 */
for (int address = 0; address < 255; address +=2) // check only for device's read addres
{
if (!i2c.write(address, NULL, 0)) // 0 returned is ok
{
printf("I2C device found at address 0x%02X (0x%02X in 8-bit)\n\r", address >> 1, address); // the address is without LSB, which is R/W flag. shoft it right once
count++;
}
wait(0.02);
}
if (count)
printf("%d", count);
else
printf("No");
printf(" device%c found\n\r\n", count == 1?'\0':'s');
pc.printf("\tKoniec metody 4\r\n");
/* method 1 - seems also weird */
int ack;
for( int address=1; address < 127; address++)
{
ack = i2c.write(address, "11", 1);
if (ack == 0)
{
pc.printf("\tFound at %3d -- %3x\r\n", address,address);
}
wait(0.05);
}
pc.printf("\tKoniec metody 1\r\n");
/* method 2 - seems not working well */
char outByte = 55;
for(int i = 0; i < 128 ; i++)
{
i2c.start(); /* zda sa, ze klucom k uspechu je pouzitie i2c.write so vsetkymi 4 parametrami: */
if(!i2c.write( (i << 1),&outByte,1,0) ) pc.printf("0x%02X ACK \r\n",i); // Send command string
i2c.stop();
}
pc.printf("\tKoniec metody 2\r\n");
/* method 3 - seems OK, but random results */
for (int address = 0; address < 127; address++)
{
if (!i2c.write(address << 1, &outByte, 1, 0)) // 0 returned is ok
{
pc.printf("I2C device found at address 0x%02X (0x%02X in 8-bit)\n", address, address << 1);
count++;
}
wait_ms(20);
}
if (count)
pc.printf("%d", count);
else
pc.printf("No");
pc.printf(" device found\n\n");
}
A toto je ukazka fungujuceho kodu pre WuKong board
#include "mbed.h"
/* Fungujuce verzia */
I2C i2c(P20, P19); // SDA pin, SCL pin ani toto nie je dobre, najde 127 zariadeni, odvsadial pride odozva
Serial pc(USBTX, USBRX);
const int addr8bit = 0x10 << 1; // 8bit I2C address -- tato zda sa funguje to je adresa Wukong periferii
int main()
{
pc.baud(115200);
i2c.frequency(100000); // pre 400000 to uz neslo
char cmd[4];
/* blue LED control */
cmd[0] = 0x12;
cmd[1] = 0; // 0-100 intensity, 150 breathe
cmd[2] = 0;
cmd[3] = 0;
i2c.write(addr8bit, cmd, 4,0);
/* Motor M1+M2 control */
/* Byte 0 Byte 1 Byte 2 Byte 3
M1 0x01 Forward:0x01 speed 0x00
M2 0x02 Reverse:0x02
*/
cmd[0] = 0x02;
cmd[1] = 0x01;
cmd[2] = 45;
cmd[3] = 0;
i2c.write(addr8bit, cmd, 4,0);
cmd[0] = 0x01;
i2c.write(addr8bit, cmd, 4,0);
pc.printf("Done.\n");
while(1); /* stop here */
}
Priklad na meranie baterie (neodskusany)
Komplexny priklad
- https://www.hackster.io/PSoC_Rocks/micro-bit-programming-with-mbed-bfb38d
- https://www.hackster.io/PSoC_Rocks/iot-cloud-access-with-micro-bit-over-ble-for-remote-sensing-351938?f=1
- Toto je hlavne kvoli radaru: https://www.hackster.io/ashokr/smart-entry-gate-with-radar-and-ada-b40349?f=1#toc-hardware-4
ADC demo + serial
Ak v nasledovnom priklade zmenime P0_3 na p15, tak priklad bez problemov funguje aj v simulatore https://simulator.mbed.com/#user_1653083117125 (mozno s tym user_xxx to pojde aj sharovat s kodom)
//Reads input through the ADC, and transfers to PC terminal
#include "mbed.h"
Serial pc(USBTX, USBRX);
AnalogIn Ain(P0_3); // toto je P0 na microbite
float ADCdata;
int ADCvalue;
int main()
{
pc.baud(19200); // bez tohoto je vzdy default 9600
pc.printf("ADC Data Values... \n\r");
while (1) {
ADCdata = Ain; // toto vrati vzdy float z intervalu 0.0 az 1.0
ADCvalue = Ain.read_u16(); // toto vrati vzdy cele cislo, na uBite asi 0 az 1000 alebo 1023
pc.printf("ADC: %f [V] %d [-]\n",ADCdata,ADCvalue);
wait (0.5);
}
}
DMA praca s pamatou
Neodskusane, je to opisane pre RPi, ale malo by to fungovat aspon principialne. Treba prestudovat: https://people.ece.cornell.edu/land/courses/ece4760/RP2040/C_SDK_DMA_machine/DMA_machine_rp2040.html
Examples
Following is a set of examples which should work on ANY arm based board, including micro:bit without need for any specialized libraries.
1. Middle LED blinks
LEDs are connected into a matrix (see the image here: https://lancaster-university.github.io/microbit-docs/ubit/display/) - from the image it is clear that middle LED is 2.3, i.e. Row 2 and Column 3. To light it ON, we have to set Row to Log.1 and Column to Log. 0. Led OFF means both Row and Col set to 0. For definition of additional rows and columns see below.
On the micro:bit, the LED matrix has 25 LEDs. These LEDs are controlled by 12 GPIO pins. Three of those pins provide power to LEDs, the other nine provide a route to ground. The pins that source power are called rows. The pins that sink power are called columns. The following diagram shows how the 5x5 grid is connected into 3 logical 'rows' and 9 'columns':
#include "mbed.h"
#define Row2 P0_14
#define Col3 P0_6
/* len mbed.h */
DigitalOut row2(P0_14); // priama definicia
DigitalOut col(Col3); // detto s vyuzitim pseudopremennej Col3
int main()
{
while(1) {
/* len mbed.h */
row2 = 1;
col = 0;
wait(0.25);
row2 = 0;
col = 0;
wait(0.25);
}
}
#define Col1 P0_4 #define Col2 P0_5 #define Col3 P0_6 #define Col4 P0_7 #define Col5 P0_8 #define Col6 P0_9 #define Col7 P0_10 #define Col8 P0_11 #define Col9 P0_12 #define Row1 P0_13 #define Row2 P0_14 #define Row3 P0_15
So, if we wanted to light up the middle LED, we would need to put a HIGH voltage (logic 1) on row 2, and a LOW voltage (logic 0) on column 3. Notice that when row 2 is HIGH, we the value we write to the 9 column pins affect all of the LEDs 2.1 to 2.7, without affecting any of the LEDS on row 1 or row 3. Sharing GPIO pins in this way is known as multiplexing. Moreover, if we scan through the different rows fast enough - faster than the eye can see - then we can provide the illusion of all the LEDS being on at the same time! This is a technique known as persistence of vision...
2. Simple Hello, World
#include "mbed.h"
Serial pc(USBTX, USBRX);
int main()
{
int myValue = 0;
pc.baud(19200); // Speed has to be the same as in terminal
pc.printf("Hello, World!\n");
while (1) {
pc.printf("Value: %d \n",myValue);
myValue++;
wait (1);
}
}
3. Pushbutton example
Please note, that in the following example the pushbutton is active Low!
#include "mbed.h"
#define Row2 P0_14
#define Col3 P0_6
DigitalOut row2(P0_14); // direct definition
DigitalOut col(Col3); // same, using a predefined value
#define BUTTON_A P0_17
#define BUTTON_B P0_26 // connection from the schematic diagram for ver 1.3B
DigitalIn b1(BUTTON_A);
DigitalIn b2(BUTTON_B);
int main()
{
while(1)
{
if (!b1) // button is active LOW therefore we need to test negation !
{
row2 = 1;
col = 0;
}
if (!b2)
{
row2 = 0;
col = 0;
}
wait(0.25);
}
}
4. ADC converter and serial
Following program measures single ADC channel and sends the value to the serial terminal
//Reads input through the ADC, and transfers to PC terminal
#include "mbed.h"
Serial pc(USBTX, USBRX);
AnalogIn Ain(P0_3); // Port labeled P0 on the board
float ADCdata;
int ADCvalue;
int main()
{
pc.baud(19200);
pc.printf("ADC Data Values... \n\r");
while (1) {
ADCdata = Ain; // returns always float from 0.0 to 1.0
ADCvalue = Ain.read_u16(); // returns always integer value
pc.printf("ADC: %f [V] %d [-]\n",ADCdata,ADCvalue);
wait (0.5);
}
}
5. Simple i2c bus example - scan
Following program checks all the devices on the i2c bus and if find one, will print its address. On the micro:bit there are two sensors on this bus, so the program should return two addresses of these 2 devices.
#include <mbed.h>
I2C i2c(I2C_SDA0,I2C_SCL0); // SDA pin, SCL pin
Serial pc(USBTX, USBRX);
int main()
{
char outByte = 42; // random byte
pc.baud(115200); // set the correct speed also in the terminal!
wait_ms(2000);
pc.printf("\nScanning i2c bus:\n");
int count = 0;
for (int address = 0; address < 127; address++)
{
if (!i2c.write(address << 1, &outByte, 1 , 0)) // 0 returned is ok 42 is random byte
{
pc.printf("I2C device found at address 0x%02X (0x%02X in 8-bit)\n", address, address << 1);
count++;
}
wait_ms(20);
}
if (count)
pc.printf("%d", count);
else
pc.printf("No");
pc.printf(" device(s) found\n\n");
}
6. micro:bit Accelerometer
Following program measures the X, Y and Z parts of the acceleration and sends the value to the serial terminal. To compile, first import the library:
- File -> Add mbed library to the active project
- enter following url: https://os.mbed.com/users/takuhachisu/code/MMA8653/
- check you have the library files in your CURRENT ACTIVE project
- done.
#include "mbed.h"
#include "MMA8653.h" // https://os.mbed.com/users/takuhachisu/code/MMA8653/
I2C i2c(I2C_SDA0,I2C_SCL0);
Serial pc(USBTX, USBRX);
MMA8653 acc(i2c); // i2c pins SDA, SCL for accelerometer //
float Xg =0.0; float Yg = 0.0; float Zg = 0.0;
void getAccXYZ(void)
{
float temp[3];
acc.ReadXYZ(temp); // accelerometer
Xg = 10.0*temp[0]; Yg = 10.0*temp[1]; Zg = 10.0*temp[2];
wait(.1);
}
int main()
{
pc.baud(19200);
pc.printf("Accelerometer demo - data follows... \n\r");
while (1)
{
getAccXYZ();
// pc.printf("AccX: %f AccY: %f AccZ: %f \n",Xg,Yg,Zg);
pc.printf("%f,%f,%f\n",Xg,Yg,Zg);
wait (0.1);
}}