对控制台,环形缓存区,虚拟串口实现注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    国内:https://weharmony.21cloudbox.com
    国外:https://weharmony.github.io
上级 aa517fb1
......@@ -51,7 +51,7 @@ static ssize_t MemWrite(FAR struct file *filep, FAR const char *buffer, size_t b
{
return 0;
}
//文件和线性区的映射关系
static ssize_t MemMap(FAR struct file *filep, FAR LosVmMapRegion *region)
{
#ifdef LOSCFG_KERNEL_VM
......@@ -69,7 +69,7 @@ static ssize_t MemMap(FAR struct file *filep, FAR LosVmMapRegion *region)
if (space == NULL) {
return -EAGAIN;
}
}//映射
if (LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, size >> PAGE_SHIFT, region->regionFlags) <= 0) {
return -EAGAIN;
}
......@@ -79,7 +79,7 @@ static ssize_t MemMap(FAR struct file *filep, FAR LosVmMapRegion *region)
#endif
return 0;
}
// vfs 接口实现
static const struct file_operations_vfs g_memDevOps = {
MemOpen, /* open */
MemClose, /* close */
......@@ -93,7 +93,7 @@ static const struct file_operations_vfs g_memDevOps = {
#endif
NULL, /* unlink */
};
// 注册访问 /dev/mem 的驱动程序
int DevMemRegister(void)
{
return register_driver("/dev/mem", &g_memDevOps, 0666, 0); /* 0666: file mode */
......
......@@ -165,7 +165,7 @@ LosTaskCB *OsGetMainTask()
VOID OsSetMainTask()
{
UINT32 i;
CHAR *name = "osMain";
CHAR *name = "osMain";//任务名称
//为每个CPU core 设置mainTask
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
......
......@@ -361,7 +361,7 @@ typedef struct {
UINT32 processID; /**< Which belong process *///所属进程ID
FutexNode futex; //实现快锁功能
LOS_DL_LIST joinList; /**< join list */ //联结链表,允许任务之间相互释放彼此
LOS_DL_LIST lockList; /**< Hold the lock list */ //拿到了哪些锁链表
LOS_DL_LIST lockList; /**< Hold the lock list */ //该链表上挂的都是已持有的锁
UINTPTR waitID; /**< Wait for the PID or GID of the child process */
UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent,
a specific child process, or any child process */ //以什么样的方式等待子进程结束(OS_TASK_WAIT_PROCESS | OS_TASK_WAIT_GID | ..)
......
......@@ -117,7 +117,7 @@ ERROUT:
set_errno(ret);
return VFS_ERROR;
}
//获取控制台 模式值
INT32 ConsoleTcGetAttr(INT32 fd, struct termios *termios)
{
struct file *filep = NULL;
......@@ -136,7 +136,7 @@ INT32 ConsoleTcGetAttr(INT32 fd, struct termios *termios)
(VOID)memcpy_s(termios, sizeof(struct termios), &consoleCB->consoleTermios, sizeof(struct termios));
return LOS_OK;
}
//设置控制台 模式值
INT32 ConsoleTcSetAttr(INT32 fd, INT32 actions, const struct termios *termios)
{
struct file *filep = NULL;
......@@ -1023,11 +1023,15 @@ STATIC const struct file_operations_vfs g_consoleDevOps = {
.poll = ConsolePoll,
#endif
};
/*
termios 结构是在POSIX规范中定义的标准接口,它类似于系统V中的termio接口,
通过设置termios类型的数据结构中的值和使用一小组函数调用,你就可以对终端接口进行控制。
*/
STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
{
struct termios consoleTermios;
//c_cc[VINTR] 默认对应的控制符是^C,作用是清空输入和输出队列的数据并且向tty设备的前台进程组中的
//每一个程序发送一个SIGINT信号,对SIGINT信号没有定义处理程序的进程会马上退出。
if ((deviceName != NULL) &&
(strlen(deviceName) == strlen(SERIAL)) &&
(!strncmp(deviceName, SERIAL, strlen(SERIAL)))) {
......@@ -1035,8 +1039,8 @@ STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
/* set console to have a buffer for user */
(VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios);
consoleTermios.c_lflag |= ICANON | ECHO;
consoleTermios.c_cc[VINTR] = 3; /* /003 for ^C */
consoleTermios.c_lflag |= ICANON | ECHO;//控制模式标志 ICANON:使用标准输入模式 ECHO:显示输入字符
consoleTermios.c_cc[VINTR] = 3; /* /003 for ^C */ //控制字符
(VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios);
}
#ifdef LOSCFG_NET_TELNET
......@@ -1046,8 +1050,8 @@ STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
consoleCB->isNonBlock = SetTelnetBlock(consoleCB);
/* set console to have a buffer for user */
(VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios);
consoleTermios.c_lflag |= ICANON | ECHO;
consoleTermios.c_cc[VINTR] = 3; /* /003 for ^C */
consoleTermios.c_lflag |= ICANON | ECHO;//控制模式标志 ICANON:使用标准输入模式 ECHO:显示输入字符
consoleTermios.c_cc[VINTR] = 3; /* /003 for ^C */ //控制字符
(VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios);
}
#endif
......@@ -1071,20 +1075,20 @@ STATIC INT32 OsConsoleFileInit(CONSOLE_CB *consoleCB)
ret = EACCES;
goto ERROUT_WITH_FULLPATH;
}
//分配一个系统文件描述符
consoleCB->fd = files_allocate(vnode, O_RDWR, (off_t)0, consoleCB, STDERR_FILENO + 1);
if (consoleCB->fd < 0) {
ret = EMFILE;
goto ERROUT_WITH_FULLPATH;
}
ret = fs_getfilep(consoleCB->fd, &filep);
ret = fs_getfilep(consoleCB->fd, &filep);//通过描述符拿到 file
if (ret < 0) {
ret = EPERM;
goto ERROUT_WITH_FULLPATH;
}
filep->f_path = fullpath;
filep->ops = (struct file_operations_vfs *)((struct drv_data *)vnode->data)->ops;
filep->ops = (struct file_operations_vfs *)((struct drv_data *)vnode->data)->ops;//关系驱动程序
VnodeDrop();
return LOS_OK;
......@@ -1113,7 +1117,7 @@ STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
}
VnodeHold();
ret = VnodeLookup(deviceName, &vnode, V_DUMMY);
ret = VnodeLookup(deviceName, &vnode, V_DUMMY); //找到对应 vnode节点
VnodeDrop(); // not correct, but can't fix perfectly here
if (ret != LOS_OK) {
ret = EACCES;
......@@ -1121,7 +1125,7 @@ STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
goto ERROUT;
}
consoleCB->devVnode = vnode;
consoleCB->devVnode = vnode;//关联vnode节点
/*
* initialize the console filep which is associated with /dev/console,
......@@ -1134,17 +1138,17 @@ STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
/dev/console的console inod,就可以像操作/dev/ttyS0的uart0 filep一样操作控制台的filep
*/
(VOID)memset_s(filep, sizeof(struct file), 0, sizeof(struct file));
filep->f_oflags = O_RDWR;
filep->f_pos = 0;
filep->f_vnode = vnode;
filep->f_path = NULL;
filep->f_priv = NULL;
filep->f_oflags = O_RDWR; //读写模式
filep->f_pos = 0; //偏移位置,默认为0
filep->f_vnode = vnode; //节点关联
filep->f_path = NULL; //
filep->f_priv = NULL; //
/*
* Use filep to connect console and uart, we can find uart driver function throught filep.
* now we can operate /dev/console to operate /dev/ttyS0 through filep.
*/
//使用filep连接控制台和uart,通过它可以找到uart驱动函数, 可以通过filep操作/dev/console
devOps = (struct file_operations_vfs *)((struct drv_data*)vnode->data)->ops;
devOps = (struct file_operations_vfs *)((struct drv_data*)vnode->data)->ops;//获取默认驱动程序
if (devOps != NULL && devOps->open != NULL) {
(VOID)devOps->open(filep);
} else {
......@@ -1152,7 +1156,7 @@ STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
goto ERROUT;
}
//达到操作/dev/ttyS0的目的
//更新驱动程序,其中再次对 达到操作/dev/ttyS0的目的
ret = register_driver(consoleCB->name, &g_consoleDevOps, DEFFILEMODE, filep);//注册字符设备驱动程序
if (ret != LOS_OK) {
goto ERROUT;
......@@ -1168,10 +1172,10 @@ ERROUT:
set_errno(ret);
return LOS_NOK;
}
//控制台设备去初始化
STATIC UINT32 OsConsoleDevDeinit(const CONSOLE_CB *consoleCB)
{
return unregister_driver(consoleCB->name);
return unregister_driver(consoleCB->name);//注销驱动
}
//创建一个控制台循环buf
......@@ -1188,14 +1192,14 @@ STATIC CirBufSendCB *ConsoleCirBufCreate(VOID)
}
(VOID)memset_s(cirBufSendCB, sizeof(CirBufSendCB), 0, sizeof(CirBufSendCB));
fifo = (CHAR *)LOS_MemAlloc(m_aucSysMem0, CONSOLE_CIRCBUF_SIZE);
fifo = (CHAR *)LOS_MemAlloc(m_aucSysMem0, CONSOLE_CIRCBUF_SIZE);//分配FIFO buf 1K
if (fifo == NULL) {
goto ERROR_WITH_SENDCB;
}
(VOID)memset_s(fifo, CONSOLE_CIRCBUF_SIZE, 0, CONSOLE_CIRCBUF_SIZE);
cirBufCB = &cirBufSendCB->cirBufCB;
ret = LOS_CirBufInit(cirBufCB, fifo, CONSOLE_CIRCBUF_SIZE);
ret = LOS_CirBufInit(cirBufCB, fifo, CONSOLE_CIRCBUF_SIZE);//环形BUF初始化
if (ret != LOS_OK) {
goto ERROR_WITH_FIFO;
}
......@@ -1304,7 +1308,7 @@ STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName)
goto ERR_WITH_NAME;
}
ret = (INT32)OsConsoleBufInit(consoleCB);//控制台buf初始化
ret = (INT32)OsConsoleBufInit(consoleCB);//控制台buf初始化,创建 ConsoleSendTask 任务
if (ret != LOS_OK) {
PRINT_ERR("console OsConsoleBufInit error. %d\n", ret);
goto ERR_WITH_NAME;
......@@ -1316,19 +1320,19 @@ STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName)
goto ERR_WITH_BUF;
}
ret = OsConsoleDevInit(consoleCB, deviceName);//控制台设备初始化
if (ret != LOS_OK) {
ret = OsConsoleDevInit(consoleCB, deviceName);//控制台设备初始化,注意这步要在 OsConsoleFileInit 的前面.
if (ret != LOS_OK) {//先注册驱动程序
PRINT_ERR("console OsConsoleDevInit error. %d\n", ret);
goto ERR_WITH_SEM;
}
ret = OsConsoleFileInit(consoleCB); //控制台文件初始化
ret = OsConsoleFileInit(consoleCB); //控制台文件初始化,其中file要绑定驱动程序
if (ret != LOS_OK) {
PRINT_ERR("console OsConsoleFileInit error. %d\n", ret);
goto ERR_WITH_DEV;
}
OsConsoleTermiosInit(consoleCB, deviceName);//控制台条款初始化
OsConsoleTermiosInit(consoleCB, deviceName);//控制台术语/控制初始化
return consoleCB;
ERR_WITH_DEV:
......@@ -1349,16 +1353,16 @@ STATIC UINT32 OsConsoleDelete(CONSOLE_CB *consoleCB)
{
UINT32 ret;
(VOID)files_close(consoleCB->fd);
ret = OsConsoleDevDeinit(consoleCB);
(VOID)files_close(consoleCB->fd);//回收系统文件句柄
ret = OsConsoleDevDeinit(consoleCB);//注销驱动程序
if (ret != LOS_OK) {
PRINT_ERR("OsConsoleDevDeinit failed!\n");
}
OsConsoleBufDeinit((CONSOLE_CB *)consoleCB);
(VOID)LOS_SemDelete(consoleCB->consoleSem);
(VOID)LOS_MemFree(m_aucSysMem0, consoleCB->name);
OsConsoleBufDeinit((CONSOLE_CB *)consoleCB);//回收环形缓存区
(VOID)LOS_SemDelete(consoleCB->consoleSem);//删除信号量
(VOID)LOS_MemFree(m_aucSysMem0, consoleCB->name);//回收控制台名称,此名称占用内核内存
consoleCB->name = NULL;
(VOID)LOS_MemFree(m_aucSysMem0, consoleCB);
(VOID)LOS_MemFree(m_aucSysMem0, consoleCB);//回收控制块本身占用的内存
return ret;
}
......@@ -1686,7 +1690,7 @@ STATIC UINT32 ConsoleSendTask(UINTPTR param)
}
#if (LOSCFG_KERNEL_SMP == YES)//多处理器情况下
VOID OsWaitConsoleSendTaskPend(UINT32 taskID)//等待控制台任务结束
VOID OsWaitConsoleSendTaskPend(UINT32 taskID)//等待控制台发送任务结束
{
UINT32 i;
CONSOLE_CB *console = NULL;
......
......@@ -79,7 +79,7 @@ TTY 是 Teletype 或 Teletypewriter 的缩写,字符设备的通称,原来是
#define CONSOLE_FIFO_SIZE 0x400 //1K
#define CONSOLE_NUM 2
#define CONSOLE_CIRCBUF_SIZE 0x400
#define CONSOLE_CIRCBUF_SIZE 0x400 //大小 1K
typedef struct {//发送环形buf控制块,通过事件发送
CirBuf cirBufCB; /* Circular buffer CB */ //循环缓冲控制块
......@@ -109,9 +109,18 @@ typedef struct {
UINT32 fifoIn; //对fifo的标记,输入位置
UINT32 currentLen; //当前fifo位置
/*---以上为 一家子 end-------*/
struct termios consoleTermios; //控制台条款
struct termios consoleTermios; //控制台术语
} CONSOLE_CB;
/*
termios 结构是在POSIX规范中定义的标准接口,它类似于系统V中的termio接口,通过设置termios类型的数据结构中的值和使用一小组函数调用,
你就可以对终端接口进行控制。可以被调整来影响终端的值按照不同的模式被分为如下几组:
1.输入模式
2.输出模式
3.控制模式
4.本地模式
5.特殊控制模式
https://blog.csdn.net/wumenglu1018/article/details/53098794
*/
extern INT32 system_console_init(const CHAR *deviceName);
extern INT32 system_console_deinit(const CHAR *deviceName);
extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB);
......
......@@ -222,7 +222,7 @@ UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size)
cirbufCB->size = size; //记录size
cirbufCB->remain = size;//剩余size
cirbufCB->status = CBUF_USED;//标记为已使用
cirbufCB->fifo = fifo; //顺序buf
cirbufCB->fifo = fifo; //顺序buf ,这1K buf 是循环利用
return LOS_OK;
}
......
......@@ -54,7 +54,7 @@ typedef struct {
UINT32 remain; //剩余多少
SPIN_LOCK_S lock; //自旋锁
CirBufStatus status;//两种状态
CHAR *fifo; //顺序buffer
CHAR *fifo; //顺序buffer ,1K
} CirBuf;
//锁循环buf
STATIC INLINE VOID LOS_CirBufLock(CirBuf *cirbufCB, UINT32 *intSave)
......
......@@ -71,9 +71,9 @@ extern VOID release_secondary_cores(VOID);
LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID)
{
/* Must be placed at the beginning of the boot process */
OsSetMainTask();
OsCurrTaskSet(OsGetMainTask());
/* Must be placed at the beginning of the boot process *///必须放在启动过程的开头
OsSetMainTask();//为每个CPU核设置临时主任务
OsCurrTaskSet(OsGetMainTask());//设置当前任务
g_sysClock = OS_SYS_CLOCK;
g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND;
......@@ -185,7 +185,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsSystemInfo(VOID)
HalIrqVersion(), __DATE__, __TIME__,\
KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType);
}
//由汇编调用,鸿蒙C语言层级的入口点
LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID)
{
UINT32 ret;
......@@ -193,7 +193,7 @@ LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID)
UINT64 startNsec, endNsec, durationUsec;
#endif
ret = EarliestInit();
ret = EarliestInit();//鸿蒙初开,天地混沌
if (ret != LOS_OK) {
return ret;
}
......@@ -220,21 +220,21 @@ LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID)
startNsec = LOS_CurrNanosec();
#endif
ret = OsTaskInit();
ret = OsTaskInit();//任务池初始化
if (ret != LOS_OK) {
return ret;
}
OsInitCall(LOS_INIT_LEVEL_KMOD_PREVM);
ret = OsSysMemInit();
ret = OsSysMemInit();//系统内存初始化
if (ret != LOS_OK) {
return ret;
}
OsInitCall(LOS_INIT_LEVEL_VM_COMPLETE);
ret = OsIpcInit();
ret = OsIpcInit();//进程间通讯模块初始化
if (ret != LOS_OK) {
return ret;
}
......@@ -286,7 +286,7 @@ STATIC VOID SystemInit(VOID)
PRINTK("dummy: *** %s ***\n", __FUNCTION__);
}
#endif
//创建系统初始任务并申请调度
STATIC UINT32 OsSystemInitTaskCreate(VOID)
{
UINT32 taskID;
......@@ -300,16 +300,16 @@ STATIC UINT32 OsSystemInitTaskCreate(VOID)
sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TestSystemInit;
#endif
sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
sysTask.pcName = "SystemInit";
sysTask.pcName = "SystemInit";
sysTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
sysTask.uwResved = LOS_TASK_STATUS_DETACHED;
#if (LOSCFG_KERNEL_SMP == 1)
sysTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());
#endif
return LOS_TaskCreate(&taskID, &sysTask);
return LOS_TaskCreate(&taskID, &sysTask);
}
//系统任务初始化
UINT32 OsSystemInit(VOID)
{
UINT32 ret;
......@@ -322,4 +322,4 @@ UINT32 OsSystemInit(VOID)
return 0;
}
LOS_MODULE_INIT(OsSystemInit, LOS_INIT_LEVEL_KMOD_TASK);
LOS_MODULE_INIT(OsSystemInit, LOS_INIT_LEVEL_KMOD_TASK);//模块初始化
......@@ -333,6 +333,7 @@ extern UINT32 __heap_end; // 堆区结束地址
#endif
/****************************** SMP module configuration **************************/
//http://www.gotw.ca/publications/concurrency-ddj.htm 免费午餐结束了:软件并发的根本转变
#ifndef LOSCFG_KERNEL_SMP
#define LOSCFG_KERNEL_SMP NO //SMP指对称多处理(Symmetrical Multi-Processing),多核时要设为 YES
#endif
......
......@@ -47,11 +47,11 @@
*/
OS_INIT_LEVEL_REG(kernel, 10, g_kernInitLevelList);
STATIC volatile UINT32 g_initCurrentLevel = OS_INVALID_VALUE;
STATIC volatile struct ModuleInitInfo *g_initCurrentModule = 0;
STATIC volatile UINT32 g_initCurrentLevel = OS_INVALID_VALUE; //当前等级
STATIC volatile struct ModuleInitInfo *g_initCurrentModule = 0; //当前模块
STATIC Atomic g_initCount = 0;
STATIC SPIN_LOCK_INIT(g_initLock);
// 建议每个启动框架都封装一层自己的调用接口
/**
* It is recommended that each startup framework encapsulate a layer of its own calling interface.
*/
......@@ -65,7 +65,7 @@ STATIC VOID InitLevelCall(const CHAR *name, const UINT32 level, struct ModuleIni
UINT32 ret = LOS_OK;
#endif
if (ArchCurrCpuid() == 0) {
if (ArchCurrCpuid() == 0) {//主CPU
#ifdef LOS_INIT_DEBUG
PRINTK("-------- %s Module Init... level = %u --------\n", name, level);
#endif
......@@ -116,7 +116,10 @@ STATIC VOID InitLevelCall(const CHAR *name, const UINT32 level, struct ModuleIni
PRINTK("%s initialization at level %u consumes %lluns on cpu %u.\n", name, level, totalTime, ArchCurrCpuid());
#endif
}
/*********************************************************
初始化调用日志打印,这个函数的功能主要是为了记录某个步骤的耗时.在一个函数前后各调用一次就知道函数的执行情况.
这为开机调试提供了很重要的日志依据.
**********************************************************/
VOID OsInitCall(const UINT32 level)
{
if (level >= LOS_INIT_LEVEL_FINISH) {
......
......@@ -33,20 +33,20 @@
#define _LOS_INIT_H
#include "los_init_info.h"
//内核模块初始化级别
/**
* Kernel Module Init Level
*/
#define LOS_INIT_LEVEL_EARLIEST 0
#define LOS_INIT_LEVEL_ARCH_EARLY 1
#define LOS_INIT_LEVEL_PLATFORM_EARLY 2
#define LOS_INIT_LEVEL_KMOD_PREVM 3
#define LOS_INIT_LEVEL_VM_COMPLETE 4
#define LOS_INIT_LEVEL_ARCH 5
#define LOS_INIT_LEVEL_PLATFORM 6
#define LOS_INIT_LEVEL_KMOD_BASIC 7
#define LOS_INIT_LEVEL_KMOD_EXTENDED 8
#define LOS_INIT_LEVEL_KMOD_TASK 9
#define LOS_INIT_LEVEL_EARLIEST 0 //最早级
#define LOS_INIT_LEVEL_ARCH_EARLY 1 //架构早期
#define LOS_INIT_LEVEL_PLATFORM_EARLY 2 //平台早期
#define LOS_INIT_LEVEL_KMOD_PREVM 3 //内存模块即将开始
#define LOS_INIT_LEVEL_VM_COMPLETE 4 //内存模块完成
#define LOS_INIT_LEVEL_ARCH 5 // 架构级
#define LOS_INIT_LEVEL_PLATFORM 6 // 平台级
#define LOS_INIT_LEVEL_KMOD_BASIC 7 // 基础级
#define LOS_INIT_LEVEL_KMOD_EXTENDED 8 //
#define LOS_INIT_LEVEL_KMOD_TASK 9 //任务级
#define LOS_INIT_LEVEL_FINISH 10
/**
......@@ -72,7 +72,7 @@
* @par Dependency:
* <ul><li>los_init.h: the header file that contains the API declaration.</li></ul>
* @see
*/
*/ //将启动模块注册到启动过程
#define LOS_MODULE_INIT(_hook, _level) OS_INIT_HOOK_REG(kernel, _hook, _level)
#endif /* _LOS_INIT_H */
......@@ -59,10 +59,10 @@
#define INIT_SECTION(_type, _level, _hook) __attribute__((section(".rodata.init."#_type"."#_level"."#_hook)))
#define INIT_ALIGN __attribute__((aligned(alignof(struct ModuleInitInfo))))
typedef UINT32 (*OsInitHook)(VOID);
typedef UINT32 (*OsInitHook)(VOID);//初始化钩子函数
struct ModuleInitInfo {
OsInitHook hook;
struct ModuleInitInfo {//模块初始化信息
OsInitHook hook; //函数指针,钩子函数
#ifdef LOS_INIT_DEBUG
const CHAR *name;
#endif
......@@ -94,14 +94,14 @@ struct ModuleInitInfo {
* @par Dependency:
* <ul><li>los_task_info.h: the header file that contains the API declaration.</li></ul>
* @see
*/
*/ //将注册模块添加到启动框架中的指定级别。
#define OS_INIT_HOOK_REG(_type, _hook, _level) \
STATIC const struct ModuleInitInfo ModuleInitInfo_##_hook \
USED INIT_SECTION(_type, _level, _hook) INIT_ALIGN = { \
.hook = (UINT32 (*)(VOID))&_hook, \
SET_MODULE_NAME(_hook) \
};
//注册到 .rodata.init.
#define EXTERN_LABEL(_type, _level) extern struct ModuleInitInfo __##_type##_init_level_##_level;
#define GET_LABEL(_type, _level) &__##_type##_init_level_##_level,
......
......@@ -194,7 +194,7 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
STATIC const struct file_operations_vfs g_serialDevOps = {
SerialOpen, /* open */
SerialClose, /* close */
......@@ -208,7 +208,7 @@ STATIC const struct file_operations_vfs g_serialDevOps = {
#endif
NULL,
};
//虚拟串口初始化
INT32 virtual_serial_init(const CHAR *deviceName)
{
INT32 ret;
......
git add -A
git commit -m '对控制台(console)实现注解
git commit -m '对控制台,环形缓存区,虚拟串口实现注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
国内:https://weharmony.21cloudbox.com
国外:https://weharmony.github.io
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册