更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
console.h 文件参考

浏览源代码.

结构体

struct  CirBufSendCB
 发送环形buf控制块,通过事件发送 更多...
 
struct  CONSOLE_CB
 控制台控制块(描述符) 更多...
 

函数

INT32 system_console_init (const CHAR *deviceName)
 https://man7.org/linux/man-pages/man3/tcflow.3.html termios 是在POSIX规范中定义的标准接口,表示终端设备,包括虚拟终端、串口等。串口通过termios进行配置。 struct termios { unsigned short c_iflag; // 输入模式标志 unsigned short c_oflag; // 输出模式标志 unsigned short c_cflag; // 控制模式标志 unsigned short c_lflag; // 本地模式标志 例如: 设置非规范模式 tios.c_lflag = ~(ICANON | ECHO | ECHOE | ISIG); unsigned char c_line; // 线路规程 unsigned char c_cc[NCC]; // 控制特性 speed_t c_ispeed; // 输入速度 speed_t c_ospeed; // 输出速度 } 终端有三种工作模式: 规范模式(canonical mode)、 非规范模式(non-canonical mode) 原始模式(raw mode)。 https://www.jianshu.com/p/fe5812469801 https://blog.csdn.net/wumenglu1018/article/details/53098794 更多...
 
INT32 system_console_deinit (const CHAR *deviceName)
 控制台结束前的处理 和 system_console_init成对出现,像控制台的析构函数 更多...
 
BOOL SetSerialNonBlock (const CONSOLE_CB *consoleCB)
 无锁方式设置串口 更多...
 
BOOL SetSerialBlock (const CONSOLE_CB *consoleCB)
 锁方式设置串口 更多...
 
BOOL SetTelnetNonBlock (const CONSOLE_CB *consoleCB)
 无锁方式设置远程登录 更多...
 
BOOL SetTelnetBlock (const CONSOLE_CB *consoleCB)
 锁方式设置远程登录 更多...
 
CONSOLE_CBOsGetConsoleByID (INT32 consoleID)
 获取参数控制台ID 获取对应的控制台控制块(描述符) 更多...
 
CONSOLE_CBOsGetConsoleByTaskID (UINT32 taskID)
 获取参数任务的控制台控制块(描述符) 更多...
 
INT32 ConsoleTaskReg (INT32 consoleID, UINT32 taskID)
 任务注册控制台,每个shell任务都有属于自己的控制台 更多...
 
INT32 ConsoleUpdateFd (VOID)
 控制台更新文件句柄 更多...
 
BOOL ConsoleEnable (VOID)
 控制台使能 更多...
 
BOOL is_nonblock (const CONSOLE_CB *consoleCB)
 
BOOL IsConsoleOccupied (const CONSOLE_CB *consoleCB)
 控制台是否被占用 更多...
 
INT32 FilepOpen (struct file *filep, const struct file_operations_vfs *fops)
 打开串口或远程登录 更多...
 
INT32 FilepClose (struct file *filep, const struct file_operations_vfs *fops)
 关闭串口或远程登录 更多...
 
INT32 FilepRead (struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen)
 从串口或远程登录中读数据 更多...
 
INT32 FilepWrite (struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen)
 写数据到串口或远程登录 更多...
 
INT32 FilepPoll (struct file *filep, const struct file_operations_vfs *fops, poll_table *fds)
 
INT32 FilepIoctl (struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg)
 
INT32 GetFilepOps (const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops)
 
VOID OsWaitConsoleSendTaskPend (UINT32 taskID)
 
VOID OsWakeConsoleSendTask (VOID)
 唤醒控制台发送任务 更多...
 
VOID KillPgrp (UINT16 consoleId)
 杀死进程组 更多...
 

详细描述

https://www.cnblogs.com/sparkdev/p/11460821.html

TTY 是 Teletype 或 Teletypewriter 的缩写,字符设备的通称,原来是指电传打字机,
后来这种设备逐渐键盘和显示器取代。不管是电传打字机还是键盘,显示器,
都是作为计算机的终端设备存在的,所以 TTY 也泛指计算机的终端(terminal)设备。
为了支持这些 TTY 设备,Linux 实现了一个叫做 TTY 的子系统。所以 TTY 既指终端,也指 Linux 的 TTY 子系统

/dev/console是一个虚拟的tty,在鸿蒙它映射到真正的dev/ttyS0(UART0)上
能直接显示系统消息的那个终端称为控制台,其他的则称为终端
版本
作者
weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
日期
2021-12-8

在文件 console.h 中定义.

函数说明

◆ ConsoleEnable()

BOOL ConsoleEnable ( VOID  )

控制台使能

ShellEntry是否在运行,其为负责接受来自终端敲入的一个个字符

在文件 console.c1415 行定义.

函数调用图:
这是这个函数的调用关系图:

◆ ConsoleTaskReg()

INT32 ConsoleTaskReg ( INT32  consoleID,
UINT32  taskID 
)

任务注册控制台,每个shell任务都有属于自己的控制台

在文件 console.c1454 行定义.

1455{
1456 UINT32 intSave;
1457
1458 LOS_SpinLockSave(&g_consoleSpin, &intSave);
1459 if (!IsShellEntryRunning(g_console[consoleID - 1]->shellEntryId)) {//如果控制台还没有捆绑shell客户端任务
1460 g_console[consoleID - 1]->shellEntryId = taskID; //给控制台捆绑一个shell客户端任务,接受终端输入.
1461 LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
1462 (VOID)OsSetCurrProcessGroupID(OsGetUserInitProcessID());// @notethinking 为何要在此处设置当前进程的组ID?
1463 return LOS_OK;
1464 }
1465 LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
1466 return (g_console[consoleID - 1]->shellEntryId == taskID) ? LOS_OK : LOS_NOK;
1467}
CONSOLE_CB * g_console[CONSOLE_NUM]
控制台全局变量,控制台是共用的, 默认为 2个
Definition: console.c:80
BOOL IsShellEntryRunning(UINT32 shellEntryId)
Definition: console.c:1442
LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID)
获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
Definition: los_process.c:2244
LITE_OS_SEC_TEXT INT32 OsSetCurrProcessGroupID(UINT32 gid)
Definition: los_process.c:1456
VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
Definition: los_spinlock.c:108
VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
Definition: los_spinlock.c:98
unsigned int UINT32
Definition: los_typedef.h:57
UINT32 shellEntryId
负责接受来自终端信息的 "ShellEntry"任务,这个值在运行过程中可能会被换掉,它始终指向当前正在运行的shell客户端
Definition: console.h:114
函数调用图:
这是这个函数的调用关系图:

◆ ConsoleUpdateFd()

INT32 ConsoleUpdateFd ( VOID  )

控制台更新文件句柄

在文件 console.c1517 行定义.

1518{
1519 INT32 consoleID;
1520
1521 if (OsCurrTaskGet() != NULL) {
1522 consoleID = g_taskConsoleIDArray[(OsCurrTaskGet())->taskID];//获取当前任务的控制台 (1,2,-1)
1523 } else {
1524 return -1;
1525 }
1526
1527 if (g_uart_fputc_en == 0) {
1528 if (g_console[CONSOLE_TELNET - 1] != NULL) {
1529 consoleID = CONSOLE_TELNET;
1530 }
1531 } else if (consoleID == 0) {
1532 if (g_console[CONSOLE_SERIAL - 1] != NULL) {
1533 consoleID = CONSOLE_SERIAL;
1534 } else if (g_console[CONSOLE_TELNET - 1] != NULL) {
1535 consoleID = CONSOLE_TELNET;
1536 } else {
1537 PRINTK("No console dev used.\n");
1538 return -1;
1539 }
1540 }
1541
1542 return (g_console[consoleID - 1] != NULL) ? g_console[consoleID - 1]->fd : -1;
1543}
STATIC UINT8 g_taskConsoleIDArray[LOSCFG_BASE_CORE_TSK_LIMIT]
task 控制台ID池,同步task数量,理论上每个task都可以有一个自己的控制台
Definition: console.c:68
UINT32 g_uart_fputc_en
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
signed int INT32
Definition: los_typedef.h:60
INT32 fd
系统文件句柄, 由内核分配
Definition: console.h:112
函数调用图:

◆ FilepClose()

INT32 FilepClose ( struct file filep,
const struct file_operations_vfs *  fops 
)

关闭串口或远程登录

在文件 console.c545 行定义.

546{
547 INT32 ret;
548 if ((fops == NULL) || (fops->close == NULL)) {
549 return -EFAULT;
550 }
551
552 /*
553 * adopt uart close function to open filep (filep is
554 * corresponding to filep of /dev/console)
555 */
556 ret = fops->close(filep);
557 return ret < 0 ? -EPERM : ret;
558}
这是这个函数的调用关系图:

◆ FilepIoctl()

INT32 FilepIoctl ( struct file filep,
const struct file_operations_vfs *  fops,
INT32  cmd,
unsigned long  arg 
)

在文件 console.c560 行定义.

561{
562 INT32 ret;
563 if (fops->ioctl == NULL) {
564 return -EFAULT;
565 }
566
567 ret = fops->ioctl(filep, cmd, arg);
568 return (ret < 0) ? -EPERM : ret;
569}
这是这个函数的调用关系图:

◆ FilepOpen()

INT32 FilepOpen ( struct file filep,
const struct file_operations_vfs *  fops 
)

打开串口或远程登录

在文件 console.c337 行定义.

338{
339 INT32 ret;
340 if (fops->open == NULL) {
341 return -EFAULT;
342 }
343 //使用 uart open函数打开filep(filep是对应 /dev/console 的 filep)
344 /*
345 * adopt uart open function to open filep (filep is
346 * corresponding to filep of /dev/console)
347 */
348 ret = fops->open(filep);
349 return (ret < 0) ? -EPERM : ret;
350}
这是这个函数的调用关系图:

◆ FilepPoll()

INT32 FilepPoll ( struct file filep,
const struct file_operations_vfs *  fops,
poll_table *  fds 
)

在文件 console.c571 行定义.

572{
573 INT32 ret;
574 if (fops->poll == NULL) {
575 return -EFAULT;
576 }
577
578 /*
579 * adopt uart poll function to poll filep (filep is
580 * corresponding to filep of /dev/serial)
581 */
582 ret = fops->poll(filep, fds);
583 return (ret < 0) ? -EPERM : ret;
584}
这是这个函数的调用关系图:

◆ FilepRead()

INT32 FilepRead ( struct file filep,
const struct file_operations_vfs *  fops,
CHAR buffer,
size_t  bufLen 
)

从串口或远程登录中读数据

在文件 console.c517 行定义.

518{
519 INT32 ret;
520 if (fops->read == NULL) {
521 return -EFAULT;
522 }
523 /*
524 * adopt uart read function to read data from filep
525 * and write data to buffer (filep is
526 * corresponding to filep of /dev/console)
527 *///采用uart read函数从文件中读取数据,将数据写入缓冲区(文件对应/dev/console的filep)
528 ret = fops->read(filep, buffer, bufLen);
529 return (ret < 0) ? -EPERM : ret;
530}
这是这个函数的调用关系图:

◆ FilepWrite()

INT32 FilepWrite ( struct file filep,
const struct file_operations_vfs *  fops,
const CHAR buffer,
size_t  bufLen 
)

写数据到串口或远程登录

在文件 console.c533 行定义.

534{
535 INT32 ret;
536 if (fops->write == NULL) {
537 return -EFAULT;
538 }
539
540 ret = fops->write(filep, buffer, bufLen);
541 return (ret < 0) ? -EPERM : ret;
542}
这是这个函数的调用关系图:

◆ GetFilepOps()

INT32 GetFilepOps ( const struct file filep,
struct file **  privFilep,
const struct file_operations_vfs **  fops 
)

在文件 console.c93 行定义.

94{
95 INT32 ret;
96
97 if ((filep == NULL) || (filep->f_vnode == NULL) || (filep->f_vnode->data == NULL)) {
98 ret = EINVAL;
99 goto ERROUT;
100 }
101 //通过 is_private 查找控制台设备的文件(现在是 *privFile)
102 /* to find console device's filep(now it is *privFilep) throught i_private */
103 struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
104 *privFilep = (struct file *)drv->priv;// file 例如 g_serialFilep
105 if (((*privFilep)->f_vnode == NULL) || ((*privFilep)->f_vnode->data == NULL)) {
106 ret = EINVAL;
107 goto ERROUT;
108 }
109
110 /* to find uart driver operation function throutht u.i_opss */
111
112 drv = (struct drv_data *)(*privFilep)->f_vnode->data;
113
114 *filepOps = (const struct file_operations_vfs *)drv->ops;//拿到串口驱动程序
115
116 return ENOERR;
117ERROUT:
118 set_errno(ret);
119 return VFS_ERROR;
120}
这是这个函数的调用关系图:

◆ is_nonblock()

BOOL is_nonblock ( const CONSOLE_CB consoleCB)

在文件 console.c1508 行定义.

1509{
1510 if (consoleCB == NULL) {
1511 PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
1512 return FALSE;
1513 }
1514 return consoleCB->isNonBlock;
1515}
BOOL isNonBlock
是否无锁方式
Definition: console.h:116
这是这个函数的调用关系图:

◆ IsConsoleOccupied()

BOOL IsConsoleOccupied ( const CONSOLE_CB consoleCB)

控制台是否被占用

在文件 console.c173 行定义.

174{
175 return ConsoleRefcountGet(consoleCB);
176}
STATIC UINT32 ConsoleRefcountGet(const CONSOLE_CB *consoleCB)
Definition: console.c:162
函数调用图:
这是这个函数的调用关系图:

◆ KillPgrp()

VOID KillPgrp ( UINT16  consoleId)

杀死进程组

在文件 console.c442 行定义.

443{
444 if ((consoleId > CONSOLE_NUM) || (consoleId <= 0)) {
445 return;
446 }
447 CONSOLE_CB *consoleCB = g_console[consoleId-1];
448 /* the default of consoleCB->pgrpId is -1, may not be set yet, avoid killing all processes */
449 if (consoleCB->pgrpId < 0) {
450 return;
451 }
452 (VOID)OsKillLock(consoleCB->pgrpId, SIGINT);//发送信号 SIGINT对应 键盘中断(ctrl + c)信号
453}
int OsKillLock(pid_t pid, int sig)
给发送信号过程加锁
Definition: los_signal.c:480
控制台控制块(描述符)
Definition: console.h:105
INT32 pgrpId
进程组ID
Definition: console.h:115
函数调用图:
这是这个函数的调用关系图:

◆ OsGetConsoleByID()

CONSOLE_CB * OsGetConsoleByID ( INT32  consoleID)

获取参数控制台ID 获取对应的控制台控制块(描述符)

在文件 console.c1546 行定义.

1547{
1548 if (consoleID != CONSOLE_TELNET) {//只允许 1,2存在,> 3 时统统变成1
1549 consoleID = CONSOLE_SERIAL;
1550 }
1551 return g_console[consoleID - 1];
1552}
这是这个函数的调用关系图:

◆ OsGetConsoleByTaskID()

CONSOLE_CB * OsGetConsoleByTaskID ( UINT32  taskID)

获取参数任务的控制台控制块(描述符)

在文件 console.c1554 行定义.

1555{
1556 INT32 consoleID = g_taskConsoleIDArray[taskID];
1557
1558 return OsGetConsoleByID(consoleID);
1559}
CONSOLE_CB * OsGetConsoleByID(INT32 consoleID)
获取参数控制台ID 获取对应的控制台控制块(描述符)
Definition: console.c:1546
函数调用图:
这是这个函数的调用关系图:

◆ OsWaitConsoleSendTaskPend()

VOID OsWaitConsoleSendTaskPend ( UINT32  taskID)

在文件 console.c1633 行定义.

1634{
1635 UINT32 i;
1636 CONSOLE_CB *console = NULL;
1637 LosTaskCB *taskCB = NULL;
1638 INT32 waitTime = 3000; /* 3000: 3 seconds */
1639
1640 for (i = 0; i < CONSOLE_NUM; i++) {//轮询控制台
1641 console = g_console[i];
1642 if (console == NULL) {
1643 continue;
1644 }
1645
1646 if (OS_TID_CHECK_INVALID(console->sendTaskID)) {
1647 continue;
1648 }
1649
1650 taskCB = OS_TCB_FROM_TID(console->sendTaskID);
1651 while ((waitTime > 0) && (taskCB->taskEvent == NULL) && (taskID != console->sendTaskID)) {
1652 LOS_Mdelay(1); /* 1: wait console task pend */ //等待控制台任务挂起/待办
1653 --waitTime;
1654 }
1655 }
1656}
LITE_OS_SEC_TEXT_MINOR VOID LOS_Mdelay(UINT32 msecs)
以ms为单位的忙等,但可以被优先级更高的任务抢占
Definition: los_hw_tick.c:73
UINT32 sendTaskID
创建任务通过事件接收数据, 见于OsConsoleBufInit
Definition: console.h:120
VOID * taskEvent
函数调用图:
这是这个函数的调用关系图:

◆ OsWakeConsoleSendTask()

VOID OsWakeConsoleSendTask ( VOID  )

唤醒控制台发送任务

在文件 console.c1658 行定义.

1659{
1660 UINT32 i;
1661 CONSOLE_CB *console = NULL;
1662
1663 for (i = 0; i < CONSOLE_NUM; i++) {//循环控制台数量,只有2个
1664 console = g_console[i];
1665 if (console == NULL) {
1666 continue;
1667 }
1668
1669 if (console->cirBufSendCB != NULL) {//循环缓存描述符
1670 (VOID)LOS_EventWrite(&console->cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT);//写循环缓存区buf事件
1671 }
1672 }
1673}
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
写指定的事件类型
Definition: los_event.c:318
CirBufSendCB * cirBufSendCB
循环缓冲发送控制块
Definition: console.h:121
EVENT_CB_S sendEvent
Definition: console.h:99
函数调用图:
这是这个函数的调用关系图:

◆ SetSerialBlock()

BOOL SetSerialBlock ( const CONSOLE_CB consoleCB)

锁方式设置串口

在文件 console.c1479 行定义.

1480{
1481 if (consoleCB == NULL) {
1482 PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
1483 return TRUE;
1484 }
1485 return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_BLOCK) != 0;
1486}
这是这个函数的调用关系图:

◆ SetSerialNonBlock()

BOOL SetSerialNonBlock ( const CONSOLE_CB consoleCB)

无锁方式设置串口

在文件 console.c1469 行定义.

1470{
1471 if (consoleCB == NULL) {
1472 PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
1473 return FALSE;
1474 }
1475 return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_NONBLOCK) == 0;
1476}

◆ SetTelnetBlock()

BOOL SetTelnetBlock ( const CONSOLE_CB consoleCB)

锁方式设置远程登录

在文件 console.c1499 行定义.

1500{
1501 if (consoleCB == NULL) {
1502 PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
1503 return TRUE;
1504 }
1505 return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_BLOCK) != 0;
1506}
这是这个函数的调用关系图:

◆ SetTelnetNonBlock()

BOOL SetTelnetNonBlock ( const CONSOLE_CB consoleCB)

无锁方式设置远程登录

在文件 console.c1489 行定义.

1490{
1491 if (consoleCB == NULL) {
1492 PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
1493 return FALSE;
1494 }
1495 return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_NONBLOCK) == 0;
1496}

◆ system_console_deinit()

INT32 system_console_deinit ( const CHAR deviceName)

控制台结束前的处理 和 system_console_init成对出现,像控制台的析构函数

在文件 console.c1375 行定义.

1376{
1377 UINT32 ret;
1378 CONSOLE_CB *consoleCB = NULL;
1379 UINT32 taskIdx;
1380 LosTaskCB *taskCB = NULL;
1381 UINT32 intSave;
1382
1383 consoleCB = OsGetConsoleByDevice(deviceName);//通过设备名称获取控制台描述符
1384 if (consoleCB == NULL) {
1385 return VFS_ERROR;
1386 }
1387
1388#ifdef LOSCFG_SHELL
1389 (VOID)OsShellDeinit((INT32)consoleCB->consoleID);//shell结束前的处理,shell的析构函数
1390#endif
1391
1392 LOS_SpinLockSave(&g_consoleSpin, &intSave);
1393 /* Redirect all tasks to serial as telnet was unavailable after deinitializing */
1394 //在远程登陆去初始化后变成无效时,将所有任务的控制台重定向到串口方式。
1395 for (taskIdx = 0; taskIdx < g_taskMaxNum; taskIdx++) {//这里是对所有的任务控制台方式设为串口化
1396 taskCB = ((LosTaskCB *)g_taskCBArray) + taskIdx;
1397 if (OsTaskIsUnused(taskCB)) {//任务还没被使用过
1398 continue;//继续
1399 } else {
1400 g_taskConsoleIDArray[taskCB->taskID] = CONSOLE_SERIAL;//任务对于的控制台变成串口方式
1401 }
1402 }
1403 g_console[consoleCB->consoleID - 1] = NULL;
1404 LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
1405
1406 ret = OsConsoleDelete(consoleCB);//删除控制台
1407 if (ret != LOS_OK) {
1408 PRINT_ERR("%s, Failed to system_console_deinit\n", __FUNCTION__);
1409 return VFS_ERROR;
1410 }
1411
1412 return ENOERR;
1413}
int OsShellDeinit(ShellCB *shellCB)
STATIC CONSOLE_CB * OsGetConsoleByDevice(const CHAR *deviceName)
Definition: console.c:236
STATIC UINT32 OsConsoleDelete(CONSOLE_CB *consoleCB)
删除控制台
Definition: console.c:1310
LITE_OS_SEC_BSS UINT32 g_taskMaxNum
任务最大数量 默认128个
Definition: los_task.c:150
LITE_OS_SEC_BSS LosTaskCB * g_taskCBArray
外部变量 任务池 默认128个
Definition: los_task.c:147
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
任务是否在使用
Definition: los_task_pri.h:255
UINT32 consoleID
控制台ID 例如 : 1 | 串口 , 2 | 远程登录
Definition: console.h:106
UINT32 taskID
函数调用图:
这是这个函数的调用关系图:

◆ system_console_init()

INT32 system_console_init ( const CHAR deviceName)

https://man7.org/linux/man-pages/man3/tcflow.3.html termios 是在POSIX规范中定义的标准接口,表示终端设备,包括虚拟终端、串口等。串口通过termios进行配置。 struct termios { unsigned short c_iflag; // 输入模式标志 unsigned short c_oflag; // 输出模式标志 unsigned short c_cflag; // 控制模式标志 unsigned short c_lflag; // 本地模式标志 例如: 设置非规范模式 tios.c_lflag = ~(ICANON | ECHO | ECHOE | ISIG); unsigned char c_line; // 线路规程 unsigned char c_cc[NCC]; // 控制特性 speed_t c_ispeed; // 输入速度 speed_t c_ospeed; // 输出速度 } 终端有三种工作模式: 规范模式(canonical mode)、 非规范模式(non-canonical mode) 原始模式(raw mode)。 https://www.jianshu.com/p/fe5812469801 https://blog.csdn.net/wumenglu1018/article/details/53098794

https://man7.org/linux/man-pages/man3/tcflow.3.html termios 是在POSIX规范中定义的标准接口,表示终端设备,包括虚拟终端、串口等。串口通过termios进行配置。 struct termios { unsigned short c_iflag; // 输入模式标志 unsigned short c_oflag; // 输出模式标志 unsigned short c_cflag; // 控制模式标志 unsigned short c_lflag; // 本地模式标志 例如: 设置非规范模式 tios.c_lflag = ~(ICANON | ECHO | ECHOE | ISIG); unsigned char c_line; // 线路规程 unsigned char c_cc[NCC]; // 控制特性 speed_t c_ispeed; // 输入速度 speed_t c_ospeed; // 输出速度 } 终端有三种工作模式: 规范模式(canonical mode)、 非规范模式(non-canonical mode) 原始模式(raw mode)。 https://www.jianshu.com/p/fe5812469801 https://blog.csdn.net/wumenglu1018/article/details/53098794

在文件 console.c1329 行定义.

1330{
1331#ifdef LOSCFG_SHELL
1332 UINT32 ret;
1333#endif
1334 INT32 consoleID;
1335 UINT32 intSave;
1336 CONSOLE_CB *consoleCB = NULL;
1337
1338 consoleID = OsGetConsoleID(deviceName);//获取控制台ID 返回[ CONSOLE_SERIAL(1) | CONSOLE_TELNET(2) | -1 ]三种结果
1339 if (consoleID == -1) {
1340 PRINT_ERR("device is full.\n");
1341 return VFS_ERROR;
1342 }
1343
1344 consoleCB = OsConsoleCreate((UINT32)consoleID, deviceName);//创建一个控制台
1345 if (consoleCB == NULL) {
1346 PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
1347 return VFS_ERROR;
1348 }
1349
1350 LOS_SpinLockSave(&g_consoleSpin, &intSave);
1351 g_console[consoleID - 1] = consoleCB;//全局变量, g_console最大值只有2 ,所有任务共用控制台.
1352 if (OsCurrTaskGet() != NULL) {//当前task
1353 g_taskConsoleIDArray[OsCurrTaskGet()->taskID] = (UINT8)consoleID;//任务绑定控制台ID
1354 }
1355 LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
1356
1357#ifdef LOSCFG_SHELL //shell支持
1358 ret = OsShellInit(consoleID);//初始化shell
1359 if (ret != LOS_OK) {//初始化shell失败
1360 PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
1361 LOS_SpinLockSave(&g_consoleSpin, &intSave);
1362 (VOID)OsConsoleDelete(consoleCB);//删除控制台
1363 g_console[consoleID - 1] = NULL;
1364 if (OsCurrTaskGet() != NULL) {
1365 g_taskConsoleIDArray[OsCurrTaskGet()->taskID] = 0;//表示当前任务还没有控制台。
1366 }
1367 LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
1368 return VFS_ERROR;
1369 }
1370#endif
1371
1372 return ENOERR;
1373}
unsigned int OsShellInit(void)
STATIC INT32 OsGetConsoleID(const CHAR *deviceName)
获取控制台ID,(/dev/console1 = SERIAL, /dev/console2 = telnet)
Definition: console.c:259
STATIC CONSOLE_CB * OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName)
创建一个控制台,这个函数的goto语句贼多
Definition: console.c:1253
unsigned char UINT8
Definition: los_typedef.h:55
函数调用图:
这是这个函数的调用关系图: