3 releases
new 0.2.3 | Oct 31, 2024 |
---|---|
0.2.2 | Feb 28, 2024 |
0.2.1 | Feb 16, 2024 |
#331 in Embedded development
87KB
1.5K
SLoC
quectel-bg77
This crate implements a driver for the Quectel BG77 and BG770 eMTC and NB-IoT modems using the
embedded-hal
traits for the underlying hardware abstractions and implementing the embedded-nal
traits for users of this library. Currently, TcpClientStack
and UdpClientStack
are supported
for both modems. From the Dns
trait, only the get_host_by_name
requesting only IPv4 addresses
is supported. Thus far, this has only been working for BG77. To select which modem is used,
activate either the bg77
or the bg770
feature.
The driver supports up to 12 sockets at the same time and implements Drop
/RAII on the socket
handle types to prevent resource leaks. This is accomplished by using the
interior mutability pattern:
All socket handles hold a reference to the driver type which owns the hardware. Whenever they need
to access the hardware, the driver is mutably borrowed (checked at runtime). This always works
because no mutable borrow outlives any method call.
Currently, AT commands are not run partially which would complicate the interior state handling
and increase the number of possible error causes, e.g. when multiple sockets try to access the
modem at the same time. As a consequence, all method calls are effectively blocking. The only
exception is receive
which returns nb::Error::WouldBlock
if no data at all is available. For
the send
method, this is not a huge problem because it only blocks until the data is transferred
to the modem (the actual transmission happens in the background then). Only connecting the modem
to the network blocks for a long time.
Usage Example
use embedded_nal::TcpClientStack;
// The hardware abstraction used for the Bg77Hal must implement the respective embedded-hal
// traits
let bg77_hal = quectel_bg77::Bg77Hal {
pin_enable: bg77_enable,
pin_reset_n: bg77_reset_n,
pin_pwrkey: bg77_pwrkey,
tx: bg77_tx,
rx: bg77_rx,
at_timer,
modem_timer,
};
// choose which radio technologies and bands to use
let radio_config = quectel_bg77::RadioConfig::OnlyNbiot {
bands: quectel_bg77::NbiotBand::B8.into(),
};
let mut bg77 = quectel_bg77::Bg77Driver::new(
bg77_hal,
radio_config,
Some("iot.1nce.net"), // configure APN
Some("26201"), // configure operator
core::time::Duration::from_secs(60), // configure connection/attach timeout
core::time::Duration::from_millis(500), // configure internal safety delays
core::time::Duration::from_millis(20), // configure internal safety delays
);
let mut bg77 = quectel_bg77::Bg77ClientStack::new(&mut bg77);
// request a new socket handle, this only fails if all sockets are already in use
let mut socket = bg77.socket().unwrap();
// turn on the modem and try to attach to the network; generally, this takes the most time
let socket_address: embedded_nal::SocketAddr = "192.168.1.1:8080".parse().unwrap();
nb::block!(bg77.connect(&mut socket, socket_address))?;
// transmit data via the socket
nb::block!(bg77.send(&mut socket, b"Hello, BG77"))?;
// close the socket; when the last socket is closed, this also turns off the modem
// with this driver, this never fails
bg77.close(socket).unwrap();
Examples
There are a few examples which can be run on appropriate hardware. This driver was initially
developed alongside the
Sensing Puck
so this was the only supported board in the beginning. Later, support for MotionAI was added. The
board in use can be selected by activating either the sensing_puck
or the motion2se
feature
which will automatically activate the right modem feature (bg77
or bg770
).
If required, more boards can be added under examples/boards
with appropriate features in
Cargo.toml
. Still, the memory.x
file has to be adjusted and possibly the build target,
depending on the MCU architecture.
Since only STM32L452-based boards are supported at the moment, an appropriate memory.x
is
shipped. Therefore, running the examples should be as easy as, e.g.:
cargo run --example tcp-client --features sensing_puck --target thumbv7em-none-eabihf
. This
uses probe-run
to flash the firmware.
Unit tests
Since the examples only build for the appropriate architecture, the tests need to be run with
the --lib
flag: cargo test --lib
Features
bg77
/bg770
selects the modem in usesensing_puck
/motion2se
selects the board for the examplesdirect-serial-access
Enables direct access to the underlying serial port. This should be used for development/debugging only.
License
Open Logistics Foundation License
Version 1.3, January 2023
See the LICENSE file in the top-level directory.
Contact
Fraunhofer IML Embedded Rust Group - embedded-rust@iml.fraunhofer.de
Dependencies
~1.2–1.8MB
~36K SLoC