对Percpu 注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    国内:https://weharmony.21cloudbox.com
    国外:https://weharmony.github.io
上级 acb38f8a
......@@ -75,7 +75,7 @@
#define lwip_recvfrom recvfrom
#define IPADDR_NONE INADDR_NONE
#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) //对应就是 chmod = 666
#define SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) \
int main(int argc, const char **argv) \
......
../../../../../../../../third_party/Linux_Kernel/fs/jffs2/mtd.h
\ No newline at end of file
../../../../../../../../third_party/Linux_Kernel/fs/jffs2/mtd.h
../../../../../third_party/NuttX/include/nuttx/fs/file.h
\ No newline at end of file
../../../../../third_party/NuttX/include/nuttx/fs/file.h
......@@ -288,7 +288,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
LOS_TraceReg(LOS_TRACE_TASK, OsTaskTrace, LOS_TRACE_TASK_NAME, LOS_TRACE_ENABLE);
#endif
ret = OsSchedInit();
ret = OsSchedInit();//调度器初始化
EXIT:
if (ret != LOS_OK) {
......
......@@ -50,23 +50,26 @@ typedef enum {
CPU_EXC /* cpu in the exc */ //CPU处于异常状态
} ExcFlag;
#endif
/*
* per-CPU变量是linux系统一个非常有趣的特性,它为系统中的每个处理器都分配了该变量的副本。
* 这样做的好处是,在多处理器系统中,当处理器操作属于它的变量副本时,不需要考虑与其他处理器的竞争的问题,
*/
typedef struct {//内核对cpu的描述
SortLinkAttribute taskSortLink; /* task sort link */ //挂等待和延时的任务
SPIN_LOCK_S taskSortLinkSpin; /* task sort link spin lock */
SortLinkAttribute swtmrSortLink; /* swtmr sort link */
SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock */
UINT64 responseTime; /* Response time for current nuclear Tick interrupts */
UINT32 responseID; /* The response ID of the current nuclear TICK interrupt */
SPIN_LOCK_S taskSortLinkSpin; /* task sort link spin lock *///操作taskSortLink链表的自旋锁
SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //挂还没到时间的定时器
SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock *///操作swtmrSortLink链表的自旋锁
UINT64 responseTime; /* Response time for current nuclear Tick interrupts *///当前CPU核 Tick 中断的响应时间
UINT32 responseID; /* The response ID of the current nuclear TICK interrupt *///当前CPU核TICK中断的响应ID
UINTPTR runProcess; /* The address of the process control block pointer to which
the current kernel is running */
the current kernel is running *///当前进程控制块地址
UINT32 idleTaskID; /* idle task id */ //每个CPU都有一个空闲任务 见于 OsIdleTaskCreate
UINT32 taskLockCnt; /* task lock flag */ //任务锁的数量,当 > 0 的时候,需要重新调度了
UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ //软时钟超时队列句柄
UINT32 swtmrTaskID; /* software timer task id */ //软时钟任务ID
UINT32 schedFlag; /* pending scheduler flag */ //调度标识 INT_NO_RESCH INT_PEND_RESCH
#if (LOSCFG_KERNEL_SMP == YES)
UINT32 excFlag; /* cpu halt or exc flag */
UINT32 excFlag; /* cpu halt or exc flag *///cpu 停止或 异常 标志
#endif
} Percpu;
......
......@@ -59,22 +59,22 @@
#define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN)
#define OS_SCHED_READY_MAX 30
#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */
#define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(OS_64BIT_MAX - 1U)
#define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(OS_64BIT_MAX - 1U) //调度最大响应时间
typedef struct {
LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];
UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM];
UINT32 queueBitmap;
typedef struct {//进程调度队列
LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];//各优先级任务调度队列,默认32级
UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM];//各优先级就绪任务个数
UINT32 queueBitmap;//任务优先级调度位图
} SchedQueue;
typedef struct {
SchedQueue queueList[OS_PRIORITY_QUEUE_NUM];
UINT32 queueBitmap;
SchedScan taskScan;
SchedScan swtmrScan;
typedef struct {//调度器
SchedQueue queueList[OS_PRIORITY_QUEUE_NUM];//进程优先级调度队列,默认32级
UINT32 queueBitmap;//进程优先级调度位图
SchedScan taskScan;//函数指针,扫描任务
SchedScan swtmrScan;//函数指针,扫描定时器
} Sched;
STATIC Sched *g_sched = NULL;
STATIC Sched *g_sched = NULL;//全局调度器
STATIC UINT64 g_schedTickMaxResponseTime;
UINT64 g_sysSchedStartTime = 0;
......@@ -770,39 +770,39 @@ UINT32 OsSchedSwtmrScanRegister(SchedScan func)
g_sched->swtmrScan = func;
return LOS_OK;
}
//调度初始化
UINT32 OsSchedInit(VOID)
{
UINT16 index, pri;
UINT32 ret;
g_sched = (Sched *)LOS_MemAlloc(m_aucSysMem0, sizeof(Sched));
g_sched = (Sched *)LOS_MemAlloc(m_aucSysMem0, sizeof(Sched));//分配调度器内存
if (g_sched == NULL) {
return LOS_ERRNO_TSK_NO_MEMORY;
}
(VOID)memset_s(g_sched, sizeof(Sched), 0, sizeof(Sched));
for (index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) {
for (index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) {//初始化进程优先级队列
SchedQueue *queueList = &g_sched->queueList[index];
LOS_DL_LIST *priList = &queueList->priQueueList[0];
LOS_DL_LIST *priList = &queueList->priQueueList[0];//每个进程优先级都有同样的任务优先级链表
for (pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) {
LOS_ListInit(&priList[pri]);
LOS_ListInit(&priList[pri]);//初始化任务优先级链表节点
}
}
for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
Percpu *cpu = OsPercpuGetByID(index);
ret = OsSortLinkInit(&cpu->taskSortLink);
for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {//初始化每个CPU核
Percpu *cpu = OsPercpuGetByID(index);//获取某个CPU信息
ret = OsSortLinkInit(&cpu->taskSortLink);//初始化任务排序链表
if (ret != LOS_OK) {
return LOS_ERRNO_TSK_NO_MEMORY;
}
cpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
LOS_SpinInit(&cpu->taskSortLinkSpin);
LOS_SpinInit(&cpu->swtmrSortLinkSpin);
LOS_SpinInit(&cpu->taskSortLinkSpin);//自旋锁初始化
LOS_SpinInit(&cpu->swtmrSortLinkSpin);//操作具体CPU核定时器排序链表
}
g_sched->taskScan = OsSchedScanTimerList;
g_sched->taskScan = OsSchedScanTimerList;//
#ifdef LOSCFG_SCHED_TICK_DEBUG
ret = OsSchedDebugInit();
......
......@@ -77,21 +77,21 @@ STATIC INT32 g_alignSize = 0;
#define VFAT_STORAGE_MOUNT_DIR_MODE 0777
#define DEFAULT_STORAGE_MOUNT_DIR_MODE 0755
#ifdef LOSCFG_DRIVERS_MMC
los_disk *GetMmcDisk(UINT8 type)
#ifdef LOSCFG_DRIVERS_MMC //mmc代表的是磁盘
los_disk *GetMmcDisk(UINT8 type)//type值( EMMC |
{
const CHAR *mmcDevHead = "/dev/mmcblk";
for (INT32 diskId = 0; diskId < SYS_MAX_DISK; diskId++) {
for (INT32 diskId = 0; diskId < SYS_MAX_DISK; diskId++) {//默认最大支持5块磁盘
los_disk *disk = get_disk(diskId);
if (disk == NULL) {
continue;
} else if (disk->disk_name == NULL) {
continue;
} else if (strncmp(disk->disk_name, mmcDevHead, strlen(mmcDevHead))) {
} else if (strncmp(disk->disk_name, mmcDevHead, strlen(mmcDevHead))) {//例如 /dev/mmcblk0p2 就符合要求
continue;
} else {
if (disk->type == type) {
if (disk->type == type) {//
return disk;
}
}
......@@ -237,7 +237,7 @@ STATIC INT32 GetArgs(CHAR **args)
}
#ifdef LOSCFG_STORAGE_EMMC
g_emmcDisk = GetMmcDisk(EMMC);
g_emmcDisk = GetMmcDisk(EMMC);//获取磁盘信息
if (g_emmcDisk == NULL) {
PRINT_ERR("Get EMMC disk failed!\n");
goto ERROUT;
......@@ -422,12 +422,12 @@ ERROUT:
#endif
#ifdef LOSCFG_STORAGE_EMMC
STATIC VOID OsMountUserdata(const CHAR *fsType)//mount emmc /userdata
STATIC VOID OsMountUserdata(const CHAR *fsType)//mount emmc /userdata 用户数据目录
{
INT32 ret;
INT32 err;
const CHAR *userdataDir = "/userdata";
ret = mkdir(userdataDir, VFAT_STORAGE_MOUNT_DIR_MODE);
ret = mkdir(userdataDir, VFAT_STORAGE_MOUNT_DIR_MODE);//创建/userdata 目录
if ((ret != LOS_OK) && ((err = get_errno()) != EEXIST)) {
PRINT_ERR("Failed to mkdir /userdata, errno %d: %s\n", err, strerror(err));
return;
......
......@@ -39,7 +39,7 @@ https://blog.csdn.net/tankai19880619/article/details/12093239
等都以文件被对待;他们具体的类型及其操作不同,但需要向上层提供统一的操作接口。
虚拟文件系统VFS就是内核中的一个软件层,向上给用户空间程序提供文件系统操作接口;
向下允许不同的文件系统共存。所以,所有实际文件系统都必须实现VFS的结构封装。
系统中任何文件系统的挂载必须满足两个条件:挂载点和文件系统。
系统中任何文件系统的支持必须满足两个条件:挂载点和文件系统。
rootfs是基于内存的文件系统,所有操作都在内存中完成;也没有实际的存储设备,所以不需要设备驱动程序的参与.
只在启动阶段使用rootfs文件系统,当磁盘驱动程序和磁盘文件系统成功加载后,系统会将系统根目录从rootfs切换
......@@ -59,12 +59,12 @@ VFS是一种机制、是每一种文件系统都必须按照这个机制去实
#define COMMAND_LINE_ADDR LOSCFG_BOOTENV_ADDR * BYTES_PER_KBYTE
#define COMMAND_LINE_SIZE 1024
#ifdef LOSCFG_STORAGE_SPINOR
#ifdef LOSCFG_STORAGE_SPINOR //spi nor flash
#define ROOTFS_ROOT_TYPE "flash" //根文件系统存放在nor flash上
#define ROOTFS_FS_TYPE "jffs2" //Journalling Flash File System(闪存设备日志型文件系统,JFFS),一般用于nor flash的文件系统
#elif defined(LOSCFG_STORAGE_SPINAND)
#define ROOTFS_ROOT_TYPE "nand"
#define ROOTFS_FS_TYPE "yaffs2"
#elif defined(LOSCFG_STORAGE_SPINAND)// nand flash
#define ROOTFS_ROOT_TYPE "nand" //在nand flash上制作根文件系统
#define ROOTFS_FS_TYPE "yaffs2"//文件系统格式选用 yaffs2
#endif
#ifdef LOSCFG_STORAGE_EMMC
......@@ -82,10 +82,10 @@ VFS是一种机制、是每一种文件系统都必须按照这个机制去实
#ifdef LOSCFG_STORAGE_SPINOR //外部开关定 使用哪种flash
#define FLASH_TYPE "spinor" //flash类型
#define FLASH_DEV_NAME "/dev/spinorblk0" //根文件系统路径
#define FLASH_DEV_NAME "/dev/spinorblk0" //设备名称
#elif defined(LOSCFG_STORAGE_SPINAND)
#define FLASH_TYPE "nand"
#define FLASH_DEV_NAME "/dev/nandblk0"
#define FLASH_DEV_NAME "/dev/nandblk0" //设备名称
#endif
//扇区是对硬盘而言,而块是对文件系统而言
#define EMMC_SEC_SIZE 512 //扇区大小,按512个字节,按扇区对齐
......
......@@ -49,20 +49,20 @@
#else
#define STORAGE_TYPE "emmc"
#endif
//分区信息
struct PartitionInfo {
const CHAR *partName;
const CHAR *cmdlineArgName;
const CHAR *partName; //分区名称
const CHAR *cmdlineArgName; //命令行参数名称
const CHAR *storageTypeArgName;
CHAR *storageType;
CHAR *storageType;
const CHAR *fsTypeArgName;
CHAR *fsType;
CHAR *fsType; //文件系统类型
const CHAR *addrArgName;
INT32 startAddr;
INT32 startAddr;
const CHAR *partSizeArgName;
INT32 partSize;
CHAR *devName;
UINT32 partNum;
UINT32 partNum; //分区编号
};
INT32 GetPartitionInfo(struct PartitionInfo *partInfo);
......
......@@ -39,17 +39,33 @@
#endif
#include "fs/path_cache.h"
/*
UART 简介
UART(Universal Asynchronous Receiver/Transmitter)通用异步收发传输器,UART 作为异步串口通信协议的一种,
工作原理是将传输数据的每个字符一位接一位地传输。是在应用程序开发过程中使用频率最高的数据总线。
UART 串口的特点是将数据一位一位地顺序传送,只要 2 根传输线就可以实现双向通信,一根线发送数据的同时用另一根线接收数据。
UART 串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用 UART 串口通信的端口,
这些参数必须匹配,否则通信将无法正常完成。
-----------------------------------------------------------------
+起始位 + 数据位(D0-D7) + 奇偶校验位 + 停止位 +
-----------------------------------------------------------------
起始位:表示数据传输的开始,电平逻辑为 “0” 。
数据位:可能值有 5、6、7、8、9,表示传输这几个 bit 位数据。一般取值为 8,因为一个 ASCII 字符值为 8 位。
奇偶校验位:用于接收方对接收到的数据进行校验,校验 “1” 的位数为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性,使用时不需要此位也可以。
停止位: 表示一帧数据的结束。电平逻辑为 “1”。
波特率:串口通信时的速率,它用单位时间内传输的二进制代码的有效位(bit)数来表示,其单位为每秒比特数 bit/s(bps)。常见的波特率值有 4800、9600、14400、38400、115200等,数值越大数据传输的越快,波特率为 115200 表示每秒钟传输 115200 位数据。
*/
STATIC volatile UINT32 g_serialType = 0;
STATIC struct file g_serialFilep;
//获取串口类型
UINT32 SerialTypeGet(VOID)
{
return g_serialType;
}
//设置串口类型
STATIC VOID SerialTypeSet(const CHAR *deviceName)
{
if (!strncmp(deviceName, SERIAL_UARTDEV, strlen(SERIAL_UARTDEV))) {
......@@ -58,7 +74,7 @@ STATIC VOID SerialTypeSet(const CHAR *deviceName)
g_serialType = SERIAL_TYPE_USBTTY_DEV;
}
}
//打开串口设备
STATIC INT32 SerialOpen(struct file *filep)
{
INT32 ret;
......@@ -86,7 +102,7 @@ ERROUT:
set_errno(ret);
return VFS_ERROR;
}
//关闭串口设备
STATIC INT32 SerialClose(struct file *filep)
{
(VOID)filep;
......@@ -102,7 +118,7 @@ STATIC INT32 SerialClose(struct file *filep)
return ENOERR;
}
//读取串口数据
STATIC ssize_t SerialRead(struct file *filep, CHAR *buffer, size_t bufLen)
{
INT32 ret;
......@@ -125,8 +141,8 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
/* Note: do not add print function in this module! */
//写入串口数据
/* Note: do not add print function in this module! */ //注意:请勿在本模块中添加打印功能!
STATIC ssize_t SerialWrite(struct file *filep, const CHAR *buffer, size_t bufLen)
{
INT32 ret;
......@@ -149,7 +165,7 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
//控制串口设备
STATIC INT32 SerialIoctl(struct file *filep, INT32 cmd, unsigned long arg)
{
INT32 ret;
......@@ -194,7 +210,7 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
//串口 对 VFS 接口实现
STATIC const struct file_operations_vfs g_serialDevOps = {
SerialOpen, /* open */
SerialClose, /* close */
......@@ -208,7 +224,7 @@ STATIC const struct file_operations_vfs g_serialDevOps = {
#endif
NULL,
};
//虚拟串口初始化
//虚拟串口初始化,注册驱动程序
INT32 virtual_serial_init(const CHAR *deviceName)
{
INT32 ret;
......@@ -233,13 +249,13 @@ INT32 virtual_serial_init(const CHAR *deviceName)
g_serialFilep.f_vnode = vnode;
g_serialFilep.ops = ((struct drv_data *)vnode->data)->ops;
if (g_serialFilep.ops->open != NULL) {
if (g_serialFilep.ops->open != NULL) {//用于检测是否有默认的驱动程序
(VOID)g_serialFilep.ops->open(&g_serialFilep);
} else {
ret = EFAULT;
PRINTK("virtual_serial_init %s open is NULL\n", deviceName);
goto ERROUT;
}
}//这是真正的注册串口的驱动程序
(VOID)register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep);
VnodeDrop();
......@@ -250,7 +266,7 @@ ERROUT:
set_errno(ret);
return VFS_ERROR;
}
//串口设备去初始化,其实就是注销驱动程序
INT32 virtual_serial_deinit(VOID)
{
return unregister_driver(SERIAL);
......
cd E:\\harmony\\third_party\\third_party_NuttX
git add -A
git commit -m ' 注解 NuttX 文件系统
git commit -m ' 块设备驱动,字符设备驱动注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
国内:https://weharmony.gitee.io
国外:https://weharmony.github.io
......
git add -A
git commit -m '对控制台,环形缓存区,虚拟串口实现注解
git commit -m '对Percpu 注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
国内: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.
先完成此消息的编辑!
想要评论请 注册