提交 9a232ce5 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

深挖串口,UART驱动实现过程

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    鸿蒙研究站 | http://weharmonyos.com (国内)
              | https://weharmony.github.io (国外)
    oschina | https://my.oschina.net/weharmony
    博客园 | https://www.cnblogs.com/weharmony/
    知乎 | https://www.zhihu.com/people/weharmonyos
    csdn | https://blog.csdn.net/kuangyufei
    51cto | https://harmonyos.51cto.com/column/34
    掘金 | https://juejin.cn/user/756888642000808
    公众号 | 鸿蒙研究站 (weharmonyos)
上级 f4e91260
......@@ -194,7 +194,7 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
/// 事件查询, UartHostPollEvent(Uart) --> Hi35xxPollEvent --> poll_wait
STATIC INT32 SerialPoll(struct file *filep, poll_table *fds)
{
INT32 ret;
......@@ -216,21 +216,69 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
///串口实现VFS接口,以便支持按文件方式操作串口
STATIC const struct file_operations_vfs g_serialDevOps = {
/*!
串口实现VFS接口, 以hi35xx为例,列出底层路径
调用读/写的过程如下,一直调到UART最底层驱动
g_consoleDevOps(上级)
g_serialDevOps(本级)
g_uartDevFops
g_uartHostMethod
Pl011Read (读)
memcpy_s(buf,rxTransfer->data, ... )
g_pl011Uops (写)
Pl011StartTx
UartPutsReg
控制函数实现
static int32_t UartDevIoctl(struct file *filep, int32_t cmd, unsigned long arg)
{
int32_t ret = HDF_FAILURE;
struct UartHost *host = NULL;
if (filep == NULL || filep->f_vnode == NULL) {
return HDF_ERR_INVALID_PARAM;
}
struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
host = (struct UartHost *)drv->priv;
switch (cmd) {
case UART_CFG_BAUDRATE:
ret = UartHostSetBaud(host, arg);
break;
case UART_CFG_RD_BLOCK:
if (arg == UART_RD_BLOCK) {
ret = UartHostSetTransMode(host, UART_MODE_RD_BLOCK);
} else if (arg == UART_RD_NONBLOCK) {
ret = UartHostSetTransMode(host, UART_MODE_RD_NONBLOCK);
}
break;
case UART_CFG_ATTR:
ret = UartCfgAttr(host, arg);
break;
case TIOCGWINSZ:
/* Simply support ioctl(f->fd, TIOCGWINSZ, &wsz) system call, and the detailed design will be done later * /
ret = LOS_OK;
break;
default:
HDF_LOGE("%s cmd %d not support", __func__, cmd);
ret = HDF_ERR_NOT_SUPPORT;
break;
}
return ret;
}
*/
STATIC const struct file_operations_vfs g_serialDevOps = {
SerialOpen, /* open */
SerialClose, /* close */
SerialRead, /* read */
SerialWrite,
SerialWrite, ///< 写串口
NULL,
SerialIoctl,
SerialIoctl, ///< 设置波特率,设置转换模式,各种配置 ==
NULL,
#ifndef CONFIG_DISABLE_POLL
SerialPoll,
#endif
NULL,
};
//虚拟串口初始化,注册驱动程序 ,例如 : deviceName = "/dev/uartdev-0"
/// 虚拟串口初始化,注册驱动程序 ,例如 : deviceName = "/dev/uartdev-0"
INT32 virtual_serial_init(const CHAR *deviceName)
{
INT32 ret;
......@@ -250,9 +298,9 @@ INT32 virtual_serial_init(const CHAR *deviceName)
goto ERROUT;
}
//接着是 vnode < -- > file 的绑定操作
(VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file));
(VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file));//文件的内核层表现file为fd背后的内容
g_serialFilep.f_oflags = O_RDWR;//可读可写
g_serialFilep.f_vnode = vnode; //
g_serialFilep.f_vnode = vnode; //绑定索引节点
g_serialFilep.ops = ((struct drv_data *)vnode->data)->ops;//这里代表 访问 /dev/serial 意味着是访问 /dev/uartdev-0
if (g_serialFilep.ops->open != NULL) {//用于检测是否有默认的驱动程序
......@@ -264,7 +312,6 @@ INT32 virtual_serial_init(const CHAR *deviceName)
}
(VOID)register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep);//注册虚拟串口驱动程序
//g_serialFilep作为私有数据给了 (drv_data)data->priv = g_serialFilep
//
VnodeDrop();
return ENOERR;
......
......@@ -139,19 +139,19 @@ extern VOID PrintExcInfo(const CHAR *fmt, ...);
/**
* @ingroup los_base
* Get a UINT8 value from addr.
* Get a UINT8 value from addr.| 从地址上获取8位值
*/
#define GET_UINT8(addr) ({ UINT8 r = *((volatile UINT8 *)((UINTPTR)(addr))); DSB; r; })
/**
* @ingroup los_base
* Get a UINT16 value from addr.
* Get a UINT16 value from addr.| 从地址上获取16位值
*/
#define GET_UINT16(addr) ({ UINT16 r = *((volatile UINT16 *)((UINTPTR)(addr))); DSB; r; })
/**
* @ingroup los_base
* Get a UINT32 value from addr.
* Get a UINT32 value from addr. | 从地址上获取32位值
*/
#define GET_UINT32(addr) ({ UINT32 r = *((volatile UINT32 *)((UINTPTR)(addr))); DSB; r; })
......
......@@ -418,14 +418,14 @@ STATIC VOID *TelnetClientLoop(VOID *arg)
(VOID)prctl(PR_SET_NAME, "TelnetClientLoop", 0, 0, 0);
TelnetLock();
if (TelnetClientPrepare(clientFd) != 0) {
if (TelnetClientPrepare(clientFd) != 0) {//做好准备工作
TelnetUnlock();
(VOID)close(clientFd);
return NULL;
}
TelnetUnlock();
while (1) {
while (1) {//死循环接受远程输入的数据
pollFd.fd = clientFd;
pollFd.events = POLLIN | POLLRDHUP;//监听读数据和挂起事件
pollFd.revents = 0;
......@@ -479,14 +479,14 @@ STATIC VOID *TelnetClientLoop(VOID *arg)
}
if ((UINT16)pollFd.revents & POLLIN) {//数据事件
nRead = read(clientFd, buf, sizeof(buf));//读外面过来的数据
nRead = read(clientFd, buf, sizeof(buf));//读远程终端过来的数据
if (nRead <= 0) {
/* telnet client shutdown */
break;
}
cmdBuf = ReadFilter(buf, (UINT32)nRead, &len);//对数据过滤
if (len > 0) {
(VOID)TelnetTx((CHAR *)cmdBuf, len);
(VOID)TelnetTx((CHAR *)cmdBuf, len);//从数据加工处理
}
}
}
......
......@@ -130,17 +130,17 @@ extern "C" {
#define QUOTES_STATUS_OPEN(qu) ((qu) == TRUE)
/*! shell 控制块 */
typedef struct {
UINT32 consoleID; ///< 控制台ID
UINT32 shellTaskHandle; ///< shell服务端任务
UINT32 shellEntryHandle; ///< shell客户端任务
UINT32 consoleID; ///< 控制台ID,shell必须捆绑一个控制台(串口或远程登录),以便接收输入和发送执行结果信息
UINT32 shellTaskHandle; ///< shell服务端任务(负责解析和执行来自客户端的信息)
UINT32 shellEntryHandle; ///< shell客户端任务(负责接受来自串口或远程登录的信息)
VOID *cmdKeyLink; ///< 待处理的shell命令链表
VOID *cmdHistoryKeyLink; ///< 已处理的历史记录链表,去重,10个
VOID *cmdMaskKeyLink; ///< 主要用于方向键上下遍历历史命令
VOID *cmdHistoryKeyLink; ///< 已处理的命令历史记录链表,去重,10个
VOID *cmdMaskKeyLink; ///< 主要用于方向键上下遍历命令历史
UINT32 shellBufOffset; ///< buf偏移量
UINT32 shellKeyType; ///< 按键类型
EVENT_CB_S shellEvent; ///< 事件类型触发
pthread_mutex_t keyMutex; ///< 按键互斥量
pthread_mutex_t historyMutex; ///< 历史记录互斥量
pthread_mutex_t historyMutex; ///< 命令历史记录互斥量
CHAR shellBuf[SHOW_MAX_LEN]; ///< shell命令buf,接受键盘的输入,需要对输入字符解析.
CHAR shellWorkingDirectory[PATH_MAX]; ///< shell的工作目录
} ShellCB;
......
git add -A
git commit -m ' 对虚拟串口,USB,UART实现注释
git commit -m ' 深挖串口,UART驱动实现过程
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册