简介

  • RadioLib 是嵌入式无线通信领域比较流行的一个开源库,主要用于 Arduino / ESP32 / STM32 等微控制器控制各种无线射频模块(如 LoRa、FSK、OOK 等)。它的发展历史其实和开源硬件社区的发展密切相关。下面按时间梳理其主要发展阶段。
  • 项目最早由开发者 jgromes 2018 年 3 月 6日创建于 GitHub(下图就是初始提交的内容)。 最初并不是一个通用库,而是为了支持一个硬件项目 RadioShield。由于需要同时驱动不同射频芯片,作者开始开发一个 统一的无线驱动库,这就是 RadioLib 的最初版本

在这里插入图片描述

早期版本

  • 早期版本的 RadioLib 主要解决一个核心问题:为不同无线射频芯片提供统一的 API 接口。在当时的 Arduino 社区中,各类无线模块通常使用完全不同的驱动库,例如 LoRa 芯片(SX1276、SX1278)以及 FSK 芯片(RFM69、CC1101)都依赖各自独立的库,接口设计和使用方式差异很大,这给开发者带来了较高的学习成本和代码迁移难度。为了解决这一问题,RadioLib 提出了 “One radio library to rule them all.” 的设计目标,通过统一接口封装不同芯片的底层驱动,使开发者能够用相似的方式控制不同的无线模块。其核心特点包括:提供统一的通信接口、支持多种射频芯片、对 Arduino 平台友好,以及采用 C++ 面向对象的设计结构,从而提高代码的可复用性和可扩展性。

https://github.com/jgromes/RadioLib/tree/9fe0e3600570b44cbcdae69f706d71c7cab95b5d

  • 同日的第三次提交放入了主要的核心代码,主要实现Arduino C++ 类,用于封装无线模块或外设模块的通信接口,实现对模块的统一管理与控制。同时支持 串口 AT 指令通信和 SPI 寄存器读写两种方式,其中通过 SoftwareSerial 实现与模块的串口通信,用于发送 AT 指令并获取模块响应;通过 SPI 接口实现对射频芯片寄存器的读取和写入,包括单寄存器操作、批量(Burst)读写以及部分位(bit 位)修改等功能。
#ifndef _KITELIB_MODULE_H
#define _KITELIB_MODULE_H

#include <SPI.h>
#include <Wire.h>
#include <SoftwareSerial.h>

#include "TypeDef.h"

#define SPI_READ  0b00000000
#define SPI_WRITE 0b10000000

class Module {
  public:
    Module();
    Module(int cs, int tx, int rx, int int0, int int1);
    
    SoftwareSerial* ModuleSerial;
    
    uint32_t baudrate = 9600;
    
    uint8_t init(uint8_t interface, uint8_t gpio);
    
    void ATemptyBuffer();
    bool ATgetResponse();
    bool ATsendCommand(String& cmd);
    bool ATsendCommand(const char* cmd);
    
    uint8_t SPIgetRegValue(uint8_t reg, uint8_t msb = 7, uint8_t lsb = 0);
    uint8_t SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes);
    uint8_t SPIreadRegisterBurstStr(uint8_t reg, uint8_t numBytes, char* str);
    uint8_t SPIreadRegister(uint8_t reg);
    
    uint8_t SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0);
    void SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, uint8_t numBytes);
    void SPIwriteRegisterBurstStr(uint8_t reg, const char* data, uint8_t numBytes);
    void SPIwriteRegister(uint8_t reg, uint8_t data);
    
    bool getInt0State();
    bool getInt1State();
    
  private:
    int _cs;
    int _tx;
    int _rx;
    int _int0;
    int _int1;
    
    uint32_t _ATtimeout = 15000;
};

#endif

协议

  • 随后,RadioLib 进入快速发展阶段,并逐渐成长为 Arduino 无线通信领域中具有重要影响力的开源库。在这一阶段,库的功能不断扩展。首先,在硬件支持方面,RadioLib 新增了对更多射频芯片的支持,例如 SX1262、SX1268、SX1280、LR1110 以及 NRF24 等,使其能够适配更广泛的无线模块。其次,在软件功能方面,RadioLib 不再仅限于提供物理层驱动,而是进一步扩展到协议层,实现了对 LoRaWAN、AX.25、APRS 以及 Pager 等通信协议的支持。此外,库中还加入了多种业余无线电常用的数字通信模式,例如 RTTY(无线电电传)、SSTV(慢扫描电视)以及 Hellschreiber。这些扩展使得 RadioLib 不仅能够完成基础的无线收发功能,还能够支持更复杂的无线通信应用和实验场景。

在这里插入图片描述

  • HTTP、UDP、MQTT等是最先实现的:
    在这里插入图片描述
// https://github.com/jgromes/RadioLib/blob/a6b7540508354d470b588c7b408cf7f0203a86a0/src/ESP8266.cpp
uint16_t ESP8266::HttpGet(const char* url, String& response) {
  String urlString(url);
  
  // get the host address and endpoint
  int32_t resourceIndex = urlString.indexOf("/", 7);
  if(resourceIndex == -1) {
    return(ERR_URL_MALFORMED);
  }
  String host = urlString.substring(7, resourceIndex);
  String endpoint = urlString.substring(resourceIndex);
  
  // build the GET request
  String request = "GET ";
  request += endpoint;
  request += " HTTP/1.1\r\nHost: ";
  request += host;
  request += "\r\n\r\n";
  
  // create TCP connection
  uint8_t state = startTCP(host.c_str());
  if(state != ERR_NONE) {
    return(state);
  }
  
  // send the GET request
  state = send(request);
  if(state != ERR_NONE) {
    return(state);
  }
  
  // read the response
  String raw = receive();
  
  // close the TCP connection
  state = closeTCP();
  if(state != ERR_NONE) {
    return(state);
  }
  
  // parse the response
  int32_t numBytesIndex = raw.indexOf(":");
  if(numBytesIndex == -1) {
    return(ERR_RESPONSE_MALFORMED_AT);
  }
  response = raw.substring(numBytesIndex + 1);
  
  // return the HTTP status code
  int32_t spaceIndex = response.indexOf(" ");
  if(spaceIndex == -1) {
    return(ERR_RESPONSE_MALFORMED);
  }
  String statusString = response.substring(spaceIndex + 1, spaceIndex + 4);
  return(statusString.toInt());
}

uint16_t ESP8266::HttpPost(const char* url, String content, String& response, const char* contentType) {
  String urlString(url);
  String contentTypeString(contentType);
  
  // get the host address and endpoint
  int32_t resourceIndex = urlString.indexOf("/", 7);
  if(resourceIndex == -1) {
    return(ERR_URL_MALFORMED);
  }
  String host = urlString.substring(7, resourceIndex);
  String endpoint = urlString.substring(resourceIndex);
  
  // build the POST request
  String request = "POST ";
  request += endpoint;
  request += " HTTP/1.1\r\nHost: ";
  request += host;
  request += "\r\nContent-Type: ";
  request += contentTypeString;
  request += "\r\nContent-length: ";
  request += content.length();
  request += "\r\n\r\n";
  
  // create TCP connection
  uint8_t state = startTCP(host.c_str());
  if(state != ERR_NONE) {
    return(state);
  }
  
  // send the POST request
  state = send(request);
  if(state != ERR_NONE) {
    return(state);
  }
  
  // close the TCP connection
  state = closeTCP();
  if(state != ERR_NONE) {
    return(state);
  }
  
  // read the response
  String raw = receive();
  
  // parse the response
  int32_t numBytesIndex = raw.indexOf(":");
  if(numBytesIndex == -1) {
    return(ERR_RESPONSE_MALFORMED_AT);
  }
  response = raw.substring(numBytesIndex + 1);
  
  // return the HTTP status code
  int32_t spaceIndex = response.indexOf(" ");
  if(spaceIndex == -1) {
    return(ERR_RESPONSE_MALFORMED);
  }
  String statusString = response.substring(spaceIndex + 1, spaceIndex + 4);
  return(statusString.toInt());
}

HAL

  • 为了减少对 Arduino 平台的依赖,RadioLib 在后续发展中引入了 HAL(Hardware Abstraction Layer,硬件抽象层) 机制。通过这一机制,库将底层的硬件操作(如 GPIO 控制和 SPI 通信)进行统一抽象,使其不再直接依赖 Arduino 的硬件接口,从而能够在更多平台上运行。借助 HAL,RadioLib 可以支持 ESP-IDF、STM32 HAL、Raspberry Pi 以及其他标准 C++ 运行环境。这一设计大大提升了库的可移植性,使 RadioLib 从最初主要面向 Arduino 的无线驱动库,逐渐发展为一个 通用的嵌入式无线通信库

  • RadioLib 包含一个轻量级的硬件抽象层(HAL)类。以下是最常用平台的HAL列表:https://github.com/jgromes/RadioLib/tree/master/src/hal
    在这里插入图片描述

  • 在 RadioLib 中,HAL(Hardware Abstraction Layer,硬件抽象层) 是通过在库内部引入 平台接口类(接口抽象) 的方式逐步加入的,其核心思想是 把所有与具体硬件平台相关的操作从驱动代码中分离出来,让无线芯片驱动只依赖统一的接口,而不是直接调用 Arduino 的函数。
    在这里插入图片描述

当前

  • Radiolib从一个 Arduino LoRa 驱动逐渐发展成支持多芯片、多协议、跨平台的通用无线通信库。,昨天还在更新(20260307):

在这里插入图片描述

CG

  • 还有更多内容请阅读官方文档,一些其他关键内容会后续添加。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐