ARM dotNet 入门指南
这篇文章描述了跨平台.NET Core 在PC机上开发,ARM上运行。.NET Core访问GPIO 串口等外设。
环境
开发环境:Visual Studio2022
.Net版本:6.0
硬件:安装dotNet6的ARM工控机,这里我们采用DTU802进行操作:
注:先把它的后台程序kill掉,这个程序也是采用.net6编写,web界面如下:
因为设备的串口等资源可能被占用,所以先kill掉。
dotNet 工程创建及ARM上运行
VS2022创建新项目,创建一个.NET控制台应用:
下一步,工程名称先保持默认:
选择框架版本6.0:
我们注释掉生成的代码Hello World,添加如下求和的代码(当然这不是必需):
选择Release 进行编译,可以在PC机上的调试控制台看下 程序输出信息!下面我们来部署到ARM工控机上:
也可采用Docker方式docker build -t sample -f Dockerfile ,这里我们直接拷贝到ARM 工控机上。
首先确认ARM工控机.NET环境:
然后运行程序:
我们可以看到第一个数字累加的程序即在ARM工控机上运行了!!!!
当然也可以直接在ARM工控机上创建,但ARM性能有限,还是推荐交叉开发,测试dotnet环境是可以的,如下:
dotNet 之GPIO
硬件我们采用DTU802,通过.NET程序 控制LED 闪烁。
GPIO 操作主要依赖于 GpioController 类 。这个类于 System.Device.Gpio 名称空间下。
// GpioController 即 GPIO 控制器
// GPIO 引脚依靠 GpioController 初始化
public class GpioController : IDisposable
{
// 构造函数
/* PinNumberingScheme 即引脚编号方案,是一个枚举类型,包含 Board 和 Gpio 两个值。
*/
public GpioController(PinNumberingScheme numbering = PinNumberingScheme.Gpio);
// 第二个构造函数中的 GpioDriver 应该是用于扩展的,一般还是用 Raspberry Pi 默认的 GPIO 驱动。
public GpioController(GpioDriver driver, PinNumberingScheme numbering = PinNumberingScheme.Gpio);
// 属性
// 获取已打开的所有 GPIO 引脚
public IEnumerable<GpioPin> OpenPins { get; }
// 方法
// 打开 GPIO 引脚,pinNumber 需要填写和 PinNumberingScheme 相对应的值。
public GpioPin OpenPin(int pinNumber);
// 关闭 GPIO 引脚
public void ClosePin(int pinNumber);
public void ClosePin(GpioPin pin);
// 判断某个引脚是否打开
// 注意:引脚连续打开会抛出异常
public bool IsPinOpen(int pinNumber);
}
// GpioPin 表示单个的引脚实体
// 需要通过 GpioController.OpenPin() 获取
public class GpioPin : IDisposable
{
// 属性
// 一个去抖时间,即在此时间间隔引脚电平变化,不触发 ValueChanged 事件
public TimeSpan DebounceTimeout { get; set; }
// 事件
// 引脚电平变化时触发
public event EventHandler<PinValueChangedEventArgs> ValueChanged;
// 方法
// 读取当前引脚电平
public PinValue Read();
// 向引脚写入指定电平
public void Write(PinValue value);
}
新建工程,打开 “工具”——“NuGet包管理器”——“程序包管理器控制台”,运行如下命令,以获取程序包。
PM> Install-Package System.Device.Gpio
在 Program.cs 中,代码替换如下:
部署
在“程序包管理器控制台”运行发布命令:
dotnet publish -c release -r linux-arm
发布路径为ConsoleApp2\ConsoleApp2\bin\Release\net6.0\linux-arm
将这个目录传入工控机中,如下图:
进入目录,加执行权限,执行程序:
此时 LED 小灯应该一闪一闪的了。
dotNet 之串口/485
在开始之前,首先要说明的是串口通信所用到的 SerialPort 类并不包含在 System.Device.Gpio NuGet 包中,而是在 System.IO.Ports NuGet 包中。在嵌入式中串口通信是与其他设备进行交互的一种重要方式,而且在某些没有屏幕的设备中充当着程序调试的工具。
public class SerialPort : Component
{
// portName 为串口的名称,可以使用静态方法 GetPortNames() 获取
public SerialPort(string portName);
// 传输的波特率
public int BaudRate { get; set; }
// 指定传输内容的编码
public Encoding Encoding { get; set; }
// 新行格式,即设置换行的字符
public string NewLine { get; set; }
// 设置停止位的格式
public StopBits StopBits { get; set; }
// 设置校验位的格式
public Parity Parity { get; set; }
// 打开串口通信流
public void Open();
// 关闭串口通信流
public void Close();
// 向串口通信流中写一行字符
public void WriteLine(string text);
// 从串口通信流中读一行字符
public string ReadLine();
// 读取缓冲区中的所有可用内容,一般用于清空缓冲区,防止读取旧的内容
public string ReadExisting();
// 获取可用的串口名称
public static string[] GetPortNames();
}
详细API 可查看.Net文档:
打开 Visual Studio ,新建一个 .NET Core 控制台应用程序,项目名称为“Serial”。
引入 System.IO.Ports NuGet 包。
Install-Package System.IO.Ports
在 Program.cs 中,将主函数代码替换如下:
注意:1. 根据硬件连接确定设备号,如上图DTU802的ttyS1与PC机相连。
- 485在应用层与串口相同,也就是说代码相同。
发布
dotnet publish -c release -r linux-arm
拷贝、更改权限、运行:
可以看到DTU802的串口与PC 机 通信正常!!!
dotNet容器化运行
docker run --rm -it Serial