Arduino 101 Serial 实现详解
Arduino 101 连接 PC 是通过一条方口 USB 数据线,并且可以通过这条数据线接收板子输出 debug 调试。
那么这是如何实现的呢?
这部分没有完全看透,只记录下目前收获(也许有误)。
概述
Arduino 中操作串口是通过 Serial1 类。
初始化:
1 |
|
发送:
1 |
|
接收:
1 |
|
分析
查看代码时发现了应用程序入口其实在 main.cpp
中,如下:
C:\Users\XXX\AppData\Local\Arduino15\packages\Intel\hardware\arc32\2.0.2\cores\arduino\main.cpp
1 |
|
从中可以看到 setup
loop
等函数,这就是通用的 Arduino 代码函数块,可以发现 loop
和 serialEvent
其实是顺序轮询方式,并不是真正中断。
初始化
Serial 部分的源码又在哪里呢?查找后发现对象初始化部分:
C:\Users\XXX\AppData\Local\Arduino15\packages\Intel\hardware\arc32\2.0.2\variants\arduino_101\variant.cpp
1 |
|
原来 Serial 是全局变量,CDCSerialClass
的构造函数只是赋值,并没有特殊操作。
现在已知如下(和板子定义一致):
- Serial 表示 USB2 串口
- Serial1 表示 UART 串口
接下来的操作在 initVariant()
中:
1 |
|
Serial.setSharedData
只是赋值串口对象指针。
C:\Users\XXX\AppData\Local\Arduino15\packages\Intel\hardware\arc32\2.0.2\cores\arduino\CDCSerialClass.cpp
1 |
|
其中 shared_data
是芯片中的 SRAM3 地址为 0xA8000000,共 80K4。
关于这段内存的作用,我推测是和内核部分进行交互,因为 CDCSerialClass
中并没有对寄存器的操作。
而内核部分也有同样的结构,并且会读取标志位以及设置标志位(内核部分没有详细查看)。
内核相关理解如下:
- 代码入口在
CODK\CODK-A\x86\projects\arduino101\quark\main.c
- 驱动部分代码
CODK\CODK-A\x86\bsp\src\drivers\usb
(usb_driver_intf
没有找到声明地方)
其他
以 Serial.print
实现为例,使用该函数会向串口发送字符串。
CDCSerialClass
中并没有定义 print
的方法,此方法乃是继承 class Print
,其所有继承关系如下:
CDCSerialClass->HardwareSerial->Stream->Print
某个方法的实现如下:
C:\Users\XXX\AppData\Local\Arduino15\packages\Intel\hardware\arc32\2.0.2\cores\arduino\Print.cpp
1 |
|
而 write
方法在 CDCSerialClass
类中被重写为向串口发送数据,如此便实现了 Serial.print
的功能。
疑问
CDCSerialClass
中波特率设置似乎没有作用。
1 |
|
以上为初始化部分,从中可以看到 dwBaudRate
只计算了 _writeDelayUsec
,没有传递到 _shared_data
中。
查找代码又会发现 _writeDelayUsec
没有在其他地方被调用过,那么该波特率还有作用吗?
为此我尝试在电脑上随便修改波特率,并和板子通信,发现波特率不匹配也可以通信,不知道是不是因为该口是 USB 虚拟串口的原因?
相对应的 Serial1 UARTClass
的 init
中是包含波特率设置代码的。
修改
添加 printf
方法5。
我使用的是添加 Print::printf
,修改后可在 Serial
中使用 printf
方法了。
C:\Users\XXX\AppData\Local\Arduino15\packages\Intel\hardware\arc32\2.0.2\cores\arduino\Print.cpp
1 |
|
- 1.Serial func ↩
- 2.USB CDC is a composite Universal Serial Bus device class ↩
- 3.static random access memory ↩
- 4.Intel® Quark™ SE Microcontroller C1000 Datasheet, Table 24, Mapping Address Spaces ↩
- 5.Arduino printf ↩