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

http://weharmonyos.com/doxygen/index.html ,支持doxygen

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    博客输出站点(国内):http://weharmonyos.com
    博客输出站点(国外):https://weharmony.github.io
    注解文件系统:https://gitee.com/weharmony/third_party_NuttX
    注解协议栈:https://gitee.com/weharmony/third_party_lwip
    注解编译子系统:https://gitee.com/weharmony/build_lite
上级 46e86676
......@@ -61,48 +61,51 @@
#ifdef LOSCFG_FS_VFS
#include "console.h"
#endif
/**@file los_swtmr.c
/**
* @file los_exc.c
* @brief 软定时器主文件
* @details
* @attention 基本概念 \n
异常接管是操作系统对运行期间发生的异常情况(芯片硬件异常)进行处理的一系列动作,\n\n
例如打印异常发生时当前函数的调用栈信息、CPU现场信息、任务的堆栈情况等。\n
* @attention @verbatim
基本概念
异常接管是操作系统对运行期间发生的异常情况(芯片硬件异常)进行处理的一系列动作,
例如打印异常发生时当前函数的调用栈信息、CPU现场信息、任务的堆栈情况等。
异常接管作为一种调测手段,可以在系统发生异常时给用户提供有用的异常信息,譬如异常类型、\n
发生异常时的系统状态等,方便用户定位分析问题。\n
异常接管作为一种调测手段,可以在系统发生异常时给用户提供有用的异常信息,譬如异常类型、
发生异常时的系统状态等,方便用户定位分析问题。
异常接管,在系统发生异常时的处理动作为:显示异常发生时正在运行的任务信息 \n
(包括任务名、任务号、堆栈大小等),以及CPU现场等信息。 \n
异常接管,在系统发生异常时的处理动作为:显示异常发生时正在运行的任务信息
(包括任务名、任务号、堆栈大小等),以及CPU现场等信息。
运作机制 \n
每个函数都有自己的栈空间,称为栈帧。调用函数时,会创建子函数的栈帧, \n
同时将函数入参、局部变量、寄存器入栈。栈帧从高地址向低地址生长。 \n
运作机制
每个函数都有自己的栈空间,称为栈帧。调用函数时,会创建子函数的栈帧,
同时将函数入参、局部变量、寄存器入栈。栈帧从高地址向低地址生长。
以ARM32 CPU架构为例,每个栈帧中都会保存PC、LR、SP和FP寄存器的历史值。 \n
ARM处理器中的R13被用作SP \n
堆栈分析 \n
LR寄存器(Link Register),链接寄存器,指向函数的返回地址。 \n
R11:可以用作通用寄存器,在开启特定编译选项时可以用作帧指针寄存器FP,用来实现栈回溯功能。 \n
GNU编译器(gcc)默认将R11作为存储变量的通用寄存器,因而默认情况下无法使用FP的栈回溯功能。 \n
为支持调用栈解析功能,需要在编译参数中添加-fno-omit-frame-pointer选项,提示编译器将R11作为FP使用。 \n
FP寄存器(Frame Point),帧指针寄存器,指向当前函数的父函数的栈帧起始地址。利用该寄存器可以得到父函数的栈帧, \n
从栈帧中获取父函数的FP,就可以得到祖父函数的栈帧,以此类推,可以追溯程序调用栈,得到函数间的调用关系。 \n
当系统发生异常时,系统打印异常函数的栈帧中保存的寄存器内容,以及父函数、祖父函数的 \n
栈帧中的LR、FP寄存器内容,用户就可以据此追溯函数间的调用关系,定位异常原因。 \n
异常接管对系统运行期间发生的芯片硬件异常进行处理,不同芯片的异常类型存在差异,具体异常类型可以查看芯片手册。 \n
以ARM32 CPU架构为例,每个栈帧中都会保存PC、LR、SP和FP寄存器的历史值。
ARM处理器中的R13被用作SP
堆栈分析
LR寄存器(Link Register),链接寄存器,指向函数的返回地址。
R11:可以用作通用寄存器,在开启特定编译选项时可以用作帧指针寄存器FP,用来实现栈回溯功能。
GNU编译器(gcc)默认将R11作为存储变量的通用寄存器,因而默认情况下无法使用FP的栈回溯功能。
为支持调用栈解析功能,需要在编译参数中添加-fno-omit-frame-pointer选项,提示编译器将R11作为FP使用。
FP寄存器(Frame Point),帧指针寄存器,指向当前函数的父函数的栈帧起始地址。利用该寄存器可以得到父函数的栈帧,
从栈帧中获取父函数的FP,就可以得到祖父函数的栈帧,以此类推,可以追溯程序调用栈,得到函数间的调用关系。
当系统发生异常时,系统打印异常函数的栈帧中保存的寄存器内容,以及父函数、祖父函数的
栈帧中的LR、FP寄存器内容,用户就可以据此追溯函数间的调用关系,定位异常原因。
异常接管对系统运行期间发生的芯片硬件异常进行处理,不同芯片的异常类型存在差异,具体异常类型可以查看芯片手册。
异常接管一般的定位步骤如下: \n
打开编译后生成的镜像反汇编(asm)文件。 \n
搜索PC指针(指向当前正在执行的指令)在asm中的位置,找到发生异常的函数。 \n
根据LR值查找异常函数的父函数。 \n
重复步骤3,得到函数间的调用关系,找到异常原因。 \n
异常接管一般的定位步骤如下:
打开编译后生成的镜像反汇编(asm)文件。
搜索PC指针(指向当前正在执行的指令)在asm中的位置,找到发生异常的函数。
根据LR值查找异常函数的父函数。
重复步骤3,得到函数间的调用关系,找到异常原因。
注意事项 \n
要查看调用栈信息,必须添加编译选项宏-fno-omit-frame-pointer支持stack frame,否则编译时FP寄存器是关闭的。 \n
注意事项
要查看调用栈信息,必须添加编译选项宏-fno-omit-frame-pointer支持stack frame,否则编译时FP寄存器是关闭的。
参考 \n
参考
http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/%E7%94%A8%E6%88%B7%E6%80%81%E5%BC%82%E5%B8%B8%E4%BF%A1%E6%81%AF%E8%AF%B4%E6%98%8E.html
* @endverbatim
*/
#ifdef LOSCFG_BLACKBOX
......
......@@ -130,24 +130,29 @@ int osShellCmdDoChdir(const char *path)
return 0;
}
/*******************************************************
命令功能
ls命令用来显示当前目录的内容。
命令格式
ls [path]
path为空时,显示当前目录的内容。
path为无效文件名时,显示失败,提示:
ls error: No such directory。
path为有效目录路径时,会显示对应目录下的内容。
使用指南
ls命令显示当前目录的内容。
ls可以显示文件的大小。
proc下ls无法统计文件大小,显示为0。
*******************************************************/
/**
* @brief
* @verbatim
命令功能
ls命令用来显示当前目录的内容。
命令格式
ls [path]
path为空时,显示当前目录的内容。
path为无效文件名时,显示失败,提示:
ls error: No such directory。
path为有效目录路径时,会显示对应目录下的内容。
使用指南
ls命令显示当前目录的内容。
ls可以显示文件的大小。
proc下ls无法统计文件大小,显示为0。
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdLs(int argc, const char **argv)
{
char *fullpath = NULL;
......@@ -176,22 +181,27 @@ int osShellCmdLs(int argc, const char **argv)
return 0;
}
/*******************************************************
命令功能
cd命令用来改变当前目录。
命令格式
cd [path]
未指定目录参数时,会跳转至根目录。
cd后加路径名时,跳转至该路径。
路径名以 /(斜杠)开头时,表示根目录。
.(点)表示当前目录。
..(点点)表示父目录。
cd ..
*******************************************************/
/**
* @brief
* @verbatim
命令功能
cd命令用来改变当前目录。
命令格式
cd [path]
未指定目录参数时,会跳转至根目录。
cd后加路径名时,跳转至该路径。
路径名以 /(斜杠)开头时,表示根目录。
.(点)表示当前目录。
..(点点)表示父目录。
cd ..
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdCd(int argc, const char **argv)
{
if (argc == 0)//没有参数时 #cd
......@@ -209,7 +219,10 @@ int osShellCmdCd(int argc, const char **argv)
#define CAT_TASK_PRIORITY 10
#define CAT_TASK_STACK_SIZE 0x3000
pthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER;
/*******************************************************
/**
* @brief
* @verbatim
cat用于显示文本文件的内容。
命令格式
......@@ -220,7 +233,10 @@ cat用于显示文本文件的内容。
使用实例
举例:cat harmony.txt
*******************************************************/
* @endverbatim
* @param arg
* @return int
*/
int osShellCmdDoCatShow(UINTPTR arg) //shellcmd_cat 任务实现
{
int ret = 0;
......@@ -278,10 +294,10 @@ out:
(void)pthread_mutex_unlock(&g_mutex_cat);
return ret;
}
/*****************************************************************
/*!
cat用于显示文本文件的内容。cat [pathname]
cat weharmony.txt
*****************************************************************/
*/
int osShellCmdCat(int argc, const char **argv)
{
char *fullpath = NULL;
......@@ -365,21 +381,28 @@ static inline void print_mount_usage(void)//mount 用法
{
PRINTK("mount [DEVICE] [PATH] [NAME]\n");
}
/*****************************************************************
命令功能
mount命令用来将设备挂载到指定目录。
命令格式
mount <device> <path> <name> [uid gid]
device 要挂载的设备(格式为设备所在路径)。系统拥有的设备。
path 指定目录。用户必须具有指定目录中的执行(搜索)许可权。N/A
name 文件系统的种类。 vfat, yaffs, jffs, ramfs, nfs,procfs, romfs.
uid gid uid是指用户ID。 gid是指组ID。可选参数,缺省值uid:0,gid:0。
使用指南
mount后加需要挂载的设备信息、指定目录以及设备文件格式,就能成功挂载文件系统到指定目录。
使用实例
举例:mount /dev/mmcblk0p0 /bin/vs/sd vfat
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
mount命令用来将设备挂载到指定目录。
命令格式
mount <device> <path> <name> [uid gid]
device 要挂载的设备(格式为设备所在路径)。系统拥有的设备。
path 指定目录。用户必须具有指定目录中的执行(搜索)许可权。N/A
name 文件系统的种类。 vfat, yaffs, jffs, ramfs, nfs,procfs, romfs.
uid gid uid是指用户ID。 gid是指组ID。可选参数,缺省值uid:0,gid:0。
使用指南
mount后加需要挂载的设备信息、指定目录以及设备文件格式,就能成功挂载文件系统到指定目录。
使用实例
举例:mount /dev/mmcblk0p0 /bin/vs/sd vfat
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdMount(int argc, const char **argv)
{
int ret;
......@@ -512,18 +535,25 @@ int osShellCmdMount(int argc, const char **argv)
free(fullpath);
return 0;
}
/*****************************************************************
命令功能
umount命令用来卸载指定文件系统。
命令格式
umount [dir]
参数说明
dir 需要卸载文件系统对应的目录。 系统已挂载的文件系统的目录。
使用指南
umount后加上需要卸载的指定文件系统的目录,即将指定文件系统卸载。
使用实例
举例:mount /bin/vs/sd
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
umount命令用来卸载指定文件系统。
命令格式
umount [dir]
参数说明
dir 需要卸载文件系统对应的目录。 系统已挂载的文件系统的目录。
使用指南
umount后加上需要卸载的指定文件系统的目录,即将指定文件系统卸载。
使用实例
举例:mount /bin/vs/sd
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdUmount(int argc, const char **argv)
{
int ret;
......@@ -571,20 +601,27 @@ int osShellCmdUmount(int argc, const char **argv)
PRINTK("umount ok\n");
return 0;
}
/*****************************************************************
命令功能
mkdir命令用来创建一个目录。
命令格式
mkdir [directory]
参数说明
directory 需要创建的目录。
使用指南
mkdir后加所需要创建的目录名会在当前目录下创建目录。
mkdir后加路径,再加上需要创建的目录名,即在指定目录下创建目录。
使用实例
举例:mkdir harmony
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
mkdir命令用来创建一个目录。
命令格式
mkdir [directory]
参数说明
directory 需要创建的目录。
使用指南
mkdir后加所需要创建的目录名会在当前目录下创建目录。
mkdir后加路径,再加上需要创建的目录名,即在指定目录下创建目录。
使用实例
举例:mkdir harmony
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdMkdir(int argc, const char **argv)
{
int ret;
......@@ -610,15 +647,22 @@ int osShellCmdMkdir(int argc, const char **argv)
free(fullpath);
return 0;
}
/*****************************************************************
命令功能
pwd命令用来显示当前路径。
命令格式
使用指南
pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / (斜线)分隔。
第一个 / 表示根目录, 最后一个目录是当前目录。
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
pwd命令用来显示当前路径。
命令格式
使用指南
pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / (斜线)分隔。
第一个 / 表示根目录, 最后一个目录是当前目录。
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdPwd(int argc, const char **argv)
{
char buf[SHOW_MAX_LEN] = {0};
......@@ -661,17 +705,24 @@ static inline void print_statfs_usage(void)
PRINTK("Example:\n");
PRINTK(" statfs /ramfs\n");
}
/*****************************************************************
命令功能
statfs 命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。
命令格式
statfs [directory]
参数说明
directory 文件系统的路径。 必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。
使用指南
打印信息因文件系统而异。
以nfs文件系统为例: statfs /nfs
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
statfs 命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。
命令格式
statfs [directory]
参数说明
directory 文件系统的路径。 必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。
使用指南
打印信息因文件系统而异。
以nfs文件系统为例: statfs /nfs
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdStatfs(int argc, const char **argv)
{
struct statfs sfs;
......@@ -713,12 +764,19 @@ int osShellCmdStatfs(int argc, const char **argv)
return 0;
}
/*****************************************************************
touch命令用来在指定的目录下创建一个不存在的空文件。
touch命令操作已存在的文件会成功,不会更新时间戳。touch [filename]
touch命令用来创建一个空文件,该文件可读写。
使用touch命令一次只能创建一个文件。
*****************************************************************/
/**
* @brief
* @verbatim
touch命令用来在指定的目录下创建一个不存在的空文件。
touch命令操作已存在的文件会成功,不会更新时间戳。touch [filename]
touch命令用来创建一个空文件,该文件可读写。
使用touch命令一次只能创建一个文件。
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdTouch(int argc, const char **argv)
{
int ret;
......@@ -751,20 +809,27 @@ int osShellCmdTouch(int argc, const char **argv)
#define CP_BUF_SIZE 4096
pthread_mutex_t g_mutex_cp = PTHREAD_MUTEX_INITIALIZER;
/*****************************************************************
cp 拷贝文件,创建一份副本。
cp [SOURCEFILE] [DESTFILE]
使用指南
同一路径下,源文件与目的文件不能重名。
源文件必须存在,且不为目录。
源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
目的文件不存在时创建新文件,已存在则覆盖。
拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
举例:cp weharmony.txt ./tmp/
*****************************************************************/
/**
* @brief
* @verbatim
cp 拷贝文件,创建一份副本。
cp [SOURCEFILE] [DESTFILE]
使用指南
同一路径下,源文件与目的文件不能重名。
源文件必须存在,且不为目录。
源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
目的文件不存在时创建新文件,已存在则覆盖。
拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
举例:cp weharmony.txt ./tmp/
* @endverbatim
* @param argc
* @param argv
* @return int
*/
static int os_shell_cmd_do_cp(const char *src_filepath, const char *dst_filename)
{
int ret;
......@@ -1282,29 +1347,36 @@ closedir_out:
(void)closedir(d);
return VFS_ERROR;
}
/*****************************************************************
命令功能
拷贝文件,创建一份副本。
命令格式
cp [SOURCEFILE] [DESTFILE]
SOURCEFILE - 源文件路径。- 目前只支持文件,不支持目录。
DESTFILE - 目的文件路径。 - 支持目录以及文件。
使用指南
同一路径下,源文件与目的文件不能重名。
源文件必须存在,且不为目录。
源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
目的文件不存在时创建新文件,已存在则覆盖。
拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
使用实例
举例:cp harmony.txt ./tmp/
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
拷贝文件,创建一份副本。
命令格式
cp [SOURCEFILE] [DESTFILE]
SOURCEFILE - 源文件路径。- 目前只支持文件,不支持目录。
DESTFILE - 目的文件路径。 - 支持目录以及文件。
使用指南
同一路径下,源文件与目的文件不能重名。
源文件必须存在,且不为目录。
源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
目的文件不存在时创建新文件,已存在则覆盖。
拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
使用实例
举例:cp harmony.txt ./tmp/
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdCp(int argc, const char **argv)
{
int ret;
......@@ -1471,24 +1543,31 @@ int osShellCmdRm(int argc, const char **argv)
free(fullpath);
return 0;
}
/*******************************************************
命令功能
rmdir命令用来删除一个目录。
命令格式
rmdir [dir]
参数说明
参数 参数说明 取值范围
dir 需要删除目录的名称,删除目录必须为空,支持输入路径。N/A
使用指南
rmdir命令只能用来删除目录。
rmdir一次只能删除一个目录。
rmdir只能删除空目录。
使用实例
举例:输入rmdir dir
*******************************************************/
/**
* @brief
* @verbatim
命令功能
rmdir命令用来删除一个目录。
命令格式
rmdir [dir]
参数说明
参数 参数说明 取值范围
dir 需要删除目录的名称,删除目录必须为空,支持输入路径。N/A
使用指南
rmdir命令只能用来删除目录。
rmdir一次只能删除一个目录。
rmdir只能删除空目录。
使用实例
举例:输入rmdir dir
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdRmdir(int argc, const char **argv)
{
int ret;
......@@ -1522,23 +1601,29 @@ int osShellCmdRmdir(int argc, const char **argv)
return 0;
}
/*****************************************************************
命令功能
sync命令用于同步缓存数据(文件系统的数据)到sd卡。
命令格式
sync
参数说明
无。
使用指南
sync命令用来刷新缓存,当没有sd卡插入时不进行操作。
有sd卡插入时缓存信息会同步到sd卡,成功返回时无显示。
使用实例
举例:输入sync,有sd卡时同步到sd卡,无sd卡时不操作。
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
sync命令用于同步缓存数据(文件系统的数据)到sd卡。
命令格式
sync
参数说明
无。
使用指南
sync命令用来刷新缓存,当没有sd卡插入时不进行操作。
有sd卡插入时缓存信息会同步到sd卡,成功返回时无显示。
使用实例
举例:输入sync,有sd卡时同步到sd卡,无sd卡时不操作。
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdSync(int argc, const char **argv)
{
ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: sync\n"), return -1);
......@@ -1546,25 +1631,32 @@ int osShellCmdSync(int argc, const char **argv)
sync();
return 0;
}
/*****************************************************************
命令功能
lsfd命令用来显示当前已经打开的系统文件描述符及对应的文件名。
命令格式
lsfd
使用指南
lsfd命令显示当前已经打开文件的fd号以及文件的名字。
使用实例
举例:输入lsfd,注意这里并不显示 (0 ~ 2)号
OHOS #lsfd
fd filename
3 /dev/console1
4 /dev/spidev1.0
5 /bin/init
6 /bin/shell
*****************************************************************/
/**
* @brief
* @verbatim
命令功能
lsfd命令用来显示当前已经打开的系统文件描述符及对应的文件名。
命令格式
lsfd
使用指南
lsfd命令显示当前已经打开文件的fd号以及文件的名字。
使用实例
举例:输入lsfd,注意这里并不显示 (0 ~ 2)号
OHOS #lsfd
fd filename
3 /dev/console1
4 /dev/spidev1.0
5 /bin/init
6 /bin/shell
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdLsfd(int argc, const char **argv)
{
ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: lsfd\n"), return -1);
......@@ -1598,13 +1690,20 @@ int checkNum(const char *arg)
}
#ifdef LOSCFG_KERNEL_SYSCALL
/*****************************************************************
shell su 用于变更为其他使用者的身份
su [uid] [gid]
su命令缺省切换到root用户,uid默认为0,gid为0。
在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。
输入参数超出范围时,会打印提醒输入正确范围参数。
*****************************************************************/
/**
* @brief
* @verbatim
shell su 用于变更为其他使用者的身份
su [uid] [gid]
su命令缺省切换到root用户,uid默认为0,gid为0。
在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。
输入参数超出范围时,会打印提醒输入正确范围参数。
* @endverbatim
* @param argc
* @param argv
* @return int
*/
int osShellCmdSu(int argc, const char **argv)
{
unsigned int su_uid;
......
......@@ -33,23 +33,25 @@
#include "los_printf.h"
#include "los_toolchain.h" //GCC 编译器的内置函数
/**
* @brief
* @verbatim
基本概念
位操作是指对二进制数的bit位进行操作。程序可以设置某一变量为状态字,状态字中的
每一bit位(标志位)可以具有自定义的含义。
/******************************************************************************
基本概念
位操作是指对二进制数的bit位进行操作。程序可以设置某一变量为状态字,状态字中的
每一bit位(标志位)可以具有自定义的含义。
使用场景
系统提供标志位的置1和清0操作,可以改变标志位的内容,同时还提供获取状态字中标志位
为1的最高位和最低位的功能。用户也可以对系统的寄存器进行位操作。
使用场景
系统提供标志位的置1和清0操作,可以改变标志位的内容,同时还提供获取状态字中标志位
为1的最高位和最低位的功能。用户也可以对系统的寄存器进行位操作。
参考
https://www.geeksforgeeks.org/builtin-functions-gcc-compiler/
******************************************************************************/
参考
https://www.geeksforgeeks.org/builtin-functions-gcc-compiler/
* @endverbatim
*/
#define OS_BITMAP_MASK 0x1FU //
#define OS_BITMAP_WORD_MASK ~0UL
/* find first zero bit starting from LSB */
/*! find first zero bit starting from LSB */
STATIC INLINE UINT16 Ffz(UINTPTR x)
{//__builtin_ffsl: 返回右起第一个1的位置,函数来自 glibc
return __builtin_ffsl(~x) - 1;//从LSB开始查找第一个零位 LSB(最低有效位) 对应 最高有效位(MSB)
......@@ -72,12 +74,17 @@ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));//在对应位上置0
}
/********************************************************
CLZ 用于计算操作数最高端0的个数,这条指令主要用于以下两个场合
  1.计算操作数规范化(使其最高位为1)时需要左移的位数
  2.确定一个优先级掩码中最高优先级
********************************************************/
//获取参数位图中最高位为1的索引位 例如: 00110110 返回 5
/**
* @brief 获取参数位图中最高位为1的索引位 例如: 00110110 返回 5
* @verbatim
CLZ 用于计算操作数最高端0的个数,这条指令主要用于以下两个场合
  1.计算操作数规范化(使其最高位为1)时需要左移的位数
  2.确定一个优先级掩码中最高优先级
* @endverbatim
* @param bitmap
* @return UINT16
*/
UINT16 LOS_HighBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
......
......@@ -59,14 +59,15 @@
* @brief 进程模块主文件
* @details 主要包括进程的创建
* @author openharmony
**********************************************************************************
* @attention
* 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
* 看起来像同时运行,实际上是线程不停切换
* 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行
* 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行)
* 多核CPU线程间可以实现宏观和微观上的并行
* LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
* @verbatim
并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
看起来像同时运行,实际上是线程不停切换
并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行
单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行)
多核CPU线程间可以实现宏观和微观上的并行
LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
@endverbatim
* @par 注解日志:
* <table>
* <tr><th>时间 <th>版本 <th>作者 <th>描述
......
......@@ -29,65 +29,68 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**@file los_swtmr.c
/*!
* @file los_swtmr.c
* @brief 软定时器主文件
* @details
* @attention 基本概念 \n
软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。\n
硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器,\n
软件定时器功能,支持如下特性:\n
创建软件定时器。\n
启动软件定时器。\n
停止软件定时器。\n
删除软件定时器。\n
获取软件定时器剩余Tick数。\n
可配置支持的软件定时器个数。\n
* @attention @verbatim
基本概念
软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。
硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器,
软件定时器功能,支持如下特性:
创建软件定时器。
启动软件定时器。
停止软件定时器。
删除软件定时器。
获取软件定时器剩余Tick数。
可配置支持的软件定时器个数。
运作机制 \n
软件定时器是系统资源,在模块初始化的时候已经分配了一块连续内存。\n
软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,\n
先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先触发的准则。\n
软件定时器以Tick为基本计时单位,当创建并启动一个软件定时器时,Huawei LiteOS会根据 \n
当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。\n
当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时,\n
若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高)\n
被唤醒,在该任务中调用已经记录下来的定时器的回调函数。\n
运作机制
软件定时器是系统资源,在模块初始化的时候已经分配了一块连续内存。
软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,
先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先触发的准则。
软件定时器以Tick为基本计时单位,当创建并启动一个软件定时器时,Huawei LiteOS会根据
当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。
当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时,
若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高)
被唤醒,在该任务中调用已经记录下来的定时器的回调函数。
定时器状态 \n
OS_SWTMR_STATUS_UNUSED(定时器未使用)\n
系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。\n
定时器状态
OS_SWTMR_STATUS_UNUSED(定时器未使用)
系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。
OS_SWTMR_STATUS_TICKING(定时器处于计数状态)\n
在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。\n
OS_SWTMR_STATUS_TICKING(定时器处于计数状态)
在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。
OS_SWTMR_STATUS_CREATED(定时器创建后未启动,或已停止)\n
定时器创建后,不处于计数状态时,定时器将变成该状态。\n
OS_SWTMR_STATUS_CREATED(定时器创建后未启动,或已停止)
定时器创建后,不处于计数状态时,定时器将变成该状态。
软件定时器提供了三类模式:\n
单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。\n
周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。\n
单次触发定时器,但这类定时器超时触发后不会自动删除,需要调用定时器删除接口删除定时器。\n
软件定时器提供了三类模式:
单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。
周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。
单次触发定时器,但这类定时器超时触发后不会自动删除,需要调用定时器删除接口删除定时器。
使用场景 \n
创建一个单次触发的定时器,超时后执行用户自定义的回调函数。\n
创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。\n
使用场景
创建一个单次触发的定时器,超时后执行用户自定义的回调函数。
创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。
软件定时器的典型开发流程 \n
通过make menuconfig配置软件定时器 \n
创建定时器LOS_SwtmrCreate,设置定时器的定时时长、定时器模式、超时后的回调函数。\n
启动定时器LOS_SwtmrStart。\n
获得软件定时器剩余Tick数LOS_SwtmrTimeGet。\n
停止定时器LOS_SwtmrStop。\n
删除定时器LOS_SwtmrDelete。\n
软件定时器的典型开发流程
通过make menuconfig配置软件定时器
创建定时器LOS_SwtmrCreate,设置定时器的定时时长、定时器模式、超时后的回调函数。
启动定时器LOS_SwtmrStart。
获得软件定时器剩余Tick数LOS_SwtmrTimeGet。
停止定时器LOS_SwtmrStop。
删除定时器LOS_SwtmrDelete。
注意事项 \n
软件定时器的回调函数中不应执行过多操作,不建议使用可能引起任务挂起或者阻塞的接口或操作, \n
如果使用会导致软件定时器响应不及时,造成的影响无法确定。\n
软件定时器使用了系统的一个队列和一个任务资源。软件定时器任务的优先级设定为0,且不允许修改 。\n
系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。\n
例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。\n
创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。\n
软件定时器的定时精度与系统Tick时钟的周期有关。\n
注意事项
软件定时器的回调函数中不应执行过多操作,不建议使用可能引起任务挂起或者阻塞的接口或操作,
如果使用会导致软件定时器响应不及时,造成的影响无法确定。
软件定时器使用了系统的一个队列和一个任务资源。软件定时器任务的优先级设定为0,且不允许修改 。
系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。
例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。
创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。
软件定时器的定时精度与系统Tick时钟的周期有关。
@endverbatim
*/
#include "los_swtmr_pri.h"
......
......@@ -32,41 +32,43 @@
#include "los_sys_pri.h"
#include "los_sched_pri.h"
/**@file los_sys.c
/*!
* @file los_sys.c
* @brief 系统时间转化
* @details
* @attention
基本概念 \n
时间管理以系统时钟为基础,给应用程序提供所有和时间有关的服务。\n
* @attention @verbatim
基本概念
时间管理以系统时钟为基础,给应用程序提供所有和时间有关的服务。
系统时钟是由定时器/计数器产生的输出脉冲触发中断产生的,一般定义为整数或长整数。\n
输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。\n
系统时钟是由定时器/计数器产生的输出脉冲触发中断产生的,一般定义为整数或长整数。
输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。
用户以秒、毫秒为单位计时,而操作系统以Tick为单位计时,当用户需要对系统进行操作时,\n
例如任务挂起、延时等,此时需要时间管理模块对Tick和秒/毫秒进行转换。\n
时间管理模块提供时间转换、统计、延迟功能\n
用户以秒、毫秒为单位计时,而操作系统以Tick为单位计时,当用户需要对系统进行操作时,
例如任务挂起、延时等,此时需要时间管理模块对Tick和秒/毫秒进行转换。
时间管理模块提供时间转换、统计、延迟功能
相关概念 \n
Cycle \n
系统最小的计时单位。Cycle的时长由系统主时钟频率决定,系统主时钟频率就是每秒钟的Cycle数。\n
相关概念
Cycle
系统最小的计时单位。Cycle的时长由系统主时钟频率决定,系统主时钟频率就是每秒钟的Cycle数。
Tick \n
Tick是操作系统的基本时间单位,由用户配置的每秒Tick数决定。\n
Tick
Tick是操作系统的基本时间单位,由用户配置的每秒Tick数决定。
使用场景 \n
用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系等。 \n
使用场景
用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系等。
时间管理的典型开发流程 \n
根据实际需求,在板级配置适配时确认是否使能LOSCFG_BASE_CORE_TICK_HW_TIME宏选择外部定时器,\n
并配置系统主时钟频率OS_SYS_CLOCK(单位Hz)。OS_SYS_CLOCK的默认值基于硬件平台配置。\n
通过make menuconfig配置LOSCFG_BASE_CORE_TICK_PER_SECOND。\n
时间管理的典型开发流程
根据实际需求,在板级配置适配时确认是否使能LOSCFG_BASE_CORE_TICK_HW_TIME宏选择外部定时器,
并配置系统主时钟频率OS_SYS_CLOCK(单位Hz)。OS_SYS_CLOCK的默认值基于硬件平台配置。
通过make menuconfig配置LOSCFG_BASE_CORE_TICK_PER_SECOND。
注意事项 \n
时间管理不是单独的功能模块,依赖于OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。\n
系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。\n
注意事项
时间管理不是单独的功能模块,依赖于OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。
系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。
参考 \n
https://gitee.com/LiteOS/LiteOS/blob/master/doc/Huawei_LiteOS_Kernel_Developer_Guide_zh.md#setup\n
参考
https://gitee.com/LiteOS/LiteOS/blob/master/doc/Huawei_LiteOS_Kernel_Developer_Guide_zh.md#setup
@endverbatim
*/
#define OS_MAX_VALUE 0xFFFFFFFFUL
......
......@@ -970,7 +970,16 @@ LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *runTask)
OsSchedResched();//申请调度
return;
}
/**
* @brief 获取参数位图中最高位为1的索引位 例如: 00110110 返回 5
* @verbatim
CLZ 用于计算操作数最高端0的个数,这条指令主要用于以下两个场合
  1.计算操作数规范化(使其最高位为1)时需要左移的位数
  2.确定一个优先级掩码中最高优先级
* @endverbatim
* @param bitmap
* @return UINT16
*/
/*
* Check if needs to do the delete operation on the running task.
* Return TRUE, if needs to do the deletion.
......@@ -980,14 +989,21 @@ LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *runTask)
* 3. Do the deletion in hard-irq
* then LOS_TaskDelete will directly return with 'ret' value.
*/
/****************************************************************
检查是否需要对正在运行的任务执行删除操作,如果需要删除,则返回TRUE。
如果满足以下情况,则返回FALSE:
1.如果启用了SMP,则跨CPU执行删除
2.禁用抢占时执行删除
3.在硬irq中删除
然后LOS_TaskDelete将直接返回ret值
****************************************************************/
/**
* @brief
* @verbatim
检查是否需要对正在运行的任务执行删除操作,如果需要删除,则返回TRUE。
如果满足以下情况,则返回FALSE:
1.如果启用了SMP,则跨CPU执行删除
2.禁用抢占时执行删除
3.在硬irq中删除
然后LOS_TaskDelete将直接返回ret值
* @endverbatim
* @param taskCB
* @param ret
* @return STATIC
*/
STATIC BOOL OsRunTaskToDeleteCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
{
/* init default out return value */
......
......@@ -39,8 +39,10 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/***************************************************** @note_pic
鸿蒙对消息队列图
/**
* @brief @note_pic
* @verbatim
鸿蒙对消息队列图
|<-----消息内容区,有2个消息---->|
+------------+------------------------------------------------------------+
| | |---------------|---------------| |
......@@ -54,17 +56,18 @@ extern "C" {
| |
| |
+<-------------+ 队列长度,消息点个数, +------------->+
* @endverbatim
*/
*****************************************************/
typedef enum {
OS_QUEUE_READ = 0, //读队列
OS_QUEUE_WRITE = 1, //写队列
OS_QUEUE_READ = 0, ///< 读队列
OS_QUEUE_WRITE = 1, ///< 写队列
OS_QUEUE_N_RW = 2
} QueueReadWrite;
typedef enum {
OS_QUEUE_HEAD = 0, //队列头部标识
OS_QUEUE_TAIL = 1 //队列尾部标识
OS_QUEUE_HEAD = 0, ///< 队列头部标识
OS_QUEUE_TAIL = 1 ///< 队列尾部标识
} QueueHeadTail;
#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite))
......@@ -80,6 +83,7 @@ typedef enum {
/**
* @ingroup los_queue
* Queue information block structure
* @attention 读写队列分离
*/
typedef struct {
UINT8 *queueHandle; /**< Pointer to a queue handle */ //指向队列句柄的指针
......@@ -94,7 +98,7 @@ typedef struct {
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
//挂的都是等待读/写消息的任务链表,0表示读消息的链表,1表示写消息的任务链表
LOS_DL_LIST memList; /**< Pointer to the memory linked list */ //@note_why 这里尚未搞明白是啥意思 ,是共享内存吗?
} LosQueueCB;//读写队列分离
} LosQueueCB;
/* queue state */
/**
......
......@@ -65,16 +65,16 @@ __attribute__ ((section(".data"))) UINT32 g_uart_fputc_en = 1;
extern UINT32 g_uart_fputc_en;
STATIC UINT32 ConsoleSendTask(UINTPTR param);
STATIC UINT8 g_taskConsoleIDArray[LOSCFG_BASE_CORE_TSK_LIMIT];//task 控制台ID池,同步task数量,理论上每个task都可以有一个自己的控制台
STATIC SPIN_LOCK_INIT(g_consoleSpin);//初始化控制台自旋锁
STATIC UINT8 g_taskConsoleIDArray[LOSCFG_BASE_CORE_TSK_LIMIT];///< task 控制台ID池,同步task数量,理论上每个task都可以有一个自己的控制台
STATIC SPIN_LOCK_INIT(g_consoleSpin);///< 初始化控制台自旋锁
#define SHELL_ENTRYID_INVALID 0xFFFFFFFF //默认值,SHELL_ENTRYID 一般为 任务ID
#define SHELL_TASK_PRIORITY 9 //shell 的优先级为 9
#define CONSOLE_CIRBUF_EVENT 0x02U //控制台循环buffer事件
#define CONSOLE_SEND_TASK_EXIT 0x04U //控制台发送任务退出事件
#define CONSOLE_SEND_TASK_RUNNING 0x10U //控制台发送任务正在执行事件
#define SHELL_ENTRYID_INVALID 0xFFFFFFFF ///< 默认值,SHELL_ENTRYID 一般为 任务ID
#define SHELL_TASK_PRIORITY 9 ///< shell 的优先级为 9
#define CONSOLE_CIRBUF_EVENT 0x02U ///< 控制台循环buffer事件
#define CONSOLE_SEND_TASK_EXIT 0x04U ///< 控制台发送任务退出事件
#define CONSOLE_SEND_TASK_RUNNING 0x10U ///< 控制台发送任务正在执行事件
CONSOLE_CB *g_console[CONSOLE_NUM];//控制台全局变量,控制台是共用的, 默认为 2个
CONSOLE_CB *g_console[CONSOLE_NUM];///< 控制台全局变量,控制台是共用的, 默认为 2个
#define MIN(a, b) ((a) < (b) ? (a) : (b))
/*
......@@ -372,11 +372,11 @@ STATIC INLINE VOID UserEndOfRead(CONSOLE_CB *consoleCB, struct file *filep,
}
///根据VT终端标准 <ESC>[37m 为设置前景色
enum {
STAT_NOMAL_KEY, //普通按键
STAT_ESC_KEY, //控制按键,只有 ESC 是
STAT_MULTI_KEY //多个按键,只有 [ 是
STAT_NOMAL_KEY, ///< 普通按键
STAT_ESC_KEY, ///< 控制按键,只有 ESC 是
STAT_MULTI_KEY ///< 多个按键,只有 [ 是
};
//用户shell检查上下左右键
///用户shell检查上下左右键
STATIC INT32 UserShellCheckUDRL(const CHAR ch, INT32 *lastTokenType)
{
INT32 ret = LOS_OK;
......
git add -A
git commit -m ' 为支持doxygen,改变注释表达方式.
git commit -m ' http://weharmonyos.com/doxygen/index.html ,支持doxygen
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
博客输出站点(国内):http://weharmonyos.com
博客输出站点(国外):https://weharmony.github.io
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册