4 个版本 (2 个破坏性更改)

0.3.1 2020 年 10 月 13 日
0.3.0 2020 年 9 月 30 日
0.2.0 2020 年 9 月 17 日
0.1.0 2020 年 8 月 21 日

#1530 in 嵌入式开发

Apache-2.0

53KB
1.5K SLoC

Drogue IoT ESP8266

crates.io docs.rs Matrix

通过 USART 连接的 ESP8266 的网络驱动程序

目前需要使用 Espressif 提供的 1.7.0.x 版本的 AT 固件烧录 ESP。

使用时,您必须将 USART 配置为 115,200 bps 和 8-N-1,同时选择将 enablereset 连接到板上的连接。

通过使用 initialize(...) 函数,您将获得一个包含 Adapter 和一个 Ingress 对象的二元组

static mut RESPONSE_QUEUE: Queue<Response, U2> = Queue(i::Queue::new());
static mut NOTIFICATION_QUEUE: Queue<Response, U16> = Queue(i::Queue::new());

let (adapter, ingress) = esp8266::initialize(
    tx, rx,
    &mut en, &mut reset,
    unsafe { &mut RESPONSE_QUEUE },
    unsafe { &mut NOTIFICATION_QUEUE },
).unwrap();

在 RTIC 应用中,这将在应用的初始化阶段发生,并将这两个部分放入共享资源中。

应将 Ingress 连接到 USART 中断,以从串行端口接收字节

#[task(binds = USART6, priority = 10, resources = [ingress])]
fn usart(ctx: usart::Context) {
    if let Err(b) = ctx.resources.ingress.isr() {
        info!("failed to ingress {}", b as char);
    }
}

此外,应将 Ingress 连接到计时器循环,以便及时处理所有接收到的字节。循环速度留作读者练习

#[task(schedule = [digest], priority = 2, resources = [ingress])]
fn digest(mut ctx: digest::Context) {
    ctx.resources.ingress.lock(|ingress| ingress.digest());
    ctx.schedule.digest(ctx.scheduled + (DIGEST_DELAY * 100_000).cycles())
        .unwrap();
}

一旦启用所有中断/任务,适配器就可以用来连接到 Wi-Fi 接入点

let result = adapter.join("myaccesspoint", "thepassword");

成功连接后,适配器可以被转换为 TCPNetworkStack

 let network = adapter.into_network_stack();

 let socket = network.open(Mode::Blocking).unwrap();

 let socket_addr = SocketAddr::new(
     IpAddr::from_str("192.168.1.245").unwrap(),
     80,
 );

 let mut socket = network.connect(socket, socket_addr).unwrap();
 let result = network.write(&mut socket, b"GET / HTTP/1.1\r\nhost:192.168.1.245\r\n\r\n").unwrap();

 loop {
     let mut buffer = [0; 128];
     let result = network.read(&mut socket, &mut buffer);
     match result {
         Ok(len) => {
             if len > 0 {
                 let s = core::str::from_utf8(&buffer[0..len]);
                 match s {
                     Ok(s) => {
                         info!("recv: {} ", s);
                     }
                     Err(_) => {
                         info!("recv: {} bytes (not utf8)", len);
                     }
                 }
             }
         }
         Err(e) => {
             info!("ERR: {:?}", e);
             break;
         }
     }
 }

依赖项

~2MB
~40K SLoC