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

制作远程登录模型图 https://gitee.com/weharmonyos/resources/raw/master/75/telnet_model.png

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    鸿蒙研究站 | 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)
上级 9a232ce5
......@@ -241,37 +241,37 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
return EINVAL;
}
SetPthreadAttr(self, attr, &userAttr);
SetPthreadAttr(self, attr, &userAttr);//设置线程属性(包括栈信息 ==)
(VOID)snprintf_s(name, sizeof(name), sizeof(name) - 1, "pth%02d", pthreadNumber);
pthreadNumber++;
taskInitParam.pcName = name;
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)startRoutine;
taskInitParam.auwArgs[0] = (UINTPTR)arg;
taskInitParam.usTaskPrio = (UINT16)userAttr.schedparam.sched_priority;
taskInitParam.uwStackSize = userAttr.stacksize;
if (OsProcessIsUserMode(OsCurrProcessGet())) {
taskInitParam.processID = OsGetKernelInitProcessID();
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)startRoutine;//线程入口函数 类似 Java thread 的 run()函数
taskInitParam.auwArgs[0] = (UINTPTR)arg;//参数
taskInitParam.usTaskPrio = (UINT16)userAttr.schedparam.sched_priority;//任务优先级
taskInitParam.uwStackSize = userAttr.stacksize;//栈大小
if (OsProcessIsUserMode(OsCurrProcessGet())) {//@note_thinking 是不是搞反了 ?
taskInitParam.processID = OsGetKernelInitProcessID();//内核进程
} else {
taskInitParam.processID = OsCurrProcessGet()->processID;
taskInitParam.processID = OsCurrProcessGet()->processID;//这里可以看出
}
if (userAttr.detachstate == PTHREAD_CREATE_DETACHED) {
taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED;
taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED;//detached状态的线程,在结束的时候,会自动释放该线程所占用的资源。
} else {
/* Set the pthread default joinable */
taskInitParam.uwResved = LOS_TASK_ATTR_JOINABLE;
}
taskInitParam.uwResved = LOS_TASK_ATTR_JOINABLE;//如果使用 PTHREAD_CREATE_JOINABLE 创建非分离线程,
}//则假设应用程序将等待线程完成。也就是说,程序将对线程执行 pthread_join()。
PthreadReap();
ret = LOS_TaskCreateOnly(&taskHandle, &taskInitParam);
ret = LOS_TaskCreateOnly(&taskHandle, &taskInitParam);//创建线程但不调度
if (ret == LOS_OK) {
*thread = (pthread_t)taskHandle;
ret = InitPthreadData(*thread, &userAttr, name, PTHREAD_DATA_NAME_MAX);
if (ret != LOS_OK) {
goto ERROR_OUT_WITH_TASK;
}
(VOID)LOS_SetTaskScheduler(taskHandle, SCHED_RR, taskInitParam.usTaskPrio);
(VOID)LOS_SetTaskScheduler(taskHandle, SCHED_RR, taskInitParam.usTaskPrio);//设置调度器,等待调度
}
if (ret == LOS_OK) {
......
/*!
* @file los_process.c
* @brief 进程模块主文件
* @link
@verbatim
并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
看起来像同时运行,实际上是线程不停切换
并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行
单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行)
多核CPU线程间可以实现宏观和微观上的并行
LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
@endverbatim
* @version
* @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
* @date 2021-12-15
*/
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
......@@ -55,34 +74,12 @@
#include "los_vm_phys.h"
#include "los_vm_syscall.h"
/**@file los_process.c
* @brief 进程模块主文件
* @details 主要包括进程的创建
* @author openharmony
* @attention
* @verbatim
并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
看起来像同时运行,实际上是线程不停切换
并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行
单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行)
多核CPU线程间可以实现宏观和微观上的并行
LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
@endverbatim
* @par 注解日志:
* <table>
* <tr><th>时间 <th>版本 <th>作者 <th>描述
* <tr><td>2020/09/19 <td>1.0 <td>turing <td>创建初始版本
* </table>
*
**********************************************************************************
*/
LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; ///< 进程池数组
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;///< 空闲状态下的进程链表, .个人觉得应该取名为 g_freeProcessList @note_thinking
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;///< 需要回收的进程列表
LITE_OS_SEC_BSS UINT32 g_userInitProcess = OS_INVALID_VALUE;///< 用户态的初始init进程,用户态下其他进程由它 fork
LITE_OS_SEC_BSS UINT32 g_kernelInitProcess = OS_INVALID_VALUE;///< 内核态初始Kprocess进程,内核态下其他进程由它 fork
LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess = OS_INVALID_VALUE;///< 内核态idle进程,由Kprocess fork
LITE_OS_SEC_BSS UINT32 g_userInitProcess = OS_INVALID_VALUE;///< 1号进程 用户态的初始init进程,用户态下其他进程由它 fork
LITE_OS_SEC_BSS UINT32 g_kernelInitProcess = OS_INVALID_VALUE;///< 2号进程 内核态初始Kprocess进程,内核态下其他进程由它 fork
LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess = OS_INVALID_VALUE;///< 0号进程 内核态idle进程,由Kprocess fork
LITE_OS_SEC_BSS UINT32 g_processMaxNum;///< 进程最大数量,默认64个
LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;///< 全局进程组,负责管理所有进程组
......@@ -160,7 +157,7 @@ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
if (g_processGroup->groupID == gid) {
return g_processGroup;
}
//变量进程组
LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
if (group->groupID == gid) {
return group;
......
......@@ -383,11 +383,11 @@ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID)
UINT32 intSave;
intSave = LOS_IntLock();
LosProcessCB *runProcess = (LosProcessCB *)OsPercpuGet()->runProcess;
LosProcessCB *runProcess = (LosProcessCB *)OsPercpuGet()->runProcess;//当前CPU正在运行的进程
LOS_IntRestore(intSave);
return runProcess;
}
/// 设置当前进程
STATIC INLINE VOID OsCurrProcessSet(const LosProcessCB *process)
{
OsPercpuGet()->runProcess = (UINTPTR)process;
......
......@@ -484,7 +484,8 @@ typedef VOID *(*TSK_ENTRY_FUNC)(UINTPTR param1,
/**
* @ingroup los_task
* You are not allowed to add any fields and adjust fields to the structure
* You are not allowed to add any fields and adjust fields to the structure
| 不允许在结构中添加任何字段和调整字段 @note_thinking 为什么呢 ?
*/
typedef struct {//用户态栈信息,(按递减满栈方式注解)
UINTPTR userArea; ///< 用户空间的堆区开始位置
......@@ -504,7 +505,7 @@ typedef struct tagTskInitParam {//Task的初始化参数
UINT16 usTaskPrio; /**< Task priority | 任务优先级*/
UINT16 policy; /**< Task policy | 任务调度方式*/
UINTPTR auwArgs[4]; /**< Task parameters, of which the maximum number is four | 入口函数的参数,最多四个*/
UINT32 uwStackSize; /**< Task stack size | 内核栈大小*/
UINT32 uwStackSize; /**< Task stack size | 栈大小*/
CHAR *pcName; /**< Task name | 任务名称*/
#ifdef LOSCFG_KERNEL_SMP
UINT16 usCpuAffiMask; /**< Task cpu affinity mask | 任务cpu亲和力掩码 */
......@@ -513,7 +514,7 @@ typedef struct tagTskInitParam {//Task的初始化参数
It is unable to be deleted if set to 0. | 如果设置为LOS_TASK_STATUS_DETACHED,则自动删除。如果设置为0,则无法删除*/
UINT16 consoleID; /**< The console id of task belongs | 任务的控制台id所属*/
UINT32 processID; ///< 进程ID
UserTaskParam userParam; ///< 任务用户态运行时参数
UserTaskParam userParam; ///< 任务用户态运行时任何参数
} TSK_INIT_PARAM_S;
/**
......
......@@ -150,7 +150,7 @@ STATIC volatile INT32 g_telnetListenFd = -1; /* listen fd of telnetd | 服务
/* each bit for a client connection, although only support 1 connection for now */
STATIC volatile UINT32 g_telnetMask = 0; //记录有任务打开了远程登录
/* taskID of telnetd */
STATIC atomic_t g_telnetTaskId = 0; ///< 任务ID
STATIC atomic_t g_telnetTaskId = 0; ///< telnet 服务端任务ID
/* protect listenFd, clientFd etc. */
pthread_mutex_t g_telnetMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
......@@ -370,19 +370,19 @@ STATIC INT32 TelnetClientPrepare(INT32 clientFd)
return -1;
}
g_telnetClientFd = clientFd;
if (TelnetDevInit(clientFd) != 0) {
if (TelnetDevInit(clientFd) != 0) {//远程登录设备初始化
g_telnetClientFd = -1;
return -1;
}
g_telnetMask = 1;//表示有任务在远程登录
/* negotiate with client */
/* negotiate with client | 与客户协商*/
(VOID)WriteToFd(clientFd, (CHAR *)doEcho, sizeof(doEcho));
(VOID)WriteToFd(clientFd, (CHAR *)doNaws, sizeof(doNaws));
(VOID)WriteToFd(clientFd, (CHAR *)willEcho, sizeof(willEcho));
(VOID)WriteToFd(clientFd, (CHAR *)willSga, sizeof(willSga));
/* enable TCP keepalive to check whether telnet link is alive */
/* enable TCP keepalive to check whether telnet link is alive | 设置保持连接的方式 */
if (setsockopt(clientFd, SOL_SOCKET, SO_KEEPALIVE, (VOID *)&keepAlive, sizeof(keepAlive)) < 0) {
PRINT_ERR("telnet setsockopt SO_KEEPALIVE error.\n");
}
......@@ -486,7 +486,7 @@ STATIC VOID *TelnetClientLoop(VOID *arg)
}
cmdBuf = ReadFilter(buf, (UINT32)nRead, &len);//对数据过滤
if (len > 0) {
(VOID)TelnetTx((CHAR *)cmdBuf, len);//数据加工处理
(VOID)TelnetTx((CHAR *)cmdBuf, len);//数据加工处理
}
}
}
......@@ -535,7 +535,7 @@ STATIC INT32 TelnetdAcceptClient(INT32 clientFd, const struct sockaddr_in *inTel
goto ERROUT_UNLOCK;
}
if (g_telnetClientFd >= 0) {
if (g_telnetClientFd >= 0) { //只接收一个客户端
/* alreay connected and support only one */
goto ERROUT_UNLOCK;
}
......@@ -571,7 +571,7 @@ STATIC VOID TelnetdAcceptLoop(INT32 listenFd)
TelnetLock();
g_telnetListenFd = listenFd;
while (g_telnetListenFd >= 0) {
while (g_telnetListenFd >= 0) {//必须启动监听
TelnetUnlock();
(VOID)memset_s(&inTelnetAddr, sizeof(inTelnetAddr), 0, sizeof(inTelnetAddr));
......@@ -580,8 +580,10 @@ STATIC VOID TelnetdAcceptLoop(INT32 listenFd)
/*
* Sleep sometime before next loop: mostly we already have one connection here,
* and the next connection will be declined. So don't waste our cpu.
| 在下一个循环来临之前休息片刻,因为鸿蒙只支持一个远程登录,此时已经有一个链接,
在TelnetdAcceptClient中创建线程不会立即调度, 休息下任务会挂起,重新调度
*/
LOS_Msleep(TELNET_ACCEPT_INTERVAL);
LOS_Msleep(TELNET_ACCEPT_INTERVAL);//以休息的方式发起调度. 直接申请调度也未尝不可吧 @note_thinking
} else {
return;
}
......@@ -615,7 +617,7 @@ STATIC INT32 TelnetdMain(VOID)
}
//2.注册
TelnetLock();
ret = TelnetedRegister();//注册驱动程序,ops
ret = TelnetedRegister();//注册驱动程序 /dev/telnet ,ops
TelnetUnlock();
if (ret != 0) {
......@@ -623,7 +625,7 @@ STATIC INT32 TelnetdMain(VOID)
(VOID)close(sock);
return -1;
}
//3.接收
//3.等待连接,处理远程终端过来的命令 例如#task 命令
PRINTK("start telnet server successfully, waiting for connection.\n");
TelnetdAcceptLoop(sock);
return 0;
......
git add -A
git commit -m ' 深挖串口,UART驱动实现过程
git commit -m ' 制作远程登录模型图 https://gitee.com/weharmonyos/resources/raw/master/75/telnet_model.png
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册