final version #27

Closed
pvz8b5rif wants to merge 0 commits from pvz8b5rif/Iot_Cs_best:zhoujin_branch into main

@ -1,3 +1,2 @@
# Brief Intro
# Iot_Cs_best
LMFAO, we do this shit just for fun :)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

BIN
doc/cache/image.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Binary file not shown.

@ -1,44 +0,0 @@
# base 下的代码阅读
根据官方的README.md,kernel/base下的文件主要为**基础内核包括调度、内存等模块**
# 1. brief intro
OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程和子进程的一系列操作来达到实现一些功能的目的.
## 1.1 描述各个子功能
* los_bitmap.c 主要提供一些位操作
* los_info.c 提供一些基本的方法来对进程的信息等内容进行操作
* los_process.c 提供对于进程操作的方法包括创建切换等..
# 2. natural expression of requirement of software
作为操作系统当中的子系统,以软件的角度来看进程管理:
## 2.1 一个完备的进程管理系统应当具备
### (1) 进程调度
鸿蒙内核的进程采用抢占式调度机制支持时间片轮转调度方式和FIFO调度机制
### (2) 进程创建
![Alt text](image-4.png)
### (3) 进程回收
### (4)
### (5)
### (6)
# 3. user case diagram and user case description
![Alt text](image.png)
# 4. software architecture
![Alt text](image-5.png)

@ -1,42 +0,0 @@
<!--
# 软件工程作业要求
## 1. 软件功能的自然语言描述
## 2. 软件的用例图和用例描述
## 3. 软件的体系结构(用包图描述其逻辑视图) -->
# LiteOS_kernel_a 泛读报告
## 一、 软件功能的自然语言描述
### 1.1 简介
Huawei LiteOS是华为面向IoT领域构建的轻量级物联网操作系统可广泛应用于智能家居、个人穿戴、车联网、城市公共服务、制造业等领域。
Huawei LiteOS发布于2015年5月的华为网络大会上。自开源社区发布以来围绕 NB-IoT 物联网市场从技术、生态、解决方案、商用支持等多维度使能合作伙伴,构建开源的物联网生态。目前已经聚合了 50+ MCU 和解决方案合作伙伴,共同推出一批开源开发套件和行业解决方案,帮助众多行业客户快速的推出物联网产品和服务。客户涵盖抄表、停车、路灯、环保、共享单车、物流等众多行业,为开发者提供 “一站式” 完整软件平台,可大幅降低设备布置及维护成本,有效降低开发门槛、缩短开发周期。
Huawei LiteOS开源项目目前支持 **ARM64、ARM Cortex-A、ARM Cortex-M0Cortex-M3Cortex-M4Cortex-M7** 等芯片架构。
### 1.2 软件功能
#### 1.2.1 提供一个简单轻便的用户交互界面以供使用。
#### 1.2.2 能够调用系统软硬件资源来完成某些操作。
#### 1.2.3 进程管理
#### 1.2.4 内存分配
#### 1.2.5 提供并行编程
## 二、 软件的用例图和用例描述
![Alt text](image.png)
## 三、 软件的体系结构
![Alt text](image-2.png)
![Alt text](image-6.png)

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,24 +0,0 @@
# General ignored file types
*.o
*.a
*.so
*.swp
# IDE settings
.vscode
.idea
.settings
.cproject
.project
# VIM files
cscope*
tags
# Menuconfig temp files
/config.h
/.config
/.config.old
# Build temp files
/out

@ -54,13 +54,13 @@ int main(int argc, char * const *argv)
const char *shellPath = "/bin/mksh";
#ifdef LOSCFG_QUICK_START
const char *samplePath = "/dev/shm/sample_quickstart";
const char *samplePath = "/dev/shm/sample_quickstart";
ret = fork();
if (ret < 0) {
printf("Failed to fork for sample_quickstart\n");
} else if (ret == 0) {
(void)execve(samplePath, NULL, NULL); // 执行可执行文件
(void)execve(samplePath, NULL, NULL);
exit(0);
}
@ -72,24 +72,24 @@ int main(int argc, char * const *argv)
close(fd);
}
#endif
ret = fork(); // 创建第一个程序来跑shell
ret = fork();
if (ret < 0) {
printf("Failed to fork for shell\n");
} else if (ret == 0) {
gid = getpgrp(); // 返回进程组ID
} else if (ret == 0) {
gid = getpgrp();
if (gid < 0) {
printf("get group id failed, pgrpid %d, errno %d\n", gid, errno);
exit(0);
}
ret = tcsetpgrp(STDIN_FILENO, gid);
ret = tcsetpgrp(STDIN_FILENO, gid);
if (ret != 0) {
printf("tcsetpgrp failed, errno %d\n", errno);
exit(0);
}
(void)execve(shellPath, NULL, NULL); // 正常执行命令行程序可执行文件
(void)execve(shellPath, NULL, NULL);
exit(0);
}
// ret > 0
while (1) {
ret = waitpid(-1, 0, WNOHANG);
if (ret == 0) {

@ -32,10 +32,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/// @brief 缓冲区写入测试
/// @param buf
/// @param start
/// @param end
static void BufWriteTest(void *buf, int start, int end)
{
for (int i = start; i <= end; i++) {
@ -43,10 +40,6 @@ static void BufWriteTest(void *buf, int start, int end)
}
}
/// @brief 缓冲区读入测试
/// @param buf
/// @param start
/// @param end
static void BufReadTest(void *buf, int start, int end)
{
char tmp;
@ -54,8 +47,7 @@ static void BufReadTest(void *buf, int start, int end)
tmp = ((char *)buf)[i];
}
}
/// @brief Lms分配测试
/// @param
static void LmsMallocTest(void)
{
#define TEST_SIZE 16
@ -72,8 +64,7 @@ static void LmsMallocTest(void)
free(buf);
printf("\n-------- LmsMallocTest End --------\n");
}
/// @brief Lms回收测试
/// @param
static void LmsReallocTest(void)
{
#define TEST_SIZE 64
@ -94,8 +85,6 @@ static void LmsReallocTest(void)
printf("\n-------- LmsReallocTest End --------\n");
}
/// @brief 分配存储器测试
/// @param
static void LmsCallocTest(void)
{
#define TEST_SIZE 16
@ -110,8 +99,6 @@ static void LmsCallocTest(void)
printf("\n-------- LmsCallocTest End --------\n");
}
/// @brief 分配虚拟存储测试
/// @param
static void LmsVallocTest(void)
{
#define TEST_SIZE 4096
@ -125,8 +112,7 @@ static void LmsVallocTest(void)
free(buf);
printf("\n-------- LmsVallocTest End --------\n");
}
/// @brief 线性分配测试
/// @param
static void LmsAlignedAllocTest(void)
{
#define TEST_ALIGN_SIZE 64
@ -141,8 +127,7 @@ static void LmsAlignedAllocTest(void)
free(buf);
printf("\n-------- LmsAlignedAllocTest End --------\n");
}
/// @brief memset测试
/// @param
static void LmsMemsetTest(void)
{
#define TEST_SIZE 32

@ -40,10 +40,7 @@
#include "perf_list.h"
#include "perf_stat.h"
#include "perf_record.h"
/// @brief 性能分析工具perf的代码
/// @param argc
/// @param argv
/// @return
int main(int argc, char **argv)
{
#define TWO_ARGS 2

@ -33,29 +33,21 @@
#include <string.h>
#include "option.h"
#include "perf_list.h"
/// @brief 解析命令行参数,并根据参数的类型将其值赋给相应的变量。
/// @param argv
/// @param index
/// @param opts
/// @return
static int ParseOption(char **argv, int *index, PerfOption *opts)
{
int ret = 0;
const char *str = NULL;
// 使用while循环遍历 opts 结构体数组,直到遇到一个空指针。
while ((opts->name != NULL) && (*opts->name != 0)) {
if (strcmp(argv[*index], opts->name) == 0) {
switch (opts->type) {
//如果选项类型是 OPTION_TYPE_UINT则将命令行参数转换为无符号整数并存储到当前选项的值中。
switch (opts->type) {
case OPTION_TYPE_UINT:
*opts->value = strtoul(argv[++(*index)], NULL, 0);
break;
//如果选项类型是 OPTION_TYPE_STRING则将命令行参数赋值给当前选项的字符串值。
case OPTION_TYPE_STRING:
*opts->str = argv[++(*index)];
break;
// 如果选项类型是 OPTION_TYPE_CALLBACK则调用当前选项的回调函数并将命令行参数作为参数传递给回调函数。
//如果回调函数返回值不为0则打印解析错误信息并将 ret 设置为-1。
case OPTION_TYPE_CALLBACK:
str = argv[++(*index)];
if ((*opts->cb)(str) != 0) {
@ -63,7 +55,6 @@ static int ParseOption(char **argv, int *index, PerfOption *opts)
ret = -1;
}
break;
//如果在while循环中没有找到匹配的选项则打印无效选项信息并将 ret 设置为-1。
default:
printf("invalid option\n");
ret = -1;
@ -76,27 +67,19 @@ static int ParseOption(char **argv, int *index, PerfOption *opts)
return -1;
}
/// @brief 这段代码是一个命令行参数解析函数它的目的是从命令行参数中提取选项和子命令并将它们存储在opts cmd中
/// @param argc
/// @param argv
/// @param opts
/// @param cmd
/// @return
int ParseOptions(int argc, char **argv, PerfOption *opts, SubCmd *cmd)
{
int i;
// 定义一个变量 index初始值为0用于表示当前正在处理的命令行参数的索引。
int index = 0;
//使用while循环遍历命令行参数直到索引超出范围或者遇到非选项参数。
//在循环中,调用 ParseOption 函数解析当前选项,并将解析结果存储在 opts 结构体中。如果解析失败,则返回-1。
while ((index < argc) && (argv[index] != NULL) && (*argv[index] == '-')) {
if (ParseOption(argv, &index, opts) != 0) {
return -1;
}
index++;
}
//如果在while循环结束后还有剩余的命令行参数则将第一个参数赋值给 cmd 结构体的 path 成员,
//并将其余参数存储在 cmd 结构体的 params 数组中。如果缺少子命令参数,则打印错误信息并返回-1。
if ((index < argc) && (argv[index] != NULL)) {
cmd->path = argv[index];
cmd->params[0] = argv[index];
@ -105,7 +88,7 @@ int ParseOptions(int argc, char **argv, PerfOption *opts, SubCmd *cmd)
printf("no subcmd to execute\n");
return -1;
}
// 使用for循环遍历剩余的命令行参数并将它们存储在 cmd 结构体的 params 数组中。循环会一直执行直到达到最大参数数量或者索引超出范围
for (i = 1; (index < argc) && (i < CMD_MAX_PARAMS); index++, i++) {
cmd->params[i] = argv[index];
}
@ -145,10 +128,7 @@ EXIT:
free(list);
return ret;
}
/// @brief 这段代码是一个C语言函数其功能是将一个字符串转换为对应的PerfEvent结构体指针。
///这个函数对于输入的字符串在全局的g_events数组中进行查找并返回匹配的PerfEvent结构体指针。
/// @param str
/// @return
static inline const PerfEvent *StrToEvent(const char *str)
{
const PerfEvent *evt = &g_events[0];
@ -160,11 +140,7 @@ static inline const PerfEvent *StrToEvent(const char *str)
}
return NULL;
}
/// @brief 这段代码定义了一个名为 ParseEvents 的函数,其目的是解析一个以逗号分隔的字符串,并将其转换为 PerfEventConfig 结构体中的事件配置。
/// @param argv
/// @param eventsCfg
/// @param len
/// @return
int ParseEvents(const char *argv, PerfEventConfig *eventsCfg, unsigned int *len)
{
int ret;

@ -2311,7 +2311,7 @@ diff -Nupr old/fs/jffs2/erase.c new/fs/jffs2/erase.c
diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
--- old/fs/jffs2/file.c 2022-05-09 17:22:53.000000000 +0800
+++ new/fs/jffs2/file.c 2022-05-10 09:43:14.250000000 +0800
@@ -9,334 +9,31 @@
@@ -9,335 +9,30 @@
* For licensing information, see the file 'LICENCE' in this directory.
*
*/
@ -2348,7 +2348,7 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+ /* FIXME: This works only with one file system mounted at a time */
int ret;
-
- ret = file_write_and_wait_range(filp, start, end);
+ ret = jffs2_read_inode_range(c, f, gc_buffer,
+ offset & ~(PAGE_SIZE-1), PAGE_SIZE);
@ -2361,10 +2361,8 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- inode_unlock(inode);
-
- return 0;
+ return ERR_PTR(ret);
+ return gc_buffer;
}
-}
-
-const struct file_operations jffs2_file_operations =
-{
- .llseek = generic_file_llseek,
@ -2389,10 +2387,7 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
-};
-
-const struct address_space_operations jffs2_file_address_operations =
+void jffs2_gc_release_page(struct jffs2_sb_info *c,
+ unsigned char *ptr,
+ unsigned long *priv)
{
-{
- .readpage = jffs2_readpage,
- .write_begin = jffs2_write_begin,
- .write_end = jffs2_write_end,
@ -2448,29 +2443,35 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
- mutex_unlock(&f->sem);
- return ret;
-}
-
+ return ERR_PTR(ret);
+ return gc_buffer;
}
-static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
-{
+void jffs2_gc_release_page(struct jffs2_sb_info *c,
+ unsigned char *ptr,
+ unsigned long *priv)
{
- struct page *pg;
- struct inode *inode = mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- pgoff_t index = pos >> PAGE_SHIFT;
- uint32_t pageofs = index << PAGE_SHIFT;
- int ret = 0;
-
- jffs2_dbg(1, "%s()\n", __func__);
-
- if (pos > inode->i_size) {
- /* Make new hole frag from old EOF to new position */
- if (pageofs > inode->i_size) {
- /* Make new hole frag from old EOF to new page */
- struct jffs2_raw_inode ri;
- struct jffs2_full_dnode *fn;
- uint32_t alloc_len;
-
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new position\n",
- (unsigned int)inode->i_size, (uint32_t)pos);
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
- (unsigned int)inode->i_size, pageofs);
-
- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
@ -2490,10 +2491,10 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- ri.mode = cpu_to_jemode(inode->i_mode);
- ri.uid = cpu_to_je16(i_uid_read(inode));
- ri.gid = cpu_to_je16(i_gid_read(inode));
- ri.isize = cpu_to_je32((uint32_t)pos);
- ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
- ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW());
- ri.offset = cpu_to_je32(inode->i_size);
- ri.dsize = cpu_to_je32((uint32_t)pos - inode->i_size);
- ri.dsize = cpu_to_je32(pageofs - inode->i_size);
- ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
- ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
@ -2523,7 +2524,7 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- goto out_err;
- }
- jffs2_complete_reservation(c);
- inode->i_size = pos;
- inode->i_size = pageofs;
- mutex_unlock(&f->sem);
- }
-

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -31,84 +31,78 @@
#include "los_bitmap.h"
#include "los_printf.h"
#include "los_toolchain.h"
/*
function:
interpretation:
*/
#define OS_BITMAP_MASK 0x1FU
#include "los_toolchain.h" //GCC 编译器的内置函数
/**
* @brief
* @verbatim
bit
bit
使
10
1
https://www.geeksforgeeks.org/builtin-functions-gcc-compiler/
* @endverbatim
*/
#define OS_BITMAP_MASK 0x1FU //
#define OS_BITMAP_WORD_MASK ~0UL
/*
function: 1
interpretation:
*/
/* find first zero bit starting from LSB */
/*! find first zero bit starting from LSB */
STATIC INLINE UINT16 Ffz(UINTPTR x)
{
// gcc 自带的内建函数
return __builtin_ffsl(~x) - 1;
{//__builtin_ffsl: 返回右起第一个1的位置函数来自 glibc
return __builtin_ffsl(~x) - 1;//从LSB开始查找第一个零位 LSB(最低有效位) 对应 最高有效位(MSB)
}
/*
funciton: 1
interpretation:
*/
///对状态字的某一标志位进行置1操作
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
return;
}
*bitmap |= 1U << (pos & OS_BITMAP_MASK); //00011111
*bitmap |= 1U << (pos & OS_BITMAP_MASK);//在对应位上置1
}
/*
function: 0
interpretation:
*/
///对状态字的某一标志位进行清0操作
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
return;
}
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));//在对应位上置0
}
/*
function:
*/
/**
* @brief 1 : 00110110 5
* @verbatim
CLZ 0
  1.使1
  2.
* @endverbatim
* @param bitmap
* @return UINT16
*/
UINT16 LOS_HighBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
return LOS_INVALID_BIT_INDEX;
}
return (OS_BITMAP_MASK - CLZ(bitmap));
return (OS_BITMAP_MASK - CLZ(bitmap));//CLZ = count leading zeros 用于计算整数的前导零
}
/*
function: 1
*/
/// 获取参数位图中最低位为1的索引位 例如: 00110110 返回 1
UINT16 LOS_LowBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
return LOS_INVALID_BIT_INDEX;
}
return CTZ(bitmap);
return CTZ(bitmap);// CTZ = count trailing zeros 用于计算给定整数的尾随零
}
/*
function: startnumsSetbit 1
*/
/// 从start位置开始设置numsSet个bit位 置1
VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
{
UINTPTR *p = bitmap + BITMAP_WORD(start);
@ -128,10 +122,7 @@ VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
*p |= maskToSet;
}
}
/*
fuction: start numsSetbit0 ,0
*/
///从start位置开始 清除numsSet个bit位置0 ,对状态字的连续标志位进行清0操作
VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
{
UINTPTR *p = bitmap + BITMAP_WORD(start);
@ -151,9 +142,7 @@ VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
*p &= ~maskToClear;
}
}
/*
fuction: numBits0
*/
///从numBits位置开始找到第一个0位
INT32 LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits)
{
INT32 bit, i;

@ -31,17 +31,15 @@
#include "los_info_pri.h"
#include "los_task_pri.h"
#include "los_vm_dump.h"
// 得到父进程的pid
//获取当前进程的父进程ID
STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB)
{
// 如果没有父进程
if (processCB->parentProcess == NULL) {
return 0;
}
#ifdef LOSCFG_PID_CONTAINER
if (pid == OS_USER_ROOT_PROCESS_ID) {
#ifdef LOSCFG_PID_CONTAINER //从容器中获取
if (pid == OS_USER_ROOT_PROCESS_ID) {//从这里可以看出 0号进程kidle1,2号进程的父进程
return 0;
}
@ -51,8 +49,7 @@ STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB)
#endif
return processCB->parentProcess->processID;
}
// 得到当前任务ID
//获取当前任务ID
STATIC INLINE UINT32 GetCurrTid(const LosTaskCB *taskCB)
{
#ifdef LOSCFG_PID_CONTAINER
@ -63,7 +60,6 @@ STATIC INLINE UINT32 GetCurrTid(const LosTaskCB *taskCB)
return taskCB->taskID;
}
// 得到进程的状态
STATIC UINT16 GetProcessStatus(LosProcessCB *processCB)
{
UINT16 status;
@ -80,7 +76,6 @@ STATIC UINT16 GetProcessStatus(LosProcessCB *processCB)
return status;
}
// 得到进程的信息
STATIC VOID GetProcessInfo(ProcessInfo *pcbInfo, const LosProcessCB *processCB)
{
SchedParam param = {0};
@ -138,7 +133,6 @@ STATIC VOID GetProcessMemInfo(ProcessInfo *pcbInfo, const LosProcessCB *processC
}
#endif
// 得到线程的信息
STATIC VOID GetThreadInfo(ProcessThreadInfo *threadInfo, LosProcessCB *processCB)
{
SchedParam param = {0};

@ -1,15 +1,25 @@
/*
/*!
* @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-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -68,15 +78,22 @@
#include "los_vm_phys.h"
#include "los_vm_syscall.h"
LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL;//进程池数组
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;//空闲状态下的进程链表,
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;//需要回的进程列表
LITE_OS_SEC_BSS UINT32 g_processMaxNum;//进程最大数量,默认64个
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_processMaxNum;///< 进程最大数量,默认64个
#ifndef LOSCFG_PID_CONTAINER
LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;//全局进程组,负责管理所有的进程组
LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;///< 全局进程组,负责管理所有进程组
#define OS_ROOT_PGRP(processCB) (g_processGroup)
#endif
/*
* @brief
* @details
* @param argc 1
* @param[LosProcessCB] processCB
* @return
* - VOID
*/
STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB)
{
#ifdef LOSCFG_PID_CONTAINER
@ -156,7 +173,7 @@ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB)
return NULL;
}
pgroup->pgroupLeader = (UINTPTR)processCB;//指定进程负责人
pgroup->pgroupLeader = (UINTPTR)processCB;//指定进程负责人
LOS_ListInit(&pgroup->processList);//初始化组员链表
LOS_ListInit(&pgroup->exitProcessList);//初始化僵死进程链表
@ -173,17 +190,19 @@ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB)
}
return pgroup;
}
//退出进程组,参数是进程地址和进程组地址的地址
/*! 退出进程组,参数是进程地址和进程组地址的地址 */
STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup)
{
LosProcessCB *pgroupCB = OS_GET_PGROUP_LEADER(processCB->pgroup);
LOS_ListDelete(&processCB->subordinateGroupList);//从进程组进程链表上摘出去
if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) {
if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) {//进程组进程链表和退出进程链表都为空时
#ifdef LOSCFG_PID_CONTAINER
if (processCB->pgroup != OS_ROOT_PGRP(processCB)) {
#endif
LOS_ListDelete(&processCB->pgroup->groupList);//从全局进程组链表上把自己摘出去 记住它是 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList) 挂上去的
*pgroup = processCB->pgroup;
LOS_ListDelete(&processCB->pgroup->groupList);//从全局进程组链表上把自己摘出去 记住它是 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList) 挂上去的
*pgroup = processCB->pgroup;//????? 这步操作没看明白,谁能告诉我为何要这么做?
#ifdef LOSCFG_PID_CONTAINER
}
#endif
@ -196,6 +215,7 @@ STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup)
processCB->pgroup = NULL;
}
/*! 通过指定组ID找到进程组 */
STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
{
@ -216,6 +236,7 @@ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
PRINT_INFO("%s failed! pgroup id = %u\n", __FUNCTION__, gid);
return NULL;
}
/*! 给指定进程组发送信号 */
STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *pgroup, siginfo_t *info, INT32 permission)
{
@ -309,6 +330,7 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, const
return NULL;
}
/*! 唤醒等待wakePID结束的任务 */
VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID)
{
@ -318,6 +340,7 @@ VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID)
LOS_MpSchedule(OS_MP_CPU_ALL);//向所有cpu发送调度指令
#endif
}
/*! 唤醒等待参数进程结束的任务 */
STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
{
@ -332,7 +355,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
if (processID == 0) {
processID = taskCB->waitID;
find = TRUE;//找到了
} else {
} else {// @note_thinking 这个代码有点多余吧,会执行到吗?
processID = OS_INVALID_VALUE;
}
@ -349,6 +372,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
return find;
}
/*! 检查父进程的等待任务并唤醒父进程去处理等待任务 */
STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
{
@ -360,7 +384,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
if (LOS_ListEmpty(&parentCB->waitList)) {//父进程中是否有在等待子进程退出的任务?
return;//没有就退出
}
// TODO
findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);//找到指定的任务
if (findSpecified == TRUE) {
/* No thread is waiting for any child process to finish */
@ -411,6 +435,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
return;
}
/*! 回收指定进程的资源 */
LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
{
@ -420,10 +445,10 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
}
#endif
#ifdef LOSCFG_SECURITY_CAPABILITY//安全开关
#ifdef LOSCFG_SECURITY_CAPABILITY //安全开关
if (processCB->user != NULL) {
(VOID)LOS_MemFree(m_aucSysMem1, processCB->user);//删除用户
processCB->user = NULL;//重置指针为空
processCB->user = NULL; //重置指针为空
}
#endif
@ -480,6 +505,7 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
processCB->resourceLimit = NULL;
}
}
/*! 回收僵死状态进程的资源 */
STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup)
{
@ -497,9 +523,10 @@ STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup
} else if (OsProcessIsPGroupLeader(childCB)) {
LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);//从尾部插入,意思就是组长尽量最后一个处理
} else {
OsInsertPCBToFreeList(childCB);//直接插到freeList中去可用于重新分配了
OsInsertPCBToFreeList(childCB);//直接插到freeList中去可用于重新分配了
}
}
/*! 当一个进程自然退出的时候,它的孩子进程由两位老祖宗收养 */
STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
{
@ -513,7 +540,6 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
return;
}
#endif
if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程
childHead = processCB->childrenList.pstNext;//获取孩子链表
LOS_ListDelete(&(processCB->childrenList));//清空自己的孩子链表
@ -537,6 +563,7 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
return;
}
/*! 回收指定进程的已经退出(死亡)的孩子进程所占资源 */
STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
{
@ -549,11 +576,13 @@ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
(VOID)LOS_MemFree(m_aucSysMem1, pgroup);
}
}
/*! 一个进程的自然消亡过程,参数是当前运行的任务*/
VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
{
OsChildProcessResourcesFree(processCB);//释放孩子进程的资源
/* is a child process */
if (processCB->parentProcess != NULL) {
LosProcessCB *parentCB = processCB->parentProcess;
@ -569,8 +598,8 @@ VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
OsDealAliveChildProcess(processCB);//孩子们要怎么处理,移交给(用户态和内核态)根进程
processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;//贴上僵死进程的标签
#ifdef LOSCFG_KERNEL_VM
(VOID)OsSendSigToProcess(parentCB, SIGCHLD, OS_KERNEL_KILL_PERMISSION);
#endif
@ -638,6 +667,7 @@ UINT32 OsProcessInit(VOID)
SystemProcessEarlyInit(OsGetKernelInitProcess());
return LOS_OK;
}
/*! 进程回收再利用过程*/
LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
{
@ -647,7 +677,7 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
SCHEDULER_LOCK(intSave);
while (!LOS_ListEmpty(&g_processRecycleList)) {//循环任务回收链表,直到为空
processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));//找到回收链表中第一个进程实体
//OS_PCB_FROM_PENDLIST 代表的是通过pendlist节点找到 PCB实体,因为g_processRecyleList上面挂的是pendlist节点位置
//OS_PCB_FROM_PENDLIST 代表的是通过pendlist节点找到 PCB实体,因为g_processRecyleList上面挂的是pendlist节点位置
if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//进程没有退出标签
break;
}
@ -683,6 +713,7 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
SCHEDULER_UNLOCK(intSave);
}
/*! 删除PCB块 其实是 PCB块回归进程池,先进入回收链表*/
STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
{
@ -698,7 +729,6 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
return;
}
#endif
OsProcessResourcesToFree(processCB);//释放进程所占用的资源
SCHEDULER_LOCK(intSave);
@ -712,7 +742,7 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
}
processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;//设置进程状态为非初始化
processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//设置进程状态为退出
processCB->processStatus |= OS_PROCESS_FLAG_EXIT; //设置进程状态为退出
LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
SCHEDULER_UNLOCK(intSave);
@ -757,19 +787,19 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
/*! 初始化PCB(进程控制块)*/
STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
{
processCB->processMode = mode;//用户态进程还是内核态进程
processCB->processStatus = OS_PROCESS_STATUS_INIT;//进程初始状态
processCB->processMode = mode; //用户态进程还是内核态进程
processCB->processStatus = OS_PROCESS_STATUS_INIT; //进程初始状态
processCB->parentProcess = NULL;
processCB->threadGroup = NULL;
processCB->umask = OS_PROCESS_DEFAULT_UMASK;//掩码
processCB->umask = OS_PROCESS_DEFAULT_UMASK; //掩码
processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
LOS_ListInit(&processCB->threadSiblingList);//初始化孩子任务/线程链表上面挂的都是由此fork的孩子线程 见于 OsTaskCBInit LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));
LOS_ListInit(&processCB->childrenList);//初始化孩子进程链表上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);
LOS_ListInit(&processCB->exitChildList);//初始化记录退出孩子进程链表上面挂的是哪些exit 见于 OsProcessNaturalExit LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);
LOS_ListInit(&(processCB->waitList));//初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&processCB->waitList, &runTask->pendList);
LOS_ListInit(&processCB->childrenList); //初始化孩子进程链表上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);
LOS_ListInit(&processCB->exitChildList); //初始化记录退出孩子进程链表上面挂的是哪些exit 见于 OsProcessNaturalExit LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);
LOS_ListInit(&(processCB->waitList)); //初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&processCB->waitList, &runTask->pendList);
#ifdef LOSCFG_KERNEL_VM
#ifdef LOSCFG_KERNEL_VM
if (OsProcessIsUserMode(processCB)) {//如果是用户态进程
processCB->vmSpace = OsCreateUserVmSpace();//创建用户空间
if (processCB->vmSpace == NULL) {
@ -788,14 +818,12 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
}
(VOID)memset_s(processCB->processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase));
#endif
#ifdef LOSCFG_SECURITY_VID
status_t status = VidMapListInit(processCB);
if (status != LOS_OK) {
return LOS_ENOMEM;
}
#endif
#ifdef LOSCFG_SECURITY_CAPABILITY
OsInitCapability(processCB);//初始化进程安全相关功能
#endif
@ -809,7 +837,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
//创建用户
#ifdef LOSCFG_SECURITY_CAPABILITY
STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size 表示组数量
{//(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费
{ //(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费
User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32));
if (user == NULL) {
return NULL;
@ -820,7 +848,7 @@ STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size
user->gid = gid;
user->effGid = gid;
user->groupNumber = size;//用户组数量
user->groups[0] = gid;//用户组列表,一个用户可以属于多个用户组
user->groups[0] = gid; //用户组列表,一个用户可以属于多个用户组
return user;
}
@ -908,8 +936,8 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C
goto EXIT;
}
#ifdef LOSCFG_SECURITY_CAPABILITY //用户安全宏
processCB->user = OsCreateUser(0, 0, 1); //创建用户
#ifdef LOSCFG_SECURITY_CAPABILITY //用户安全宏
processCB->user = OsCreateUser(0, 0, 1);//创建用户
if (processCB->user == NULL) {
ret = LOS_ENOMEM;
goto EXIT;
@ -917,7 +945,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C
#endif
#ifdef LOSCFG_KERNEL_PLIMITS
ret = OsPLimitsAddProcess(NULL, processCB);//删除进程控制块,归还内存
ret = OsPLimitsAddProcess(NULL, processCB);
if (ret != LOS_OK) {
ret = LOS_ENOMEM;
goto EXIT;
@ -926,7 +954,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C
return LOS_OK;
EXIT:
OsDeInitPCB(processCB);
OsDeInitPCB(processCB);//删除进程控制块,归还内存
return ret;
}
/*! 创建2,0号进程,即内核态进程的老祖宗*/
@ -962,7 +990,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
}
return LOS_OK;
}
// 进程调度参数检查
/// 进程调度参数检查
INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param)
{
if (param == NULL) {
@ -1006,7 +1034,7 @@ STATIC INLINE INT32 ProcessSchedulerParamCheck(INT32 which, INT32 pid, UINT16 po
return OsSchedulerParamCheck(policy, FALSE, param);
}
#ifdef LOSCFG_SECURITY_CAPABILITY//检查进程的安全许可证
#ifdef LOSCFG_SECURITY_CAPABILITY //检查进程的安全许可证
STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 policy, UINT16 prio)
{
LosProcessCB *runProcess = OsCurrProcessGet();//获得当前进程
@ -1028,7 +1056,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa
return FALSE;
}
#endif
// 设置进程调度计划
/// 设置进程调度计划
LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *schedParam)
{
SchedParam param = { 0 };
@ -1090,12 +1118,12 @@ TO_SCHED:
}
return LOS_OK;
}
// 设置指定进程的调度参数,包括优先级和调度策略
/// 设置指定进程的调度参数,包括优先级和调度策略
LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam)
{
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, policy, schedParam);
}
// 获得指定进程的调度策略
/// 获得指定进程的调度策略
LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam)
{
UINT32 intSave;
@ -1139,7 +1167,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSche
}
return LOS_OK;
}
// 接口封装 - 设置进程优先级
/// 接口封装 - 设置进程优先级
LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio)
{
INT32 ret;
@ -1159,7 +1187,7 @@ LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio)
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, (UINT16)policy, &param);
}
// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户
/// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户
LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
{
UINT32 intSave;
@ -1192,11 +1220,12 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
SCHEDULER_UNLOCK(intSave);
return param.basePrio;
}
// 接口封装 - 获取指定进程优先级
/// 接口封装 - 获取指定进程优先级
LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid)
{
return OsGetProcessPriority(LOS_PRIO_PROCESS, pid);
}
/*!
* waitList,退
* 退退退.
@ -1232,7 +1261,7 @@ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *proces
(VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER);
return;
}
// 设置等待子进程退出方式方法
/// 设置等待子进程退出方式方法
STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask,
const LosProcessCB *processCB, LosProcessCB **childCB)
{
@ -1253,16 +1282,15 @@ STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask,
#endif
/* Wait for the child process whose process number is pid. */
*childCB = OsFindExitChildProcess(processCB, waitProcess);
if (*childCB != NULL) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上
if (*childCB != NULL) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上
return LOS_OK;
}
if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) {
return LOS_ECHILD;
}
}
runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型
runTask->waitID = (UINTPTR)waitProcess;
if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) {
return LOS_ECHILD;
}
runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型
runTask->waitID = (UINTPTR)waitProcess;
return LOS_OK;
}
@ -1294,9 +1322,9 @@ STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcess
if (childCB != NULL) {//找到了,确实有一个已经退出的PID
goto WAIT_BACK;
}
runTask->waitID = pid;
runTask->waitFlag = OS_PROCESS_WAIT_ANY;
} else { /* pid < -1 */
runTask->waitID = pid;//等待PID,这个PID可以和当前进程没有任何关系
runTask->waitFlag = OS_PROCESS_WAIT_ANY;//设置当前任务的等待类型
} else { /* pid < -1 */ //等待指定进程组内为|pid|的所有子进程
/* Wait for any child process whose group number is the pid absolute value. */
ProcessGroup *pgroup = OsFindProcessGroup(-pid);
if (pgroup == NULL) {
@ -1316,7 +1344,7 @@ WAIT_BACK:
*child = childCB;
return LOS_OK;
}
// 等待回收孩子进程
/// 等待回收孩子进程 @note_thinking 这样写Porcess不太好吧
STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
{
ProcessGroup *pgroup = NULL;
@ -1336,7 +1364,7 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS
if (status != NULL) {
if (mode == OS_USER_MODE) {//孩子为用户态进程
(VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));
(VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));//从内核空间拷贝退出码
} else {
*status = exitCode;
}
@ -1371,9 +1399,9 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS
(VOID)LOS_MemFree(m_aucSysMem1, pgroup);
return pid;
}
// 检查要等待的孩子进程
/// 检查要等待的孩子进程
STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB)
{//当进程没有孩子且没有退出的孩子进程
{ //当进程没有孩子且没有退出的孩子进程
if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) {
return LOS_ECHILD;
}
@ -1399,8 +1427,8 @@ STATIC UINT32 OsWaitOptionsCheck(UINT32 options)
}
return LOS_OK;
}
//等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号并清除僵死进程。
}
///等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号并清除僵死进程。
STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
{
(VOID)rusage;
@ -1429,28 +1457,28 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32
#endif
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
}
//没有找到,看是否要返回还是去做个登记
//没有找到,看是否要返回还是去做个登记
if ((options & LOS_WAIT_WNOHANG) != 0) {//有LOS_WAIT_WNOHANG标签
runTask->waitFlag = 0;//等待标识置0
pid = 0;//这里置0,是为了 return 0
goto ERROR;
}
//等待孩子进程退出
OsWaitInsertWaitListInOrder(runTask, processCB);
//发起调度的目的是为了让出CPU,让其他进程/任务运行
//等待孩子进程退出
OsWaitInsertWaitListInOrder(runTask, processCB);//将当前任务挂入进程waitList链表
//发起调度的目的是为了让出CPU,让其他进程/任务运行
runTask->waitFlag = 0;
if (runTask->waitID == OS_INVALID_VALUE) {
pid = -LOS_ECHILD;//没有此子进程
goto ERROR;
}
//回收僵死进程
childCB = (LosProcessCB *)runTask->waitID;
if (!OsProcessIsDead(childCB)) {
pid = -LOS_ESRCH;
goto ERROR;
}
//回收僵死进程
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
ERROR:
@ -1536,7 +1564,7 @@ STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, LosProcessCB
if (OsProcessIsInactive(processCB)) {//进程是否活动
return LOS_ESRCH;
}
//参数进程不在用户态或者组长不在用户态
//参数进程不在用户态或者组长不在用户态
#ifdef LOSCFG_PID_CONTAINER
if ((processCB->processID == OS_USER_ROOT_PROCESS_ID) || OS_PROCESS_CONTAINER_CHECK(processCB, runProcessCB)) {
return LOS_EPERM;
@ -1653,12 +1681,12 @@ EXIT:
SCHEDULER_UNLOCK(intSave);
return gid;
}
// 获取当前进程的组ID
/// 获取当前进程的组ID
LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
{
return LOS_GetProcessGroupID(OsCurrProcessGet()->processID);
}
// 为用户态任务分配栈空间
/// 为用户态任务分配栈空间
#ifdef LOSCFG_KERNEL_VM
STATIC LosProcessCB *OsGetFreePCB(VOID)
{
@ -1683,7 +1711,7 @@ STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size)
{
LosVmMapRegion *region = NULL;
UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE);//1M栈空间 按页对齐
//线性区分配虚拟内存
//线性区分配虚拟内存
region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize,
VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ |
VM_MAP_REGION_FLAG_PERM_WRITE, 0);//可使用可读可写区
@ -1781,12 +1809,12 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
}
#endif
processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;
processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC;
processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; //去掉进程退出标签
processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC;//加上进程运行elf标签
return LOS_OK;
}
// 执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
/// 执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize)
{
UINT32 intSave;
@ -1798,18 +1826,18 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {//对齐
return LOS_NOK;
}
//注意 sp此时指向栈底,栈底地址要大于栈顶
//注意 sp此时指向栈底,栈底地址要大于栈顶
if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) {//参数检查
return LOS_NOK;
}
LosTaskCB *taskCB = OsCurrTaskGet();//获取当前任务
SCHEDULER_LOCK(intSave);//拿自旋锁
taskCB->userMapBase = mapBase;//用户态栈顶位置
taskCB->userMapSize = mapSize;//用户态栈
taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;//任务的入口函数
//初始化内核态栈
//初始化内核态栈
TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize,
(VOID *)taskCB->topOfStack, FALSE);
OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);//初始化用户栈,将内核栈中上下文的 context->R[0] = sp ,context->sp = sp
@ -1818,7 +1846,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
return LOS_OK;
}
#endif
// 用户进程开始初始化
/// 用户进程开始初始化
STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param)
{
UINT32 intSave;
@ -1958,7 +1986,7 @@ ERROR:
OsDeInitPCB(processCB);
return ret;
}
// 拷贝用户信息 直接用memcpy_s
/// 拷贝用户信息 直接用memcpy_s
STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
{
#ifdef LOSCFG_SECURITY_CAPABILITY
@ -1983,10 +2011,10 @@ STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32
SCHEDULER_LOCK(intSave);
if (OsProcessIsUserMode(childProcessCB)) {//用户态进程
taskParam->pfnTaskEntry = runTask->taskEntry;//拷贝当前任务入口地址
taskParam->uwStackSize = runTask->stackSize;//栈空间大小
taskParam->userParam.userArea = runTask->userArea;//用户态栈区栈顶位置
taskParam->userParam.userMapBase = runTask->userMapBase;//用户态栈底
taskParam->userParam.userMapSize = runTask->userMapSize;//用户态栈大小
taskParam->uwStackSize = runTask->stackSize; //栈空间大小
taskParam->userParam.userArea = runTask->userArea; //用户态栈区栈顶位置
taskParam->userParam.userMapBase = runTask->userMapBase; //用户态栈底
taskParam->userParam.userMapSize = runTask->userMapSize; //用户态栈大小
} else {//注意内核态进程创建任务的入口由外界指定,例如 OsCreateIdleProcess 指定了OsIdleTask
taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry;//参数(sp)为内核态入口地址
taskParam->uwStackSize = size;//参数(size)为内核态栈大小
@ -2028,7 +2056,7 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR
childTaskCB->taskStatus = runTask->taskStatus;//任务状态先同步,注意这里是赋值操作. ...01101001
childTaskCB->ops->schedParamModify(childTaskCB, &param);
if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//因只能有一个运行的task,所以如果一样要改4号位
childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001
childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001
} else {//非运行状态下会发生什么?
if (OS_SCHEDULER_ACTIVE) {//克隆线程发生错误未运行
LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus);
@ -2051,16 +2079,15 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces
SCHEDULER_LOCK(intSave);
if (childProcessCB->parentProcess == NULL) {
if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系
parentProcessCB = runProcessCB->parentProcess;
} else {
parentProcessCB = runProcessCB;//指认父亲,这个赋值代表从此是你儿了
}
childProcessCB->parentProcess = parentProcessCB;
LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹
//不会被排序,老大,老二,老三 老天爷指定了。
if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系
parentProcessCB = runProcessCB->parentProcess;
} else {
parentProcessCB = runProcessCB;
}
childProcessCB->parentProcess = parentProcessCB;//指认父亲,这个赋值代表从此是你儿了
LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹
//不会被排序,老大,老二,老三 老天爷指定了。
}
if (childProcessCB->pgroup == NULL) {
childProcessCB->pgroup = parentProcessCB->pgroup;
LOS_ListTailInsert(&parentProcessCB->pgroup->processList, &childProcessCB->subordinateGroupList);
@ -2086,13 +2113,13 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB
return LOS_OK;
}
status = LOS_VmSpaceClone(flags, runProcessCB->vmSpace, childProcessCB->vmSpace);
status = LOS_VmSpaceClone(flags, runProcessCB->vmSpace, childProcessCB->vmSpace);//虚拟空间clone
if (status != LOS_OK) {
return LOS_ENOMEM;
}
return LOS_OK;
}
// 拷贝进程文件描述符(proc_fd)信息
/// 拷贝进程文件描述符(proc_fd)信息
STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
{
#ifdef LOSCFG_FS_VFS
@ -2163,7 +2190,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *
(VOID)LOS_MemFree(m_aucSysMem1, pgroup);
return LOS_OK;
}
// 拷贝进程资源
/// 拷贝进程资源
STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run)
{
UINT32 ret;
@ -2184,7 +2211,7 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce
}
#ifdef LOSCFG_KERNEL_LITEIPC
if (run->ipcInfo != NULL) {//重新初始化IPC池
if (run->ipcInfo != NULL) { //重新初始化IPC池
child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));//@note_good 将沿用用户态空间地址(即线性区地址)
if (child->ipcInfo == NULL) {//因为整个进程虚拟空间都是拷贝的,ipc的用户态虚拟地址当然可以拷贝,但因进程不同了,所以需要重新申请ipc池和重新
return LOS_ENOMEM;//映射池中两个地址.
@ -2195,9 +2222,10 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce
#ifdef LOSCFG_SECURITY_CAPABILITY
OsCopyCapability(run, child);//拷贝安全能力
#endif
return LOS_OK;
}
// 拷贝进程
/// 拷贝进程
STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
{
UINT32 ret, processID;
@ -2219,7 +2247,6 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si
if (ret != LOS_OK) {
goto ERROR_INIT;
}
#ifdef LOSCFG_KERNEL_PLIMITS
ret = OsPLimitsAddProcess(run->plimits, child);
if (ret != LOS_OK) {
@ -2227,7 +2254,6 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si
}
#endif
#endif
ret = OsForkInitPCB(flags, child, name, sp, size);//初始化进程控制块
if (ret != LOS_OK) {
goto ERROR_INIT;
@ -2315,6 +2341,7 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
return OsCopyProcess(cloneFlag & flags, NULL, sp, size);
}
//著名的 fork 函数 记得前往 https://gitee.com/weharmony/kernel_liteos_a_note fork一下 :)
LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize)
{
UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES;
@ -2346,7 +2373,6 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
UINT32 intSave;
(void)status;
/* The exit of a kernel - state process must be kernel - state and all threads must actively exit */
LosProcessCB *processCB = OsCurrProcessGet();
SCHEDULER_LOCK(intSave);
@ -2361,6 +2387,7 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK);
}
/*!
* @brief LOS_GetUsedPIDList
* 使
@ -2413,12 +2440,12 @@ LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid)
return files->fdt;
}
#endif
// 获取当前进程的进程ID
/// 获取当前进程的进程ID
LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
{
return OsCurrProcessGet()->processID;
}
// 按指定状态退出指定进程
/// 按指定状态退出指定进程
#ifdef LOSCFG_KERNEL_VM
STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB)
{
@ -2491,12 +2518,12 @@ LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
#endif
return;
}
// 获取系统支持的最大进程数目
/// 获取系统支持的最大进程数目
LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID)
{
return g_processMaxNum;
}
// 获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
/// 获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
LITE_OS_SEC_TEXT LosProcessCB *OsGetUserInitProcess(VOID)
{
return &g_processCBArray[OS_USER_ROOT_PROCESS_ID];
@ -2506,7 +2533,7 @@ LITE_OS_SEC_TEXT LosProcessCB *OsGetKernelInitProcess(VOID)
{
return &g_processCBArray[OS_KERNEL_ROOT_PROCESS_ID];
}
// 获取空闲进程0号进程为空闲进程该进程不干活专给CPU休息的。
/// 获取空闲进程0号进程为空闲进程该进程不干活专给CPU休息的。
LITE_OS_SEC_TEXT LosProcessCB *OsGetIdleProcess(VOID)
{
return &g_processCBArray[OS_KERNEL_IDLE_PROCESS_ID];

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:

@ -1,34 +1,9 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*基本概念
/*!
* @file los_swtmr.c
* @brief
* @details
* @attention @verbatim
TickTick
@ -83,7 +58,41 @@
使使
使
Tick*/
Tick
@endverbatim
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_swtmr_pri.h"
#include "los_init.h"
#include "los_process_pri.h"
@ -100,20 +109,19 @@
STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr);
STATIC INLINE UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid);
LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */
LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler */
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */
LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /**< First address in Timer memory space \n 定时器池 */
LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /**< Pool of Swtmr Handler \n 用于注册软时钟的回调函数 */
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /**< Free list of Software Timer \n 空闲定时器链表 */
/* spinlock for swtmr module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);//初始化软件钟自旋锁只有SMP情况才需要只要是自旋锁都是由于CPU多核的同步
#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))//持有软时钟自旋锁
#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))//释放软时钟自旋锁
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);///< 初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步
#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))///< 持有软时钟自旋锁
#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))///< 释放软时钟自旋锁
typedef struct {
SortLinkAttribute swtmrSortLink;
LosTaskCB *swtmrTask; /* software timer task id *///定时器任务ID
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id *///定时器超时队列
LosTaskCB *swtmrTask; /* software timer task id | 定时器任务ID */
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id | 定时器超时队列*/
} SwtmrRunqueue;
STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM];
@ -309,7 +317,11 @@ STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq)
LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave);
return;
}
//软时钟的入口函数拥有任务的最高优先级0级
/**
* @brief , 0 !
*
* @return LITE_OS_SEC_TEXT
*/
STATIC VOID SwtmrTask(VOID)
{
SwtmrHandlerItem swtmrHandle;
@ -318,7 +330,7 @@ STATIC VOID SwtmrTask(VOID)
SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()];
LOS_DL_LIST *head = &srq->swtmrHandlerQueue;
for (;;) {//死循环获取队列item一直读干净为止
for (;;) {//死循环获取队列item,一直读干净为止
waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink);
if (waitTime != 0) {
SCHEDULER_LOCK(intSave);
@ -334,13 +346,13 @@ STATIC VOID SwtmrTask(VOID)
LOS_ListDelete(&swtmrHandlePtr->node);
(VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem));
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存注意在鸿蒙内核只有软时钟注册用到了静态内存
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存
SwtmrHandler(&swtmrHandle);
}
}
}
}
//创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
///创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
{
UINT32 ret;
@ -348,16 +360,16 @@ STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16k默认内核任务栈
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K默认内核任务栈
swtmrTask.pcName = "Swt_Task";//任务名称
swtmrTask.usTaskPrio = 0;//
swtmrTask.usTaskPrio = 0;//哇塞! 逮到一个最高优先级的任务 @note_thinking 这里应该用 OS_TASK_PRIORITY_HIGHEST 表示
swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式
#ifdef LOSCFG_KERNEL_SMP
swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务
#endif
ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);//创建任务并申请调度
if (ret == LOS_OK) {
OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是个任务系统
OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是系统任务
}
return ret;
@ -375,7 +387,7 @@ BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
}
return FALSE;
}
//回收指定进程的软时钟
///回收指定进程的软时钟
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID)
{
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器
@ -384,7 +396,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID)
}
}
}
//软时钟初始化,注意函数在多CPU情况下会执行多次
///软时钟初始化 ,注意函数在多CPU情况下会执行多次
STATIC UINT32 SwtmrBaseInit(VOID)
{
UINT32 ret;
@ -396,13 +408,13 @@ STATIC UINT32 SwtmrBaseInit(VOID)
(VOID)memset_s(swtmr, size, 0, size);//清0
g_swtmrCBArray = swtmr;//软时钟
LOS_ListInit(&g_swtmrFreeList);//初始化空链表
LOS_ListInit(&g_swtmrFreeList);//初始化空链表
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
swtmr->usTimerID = index;//按顺序赋值
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
swtmr->usTimerID = index;//按顺序赋值
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
}
//想要用静态内存池管理就必须要使用LOS_MEMBOX_SIZE来计算申请列表的内存大小因为需要点前缀内存承载头部信息
size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池
//想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息.
size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */
if (g_swtmrHandlerPool == NULL) {
return LOS_ERRNO_SWTMR_NO_MEMORY;
@ -531,13 +543,13 @@ STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器
ticks = swtmr->uwExpiry;//获取时间隔
ticks = swtmr->uwExpiry; //获取间隔
} else {
ticks = swtmr->uwInterval;
ticks = swtmr->uwInterval;//获取周期性定时器时间间隔
}
swtmr->ucState = OS_SWTMR_STATUS_TICKING;//获取周期性定时器时间间隔
swtmr->ucState = OS_SWTMR_STATUS_TICKING;//计数状态
UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;//计数状态
UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;
UINT64 responseTime = swtmr->startTime + period;
UINT64 currTime = OsGetCurrSchedTimeCycle();
if (responseTime < currTime) {
@ -578,10 +590,9 @@ STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr)
STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr)
{
/* insert to free list */
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中回收再利用
swtmr->ucState = OS_SWTMR_STATUS_UNUSED;
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用
swtmr->ucState = OS_SWTMR_STATUS_UNUSED;//又干净着呢
swtmr->uwOwnerPid = OS_INVALID_VALUE;
SwtmrDebugDataClear(swtmr->usTimerID);
}
@ -697,7 +708,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
}
return (UINT32)time;
}
//创建定时器,设置定时器的定时时长、定时模式、回调函数、并返回定时器ID
///创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode,
SWTMR_PROC_FUNC handler,
@ -726,30 +737,30 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
}
SWTMR_LOCK(intSave);
if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲表不能为空
if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲表不能为空
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_MAXSIZE;
}
sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode);
swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));//
SWTMR_UNLOCK(intSave);
swtmr->uwOwnerPid = (UINTPTR)OsCurrProcessGet();
swtmr->pfnHandler = handler;//时间到了的回调函数
swtmr->ucMode = mode;//定时模式
swtmr->ucMode = mode; //定时模式
swtmr->uwOverrun = 0;
swtmr->uwInterval = interval;//周期性超时间隔
swtmr->uwExpiry = interval;//一次性超时间隔
swtmr->uwArg = arg;//回调函数的参数
swtmr->ucState = OS_SWTMR_STATUS_CREATED;//已创建状态
swtmr->uwInterval = interval; //周期性超时间隔
swtmr->uwExpiry = interval; //一次性超时间隔
swtmr->uwArg = arg; //回调函数的参数
swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态
SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
*swtmrID = swtmr->usTimerID;
OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
return LOS_OK;
}
//接口函数 启动定时器 参数定时任务ID
///接口函数 启动定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -774,12 +785,12 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
/*如果定时器的状态为启动中,应先停止定时器再重新启动
/* 如果定时器的状态为启动中,应先停止定时器再重新启动
* If the status of swtmr is timing, it should stop the swtmr first,
* then start the swtmr again.
*/
case OS_SWTMR_STATUS_TICKING://正在计数的定时器
SwtmrStop(swtmr);//先停止定时器注意这里没有break在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CRWEATED接下来就是执行启动了
SwtmrStop(swtmr);//先停止定时器,注意这里没有break;,在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CREATED 接下来就是执行启动了
/* fall-through */
case OS_SWTMR_STATUS_CREATED://已经创建好了
SwtmrStart(swtmr);
@ -793,7 +804,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
return ret;
}
//接口函数 停止计时器 参加定时任务ID
///接口函数 停止定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -822,7 +833,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始
break;
case OS_SWTMR_STATUS_TICKING://正在计数
SwtmrStop(swtmr);//执行正在停止时器操作
SwtmrStop(swtmr);//执行正在停止时器操作
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -833,7 +844,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
return ret;
}
//接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
///接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -874,7 +885,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
SWTMR_UNLOCK(intSave);
return ret;
}
//接口函数 删除定时器
///接口函数 删除定时器
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -899,7 +910,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
case OS_SWTMR_STATUS_TICKING://正在计数就先停止在删除这里没有break
case OS_SWTMR_STATUS_TICKING://正在计数就先停止再删除,这里没有break;
SwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED://再删除定时器
@ -915,4 +926,5 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
return ret;
}
#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */
#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -32,19 +32,72 @@
#include "los_sys_pri.h"
#include "los_sched_pri.h"
/*!
* @file los_sys.c
* @brief
* @details
* @link kernel-small-basic-time http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-time.html @endlink
* @verbatim
/
Tick
Tick
Tick/
Cycle
CycleCycle
Tick
TickTick
使
Tick
使LOSCFG_BASE_CORE_TICK_HW_TIME
OS_SYS_CLOCKHzOS_SYS_CLOCK
make menuconfigLOSCFG_BASE_CORE_TICK_PER_SECOND
http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-time.html
@endverbatim
* @attention
Tick使
los_config.hOS_SYS_CLOCKLOSCFG_BASE_CORE_TICK_PER_SECOND
TickTick
*/
#define OS_MAX_VALUE 0xFFFFFFFFUL
/**
* @brief Tick
*
* @return LITE_OS_SEC_TEXT_MINOR
*/
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
{
return OsGetCurrSchedTimeCycle() / OS_CYCLE_PER_TICK;
}
/**
* @brief TickCycle
*
* @return LITE_OS_SEC_TEXT_MINOR
*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID)
{
return g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND;
}
/**
* @brief Tick
*
* @param millisec
* @return LITE_OS_SEC_TEXT_MINOR
*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
{
if (millisec == OS_MAX_VALUE) {
@ -53,12 +106,22 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND;
}
/**
* @brief Tick
*
* @param tick
* @return LITE_OS_SEC_TEXT_MINOR
*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick)
{
return ((UINT64)tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND;
}
/**
* @brief tick
*
* @param nanoseconds
* @return LITE_OS_SEC_TEXT_MINOR
*/
LITE_OS_SEC_TEXT_MINOR UINT32 OsNS2Tick(UINT64 nanoseconds)
{
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -64,12 +64,11 @@
#ifdef LOSCFG_KERNEL_CONTAINER
#include "los_container_pri.h"
#endif
#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0)
#error "task maxnum cannot be zero"
#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */
/*
/**
* @file los_task.c
* @brief
* @verbatim
使CPU
使
@ -138,12 +137,20 @@
*/
* @endverbatim
* @param pathname
* @return int
*/
#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0)
#error "task maxnum cannot be zero"
#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */
LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;//任务池 128个
LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;//空闲任务链表
LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;//回收任务链表
LITE_OS_SEC_BSS UINT32 g_taskMaxNum;//任务最大个数
LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores */
LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores *///任务调度器,每个CPU都有对应位
LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;//资源的事件
/* spinlock for task module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin);
@ -168,7 +175,7 @@ VOID OsSetMainTask(VOID)
schedParam.policy = LOS_SCHED_RR;
schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST;
schedParam.priority = OS_TASK_PRIORITY_LOWEST;
//为每个CPU core 设置mainTask
//为每个CPU core 设置mainTask
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED;
g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;//128
@ -178,11 +185,10 @@ VOID OsSetMainTask(VOID)
g_mainTask[i].lockDep.waitLock = NULL;
#endif
(VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1);
LOS_ListInit(&g_mainTask[i].lockList);//初始化任务锁链表上面挂的是任务已申请到的互斥锁
LOS_ListInit(&g_mainTask[i].lockList);//初始化任务锁链表,上面挂的是任务已申请到的互斥锁
(VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL);
}
}
VOID OsSetMainTaskProcess(UINTPTR processCB)
{
for (UINT32 i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
@ -192,11 +198,11 @@ VOID OsSetMainTaskProcess(UINTPTR processCB)
#endif
}
}
//空闲任务,每个CPU都有自己的空闲任务
///空闲任务,每个CPU都有自己的空闲任务
LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID)
{
while (1) {//只有一个死循环
WFI;//WFI指令arm core立即进入low-power standly state,进入休眠模式,等待中断
WFI;//WFI指令:arm core 立即进入low-power standby state进入休眠模式等待中断。
}
}
@ -204,14 +210,20 @@ VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB)
{
LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);//将任务挂入回收链表,等待回收
}
/*
taskOS_TCB_FROM_PENDLISTLOS_DL_LISTLosTaskCB,
task
*/
/*!
* @brief OsTaskJoinPostUnsafe
* task OS_TCB_FROM_PENDLIST ,LOS_DL_LISTLosTaskCB,
* task.
* @param taskCB
* @return
*
* @see
*/
LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join任务处理
if (!LOS_ListEmpty(&taskCB->joinList)) {//joinList中的节点身上都有阻塞标签
if (!LOS_ListEmpty(&taskCB->joinList)) {//注意到了这里 joinList中的节点身上都有阻塞标签
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));//通过贴有JOIN标签链表的第一个节点找到Task
OsTaskWakeClearPendMask(resumedTask);//清除任务的挂起标记
resumedTask->ops->wake(resumedTask);
@ -219,7 +231,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
}
taskCB->taskStatus |= OS_TASK_STATUS_EXIT;//贴上任务退出标签
}
//挂起任务任务进入等待链表Join代表是支持通过的第一个任务去唤醒其他的任务
/// 挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
@ -231,14 +243,14 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
}
if ((taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) && LOS_ListEmpty(&taskCB->joinList)) {
OsTaskWaitSetPendMask(OS_TASK_WAIT_JOIN, taskCB->taskID, LOS_WAIT_FOREVER);
OsTaskWaitSetPendMask(OS_TASK_WAIT_JOIN, taskCB->taskID, LOS_WAIT_FOREVER);//设置任务的等待标记
LosTaskCB *runTask = OsCurrTaskGet();
return runTask->ops->wait(runTask, &taskCB->joinList, LOS_WAIT_FOREVER);
}
return LOS_EINVAL;
}
//任务设置分离模式Deatch和JOIN是一对有你没我的状态
///任务设置分离模式 Deatch和JOIN是一对有你没我的状态
LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join状态时
@ -261,13 +273,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(UINTPTR processCB)
UINT32 size;
UINT32 ret;
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个可谓铁打的任务池流水的线程
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个,可谓铁打的任务池流水的线程
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//计算需分配内存总大小
/*
* This memory is resident memory and is used to save the system resources
* of task control block and will not be freed.
*/
g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);//任务池常驻内存不被释放
g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);//任务池常驻内存,不被释放
if (g_taskCBArray == NULL) {
ret = LOS_ERRNO_TSK_NO_MEMORY;
goto EXIT;
@ -277,12 +289,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(UINTPTR processCB)
LOS_ListInit(&g_losFreeTask);//初始化空闲任务链表
LOS_ListInit(&g_taskRecycleList);//初始化回收任务链表
for (index = 0; index < g_taskMaxNum; index++) {//任务挨个初始化
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;//默认未使用
g_taskCBArray[index].taskID = index;//任务ID[0~g_taskMaxNum-1]
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;//默认未使用,干净.
g_taskCBArray[index].taskID = index;//任务ID [0 ~ g_taskMaxNum - 1]
g_taskCBArray[index].processCB = processCB;
LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);//通过pendlist节点插入空闲任务列表
}//注意这里挂的是pendList节点可以取TCB也要通过OS_TCB_FROM-PENDLIST取
LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);//通过pendList节点插入空闲任务列表
}//注意:这里挂的是pendList节点,所以取TCB也要通过 OS_TCB_FROM_PENDLIST 取.
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;
g_taskCBArray[index].taskID = index;
g_taskCBArray[index].processCB = processCB;
@ -295,41 +306,41 @@ EXIT:
}
return ret;
}
//获取IdletaskId每个CPU核都对Task进行了内部管理做到真正的并行处理
///获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理
UINT32 OsGetIdleTaskId(VOID)
{
return OsSchedRunqueueIdleGet()->taskID;
}
//创建一个空闲任务
///创建一个空闲任务
LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(UINTPTR processID)
{
UINT32 ret;
TSK_INIT_PARAM_S taskInitParam;
UINT32 idleTaskID;
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清0
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;//任务栈大小 2K
taskInitParam.pcName = "Idle";//任务名称叫pcNAME
taskInitParam.pcName = "Idle";//任务名称 叫pcName有点怪怪的,不能换个撒
taskInitParam.policy = LOS_SCHED_IDLE;
taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;//默认最低优先级31
taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;//默认最低优先级 31
taskInitParam.processID = processID;
#ifdef LOSCFG_KERNEL_SMP
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的CPU上运行
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的cpu上运行
#endif
ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam);
if (ret != LOS_OK) {
return ret;
}
LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID);
idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//标记为系统任务idle任务是给CPU休息用的当然是个系统任务
idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; //标记为系统任务,idle任务是给CPU休息用的,当然是个系统任务
OsSchedRunqueueIdleInit(idleTask);
return LOS_TaskResume(idleTaskID);
}
/*
* Description : get id of current running task. |CPUID
* Description : get id of current running task. | CPUID
* Return : task id
*/
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
@ -341,7 +352,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
}
return runTask->taskID;
}
//创建指定任务同步信号量
/// 创建指定任务同步信号量
STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -354,7 +365,7 @@ STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB)
#endif
return LOS_OK;
}
//销毁指定任务同步信号量
/// 销毁指定任务同步信号量
STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -365,7 +376,14 @@ STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
}
#ifdef LOSCFG_KERNEL_SMP
//任务同步等待,通过信号量保持同步
/*!
* @brief OsTaskSyncWait
* ,
* @param taskCB
* @return
*
* @see
*/
STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -376,9 +394,9 @@ STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
/*
* gc soft timer works every OS_MP_GC_PERIOD period, to prevent this timer
* triggered right at the timeout has reached, we set the timeout as double
* of the gc period.
* of the gc peroid.
*/
if (LOS_SemPend(taskCB->syncSignal, OS_MP_GC_PERIOD * 2) != LOS_OK) { /* 2: Wait 200 ms */
if (LOS_SemPend(taskCB->syncSignal, OS_MP_GC_PERIOD * 2) != LOS_OK) {
ret = LOS_ERRNO_TSK_MP_SYNC_FAILED;
}
@ -391,7 +409,7 @@ STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
#endif
}
#endif
//同步唤醒
/// 同步唤醒
STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -413,7 +431,7 @@ STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB)
taskCB->taskStatus = OS_TASK_STATUS_UNUSED;
LOS_ListAdd(&g_losFreeTask, &taskCB->pendList);
}
//释放任务在内核态下占用的资源
//释放任务在内核态下占用的资源
STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack)
{
OsTaskSyncDestroy(syncSignal);//任务销毁,同步信息
@ -445,19 +463,19 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
}
#ifdef LOSCFG_KERNEL_LITEIPC
LiteIpcRemoveServiceHandle(taskCB->taskID);
LiteIpcRemoveServiceHandle(taskCB->taskID);//详见百篇博客之IPC篇
#endif
}
#endif
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务还使用情况
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务还没有使用情况
topOfStack = taskCB->topOfStack;
taskCB->topOfStack = 0;
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
syncSignal = taskCB->syncSignal;
taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
#endif
OsTaskKernelResourcesToFree(syncSignal, topOfStack);//释放内核所占内存,即内核栈的栈空间
OsTaskKernelResourcesToFree(syncSignal, topOfStack);//释放内核态所占内存,即内核态的栈空间
SCHEDULER_LOCK(intSave);
#ifdef LOSCFG_KERNEL_VM
@ -489,7 +507,7 @@ LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void)
/*
* Description : All task entry
* Input : taskID --- The ID of the task to be run
*///所有任务的入口函数OsTaskEntry是new task OsTaskStackInit时指定的
*///所有任务的入口函数,OsTaskEntry是在new task OsTaskStackInit 时指定的
LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
{
LOS_ASSERT(!OS_TID_CHECK_INVALID(taskID));
@ -503,15 +521,15 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
(VOID)LOS_IntUnLock();//恢复中断
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调任务的入口函数
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调任务的入口函数
taskCB->args[2], taskCB->args[3]); /* 2 & 3: just for args array index */
if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
taskCB->joinRetval = 0;//结合数为0
}
OsRunningTaskToExit(taskCB, 0);
}
//任务创建参数检查
///任务创建参数检查
STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
{
UINT32 poolSize = OS_SYS_MEM_SIZE;
@ -542,7 +560,7 @@ STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initP
return LOS_ERRNO_TSK_STKSZ_TOO_LARGE;
}
if (initParam->uwStackSize == 0) {//任何任务都必须由内核态栈所以uwStackSize不能为0
if (initParam->uwStackSize == 0) {//任何任务都必须由内核态栈,所以uwStackSize不能为0
initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
}
initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE);
@ -553,7 +571,7 @@ STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initP
return LOS_OK;
}
//任务栈内核态内存分配由内核态进程空间提供即KProcess进程空间
///任务栈(内核态)内存分配,由内核态进程空间提供,即 KProcess 的进程空间
STATIC VOID TaskCBDeInit(LosTaskCB *taskCB)
{
UINT32 intSave;
@ -612,7 +630,7 @@ STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
taskCB->futex.index = OS_INVALID_VALUE;
#endif
}
//任务初始化
///任务初始化
STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
{
UINT32 ret;
@ -621,7 +639,8 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
LosSchedParam initSchedParam = {0};
UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
TaskCBBaseInit(taskCB, initParam);//初始化任务的基本信息task->stackPointer指向内核态栈sp位置该位置存着任务初始上下文
TaskCBBaseInit(taskCB, initParam);//初始化任务的基本信息,
//taskCB->stackPointer指向内核态栈 sp位置,该位置存着 任务初始上下文
schedParam.policy = policy;
ret = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam, &numCount);
@ -673,7 +692,7 @@ STATIC UINT32 TaskStackInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam
#endif
return LOS_OK;
}
//获取一个空闲TCB
///获取一个空闲TCB
STATIC LosTaskCB *GetFreeTaskCB(VOID)
{
UINT32 intSave;
@ -691,9 +710,16 @@ STATIC LosTaskCB *GetFreeTaskCB(VOID)
return taskCB;
}
/*
使suspendLOS_TaskResume使ready
*/
/*!
* @brief LOS_TaskCreateOnly
* 使suspendLOS_TaskResume使ready
* @param initParam
* @param taskID
* @return
*
* @see
*/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
{
UINT32 errRet = TaskCreateParamCheck(taskID, initParam);
@ -733,7 +759,7 @@ DEINIT_TCB:
TaskCBDeInit(taskCB);
return errRet;
}
//创建任务并使该任务进入ready状态如果就绪队列中没有更高优先级的任务则运行该任务
///创建任务并使该任务进入ready状态如果就绪队列中没有更高优先级的任务则运行该任务
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
{
UINT32 ret;
@ -747,7 +773,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
return LOS_ERRNO_TSK_YIELD_IN_INT;
}
if (OsProcessIsUserMode(OsCurrProcessGet())) {//当前进程为用户进程
if (OsProcessIsUserMode(OsCurrProcessGet())) { //当前进程为用户进程
initParam->processID = (UINTPTR)OsGetKernelInitProcess();
} else {
initParam->processID = (UINTPTR)OsCurrProcessGet();
@ -773,7 +799,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
return LOS_OK;
}
//恢复挂起的任务,是该任务进入ready状态
///恢复挂起的任务,使该任务进入ready状态
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
{
UINT32 intSave;
@ -814,13 +840,13 @@ LOS_ERREND:
}
/*
* Check if needs to do the suspend operation on the running task.//检查是否需要对正在运行的任务执行挂起操作。
* Return TRUE, if needs to do the suspension. //如果需要暂停返回TRUE。
* Return FALSE, if meets following circumstances: //如果满足一下情况则返回FALSE
* 1. Do the suspension across cores, if SMP is enabled //1.如果启用了SMP则跨CPU核执行挂起操作
* 2. Do the suspension when preemption is disabled //2.当禁用抢占时则挂起
* 3. Do the suspension in hard-irq //3.在硬中断时则挂起
* then LOS_TaskSuspend will directly return with 'ret' value. //那么LOS_taskssuspend将直接返回ret值。
* Check if needs to do the suspend operation on the running task. //检查是否需要对正在运行的任务执行挂起操作。
* Return TRUE, if needs to do the suspension. //如果需要暂停返回TRUE。
* Rerturn FALSE, if meets following circumstances: //如果满足以下情况则返回FALSE
* 1. Do the suspension across cores, if SMP is enabled //1.如果启用了SMP则跨CPU核执行挂起操作
* 2. Do the suspension when preemption is disabled //2.当禁用抢占时则挂起
* 3. Do the suspension in hard-irq //3.在硬中断时则挂起
* then LOS_TaskSuspend will directly return with 'ret' value. //那么LOS_taskssuspend将直接返回ret值。
*/
LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
{
@ -842,7 +868,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
return FALSE;
}
if (OS_INT_ACTIVE) {//正在硬抢断时
if (OS_INT_ACTIVE) {//正在硬中断中
/* suspend running task in interrupt */
taskCB->signal = SIGNAL_SUSPEND;
return FALSE;
@ -850,7 +876,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
return TRUE;
}
//任务暂停参数可以不是当前任务也就是说A任务可以让B任务处于阻塞状态挂起指定的任务,然后切换任务
///任务暂停,参数可以不是当前任务,也就是说 A任务可以让B任务处于阻塞状态,挂起指定的任务,然后切换任务
LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
{
UINT32 errRet;
@ -863,14 +889,14 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
return LOS_ERRNO_TSK_ALREADY_SUSPENDED;
}
if ((tempStatus & OS_TASK_STATUS_RUNNING) &&//如果参数任务正在运行注意多Cpu core情况贴着正在运行标签的任务并不一定是当前CPU的执行任务
if ((tempStatus & OS_TASK_STATUS_RUNNING) && //如果参数任务正在运行注意多Cpu core情况贴着正在运行标签的任务并不一定是当前CPU的执行任务
!OsTaskSuspendCheckOnRun(taskCB, &errRet)) {//很有可能是别的CPU core在跑的任务
return errRet;
}
return taskCB->ops->suspend(taskCB);
}
//外部接口对OsTaskSuspend的封装
///外部接口对OsTaskSuspend的封装
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
{
UINT32 intSave;
@ -890,7 +916,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
SCHEDULER_UNLOCK(intSave);
return errRet;
}
//设置任务为不使用状态
///设置任务为不使用状态
STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB)
{
taskCB->taskStatus |= OS_TASK_STATUS_UNUSED;
@ -1002,7 +1028,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
if (!OsPreemptable()) {
return LOS_ERRNO_TSK_DELETE_LOCKED;
}
OsRunningTaskToExit(taskCB, OS_PRO_EXIT_OK);
return LOS_NOK;
}
@ -1036,7 +1061,7 @@ LOS_ERREND:
}
return ret;
}
//任务延时等待释放CPU等待时间到期后该任务会重新进入ready状态
///任务延时等待释放CPU等待时间到期后该任务会重新进入ready状态
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
{
UINT32 intSave;
@ -1066,7 +1091,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
SCHEDULER_UNLOCK(intSave);
return ret;
}
//获取任务的优先级
///获取任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
{
UINT32 intSave;
@ -1078,7 +1103,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//就这么一句话也要来个自旋锁,内核代码自旋锁真是无处不在啊
SCHEDULER_UNLOCK(intSave);
return (UINT16)OS_INVALID;
}
@ -1087,7 +1112,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
SCHEDULER_UNLOCK(intSave);
return param.priority;
}
//设置指定任务的优先级
///设置指定任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
{
UINT32 intSave;
@ -1125,12 +1150,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
}
return LOS_OK;
}
//设置当前任务的优先级
///设置当前任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
{
return LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio);
}
//当前任务释放CPU并将其移到具有相同优先级的就绪任务队列的末尾。
//当前任务释放CPU并将其移到具有相同优先级的就绪任务队列的末尾. 读懂这个函数 你就彻底搞懂了 yield
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
{
UINT32 intSave;
@ -1176,7 +1202,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
LOS_Schedule();
}
}
//获取任务信息给shell使用的
//获取任务信息,给shell使用的
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
{
UINT32 intSave;
@ -1206,7 +1232,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
taskCB->ops->schedParamGet(taskCB, &param);
taskInfo->usTaskStatus = taskCB->taskStatus;
taskInfo->usTaskPrio = param.priority;
taskInfo->uwStackSize = taskCB->stackSize;//内核态栈大小
taskInfo->uwStackSize = taskCB->stackSize; //内核态栈大小
taskInfo->uwTopOfStack = taskCB->topOfStack;//内核态栈顶位置
taskInfo->uwEventMask = taskCB->eventMask;
taskInfo->taskEvent = taskCB->taskEvent;
@ -1218,7 +1244,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
}
taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0';
taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈地址是高于栈顶
taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈地址是高于栈顶
OS_TASK_STACK_ADDR_ALIGN);
taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);//当前任务栈已使用了多少
@ -1227,7 +1253,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
//CPU亲和性affinity将任务绑定在指定CPU上用于多核CPU情况该函数仅在SMP模式下支持
///CPU亲和性affinity将任务绑在指定CPU上,用于多核CPU情况,该函数仅在SMP模式下支持
LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask)
{
#ifdef LOSCFG_KERNEL_SMP
@ -1253,7 +1279,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa
UINT32 intSave;
UINT16 currCpuMask;
if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效task由task池分配鸿蒙默认128个任务 ID范围[0:127]
if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效,task由task池分配,鸿蒙默认128个任务 ID范围[0:127]
return LOS_ERRNO_TSK_ID_INVALID;
}
@ -1270,14 +1296,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa
needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuAffiMask, &currCpuMask);
SCHEDULER_UNLOCK(intSave);
if (needSched && OS_SCHEDULER_ACTIVE) {
LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标cpu
LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标CPU
LOS_Schedule();//申请调度
}
return LOS_OK;
}
//查询任务被绑在哪个cpu
///查询任务被绑在哪个CPU
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
{
#ifdef LOSCFG_KERNEL_SMP
@ -1291,50 +1318,54 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务必须在使用
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { //任务必须在使用
SCHEDULER_UNLOCK(intSave);
return INVALID_CPU_AFFI_MASK;
}
cpuAffiMask = taskCB->cpuAffiMask;//获取亲和力掩码
cpuAffiMask = taskCB->cpuAffiMask; //获取亲和力掩码
SCHEDULER_UNLOCK(intSave);
return cpuAffiMask;
#else
(VOID)taskID;
return 1;//单核情况直接返回10号cpu对应0x01
return 1;//单核情况直接返回1 ,0号cpu对应0x01
#endif
}
/*
* Description : Process pending signals tagged by others cores
*/
/*!
CPU
..\arch\arm\arm\src\los_dispatch.S
*/
LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
{
UINT32 ret;
//私有且不可中断无需保护。这个任务在其他cpu核看到它时总是在运行所以它在执行代码的同时也可以继续接收信号
//私有且不可中断无需保护。这个任务在其他CPU核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号
/*
* private and uninterruptable, no protection needed.
* while this task is always running when others cores see it,
* so it keeps receiving signals while follow code executing.
*/
LosTaskCB *runTask = OsCurrTaskGet();
if (runTask->signal == SIGNAL_NONE) {//意思是其他cpu发起了要干掉你的信号
if (runTask->signal == SIGNAL_NONE) {
return;
}
if (runTask->signal & SIGNAL_KILL) {
if (runTask->signal & SIGNAL_KILL) {//意思是其他cpu发起了要干掉你的信号
/*
* clear the signal, and do the task deletion. if the signaled task has been
* scheduled out, then this deletion will wait until next run.
*///如果发出信号的任务出调度就绪队列,则此删除将等待下次运行
runTask->signal = SIGNAL_NONE;//清除信号
*///如果发出信号的任务出调度就绪队列,则此删除将等待下次运行
runTask->signal = SIGNAL_NONE;//清除信号
ret = LOS_TaskDelete(runTask->taskID);
if (ret != LOS_OK) {
PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret);
}
} else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号
runTask->signal &= ~SIGNAL_SUSPEND;//任务贴在被其他cpu挂起的标签
runTask->signal &= ~SIGNAL_SUSPEND;//任务贴上被其他CPU挂起的标签
/* suspend killed task may fail, ignore the result */
(VOID)LOS_TaskSuspend(runTask->taskID);
@ -1342,7 +1373,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
} else if (runTask->signal & SIGNAL_AFFI) {//意思是下次调度其他cpu要媾和你
runTask->signal &= ~SIGNAL_AFFI;//任务贴上被其他CPU媾和的标签
/* priority queue has updated, notify the target cpu */
/* pri-queue has updated, notify the target cpu */
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);//发生调度,此任务将移交给媾和CPU运行.
#endif
}
@ -1416,7 +1447,7 @@ INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINTPTR proc
return LOS_OK;
}
//创建任务之前,检查用户态任务栈的参数,是否地址在用户空间
///创建任务之前,检查用户态任务栈的参数,是否地址在用户空间
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param)
{
UserTaskParam *userParam = NULL;
@ -1433,18 +1464,18 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID,
if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {//入口函数必须在用户空间
return OS_INVALID_VALUE;
}
//堆栈必须在用户空间
//堆栈必须在用户空间
if (userParam->userMapBase && !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) {
return OS_INVALID_VALUE;
}
//检查堆,栈范围
//检查堆,栈范围
if (!LOS_IsUserAddress(userParam->userSP)) {
return OS_INVALID_VALUE;
}
return LOS_OK;
}
//创建一个用户态任务
///创建一个用户态任务
LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_S *initParam)
{
UINT32 taskID;
@ -1457,9 +1488,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
if (ret != LOS_OK) {
return ret;
}
//这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小)
//这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小)
initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE;
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级31级
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级 31级
if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理
SCHEDULER_LOCK(intSave);
LosProcessCB *processCB = OsCurrProcessGet();
@ -1478,19 +1509,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
initParam->periodUs = param.periodUs;
}
} else {//进程已经创建
initParam->policy = LOS_SCHED_RR;//调度方式为抢占式注意鸿蒙不仅仅只支持抢占式调度方式
initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式
initParam->processID = processID;//进程ID赋值
initParam->consoleID = 0;//默认0号控制台
}
ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体不申请调度
ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体,不申请调度
if (ret != LOS_OK) {
return OS_INVALID_VALUE;
}
return taskID;
}
//获取任务的调度方式
///获取任务的调度方式
LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
{
UINT32 intSave;
@ -1503,7 +1534,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务不能是没有在使用
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//状态不能是没有在使用
policy = -LOS_EINVAL;
OS_GOTO_ERREND();
}
@ -1515,6 +1546,7 @@ LOS_ERREND:
SCHEDULER_UNLOCK(intSave);
return policy;
}
//设置任务的调度信息
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
{
@ -1540,7 +1572,7 @@ LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
SCHEDULER_UNLOCK(intSave);
SCHEDULER_UNLOCK(intSave);
return LOS_EINVAL;
}
@ -1664,7 +1696,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID)
{
return g_taskMaxNum;
}
//任务池中最后一个
/// 任务池中最后一个
LosTaskCB *OsGetDefaultTaskCB(VOID)
{
return &g_taskCBArray[g_taskMaxNum];
@ -1679,28 +1711,27 @@ LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events)
{
(VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL);
}
//资源回收任务
///资源回收任务
STATIC VOID OsResourceRecoveryTask(VOID)
{
UINT32 ret;
while (1) {//死循环,回收资源不存在退出情况,只要系统在运行资源就需要回收
while (1) {//死循环,回收资源不存在退出情况,只要系统在运行资源就需要回收
ret = LOS_EventRead(&g_resourceEvent, OS_RESOURCE_EVENT_MASK,
LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);//读取资源事件
if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {//收到资源释放或内存异常情况
OsTaskCBRecycleToFree();
OsProcessCBRecycleToFree();//回收进程到空闲进程池
}
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK//内存溢出检测任务开关
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK //内存溢出监测任务开关
if (ret & OS_RESOURCE_EVENT_OOM) {//触发了这个事件
(VOID)OomCheckProcess();//检查进程的内存溢出情况
}
#endif
}
}
//创建一个回收资源的任务
///创建一个回收资源的任务
LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
{
UINT32 ret;
@ -1716,7 +1747,7 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;//入口函数
taskInitParam.uwStackSize = OS_TASK_RESOURCE_STATIC_SIZE;
taskInitParam.pcName = "ResourcesTask";
taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;//5优先级很高
taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;// 5 ,优先级很高
ret = LOS_TaskCreate(&taskID, &taskInitParam);
if (ret == LOS_OK) {
OS_TCB_FROM_TID(taskID)->taskStatus |= OS_TASK_FLAG_NO_DELETE;
@ -1725,4 +1756,3 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
}
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);//资源回收任务初始化

@ -37,24 +37,24 @@
#endif
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; //系统时钟,绝大部分部件工作的时钟源,以及所有外设的始终来源
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; //每秒Tick数harmony默认为每秒100次即10ms
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //将周期转为纳秒级
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; ///< 系统时钟,是绝大部分部件工作的时钟源,也是其他所有外设的时钟的来源
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; ///< 每秒Tick数,鸿蒙默认是每秒100次,即:10ms
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; ///< 周期转纳秒级
/* spinlock for task module */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //节拍器自旋锁
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); ///< 节拍器自旋锁
/*
* Description : Tick interruption handler
* Description : Tick interruption handler | ,鸿1ms
*/
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)//节拍中断处理函数harmony默认1ms触发一次
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
{
#ifdef LOSCFG_SCHED_TICK_DEBUG
#ifdef LOSCFG_SCHED_TICK_DEBUG
OsSchedDebugRecordData();
#endif
#ifdef LOSCFG_KERNEL_VDSO
OsVdsoTimevalUpdate(); //更新vdso数据页时间vsdo可以直接在用户进程空间绕过系统调用获取系统时间
OsVdsoTimevalUpdate();//更新vdso数据页时间,vdso可以直接在用户进程空间绕过系统调用获取系统时间(例如:gettimeofday)
#endif
#ifdef LOSCFG_BASE_CORE_TICK_HW_TIME

@ -40,21 +40,78 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_err
* Define the error magic word.
*/
#define OS_ERR_MAGIC_WORD 0xa1b2c3f8
/**
* @ingroup los_err
* @brief Error handling macro capable of returning error codes.
*
* @par Description:
* This API is used to call the error handling function by using an error code and return the same error code.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param errNo [IN] Error code.
*
* @retval errNo
* @par Dependency:
* <ul><li>los_err_pri.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
#define OS_RETURN_ERROR(errNo) do { \
(VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \
return errNo; \
} while (0)
/**
* @ingroup los_err
* @brief Error handling macro capable of returning error codes.
*
* @par Description:
* This API is used to call the error handling function by using an error code and the line number of
* the erroneous line, and return the same error code.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param errLine [IN] Line number of the erroneous line.
* @param errNo [IN] Error code.
*
* @retval errNo
* @par Dependency:
* <ul><li>los_err_pri.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
#define OS_RETURN_ERROR_P2(errLine, errNo) do { \
(VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \
return errNo; \
} while (0)
/**
* @ingroup los_err
* @brief Macro for jumping to error handler.
*
* @par Description:
* This API is used to call the error handling function by using an error code.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param errorNo [IN] Error code.
*
* @retval None.
* @par Dependency:
* <ul><li>los_err_pri.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
#define OS_GOTO_ERR_HANDLER(errorNo) do { \
errNo = errorNo; \
errLine = OS_ERR_MAGIC_WORD; \

@ -1,3 +1,31 @@
/*!
* @file los_futex_pri.h
* @brief
* @link
@verbatim
FUTEX_WAIT
uaddrfutexvalsleepFUTEX_WAKE
futexsleep
futex线线sleepwaiterfutex
futexEAGAIN
线
线FUTEX_WAITFUTEX_WAKE线
FUTEX_WAIT
FUTEX_WAIT
线FUTEX_WAKE线FUTEX_WAKEFUTEX_WAIT线
timeoutNULL使
CLOCK_MONOTONICLinux 4.5futex_op
FUTEX_CLOCK_REALTIME使CLOCK_REALTIMEtimeoutNULL
FUTEX_WAITtimeoutfutextimeout
使FUTEX_BITSET_MATCH_ANYval3FUTEX_WAIT_BITSETtimeoutFUTEX_WAIT
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-24
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.

@ -286,28 +286,52 @@ STATIC INLINE BOOL OsProcessIsPGroupLeader(const LosProcessCB *processCB)
return ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) != 0);
}
/**
* @ingroup los_process
* The highest priority of a kernel mode process.
*/
#define OS_PROCESS_PRIORITY_HIGHEST 0 ///< 进程最高优先级
/**
* @ingroup los_process
* The lowest priority of a kernel mode process
*/
#define OS_PROCESS_PRIORITY_LOWEST 31 ///< 进程最低优先级
/**
* @ingroup los_process
* The highest priority of a user mode process.
*/
#define OS_USER_PROCESS_PRIORITY_HIGHEST 10 ///< 内核模式和用户模式的优先级分割线 10-31 用户级, 0-9内核级
/**
* @ingroup los_process
* The lowest priority of a user mode process
*/
#define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST ///< 用户进程的最低优先级
/**
* @ingroup los_process
* User state root process default priority
*/
#define OS_PROCESS_USERINIT_PRIORITY 28 ///< 用户进程默认的优先级,28级好低啊
/**
* @ingroup los_process
* ID of the kernel idle process
*/
#define OS_KERNEL_IDLE_PROCESS_ID 0U //0号进程为空闲进程
/**
* @ingroup los_process
* ID of the user root process
*/
#define OS_USER_ROOT_PROCESS_ID 1U //1号为用户态根进程
/**
* @ingroup los_process
* ID of the kernel root process
*/
#define OS_KERNEL_ROOT_PROCESS_ID 2U //1号为内核态根进程
#define OS_TASK_DEFAULT_STACK_SIZE 0x2000 ///< task默认栈大小 8K
#define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000 ///< 用户通过系统调用的栈大小 12K ,这时是运行在内核模式下

@ -39,16 +39,35 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @brief @note_pic
* @verbatim
鸿
|<-----,2---->|
+------------+------------------------------------------------------------+
| | |---------------|---------------| |
| | |---------------|---------------| |
| | |---------------|---------------| |
+-------------------------------------------------------------------------+
| | ^ ^ |
|<> | | | |
| | |head |tail |
| + + + |
| |
| |
+<-------------+ ,, +------------->+
* @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))
@ -64,18 +83,21 @@ typedef enum {
/**
* @ingroup los_queue
* Queue information block structure
* @attention
*/
typedef struct TagQueueCB {
UINT8 *queueHandle; /**< Pointer to a queue handle */
UINT16 queueState; /**< Queue state */
UINT16 queueLen; /**< Queue length */
UINT16 queueSize; /**< Node size */
UINT32 queueID; /**< queueID */
UINT16 queueHead; /**< Node head */
UINT16 queueTail; /**< Node tail */
UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
LOS_DL_LIST memList; /**< Pointer to the memory linked list */
typedef struct TagQueueCB{
UINT8 *queueHandle; /**< Pointer to a queue handle | 队列消息内存空间的指针*/
UINT16 queueState; /**< Queue state | 队列状态*/
UINT16 queueLen; /**< Queue length | 队列中消息节点个数,即队列长度,由创建时确定,不再改变*/
UINT16 queueSize; /**< Node size | 消息节点大小,由创建时确定,不再改变,即定义了每个消息长度的上限.*/
UINT32 queueID; /**< queueID | 队列ID*/
UINT16 queueHead; /**< Node head | 消息头节点位置(数组下标)*/
UINT16 queueTail; /**< Node tail | 消息尾节点位置(数组下标)*/
UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable
| 01*/
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist
| /01*/
LOS_DL_LIST memList; /**< Pointer to the memory linked list | 内存块链表*/
} LosQueueCB;
/* queue state */
@ -83,13 +105,13 @@ typedef struct TagQueueCB {
* @ingroup los_queue
* Message queue state: not in use.
*/
#define OS_QUEUE_UNUSED 0
#define OS_QUEUE_UNUSED 0 ///< 队列没有使用
/**
* @ingroup los_queue
* Message queue state: used.
*/
#define OS_QUEUE_INUSED 1
#define OS_QUEUE_INUSED 1 ///< 队列被使用
/**
* @ingroup los_queue

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -41,14 +41,14 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_RWLOCK_MAGIC 0xEFDCAU
#define OS_RWLOCK_MAGIC 0xEFDCAU ///< 读写锁魔法数字
enum RwlockMode {
RWLOCK_NONE_MODE,
RWLOCK_READ_MODE,
RWLOCK_WRITE_MODE,
RWLOCK_READFIRST_MODE,
RWLOCK_WRITEFIRST_MODE
RWLOCK_NONE_MODE, ///< 自由模式: 读写链表都没有内容
RWLOCK_READ_MODE, ///< 读模式: 读链表有数据,写链表没有数据
RWLOCK_WRITE_MODE, ///< 写模式: 写链表有数据,读链表没有数据
RWLOCK_READFIRST_MODE, ///< 读优先模式: 读链表中的任务最高优先级高于写链表中任务最高优先级
RWLOCK_WRITEFIRST_MODE ///< 写优先模式: 写链表中的任务最高优先级高于读链表中任务最高优先级
};
extern UINT32 OsRwlockRdUnsafe(LosRwlock *rwlock, UINT32 timeout);

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -62,8 +62,8 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI)
#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100)
#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) ///< 1毫秒的时钟周期
#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100) ///< 不明白为啥是 * 75 就精确了??? @note_thinking
#define OS_SCHED_MAX_RESPONSE_TIME OS_SORT_LINK_INVALID_TIME
#define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK)
#define AFFI_MASK_TO_CPUID(mask) ((UINT16)((mask) - 1))
@ -78,30 +78,30 @@ extern UINT32 g_taskScheduled;
typedef struct TagTaskCB LosTaskCB;
typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR);
//获取当前调度经历了多少个时间周期
STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID)
{
return HalClockGetCycles();
}
typedef enum {
INT_NO_RESCH = 0x0, /* no needs to schedule */
INT_PEND_RESCH = 0x1, /* pending schedule flag */
INT_PEND_TICK = 0x2, /* pending tick */
INT_NO_RESCH = 0x0, /* no needs to schedule | 无需调度*/
INT_PEND_RESCH = 0x1, /* pending schedule flag | 因阻塞而引起的调度*/
INT_PEND_TICK = 0x2, /* pending tick | 因Tick而引起的调度*/
} SchedFlag;
#define OS_PRIORITY_QUEUE_NUM 32
#define OS_PRIORITY_QUEUE_NUM 32 //队列优先级
typedef struct {
LOS_DL_LIST priQueList[OS_PRIORITY_QUEUE_NUM];
UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM];
UINT32 queueBitmap;
LOS_DL_LIST priQueList[OS_PRIORITY_QUEUE_NUM]; //任务
UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM]; //已就绪任务
UINT32 queueBitmap; //位图
} HPFQueue;
typedef struct {
HPFQueue queueList[OS_PRIORITY_QUEUE_NUM];
HPFQueue queueList[OS_PRIORITY_QUEUE_NUM]; //
UINT32 queueBitmap;
} HPFRunqueue;
//调度运行队列
typedef struct {
LOS_DL_LIST root;
LOS_DL_LIST waitList;
@ -119,10 +119,10 @@ typedef struct {
UINT32 schedFlag; /* pending scheduler flag */
} SchedRunqueue;
extern SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM];
extern SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM];//每个CPU核都有一个属于自己的调度队列
VOID OsSchedExpireTimeUpdate(VOID);
//获取当前CPU
STATIC INLINE SchedRunqueue *OsSchedRunqueue(VOID)
{
return &g_schedRunqueue[ArchCurrCpuid()];
@ -223,10 +223,10 @@ STATIC INLINE VOID OsSchedRunqueuePendingSet(VOID)
OsSchedRunqueue()->schedFlag |= INT_PEND_RESCH;
}
#define LOS_SCHED_NORMAL 0U
#define LOS_SCHED_FIFO 1U
#define LOS_SCHED_RR 2U
#define LOS_SCHED_IDLE 3U
#define LOS_SCHED_NORMAL 0U
#define LOS_SCHED_FIFO 1U
#define LOS_SCHED_RR 2U
#define LOS_SCHED_IDLE 3U
#define LOS_SCHED_DEADLINE 6U
typedef struct {
@ -242,19 +242,21 @@ typedef struct {
UINT32 periodUs;
} SchedParam;
typedef struct {
UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure */
UINT16 basePrio;
UINT16 priority;
UINT32 initTimeSlice; /* cycle */
UINT32 priBitmap; /* Bitmap for recording the change of task priority, the priority can not be greater than 31 */
typedef struct {//记录任务调度信息
UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure
| */
UINT16 basePrio; ///< 起始优先级
UINT16 priority; ///< 当前优先级
UINT32 initTimeSlice;///< 初始化时间片
UINT32 priBitmap; /**< Bitmap for recording the change of task priority, the priority can not be greater than 31
| 31 */
} SchedHPF;
#define EDF_UNUSED 0
#define EDF_NEXT_PERIOD 1
#define EDF_WAIT_FOREVER 2
#define EDF_INIT 3
typedef struct {
typedef struct { //调度策略
UINT16 policy;
UINT16 cpuid;
UINT32 flags;
@ -267,29 +269,29 @@ typedef struct {
typedef struct {
union {
SchedEDF edf;
SchedHPF hpf;
SchedHPF hpf; // 目前只支持 优先级策略Highest-Priority-FirstHPF
};
} SchedPolicy;
typedef struct {
VOID (*dequeue)(SchedRunqueue *rq, LosTaskCB *taskCB);
VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB);
VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB);
VOID (*exit)(LosTaskCB *taskCB);
typedef struct {//调度接口函数
VOID (*dequeue)(SchedRunqueue *rq, LosTaskCB *taskCB); ///< 出队列
VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB); ///< 入队列
VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB); ///< 开始执行任务
VOID (*exit)(LosTaskCB *taskCB); ///< 任务退出
UINT64 (*waitTimeGet)(LosTaskCB *taskCB);
UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout);
VOID (*wake)(LosTaskCB *taskCB);
BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param);
UINT32 (*schedParamGet)(const LosTaskCB *taskCB, SchedParam *param);
UINT32 (*delay)(LosTaskCB *taskCB, UINT64 waitTime);
VOID (*yield)(LosTaskCB *taskCB);
UINT32 (*suspend)(LosTaskCB *taskCB);
UINT32 (*resume)(LosTaskCB *taskCB, BOOL *needSched);
UINT64 (*deadlineGet)(const LosTaskCB *taskCB);
VOID (*timeSliceUpdate)(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime);
INT32 (*schedParamCompare)(const SchedPolicy *sp1, const SchedPolicy *sp2);
VOID (*priorityInheritance)(LosTaskCB *owner, const SchedParam *param);
VOID (*priorityRestore)(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout); ///< 任务等待
VOID (*wake)(LosTaskCB *taskCB);///< 任务唤醒
BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param);///< 修改调度参数
UINT32 (*schedParamGet)(const LosTaskCB *taskCB, SchedParam *param);///< 获取调度参数
UINT32 (*delay)(LosTaskCB *taskCB, UINT64 waitTime);///< 延时执行
VOID (*yield)(LosTaskCB *taskCB);///< 让出控制权
UINT32 (*suspend)(LosTaskCB *taskCB);///< 挂起任务
UINT32 (*resume)(LosTaskCB *taskCB, BOOL *needSched);///< 恢复任务
UINT64 (*deadlineGet)(const LosTaskCB *taskCB);///< 获取最后期限
VOID (*timeSliceUpdate)(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime);///< 更新时间片
INT32 (*schedParamCompare)(const SchedPolicy *sp1, const SchedPolicy *sp2); ///< 比较调度参数
VOID (*priorityInheritance)(LosTaskCB *owner, const SchedParam *param);//继承调度参数
VOID (*priorityRestore)(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);///< 恢复调度参数
} SchedOps;
/**
@ -298,7 +300,7 @@ typedef struct {
*
* Highest task priority.
*/
#define OS_TASK_PRIORITY_HIGHEST 0
#define OS_TASK_PRIORITY_HIGHEST 0 /// 任务最高优先级
/**
* @ingroup los_sched
@ -306,7 +308,7 @@ typedef struct {
*
* Lowest task priority.
*/
#define OS_TASK_PRIORITY_LOWEST 31
#define OS_TASK_PRIORITY_LOWEST 31 /// 任务最低优先级
/**
* @ingroup los_sched
@ -314,7 +316,7 @@ typedef struct {
*
* The task is init.
*/
#define OS_TASK_STATUS_INIT 0x0001U
#define OS_TASK_STATUS_INIT 0x0001U /// 任务初始状态
/**
* @ingroup los_sched
@ -390,80 +392,80 @@ typedef struct {
* The delayed operation of this task is frozen.
*/
#define OS_TASK_STATUS_FROZEN 0x0200U
#define OS_TCB_NAME_LEN 32
typedef struct TagTaskCB {
VOID *stackPointer; /**< Task stack pointer */
UINT16 taskStatus; /**< Task status */
UINT64 startTime; /**< The start time of each phase of task */
UINT64 waitTime; /**< Task delay time, tick number */
UINT64 irqStartTime; /**< Interrupt start time */
UINT32 irqUsedTime; /**< Interrupt consumption time */
INT32 timeSlice; /**< Task remaining time slice */
SortLinkList sortList; /**< Task sortlink node */
VOID *stackPointer; /**< Task stack pointer | 内核栈指针位置(SP) */
UINT16 taskStatus; /**< Task status | 各种状态标签,可以拥有多种标签,按位标识 */
UINT64 startTime; /**< The start time of each phase of task | 任务开始时间 */
UINT64 waitTime; /**< Task delay time, tick number | 设置任务调度延期时间 */
UINT64 irqStartTime; /**< Interrupt start time | 任务中断开始时间 */
UINT32 irqUsedTime; /**< Interrupt consumption time | 任务中断消耗时间 */
INT32 timeSlice; /**< Task remaining time slice | 任务剩余时间片 */
SortLinkList sortList; /**< Task sortlink node | 跟CPU捆绑的任务排序链表节点,上面挂的是就绪队列的下一个阶段,进入CPU要执行的任务队列 */
const SchedOps *ops;
SchedPolicy sp;
UINT32 stackSize; /**< Task stack size */
UINTPTR topOfStack; /**< Task stack top */
UINT32 taskID; /**< Task ID */
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */
VOID *joinRetval; /**< pthread adaption */
VOID *taskMux; /**< Task-held mutex */
VOID *taskEvent; /**< Task-held event */
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */
LOS_DL_LIST pendList; /**< Task pend node */
LOS_DL_LIST threadList; /**< thread list */
UINT32 eventMask; /**< Event mask */
UINT32 eventMode; /**< Event mode */
UINT32 stackSize; /**< Task stack size | 内核态栈大小,内存来自内核空间 */
UINTPTR topOfStack; /**< Task stack top | 内核态栈顶 bottom = top + size */
UINT32 taskID; /**< Task ID | 任务ID任务池本质是一个大数组ID就是数组的索引默认 < 128 */
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function | 任务执行入口地址 */
VOID *joinRetval; /**< pthread adaption | 用来存储join线程的入口地址 */
VOID *taskMux; /**< Task-held mutex | task在等哪把锁 */
VOID *taskEvent; /**< Task-held event | task在等哪个事件 */
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 | 入口函数的参数 例如 main (int argc,char *argv[]) */
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name | 任务的名称 */
LOS_DL_LIST pendList; /**< Task pend node | 如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 */
LOS_DL_LIST threadList; /**< thread list | 挂到所属进程的线程链表上 */
UINT32 eventMask; /**< Event mask | 任务对哪些事件进行屏蔽 */
UINT32 eventMode; /**< Event mode | 事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR) */
#ifdef LOSCFG_KERNEL_CPUP
OsCpupBase taskCpup; /**< task cpu usage */
OsCpupBase taskCpup; /**< task cpu usage | CPU 使用统计 */
#endif
INT32 errorNo; /**< Error Num */
UINT32 signal; /**< Task signal */
sig_cb sig;
INT32 errorNo; /**< Error Num | 错误序号 */
UINT32 signal; /**< Task signal | 任务信号类型,(SIGNAL_NONE,SIGNAL_KILL,SIGNAL_SUSPEND,SIGNAL_AFFI) */
sig_cb sig; ///< 信号控制块,用于异步通信,类似于 linux singal模块
#ifdef LOSCFG_KERNEL_SMP
UINT16 currCpu; /**< CPU core number of this task is running on */
UINT16 lastCpu; /**< CPU core number of this task is running on last time */
UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
UINT32 syncSignal; /**< Synchronization for signal handling */
UINT16 currCpu; /**< CPU core number of this task is running on | 正在运行此任务的CPU内核号 */
UINT16 lastCpu; /**< CPU core number of this task is running on last time | 上次运行此任务的CPU内核号 */
UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores | CPU亲和力掩码最多支持16核亲和力很重要多核情况下尽量一个任务在一个CPU核上运行提高效率 */
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC //多核情况下的任务同步开关,采用信号量实现
UINT32 syncSignal; /**< Synchronization for signal handling | 用于CPU之间同步信号量 */
#endif
#ifdef LOSCFG_KERNEL_SMP_LOCKDEP
LockDep lockDep;
#ifdef LOSCFG_KERNEL_SMP_LOCKDEP //SMP死锁检测开关
LockDep lockDep; ///< 死锁依赖检测
#endif
#endif
#ifdef LOSCFG_SCHED_DEBUG
SchedStat schedStat; /**< Schedule statistics */
#ifdef LOSCFG_SCHED_DEBUG //调试调度开关
SchedStat schedStat; /**< Schedule statistics | 调度统计 */
#endif
#ifdef LOSCFG_KERNEL_VM
UINTPTR archMmu;
UINTPTR userArea;
UINTPTR userMapBase;
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
FutexNode futex;
UINTPTR userArea; ///< 用户空间的堆区开始位置
UINTPTR userMapBase; ///< 用户空间的栈顶位置,内存来自用户空间,和topOfStack有本质的区别.
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE | 用户栈大小 */
FutexNode futex; ///< 指明任务在等待哪把快锁,一次只等一锁,锁和任务的关系是(1:N)关系
#endif
UINTPTR processCB; /**< Which belong process */
LOS_DL_LIST joinList; /**< join list */
LOS_DL_LIST lockList; /**< Hold the lock list */
UINTPTR waitID; /**< Wait for the PID or GID of the child process */
LOS_DL_LIST joinList; /**< join list | 联结链表,允许任务之间相互释放彼此 */
LOS_DL_LIST lockList; /**< Hold the lock list | 该链表上挂的都是已持有的锁 */
UINTPTR waitID; /**< Wait for the PID or GID of the child process | 等待子进程的PID或GID */
UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent,
a specific child process, or any child process */
#ifdef LOSCFG_KERNEL_LITEIPC
IpcTaskInfo *ipcTaskInfo;
a specific child process, or any child process | ? (OS_TASK_WAIT_PROCESS | OS_TASK_WAIT_GID | OS_TASK_WAIT_LITEIPC ..)
,*/
#ifdef LOSCFG_KERNEL_LITEIPC //轻量级进程间通信开关
IpcTaskInfo *ipcTaskInfo; ///< 任务间通讯信息结构体
#endif
#ifdef LOSCFG_KERNEL_PERF
UINTPTR pc;
UINTPTR fp;
UINTPTR pc; ///< pc寄存器
UINTPTR fp; ///< fp寄存器
#endif
#ifdef LOSCFG_PID_CONTAINER
PidContainer *pidContainer;
PidContainer *pidContainer;//进程容器
#endif
#ifdef LOSCFG_IPC_CONTAINER
BOOL cloneIpc;
BOOL cloneIpc;//是否克隆过IPC flags & CLONE_NEWIPC
#endif
} LosTaskCB;
@ -507,7 +509,7 @@ STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
{
return (LosTaskCB *)ArchCurrTaskGet();
}
/// 注意任务地址由硬件保存,见于 CP15 | TPIDRPRW
STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task)
{
ArchCurrTaskSet(task);
@ -521,13 +523,13 @@ STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread)
STATIC INLINE VOID OsSchedIrqUsedTimeUpdate(VOID)
{
LosTaskCB *runTask = OsCurrTaskGet();
runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime;
runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime;//获取时间差
}
/// 获取中断开始时间
STATIC INLINE VOID OsSchedIrqStartTime(VOID)
{
LosTaskCB *runTask = OsCurrTaskGet();
runTask->irqStartTime = OsGetCurrSchedTimeCycle();
runTask->irqStartTime = OsGetCurrSchedTimeCycle(); //获取当前时间
}
#ifdef LOSCFG_KERNEL_SMP
@ -654,11 +656,11 @@ STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB)
#define OS_SCHEDULER_SET(cpuid) do { \
g_taskScheduled |= (1U << (cpuid)); \
} while (0);
//清楚调度标识位,对应位设置为0
#define OS_SCHEDULER_CLR(cpuid) do { \
g_taskScheduled &= ~(1U << (cpuid)); \
} while (0);
//获取最高优先级任务
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
BOOL OsSchedLimitCheckTime(LosTaskCB *task);
#endif

@ -46,7 +46,7 @@ extern UINT32 OsSemDbgInit(VOID);
STATIC INLINE UINT32 OsSemDbgInitHook(VOID)
{
#ifdef LOSCFG_DEBUG_SEMAPHORE
return OsSemDbgInit();
return OsSemDbgInit();//信号量debug初始化
#else
return LOS_OK;
#endif

@ -45,11 +45,11 @@ extern "C" {
* Semaphore control structure.
*/
typedef struct {
UINT8 semStat; /**< Semaphore state */
UINT16 semCount; /**< Number of available semaphores */
UINT16 maxSemCount; /**< Max number of available semaphores */
UINT32 semID; /**< Semaphore control structure ID */
LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore */
UINT8 semStat; /**< Semaphore state | 信号量的状态 */
UINT16 semCount; /**< Number of available semaphores | 有效信号量的数量 */
UINT16 maxSemCount; /**< Max number of available semaphores | 有效信号量的最大数量 */
UINT32 semID; /**< Semaphore control structure ID | 信号量索引号 */
LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore | 挂接阻塞于该信号量的任务 */
} LosSemCB;
/**

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -43,15 +43,76 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @file los_signal.h
* @brief
* @verbatim
Linux
#define LOS_BIT_SET(val, bit) ((val) = (val) | (1ULL << (UINT32)(bit)))
#define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit)))
#define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL))
signal
kill
: ..\third_party\musl\arch\aarch64\bits\signal.h
#define SIGHUP 1 //终端挂起或者控制进程终止
#define SIGINT 2 //键盘中断如break键被按下
#define SIGQUIT 3 //键盘的退出键被按下
#define SIGILL 4 //非法指令
#define SIGTRAP 5 //跟踪陷阱trace trap启动进程跟踪代码的执行
#define SIGABRT 6 //由abort(3)发出的退出指令
#define SIGIOT SIGABRT //abort发出的信号
#define SIGBUS 7 //总线错误
#define SIGFPE 8 //浮点异常
#define SIGKILL 9 //常用的命令 kill 9 123 | 不能被忽略、处理和阻塞
#define SIGUSR1 10 //用户自定义信号1
#define SIGSEGV 11 //无效的内存引用, 段违例segmentation violation进程试图去访问其虚地址空间以外的位置
#define SIGUSR2 12 //用户自定义信号2
#define SIGPIPE 13 //向某个非读管道中写入数据
#define SIGALRM 14 //由alarm(2)发出的信号,默认行为为进程终止
#define SIGTERM 15 //终止信号, kill不带参数时默认发送这个信号
#define SIGSTKFLT 16 //栈溢出
#define SIGCHLD 17 //子进程结束信号
#define SIGCONT 18 //进程继续(曾被停止的进程)
#define SIGSTOP 19 //终止进程 | 不能被忽略、处理和阻塞
#define SIGTSTP 20 //控制终端tty上 按下停止键
#define SIGTTIN 21 //进程停止,后台进程企图从控制终端读
#define SIGTTOU 22 //进程停止,后台进程企图从控制终端写
#define SIGURG 23 //I/O有紧急数据到达当前进程
#define SIGXCPU 24 //进程的CPU时间片到期
#define SIGXFSZ 25 //文件大小的超出上限
#define SIGVTALRM 26 //虚拟时钟超时
#define SIGPROF 27 //profile时钟超时
#define SIGWINCH 28 //窗口大小改变
#define SIGIO 29 //I/O相关
#define SIGPOLL 29 //
#define SIGPWR 30 //电源故障,关机
#define SIGSYS 31 //系统调用中参数错,如系统调用号非法
#define SIGUNUSED SIGSYS //系统调用异常
#define _NSIG 65 //信号范围,不超过_NSIG
https://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html
Musl http://musl.libc.org/
muslLinuxAPICPOSIX
广musl.
* @endverbatim
* @param pathname
* @return int
*/
#define LOS_BIT_SET(val, bit) ((val) = (val) | (1ULL << (UINT32)(bit))) ///< 按位设置
#define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit))) ///< 按位清除
#define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL)) ///< 位是否设置为1
#define SIG_STOP_VISIT 1
#define OS_KERNEL_KILL_PERMISSION 0U
#define OS_USER_KILL_PERMISSION 3U
#define OS_KERNEL_KILL_PERMISSION 0U ///< 内核态 kill 权限
#define OS_USER_KILL_PERMISSION 3U ///< 用户态 kill 权限
#define OS_RETURN_IF(expr, errcode) \
if ((expr)) { \
@ -91,20 +152,37 @@ typedef void (*sa_sighandler_t)(int);
typedef void (*sa_siginfoaction_t)(int, siginfo_t *, void *);
#define SIGNO2SET(s) ((sigset_t)1ULL << (s))
#define NULL_SIGNAL_SET ((sigset_t)0ULL)
#define FULL_SIGNAL_SET ((sigset_t)~0ULL)
#define NULL_SIGNAL_SET ((sigset_t)0ULL) ///< 信号集全部清0
#define FULL_SIGNAL_SET ((sigset_t)~0ULL) ///< 信号集全部置1
///信号ID是否有效
static inline int GOOD_SIGNO(unsigned int sig)
{
return (sig < _NSIG) ? 1 : 0;
return (sig < _NSIG) ? 1 : 0;//
}
#define MAX_SIG_ARRAY_IN_MUSL 128
#define MAX_SIG_ARRAY_IN_MUSL 128 ///< 128个信号
typedef struct {
unsigned long sig[MAX_SIG_ARRAY_IN_MUSL / sizeof(unsigned long)];
} sigset_t_l;
/***************************************************
struct sigaction {
union {
void (*sa_handler)(int); //信号处理函数——普通版
void (*sa_sigaction)(int, siginfo_t *, void *);//信号处理函数——高级版
} __sa_handler;
sigset_t sa_mask;//指定信号处理程序执行过程中需要阻塞的信号;
int sa_flags; //标示位
// SA_RESTART使被信号打断的syscall重新发起。
// SA_NOCLDSTOP使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。
// SA_NOCLDWAIT使父进程在它的子进程退出时不会收到SIGCHLD信号这时子进程如果退出也不会成为僵 尸进程。
// SA_NODEFER使对信号的屏蔽无效即在信号处理函数执行期间仍能发出这个信号。
// SA_RESETHAND信号处理之后重新设置为默认的处理方式。
// SA_SIGINFO使用sa_sigaction成员而不是sa_handler作为信号处理函数。
void (*sa_restorer)(void);
};
****************************************************/
typedef struct sigaction sigaction_t;
struct sigactq {
@ -126,7 +204,7 @@ struct sigpendq {
};
typedef struct sigpendq sigpendq_t;
struct sq_queue_s {
struct sq_queue_s {//信号队列
sq_entry_t *head;
sq_entry_t *tail;
};
@ -136,23 +214,24 @@ typedef struct SigInfoListNode {
struct SigInfoListNode *next;
siginfo_t info;
} SigInfoListNode;
/**
* @brief ()
*/
typedef struct {
sigset_t sigFlag;
sigset_t sigPendFlag;
sigset_t sigprocmask; /* Signals that are blocked */
sq_queue_t sigactionq;
LOS_DL_LIST waitList;
sigset_t sigwaitmask; /* Waiting for pending signals */
siginfo_t sigunbinfo; /* Signal info when task unblocked */
SigInfoListNode *tmpInfoListHead; /* Signal info List */
unsigned int sigIntLock;
void *sigContext;
unsigned int count;
sigset_t sigFlag; ///< 不屏蔽的信号集
sigset_t sigPendFlag; ///< 信号阻塞标签集,记录那些信号来过,任务依然阻塞的集合.即:这些信号不能唤醒任务
sigset_t sigprocmask; ///< Signals that are blocked | 任务屏蔽了哪些信号
sq_queue_t sigactionq; ///< 信号捕捉队列
LOS_DL_LIST waitList; ///< 待链表,上面挂的是等待信号到来的任务, 请查找 OsTaskWait(&sigcb->waitList, timeout, TRUE) 理解
sigset_t sigwaitmask; /*! Waiting for pending signals | 任务在等待哪些信号的到来 */
siginfo_t sigunbinfo; /*! Signal info when task unblocked | 任务解锁时的信号信息 */
SigInfoListNode *tmpInfoListHead; /*! Signal info List */
unsigned int sigIntLock;///< 信号中断锁
void *sigContext; ///< 信号上下文
unsigned int count;///< 信号数量
} sig_cb;
typedef struct ProcessCB LosProcessCB;
#define SIGEV_THREAD_ID 4
int sys_sigqueue(pid_t, int, const union sigval);

@ -42,17 +42,24 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*! \struct SortLinkList
*
*/
typedef struct {
LOS_DL_LIST sortLinkNode;
UINT64 responseTime;
LOS_DL_LIST sortLinkNode; ///< 排序链表,注意上面挂的是一个个等待被执行的任务/软件定时器
UINT64 responseTime; ///< 响应时间,这里提取了最近需要触发的定时器/任务的时间,见于 OsAddNode2SortLink 的实现
#ifdef LOSCFG_KERNEL_SMP
UINT32 cpuid;
UINT32 cpuid; ///< 需要哪个CPU处理
#endif
} SortLinkList;
/*! \struct SortLinkAttribute
* @brief
*/
typedef struct {
LOS_DL_LIST sortLink;
UINT32 nodeNum;
LOS_DL_LIST sortLink; ///< 排序链表,上面挂的任务/软件定时器
UINT32 nodeNum; ///< 链表结点数量
SPIN_LOCK_S spinLock; /* swtmr sort link spin lock */
} SortLinkAttribute;

@ -41,14 +41,17 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*! \struct StackInfo
*
*/
typedef struct {
VOID *stackTop;
UINT32 stackSize;
CHAR *stackName;
VOID *stackTop; ///< 栈顶
UINT32 stackSize; ///< 栈大小
CHAR *stackName; ///< 栈名称
} StackInfo;
#define OS_INVALID_WATERLINE 0xFFFFFFFF
#define OS_STACK_MAGIC_CHECK(topstack) (*(UINTPTR *)(topstack) == OS_STACK_MAGIC_WORD) /* 1:magic valid 0:invalid */
#define OS_STACK_MAGIC_CHECK(topstack) (*(UINTPTR *)(topstack) == OS_STACK_MAGIC_WORD) /* 1:magic valid 0:unvalid */
extern VOID OsExcStackInfo(VOID);
extern VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum);
@ -81,4 +84,4 @@ extern UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *sta
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_STACK_INFO_PRI_H */
#endif /* _LOS_STACK_INFO_PRI_H */

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -39,7 +39,7 @@
#ifdef LOSCFG_SECURITY_VID
#include "vid_api.h"
#else
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID //最大支持的软件定时器数量 < 65535
#endif
#ifdef __cplusplus
@ -52,21 +52,21 @@ extern "C" {
* @ingroup los_swtmr_pri
* Software timer state
*/
enum SwtmrState {
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */
enum SwtmrState { //定时器状态
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. | 定时器未使用,系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。 */
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. | 定时器创建后未启动,或已停止.定时器创建后,不处于计数状态时,定时器将变成该状态。 */
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. | 定时器处于计数状态,在定时器创建后调用LOS_SwtmrStart接口启动定时器将变成该状态是定时器运行时的状态。 */
};
/**
* @ingroup los_swtmr_pri
* Structure of the callback function that handles software timer timeout
*/
typedef struct {
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */
typedef struct {//处理软件定时器超时的回调函数的结构体
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout | 处理软件定时器超时的回调函数*/
UINTPTR arg; /**< Parameter passed in when the callback function
that handles software timer timeout is called */
LOS_DL_LIST node;
that handles software timer timeout is called | */
LOS_DL_LIST node; ///< 挂入定时器超时队列,详见 SwtmrWake( ... )
#ifdef LOSCFG_SWTMR_DEBUG
UINT32 swtmrID;
#endif
@ -75,11 +75,12 @@ typedef struct {
/**
* @ingroup los_swtmr_pri
* Type of the pointer to the structure of the callback function that handles software timer timeout
*/
*/ //指向处理软件计时器超时的回调函数结构的指针的类型
typedef SwtmrHandlerItem *SwtmrHandlerItemPtr;
extern SWTMR_CTRL_S *g_swtmrCBArray;
extern SWTMR_CTRL_S *g_swtmrCBArray;//软件定时器数组,后续统一注解为定时器池
//通过参数ID找到对应定时器描述体
#define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT))
/**

@ -43,63 +43,62 @@ extern "C" {
/**
* @ingroup los_sys
* Number of milliseconds in one second.
* Number of milliseconds in one second.
*/
#define OS_SYS_MS_PER_SECOND 1000
#define OS_SYS_MS_PER_SECOND 1000 ///< 一秒多少毫秒
/**
* @ingroup los_sys
* Number of microseconds in one second.
*/
#define OS_SYS_US_PER_SECOND 1000000
#define OS_SYS_US_PER_SECOND 1000000 ///< 一秒多少微秒
/**
* @ingroup los_sys
* Number of nanoseconds in one second.
*/
#define OS_SYS_NS_PER_SECOND 1000000000
#define OS_SYS_NS_PER_SECOND 1000000000 ///< 一秒多少纳秒
/**
* @ingroup los_sys
* Number of microseconds in one milliseconds.
*/
#define OS_SYS_US_PER_MS 1000
#define OS_SYS_US_PER_MS 1000 ///< 一毫秒的微秒数
/**
* @ingroup los_sys
* Number of nanoseconds in one milliseconds.
*/
#define OS_SYS_NS_PER_MS 1000000
#define OS_SYS_NS_PER_MS 1000000 ///< 一毫秒的纳秒数
/**
* @ingroup los_sys
* Number of nanoseconds in one microsecond.
*/
#define OS_SYS_NS_PER_US 1000
#define OS_SYS_NS_PER_US 1000 ///< 一微秒的纳秒数
/**
* @ingroup los_sys
* Number of cycle in one tick.
*/
#define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND)
#define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND) ///< 一个节拍的周期数
/**
* @ingroup los_sys
* Number of nanoseconds in one cycle.
*/
#define OS_NS_PER_CYCLE (OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK)
#define OS_NS_PER_CYCLE (OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK) ///< 一周期的纳秒数
/**
* @ingroup los_sys
* Number of microseconds in one tick.
*/
#define OS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
#define OS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) ///< 一个tick的微秒数
/**
* @ingroup los_sys
* Number of nanoseconds in one tick.
*/
#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) ///< 一个tick的纳秒数
#define OS_US_TO_CYCLE(time, freq) ((((time) / OS_SYS_US_PER_SECOND) * (freq)) + \
(((time) % OS_SYS_US_PER_SECOND) * (freq) / OS_SYS_US_PER_SECOND))
@ -115,19 +114,19 @@ extern "C" {
* @ingroup los_sys
* The maximum length of name.
*/
#define OS_SYS_APPVER_NAME_MAX 64
#define OS_SYS_APPVER_NAME_MAX 64 ///< 名字的最大长度
/**
* @ingroup los_sys
* The magic word.
*/
#define OS_SYS_MAGIC_WORD 0xAAAAAAAA
#define OS_SYS_MAGIC_WORD 0xAAAAAAAA ///< 魔法数字,还记得栈顶的魔法数字是多少吗? 0xCCCCCCCC
/**
* @ingroup los_sys
* The initialization value of stack space.
*/
#define OS_SYS_EMPTY_STACK 0xCACACACA
#define OS_SYS_EMPTY_STACK 0xCACACACA ///< 栈的填充内容魔法数字
/**
* @ingroup los_sys

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -43,17 +43,17 @@ extern "C" {
/**
* @ingroup los_task
* Define task signal types.
* Define task siginal types.
*
* Task signal types.
* Task siginal types.
*/
#define SIGNAL_NONE 0U
#define SIGNAL_KILL (1U << 0)
#define SIGNAL_SUSPEND (1U << 1)
#define SIGNAL_AFFI (1U << 2)
#define SIGNAL_NONE 0U ///< 无信号
#define SIGNAL_KILL (1U << 0) ///< 干掉
#define SIGNAL_SUSPEND (1U << 1) ///< 挂起
#define SIGNAL_AFFI (1U << 2) ///< CPU 亲和性,一个任务被切换后被同一个CPU再次执行,则亲和力高
/* scheduler lock */
extern SPIN_LOCK_S g_taskSpin;
extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
#define SCHEDULER_HELD() LOS_SpinHeld(&g_taskSpin)
#define SCHEDULER_LOCK(state) LOS_SpinLockSave(&g_taskSpin, &(state))
#define SCHEDULER_UNLOCK(state) LOS_SpinUnlockRestore(&g_taskSpin, state)
@ -66,7 +66,7 @@ extern SPIN_LOCK_S g_taskSpin;
* Null task ID
*
*/
#define OS_TASK_ERRORID 0xFFFFFFFF
#define OS_TASK_ERRORID 0xFFFFFFFF
/**
* @ingroup los_task
@ -74,7 +74,7 @@ extern SPIN_LOCK_S g_taskSpin;
*
* The task control block is unused.
*/
#define OS_TASK_STATUS_UNUSED 0x0400U
#define OS_TASK_STATUS_UNUSED 0x0400U ///< 任务状态:未使用
/**
* @ingroup los_task
@ -82,7 +82,7 @@ extern SPIN_LOCK_S g_taskSpin;
*
* The task is joinable.
*/
#define OS_TASK_FLAG_PTHREAD_JOIN 0x0800U
#define OS_TASK_FLAG_PTHREAD_JOIN 0x0800U ///< 主task和子task连在一块不分离
/**
* @ingroup los_task
@ -98,15 +98,15 @@ extern SPIN_LOCK_S g_taskSpin;
*
* The task is system-level task, like idle, swtmr and etc.
*/
#define OS_TASK_FLAG_SYSTEM_TASK 0x2000U
#define OS_TASK_FLAG_SYSTEM_TASK 0x2000U ///< 系统任务
/**
* @ingroup los_task
* Flag that indicates the task property.
*
* The task is no-delete system task, like resourceTask.
* The task is no-delete system task, like resourceTask.
*/
#define OS_TASK_FLAG_NO_DELETE 0x4000U
#define OS_TASK_FLAG_NO_DELETE 0x4000U ///< 该任务是不可删除的系统任务,如资源回收任务
/**
* @ingroup los_task
@ -114,7 +114,7 @@ extern SPIN_LOCK_S g_taskSpin;
*
* Kills the thread during process exit.
*/
#define OS_TASK_FLAG_EXIT_KILL 0x8000U
#define OS_TASK_FLAG_EXIT_KILL 0x8000U ///< 在进程退出期间一同被干掉的任务
/**
* @ingroup los_task
@ -122,25 +122,25 @@ extern SPIN_LOCK_S g_taskSpin;
*
* Specifies the process creation task.
*/
#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U
#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U ///< 创建指定任务 例如: cat weharmony.net 的实现
/**
* @ingroup los_task
* Boundary on which the stack size is aligned.
*
*/
#define OS_TASK_STACK_SIZE_ALIGN 16U
#define OS_TASK_STACK_SIZE_ALIGN 16U ///< 堆栈大小对齐
/**
* @ingroup los_task
* Boundary on which the stack address is aligned.
*
*/
#define OS_TASK_STACK_ADDR_ALIGN 8U
#define OS_TASK_STACK_ADDR_ALIGN 8U ///< 堆栈地址对齐
/**
* @ingroup los_task
* Number of usable task priorities.
* Number of usable task priorities. |
*/
#define OS_TSK_PRINUM (OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST + 1)
@ -175,9 +175,9 @@ extern SPIN_LOCK_S g_taskSpin;
* @par Dependency:
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
* @see
*/
*/ ///通过pendList取出TCB,用于挂入链表节点时使用 pendList的情况
#define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosTaskCB, pendList)
/**
* @ingroup los_task
* @brief Obtain the pointer to a task control block.
@ -204,56 +204,60 @@ extern SPIN_LOCK_S g_taskSpin;
#define LOSCFG_STACK_POINT_ALIGN_SIZE (sizeof(UINTPTR) * 2)
#endif
#define OS_TASK_RESOURCE_STATIC_SIZE 0x1000
#define OS_TASK_RESOURCE_FREE_PRIORITY 5
#define OS_RESOURCE_EVENT_MASK 0xFF
#define OS_RESOURCE_EVENT_OOM 0x02
#define OS_RESOURCE_EVENT_FREE 0x04
#define OS_TASK_RESOURCE_STATIC_SIZE 0x1000 ///< 4K
#define OS_TASK_RESOURCE_FREE_PRIORITY 5 ///< 回收资源任务的优先级
#define OS_RESOURCE_EVENT_MASK 0xFF ///< 资源事件的掩码
#define OS_RESOURCE_EVENT_OOM 0x02 ///< 内存溢出事件
#define OS_RESOURCE_EVENT_FREE 0x04 ///< 资源释放事件
///< LosTask结构体是给外部使用的
typedef struct {
LosTaskCB *runTask;
LosTaskCB *newTask;
} LosTask;
///< 进程信号描述符
struct ProcessSignalInfo {
siginfo_t *sigInfo; /**< Signal to be dispatched */
LosTaskCB *defaultTcb; /**< Default TCB */
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB*/
LosTaskCB *awakenedTcb; /**< This TCB was awakened */
LosTaskCB *receivedTcb; /**< This TCB received the signal */
siginfo_t *sigInfo; /**< Signal to be dispatched | 要发送的信号*/
LosTaskCB *defaultTcb; /**< Default TCB | 默认task,默认接收信号的任务. */
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB | 信号在此TCB上解除阻塞 */
LosTaskCB *awakenedTcb; /**< This TCB was awakened | 即 任务在等待这个信号,此信号一来任务被唤醒.*/
LosTaskCB *receivedTcb; /**< This TCB received the signal | 如果没有屏蔽信号,任务将接收这个信号. */
};
typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);
typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);///< 回调任务函数,例如:进程被kill 9 时,通知所有任务善后处理
/**
* @ingroup los_task
* Maximum number of tasks.
*
*/
extern UINT32 g_taskMaxNum;
extern UINT32 g_taskMaxNum;///< 任务最大数量 默认128个
/**
* @ingroup los_task
* Starting address of a task.
*
*/
extern LosTaskCB *g_taskCBArray;
extern LosTaskCB *g_taskCBArray;///< 外部变量 任务池 默认128个
/**
* @ingroup los_task
* Time slice structure.
*/
typedef struct {
LosTaskCB *task; /**< Current running task */
UINT16 time; /**< Expiration time point */
UINT16 timeout; /**< Expiration duration */
typedef struct {//时间片结构体,任务轮询
LosTaskCB *task; /**< Current running task | 当前运行着的任务*/
UINT16 time; /**< Expiration time point | 到期时间点*/
UINT16 timeout; /**< Expiration duration | 有效期*/
} OsTaskRobin;
/// 通过任务ID获取任务实体task由任务池分配本质是个数组彼此都挨在一块
STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID)
{
return OS_TCB_FROM_TID(taskID);
}
/// 任务是否在使用
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
{
return ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) != 0);
@ -261,45 +265,46 @@ STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB)
{
return((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) != 0);
return ((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) != 0);
}
STATIC INLINE BOOL OsTaskIsNotDelete(const LosTaskCB *taskCB)
{
return ((taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) != 0);
}
STATIC INLINE BOOL OsTaskIsUserMode(const LosTaskCB *taskCB)
{
return ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) != 0);
}
#define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum)
#define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum)//是否有无效的任务 > 128
/* get task info */
#define OS_ALL_TASK_MASK 0xFFFFFFFF
#define OS_TASK_WAIT_ANYPROCESS (1 << 0U)
#define OS_TASK_WAIT_PROCESS (1 << 1U)
#define OS_TASK_WAIT_GID (1 << 2U)
#define OS_TASK_WAIT_SEM (OS_TASK_WAIT_GID + 1)
#define OS_TASK_WAIT_QUEUE (OS_TASK_WAIT_SEM + 1)
#define OS_TASK_WAIT_JOIN (OS_TASK_WAIT_QUEUE + 1)
#define OS_TASK_WAIT_SIGNAL (OS_TASK_WAIT_JOIN + 1)
#define OS_TASK_WAIT_LITEIPC (OS_TASK_WAIT_SIGNAL + 1)
#define OS_TASK_WAIT_MUTEX (OS_TASK_WAIT_LITEIPC + 1)
#define OS_TASK_WAIT_FUTEX (OS_TASK_WAIT_MUTEX + 1)
#define OS_TASK_WAIT_EVENT (OS_TASK_WAIT_FUTEX + 1)
#define OS_TASK_WAIT_COMPLETE (OS_TASK_WAIT_EVENT + 1)
/// 任务的等待事件/信号列表
#define OS_TASK_WAIT_ANYPROCESS (1 << 0U) ///< 等待任意进程出现
#define OS_TASK_WAIT_PROCESS (1 << 1U) ///< 等待指定进程出现
#define OS_TASK_WAIT_GID (1 << 2U) ///< 等待组ID
#define OS_TASK_WAIT_SEM (OS_TASK_WAIT_GID + 1) ///< 等待信号量发生
#define OS_TASK_WAIT_QUEUE (OS_TASK_WAIT_SEM + 1) ///< 等待队列到来
#define OS_TASK_WAIT_JOIN (OS_TASK_WAIT_QUEUE + 1) ///< 等待联结到来
#define OS_TASK_WAIT_SIGNAL (OS_TASK_WAIT_JOIN + 1) ///< 等待普通信号到来
#define OS_TASK_WAIT_LITEIPC (OS_TASK_WAIT_SIGNAL + 1) ///< 等待liteipc到来
#define OS_TASK_WAIT_MUTEX (OS_TASK_WAIT_LITEIPC + 1) ///< 等待MUTEX到来
#define OS_TASK_WAIT_FUTEX (OS_TASK_WAIT_MUTEX + 1) ///< 等待FUTEX到来
#define OS_TASK_WAIT_EVENT (OS_TASK_WAIT_FUTEX + 1) ///< 等待事件发生
#define OS_TASK_WAIT_COMPLETE (OS_TASK_WAIT_EVENT + 1) ///< 等待结束信号
/// 设置事件阻塞掩码,即设置任务的等待事件.
STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 timeout)
{
LosTaskCB *runTask = OsCurrTaskGet();
runTask->waitID = lockID;
runTask->waitFlag = mask;
runTask->waitID = lockID; //
runTask->waitFlag = mask; //当前任务在等待什么东东到来 例如: OS_TASK_WAIT_LITEIPC
(VOID)timeout;
}
/// 清除事件阻塞掩码,即任务不再等待任何事件.
STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask)
{
resumeTask->waitID = 0;

@ -50,13 +50,13 @@ typedef struct UidGidMap {
UidGidExtent extent[UID_GID_MAP_MAX_EXTENTS];
};
} UidGidMap;
//用户容器
typedef struct UserContainer {
Atomic rc;
INT32 level;
UINT32 owner;
UINT32 group;
struct UserContainer *parent;
struct UserContainer *parent;
UidGidMap uidMap;
UidGidMap gidMap;
UINT32 containerID;

@ -39,11 +39,15 @@
typedef struct ProcessCB LosProcessCB;
struct Container;
/****************************************
* https://unix.stackexchange.com/questions/183717/whats-a-uts-namespace
* uts: UNIX Time Sharing, UNIX
* setting hostname, domainname will not affect rest of the system (CLONE_NEWUTS flag)
****************************************/
typedef struct UtsContainer {
Atomic rc;
UINT32 containerID;
struct utsname utsName;
Atomic rc; //原子操作 LDREX 和 STREX 指令保证了原子操作的底层实现
UINT32 containerID; //容器ID
struct utsname utsName; //存放系统信息的缓冲区
} UtsContainer;
UINT32 OsInitRootUtsContainer(UtsContainer **utsContainer);

@ -47,17 +47,17 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_KHEAP_BLOCK_SIZE (512 * 1024UL)
#define OS_KHEAP_BLOCK_SIZE (512 * 1024UL) ///< 内核空间 堆内存部分大小, 512K
//记录 MMU 映射关系
typedef struct ArchMmuInitMapping {
PADDR_T phys;
VADDR_T virt;
size_t size;
unsigned int flags;
const char *name;
PADDR_T phys;///< 物理地址
VADDR_T virt;///< 虚拟地址
size_t size;///< 大小
unsigned int flags;///< 标识 读/写/.. VM_MAP_REGION_FLAG_PERM_*
const char *name;///< 名称
} LosArchMmuInitMapping;
extern LosArchMmuInitMapping g_archMmuInitMapping[];
extern LosArchMmuInitMapping g_archMmuInitMapping[];//映射关系表
extern UINTPTR g_vmBootMemBase;
extern BOOL g_kHeapInited;

@ -1,3 +1,64 @@
/*!
* @file los_vm_common.h
* @brief
* @link
@verbatim
@note_pic
鸿- USER_ASPACE_BASE USER_ASPACE_TOP_MAX
鸿: https://blog.csdn.net/kuangyufei
https://my.oschina.net/u/3751245
| /\ |
| || |
|---------------------------|KERNEL_ASPACE_BASE + KERNEL_ASPACE_SIZE
| |
| |
| |
| |
|---------------------------| KERNEL_ASPACE_BASE
| |
| 16M |
|---------------------------| USER_ASPACE_TOP_MAX = USER_ASPACE_BASE + USER_ASPACE_SIZE
| |
| stack |
| |
| || |
| || |
| || |
| \/ |
| |
|---------------------------| USER_MAP_BASE + USER_MAP_SIZE
| (,,I/O) |
| |
| |
| .so |
| |
| L1/L2 |
|---------------------------| USER_MAP_BASE = (USER_ASPACE_TOP_MAX >> 1)
| |
| |
| /\ |
| || |
| || |
| || |
| |
| heap |
| |
|---------------------------| USER_HEAP_BASE = USER_ASPACE_TOP_MAX >> 2
| |
| .bss |
| .data |
| .text |
|---------------------------| USER_ASPACE_BASE = 0x01000000UL
| |
| 16M |
|---------------------------| 0x00000000
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-30
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -43,38 +104,51 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* user address space, defaults to below kernel space with a 16MB guard gap on either side */
#ifndef USER_ASPACE_BASE
#define USER_ASPACE_BASE ((vaddr_t)0x01000000UL)
#ifndef USER_ASPACE_BASE ///< 用户地址空间默认为低于内核空间两侧各有16MB的保护间隙
#define USER_ASPACE_BASE ((vaddr_t)0x01000000UL) ///< 用户空间基地址 从16M位置开始 user_ram : ORIGIN = 0x1000000, LENGTH = 0x100000
#endif
#ifndef USER_ASPACE_SIZE
#define USER_ASPACE_SIZE ((vaddr_t)KERNEL_ASPACE_BASE - USER_ASPACE_BASE - 0x01000000UL)
#define USER_ASPACE_SIZE ((vaddr_t)KERNEL_ASPACE_BASE - USER_ASPACE_BASE - 0x01000000UL)///< 用户空间 < 内核空间 2个16M
#endif
#define USER_ASPACE_TOP_MAX ((vaddr_t)(USER_ASPACE_BASE + USER_ASPACE_SIZE))
#define USER_HEAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 2))
#define USER_MAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 1))
#define USER_MAP_SIZE ((vaddr_t)(USER_ASPACE_SIZE >> 3))
#define USER_ASPACE_TOP_MAX ((vaddr_t)(USER_ASPACE_BASE + USER_ASPACE_SIZE))///< 用户空间顶部位置
#define USER_HEAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 2)) ///< 堆的开始地址
#define USER_MAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 1)) ///< 用户映射区开始地址
#define USER_MAP_SIZE ((vaddr_t)(USER_ASPACE_SIZE >> 3)) ///< 用户空间映射大小 = 1/8 用户空间
#ifndef PAGE_SIZE
#define PAGE_SIZE (0x1000U)
#define PAGE_SIZE (0x1000U) ///< 页大小4K
#endif
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define PAGE_SHIFT (12)
#define PAGE_MASK (~(PAGE_SIZE - 1)) ///< 页掩码,用于页内偏移地址的计算
#define PAGE_SHIFT (12)///< 12位 - 4K 偏移
#define KB (1024UL)
#define MB (1024UL * 1024UL)
#define GB (1024UL * 1024UL * 1024UL)
#define ROUNDUP(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
#define ROUNDDOWN(a, b) ((a) & ~((b) - 1))
#define ROUNDOFFSET(a, b) ((a) & ((b) - 1))
#define MIN2(a, b) (((a) < (b)) ? (a) : (b))
#define IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1)))
#define IS_PAGE_ALIGNED(x) IS_ALIGNED(x, PAGE_SIZE)
#define IS_SECTION_ALIGNED(x) IS_ALIGNED(x, SECTION_SIZE)
/**
* @brief
* @verbatim
:
ROUNDUP(7,4) = 8 ,ROUNDUP(8,4) = 8 ,ROUNDUP(9,4) = 12
ROUNDDOWN(7,4) = 4 ,ROUNDDOWN(8,4) = 8 ,ROUNDDOWN(9,4) = 8
ROUNDOFFSET(7,4) = 3 ,ROUNDOFFSET(8,4) = 0 ,ROUNDOFFSET(9,4) = 1
* @endverbatim
*/
#define ROUNDUP(a, b) (((a) + ((b) - 1)) & ~((b) - 1)) ///< 向上圆整
#define ROUNDDOWN(a, b) ((a) & ~((b) - 1)) ///< 向下圆整
#define ROUNDOFFSET(a, b) ((a) & ((b) - 1)) ///< 圆整偏移
#define MIN2(a, b) (((a) < (b)) ? (a) : (b)) ///< 找到最小值
#define IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1)))///< 是否按指定的参数对齐
#define IS_PAGE_ALIGNED(x) IS_ALIGNED(x, PAGE_SIZE) ///< 是否按页大小对齐 4K
#define IS_SECTION_ALIGNED(x) IS_ALIGNED(x, SECTION_SIZE)///< 是否按段大小对齐
//虚拟内存的异常提示
#define LOS_ERRNO_VM_NO_ERROR (0)
#define LOS_ERRNO_VM_GENERIC (-1)
#define LOS_ERRNO_VM_NOT_FOUND (-2)

@ -55,7 +55,7 @@ typedef struct {
#define VM_MAP_PF_FLAG_USER (1U << 1)
#define VM_MAP_PF_FLAG_INSTRUCTION (1U << 2)
#define VM_MAP_PF_FLAG_NOT_PRESENT (1U << 3)
//缺页中断处理函数
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame);
#ifdef __cplusplus
#if __cplusplus

@ -1,3 +1,23 @@
/*!
* @file los_vm_filemap.h
* @brief
* @link
@verbatim
RAM 便
访访
A.
B.
C.
D.
E.
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-12-9
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -51,133 +71,158 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if 0 //@note_#if0
//page_mapping描述的是一个文件在内存中被映射了多少页,<文件,文件页的关系>
/* file mapped in VMM pages */
struct page_mapping {//记录文件页和文件关系的结构体,叫文件页映射
LOS_DL_LIST page_list; /* all pages | 链表上挂的是属于该文件的所有FilePage这些页的内容都来源同一个文件*/
SPIN_LOCK_S list_lock; /* lock protecting it | 操作page_list的自旋锁*/
LosMux mux_lock; /* mutex lock | 操作page_mapping的互斥量*/
unsigned long nrpages; /* number of total pages |page_list的节点数量 */
unsigned long flags; ///< @note_why 全量代码中也没查到源码中对其操作
Atomic ref; /* reference counting | 引用次数(自增/自减),对应add_mapping/dec_mapping*/
struct Vnode *host; /* owner of this mapping | 属于哪个文件的映射*/
};
/* map: full_path(owner) <-> mapping */ //叫文件映射
struct file_map { //为在内核层面文件在内存的身份证,每个需映射到内存的文件必须创建一个file_map都挂到全局g_file_mapping链表上
LOS_DL_LIST head; ///< 链表节点,用于挂到g_file_mapping上
LosMux lock; /* lock to protect this mapping */
struct page_mapping mapping; ///< 每个文件都有唯一的page_mapping标识其在内存的身份
char *owner; /* owner: full path of file | 文件全路径来标识唯一性*/
};
#endif
/// 文件页结构体
typedef struct FilePage {
LOS_DL_LIST node;
LOS_DL_LIST lru;
LOS_DL_LIST i_mmap; /* list of mappings */
UINT32 n_maps; /* num of mapping */
struct VmPhysSeg *physSeg; /* physical memory that file page belongs to */
struct VmPage *vmPage;
struct page_mapping *mapping;
VM_OFFSET_T pgoff;
UINT32 flags;
UINT16 dirtyOff;
UINT16 dirtyEnd;
LOS_DL_LIST node; ///< 节点,节点挂到page_mapping.page_list上,链表以 pgoff 从小到大方式排序.
LOS_DL_LIST lru; ///< lru节点, 结合 LosVmPhysSeg: LOS_DL_LIST lruList[VM_NR_LRU_LISTS] 理解
LOS_DL_LIST i_mmap; /* list of mappings | 链表记录文件页被哪些进程映射 MapInfo.node挂上来*/
UINT32 n_maps; /* num of mapping | 记录被进程映射的次数*/
struct VmPhysSeg *physSeg; /* physical memory that file page belongs to | 物理段:物理页框 = 1:N */
struct VmPage *vmPage; ///< 物理页框
struct page_mapping *mapping; ///< 此结构由文件系统提供,用于描述装入点 见于 ..\third_party\NuttX\include\nuttx\fs\fs.h
VM_OFFSET_T pgoff; ///< 页标,文件被切成一页一页读到内存
UINT32 flags; ///< 标签
UINT16 dirtyOff; ///< 脏页的页内偏移地址
UINT16 dirtyEnd; ///< 脏页的结束位置
} LosFilePage;
/// 虚拟地址和文件页的映射信息,在一个进程使用文件页之前,需要提前做好文件页在此内存空间的映射关系,如此通过虚拟内存就可以对文件页读写操作.
typedef struct MapInfo {
LOS_DL_LIST node;
VADDR_T vaddr;
LosFilePage *page;
LosArchMmu *archMmu;
LOS_DL_LIST node; ///< 节点,挂到page->i_mmap链表上.链表上记录要操作文件页的进程对这个page的映射信息
VADDR_T vaddr; ///< 虚拟地址.每个进程访问同一个文件页的虚拟地址都是不一样的
LosFilePage *page; ///< 文件页中只记录物理地址,是不会变的.但它是需要被多个进程访问,和映射的.
LosArchMmu *archMmu; ///< mmu完成vaddr和page->vmPage->physAddr物理地址的映射
} LosMapInfo;
/// Flags由 bitmap 管理
enum OsPageFlags {
FILE_PAGE_FREE,
FILE_PAGE_LOCKED,
FILE_PAGE_REFERENCED,
FILE_PAGE_DIRTY,
FILE_PAGE_LRU,
FILE_PAGE_ACTIVE,
FILE_PAGE_SHARED,
FILE_PAGE_FREE, ///< 空闲页
FILE_PAGE_LOCKED, ///< 被锁页
FILE_PAGE_REFERENCED, ///< 被引用页
FILE_PAGE_DIRTY, ///< 脏页
FILE_PAGE_LRU, ///< LRU置换页
FILE_PAGE_ACTIVE, ///< 活动页
FILE_PAGE_SHARED, ///< 共享页
};
#define PGOFF_MAX 2000
#define MAX_SHRINK_PAGECACHE_TRY 2
#define VM_FILEMAP_MAX_SCAN (SYS_MEM_SIZE_DEFAULT >> PAGE_SHIFT)
#define VM_FILEMAP_MIN_SCAN 32
#define VM_FILEMAP_MAX_SCAN (SYS_MEM_SIZE_DEFAULT >> PAGE_SHIFT) ///< 扫描文件映射页最大数量
#define VM_FILEMAP_MIN_SCAN 32 ///< 扫描文件映射页最小数量
/// 给页面贴上被锁的标签
STATIC INLINE VOID OsSetPageLocked(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_LOCKED);
}
/// 给页面撕掉被锁的标签
STATIC INLINE VOID OsCleanPageLocked(LosVmPage *page)
{
LOS_BitmapClr(&page->flags, FILE_PAGE_LOCKED);
}
/// 给页面贴上数据被修改的标签
STATIC INLINE VOID OsSetPageDirty(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_DIRTY);
}
/// 给页面撕掉数据被修改的标签
STATIC INLINE VOID OsCleanPageDirty(LosVmPage *page)
{
LOS_BitmapClr(&page->flags, FILE_PAGE_DIRTY);
}
/// 给页面贴上活动的标签
STATIC INLINE VOID OsSetPageActive(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_ACTIVE);
}
/// 给页面撕掉活动的标签
STATIC INLINE VOID OsCleanPageActive(LosVmPage *page)
{
LOS_BitmapClr(&page->flags, FILE_PAGE_ACTIVE);
}
/// 给页面贴上置换页的标签
STATIC INLINE VOID OsSetPageLRU(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_LRU);
}
/// 给页面贴上被释放的标签
STATIC INLINE VOID OsSetPageFree(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_FREE);
}
/// 给页面撕掉被释放的标签
STATIC INLINE VOID OsCleanPageFree(LosVmPage *page)
{
LOS_BitmapClr(&page->flags, FILE_PAGE_FREE);
}
/// 给页面贴上被引用的标签
STATIC INLINE VOID OsSetPageReferenced(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_REFERENCED);
}
/// 给页面撕掉被引用的标签
STATIC INLINE VOID OsCleanPageReferenced(LosVmPage *page)
{
LOS_BitmapClr(&page->flags, FILE_PAGE_REFERENCED);
}
/// 页面是否活动
STATIC INLINE BOOL OsIsPageActive(LosVmPage *page)
{
return BIT_GET(page->flags, FILE_PAGE_ACTIVE);
}
/// 页面是否被锁
STATIC INLINE BOOL OsIsPageLocked(LosVmPage *page)
{
return BIT_GET(page->flags, FILE_PAGE_LOCKED);
}
/// 页面是否被引用,只被一个进程引用的页叫私有页,多个进程引用就是共享页,此为共享内存的本质所在
STATIC INLINE BOOL OsIsPageReferenced(LosVmPage *page)
{
return BIT_GET(page->flags, FILE_PAGE_REFERENCED);
}
/// 页面是否为脏页,所谓脏页就是页内数据是否被更新过,只有脏页才会有写时拷贝
STATIC INLINE BOOL OsIsPageDirty(LosVmPage *page)
{
return BIT_GET(page->flags, FILE_PAGE_DIRTY);
}
/// 文件页是否映射过了
STATIC INLINE BOOL OsIsPageMapped(LosFilePage *page)
{
return (page->n_maps != 0);
return (page->n_maps != 0);//由映射的次数来判断
}
/* The follow three functions is used to SHM module */
/*! The follow three functions is used to SHM module | 给页面贴上共享页标签*/
STATIC INLINE VOID OsSetPageShared(LosVmPage *page)
{
LOS_BitmapSet(&page->flags, FILE_PAGE_SHARED);
LOS_BitmapSet(&page->flags, FILE_PAGE_SHARED);//设为共享页面,共享页位 置0
}
/// 给页面撕掉共享页标签
STATIC INLINE VOID OsCleanPageShared(LosVmPage *page)
{
LOS_BitmapClr(&page->flags, FILE_PAGE_SHARED);
LOS_BitmapClr(&page->flags, FILE_PAGE_SHARED);//共享页位 置0
}
/// 是否为共享页
STATIC INLINE BOOL OsIsPageShared(LosVmPage *page)
{
return BIT_GET(page->flags, FILE_PAGE_SHARED);

@ -41,9 +41,19 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
enum DmaMemType {
DMA_CACHE,
DMA_NOCACHE
/**
* @brief
* @verbatim
DMADirect Memory Access访
DMA
DMACPU
* @endverbatim
*/
enum DmaMemType {
DMA_CACHE, ///< 有缓存的DMA
DMA_NOCACHE ///< 无缓存的DMA
};
/* thread safety */

@ -46,19 +46,43 @@
#include "los_vm_common.h"
struct Vnode;
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if 0 // @note_#if0
file ..\third_party\NuttX\include\nuttx\fs\fs.h
struct file //打开文件的基本表示形式
{
unsigned int f_magicnum; /* file magic number */
int f_oflags; /* Open mode flags */
FAR struct inode *f_inode; /* Driver interface */
loff_t f_pos; /* File position */
unsigned long f_refcount; /* reference count */
char *f_path; /* File fullpath */
void *f_priv; /* Per file driver private data */
const char *f_relpath; /* realpath */
struct page_mapping *f_mapping; /* mapping file to memory */
void *f_dir; /* DIR struct for iterate the directory if open a directory */
};
struct page_mapping {
LOS_DL_LIST page_list; /* all pages */
SPIN_LOCK_S list_lock; /* lock protecting it */
LosMux mux_lock; /* mutex lock */
unsigned long nrpages; /* number of total pages */
unsigned long flags;
Atomic ref; /* reference counting */
struct file *host; /* owner of this mapping */
};
#endif
/* If the kernel malloc size is less than 16k, use heap, otherwise use physical pages */
#define KMALLOC_LARGE_SIZE (PAGE_SIZE << 2)
typedef struct VmMapRange {
VADDR_T base; /**< vm region base addr */
UINT32 size; /**< vm region size */
typedef struct VmMapRange {//线性区范围结构体
VADDR_T base; /**< vm region base addr | 线性区基地址*/
UINT32 size; /**< vm region size | 线性区大小*/
} LosVmMapRange;
struct VmMapRegion;
@ -67,104 +91,115 @@ struct VmFileOps;
typedef struct VmFileOps LosVmFileOps;
struct VmSpace;
typedef struct VmSpace LosVmSpace;
/// 缺页结构信息体
typedef struct VmFault {
UINT32 flags; /* FAULT_FLAG_xxx flags */
unsigned long pgoff; /* Logical page offset based on region */
VADDR_T vaddr; /* Faulting virtual address */
VADDR_T *pageKVaddr; /* KVaddr of pagefault's vm page's paddr */
UINT32 flags; /*! FAULT_FLAG_xxx flags | 缺页标识*/
unsigned long pgoff; /*! Logical page offset based on region | 基于线性区的逻辑页偏移量*/
VADDR_T vaddr; /*! Faulting virtual address | 产生缺页的虚拟地址*/
VADDR_T *pageKVaddr; /*! KVaddr of pagefault's vm page's paddr | page cache中的虚拟地址*/
} LosVmPgFault;
/// 虚拟内存文件操作函数指针,上层开发可理解为 class 里的方法,注意是对线性区的操作 , 文件操作 见于g_commVmOps
struct VmFileOps {
void (*open)(struct VmMapRegion *region);
void (*close)(struct VmMapRegion *region);
int (*fault)(struct VmMapRegion *region, LosVmPgFault *pageFault);
void (*remove)(struct VmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T offset);
void (*open)(struct VmMapRegion *region); ///< 打开
void (*close)(struct VmMapRegion *region); ///< 关闭
int (*fault)(struct VmMapRegion *region, LosVmPgFault *pageFault); ///< 缺页,OsVmmFileFault
void (*remove)(struct VmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T offset); ///< 删除 OsVmmFileRemove
};
/*!
线,线,线
,访.
访访,.
. .
., open ,read, write .
,,使 ,
. ,: open,read,write,close,mmap...
. malloc .
*/
struct VmMapRegion {
LosRbNode rbNode; /**< region red-black tree node */
LosVmSpace *space;
LOS_DL_LIST node; /**< region dl list */
LosVmMapRange range; /**< region address range */
VM_OFFSET_T pgOff; /**< region page offset to file */
UINT32 regionFlags; /**< region flags: cow, user_wired */
UINT32 shmid; /**< shmid about shared region */
UINT8 forkFlags; /**< vm space fork flags: COPY, ZERO, */
UINT8 regionType; /**< vm region type: ANON, FILE, DEV */
union {
struct VmRegionFile {
int f_oflags;
struct Vnode *vnode;
const LosVmFileOps *vmFOps;
LosRbNode rbNode; /**< region red-black tree node | 红黑树节点,通过它将本线性区挂在VmSpace.regionRbTree*/
LosVmSpace *space; ///< 所属虚拟空间,虚拟空间由多个线性区组成
LOS_DL_LIST node; /**< region dl list | 链表节点,通过它将本线性区挂在VmSpace.regions上 ,但最新版本没有regions了,可以删除了 */
LosVmMapRange range; /**< region address range | 记录线性区的范围*/
VM_OFFSET_T pgOff; /**< region page offset to file | 以文件开始处的偏移量, 必须是分页大小的整数倍, 通常为0, 表示从文件头开始映射。*/
UINT32 regionFlags; /**< region flags: cow, user_wired | 线性区标签*/
UINT32 shmid; /**< shmid about shared region | shmid为共享线性区id,id背后就是共享线性区*/
UINT8 forkFlags; /**< vm space fork flags: COPY, ZERO, | 线性区标记方式*/
UINT8 regionType; /**< vm region type: ANON, FILE, DEV | 映射类型是匿名,文件,还是设备,所谓匿名可理解为内存映射*/
union {
struct VmRegionFile {// <磁盘文件 , 物理内存, 用户进程虚拟地址空间 >
int f_oflags; ///< 读写标签
struct Vnode *vnode;///< 文件索引节点
const LosVmFileOps *vmFOps;///< 文件处理各操作接口,open,read,write,close,mmap
} rf;
struct VmRegionAnon {
LOS_DL_LIST node; /**< region LosVmPage list */
//匿名映射是指那些没有关联到文件页,如进程堆、栈、数据段和任务已修改的共享库等与物理内存的映射
struct VmRegionAnon {//<swap区 , 物理内存, 用户进程虚拟地址空间 >
LOS_DL_LIST node; /**< region LosVmPage list | 线性区虚拟页链表*/
} ra;
struct VmRegionDev {
LOS_DL_LIST node; /**< region LosVmPage list */
const LosVmFileOps *vmFOps;
struct VmRegionDev {//设备映射,也是一种文件
LOS_DL_LIST node; /**< region LosVmPage list | 线性区虚拟页链表*/
const LosVmFileOps *vmFOps; ///< 操作设备像操作文件一样方便.
} rd;
} unTypeData;
};
/// 虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
typedef struct VmSpace {
LOS_DL_LIST node; /**< vm space dl list */
LosRbTree regionRbTree; /**< region red-black tree root */
LosMux regionMux; /**< region red-black tree mutex lock */
VADDR_T base; /**< vm space base addr */
UINT32 size; /**< vm space size */
VADDR_T heapBase; /**< vm space heap base address */
VADDR_T heapNow; /**< vm space heap base now */
LosVmMapRegion *heap; /**< heap region */
VADDR_T mapBase; /**< vm space mapping area base */
UINT32 mapSize; /**< vm space mapping area size */
LosArchMmu archMmu; /**< vm mapping physical memory */
LOS_DL_LIST node; /**< vm space dl list | 节点,通过它挂到全局虚拟空间 g_vmSpaceList 链表上*/
LosRbTree regionRbTree; /**< region red-black tree root | 采用红黑树方式管理本空间各个线性区*/
LosMux regionMux; /**< region list mutex lock | 虚拟空间操作红黑树互斥锁*/
VADDR_T base; /**< vm space base addr | 虚拟空间的基地址,线性区的分配范围,常用于判断地址是否在内核还是用户空间*/
UINT32 size; /**< vm space size | 虚拟空间大小*/
VADDR_T heapBase; /**< vm space heap base address | 堆区基地址,指向堆区起点*/
VADDR_T heapNow; /**< vm space heap base now | 堆顶地址指向堆区终点do_brk()直接修改堆的大小返回新的堆区结束地址, heapNow >= heapBase*/
LosVmMapRegion *heap; /**< heap region | 传说中的堆区用于满足进程的动态内存需求大家熟知的malloc,realloc,free其实就是在操作这个区*/
VADDR_T mapBase; /**< vm space mapping area base | 虚拟空间映射区基地址,L1L2表存放在这个区 */
UINT32 mapSize; /**< vm space mapping area size | 虚拟空间映射区大小,映射区是个很大的区。*/
LosArchMmu archMmu; /**< vm mapping physical memory | MMU记录<虚拟地址,物理地址>的映射情况 */
#ifdef LOSCFG_DRIVERS_TZDRIVER
VADDR_T codeStart; /**< user process code area start */
VADDR_T codeEnd; /**< user process code area end */
VADDR_T codeStart; /**< user process code area start | 代码区开始位置 */
VADDR_T codeEnd; /**< user process code area end | 代码区结束位置 */
#endif
} LosVmSpace;
#define VM_MAP_REGION_TYPE_NONE (0x0)
#define VM_MAP_REGION_TYPE_ANON (0x1)
#define VM_MAP_REGION_TYPE_FILE (0x2)
#define VM_MAP_REGION_TYPE_DEV (0x4)
#define VM_MAP_REGION_TYPE_MASK (0x7)
#define VM_MAP_REGION_TYPE_NONE (0x0) ///< 初始化使用
#define VM_MAP_REGION_TYPE_ANON (0x1) ///< 匿名映射线性区
#define VM_MAP_REGION_TYPE_FILE (0x2) ///< 文件映射线性区
#define VM_MAP_REGION_TYPE_DEV (0x4) ///< 设备映射线性区
#define VM_MAP_REGION_TYPE_MASK (0x7) ///< 映射线性区掩码
/* the high 8 bits(24~31) should reserved, shm will use it */
#define VM_MAP_REGION_FLAG_CACHED (0<<0)
#define VM_MAP_REGION_FLAG_UNCACHED (1<<0)
#define VM_MAP_REGION_FLAG_CACHED (0<<0) ///< 缓冲区
#define VM_MAP_REGION_FLAG_UNCACHED (1<<0) ///< 非缓冲区
#define VM_MAP_REGION_FLAG_UNCACHED_DEVICE (2<<0) /* only exists on some arches, otherwise UNCACHED */
#define VM_MAP_REGION_FLAG_STRONGLY_ORDERED (3<<0) /* only exists on some arches, otherwise UNCACHED */
#define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0)
#define VM_MAP_REGION_FLAG_PERM_USER (1<<2)
#define VM_MAP_REGION_FLAG_PERM_READ (1<<3)
#define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4)
#define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5)
#define VM_MAP_REGION_FLAG_PROT_MASK (0xF<<2)
#define VM_MAP_REGION_FLAG_NS (1<<6) /* NON-SECURE */
#define VM_MAP_REGION_FLAG_SHARED (1<<7)
#define VM_MAP_REGION_FLAG_PRIVATE (1<<8)
#define VM_MAP_REGION_FLAG_FLAG_MASK (3<<7)
#define VM_MAP_REGION_FLAG_STACK (1<<9)
#define VM_MAP_REGION_FLAG_HEAP (1<<10)
#define VM_MAP_REGION_FLAG_DATA (1<<11)
#define VM_MAP_REGION_FLAG_TEXT (1<<12)
#define VM_MAP_REGION_FLAG_BSS (1<<13)
#define VM_MAP_REGION_FLAG_VDSO (1<<14)
#define VM_MAP_REGION_FLAG_MMAP (1<<15)
#define VM_MAP_REGION_FLAG_SHM (1<<16)
#define VM_MAP_REGION_FLAG_FIXED (1<<17)
#define VM_MAP_REGION_FLAG_FIXED_NOREPLACE (1<<18)
#define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0) ///< 缓冲区掩码
#define VM_MAP_REGION_FLAG_PERM_USER (1<<2) ///< 用户空间永久区,PERM表示常驻区,可理解为非栈,非堆区
#define VM_MAP_REGION_FLAG_PERM_READ (1<<3) ///< 永久可读取区
#define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4) ///< 永久可写入区
#define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5) ///< 永久可被执行区
#define VM_MAP_REGION_FLAG_PROT_MASK (0xF<<2) ///< 访问权限掩码
#define VM_MAP_REGION_FLAG_NS (1<<6) /* NON-SECURE */
#define VM_MAP_REGION_FLAG_SHARED (1<<7) ///< MAP_SHARED把对该内存段的修改保存到磁盘文件中 详见 OsCvtProtFlagsToRegionFlags ,要和 VM_MAP_REGION_FLAG_SHM区别理解
#define VM_MAP_REGION_FLAG_PRIVATE (1<<8) ///< MAP_PRIVATE内存段私有对它的修改值仅对本进程有效,详见 OsCvtProtFlagsToRegionFlags。
#define VM_MAP_REGION_FLAG_FLAG_MASK (3<<7) ///< 掩码
#define VM_MAP_REGION_FLAG_STACK (1<<9) ///< 线性区的类型:栈区
#define VM_MAP_REGION_FLAG_HEAP (1<<10) ///< 线性区的类型:堆区
#define VM_MAP_REGION_FLAG_DATA (1<<11) ///< data数据区 编译在ELF中
#define VM_MAP_REGION_FLAG_TEXT (1<<12) ///< 代码区
#define VM_MAP_REGION_FLAG_BSS (1<<13) ///< bbs数据区 由运行时动态分配,bss段Block Started by Symbol segment通常是指用来存放程序中未初始化的全局变量的一块内存区域。
#define VM_MAP_REGION_FLAG_VDSO (1<<14) ///< VDSOVirtual Dynamic Shared Object虚拟动态共享库由内核提供的虚拟.so文件它不在磁盘上而在内核里内核将其映射到一个地址空间中被所有程序共享正文段大小为一个页面。
#define VM_MAP_REGION_FLAG_MMAP (1<<15) ///< 映射区,虚拟空间内有专门用来存储<虚拟地址-物理地址>映射的区域
#define VM_MAP_REGION_FLAG_SHM (1<<16) ///< 共享内存区, 被多个进程线性区映射
#define VM_MAP_REGION_FLAG_FIXED (1<<17) ///< 线性区被填满
#define VM_MAP_REGION_FLAG_FIXED_NOREPLACE (1<<18) ///< 线性区不被替换
#define VM_MAP_REGION_FLAG_INVALID (1<<19) /* indicates that flags are not specified */
/// 从外部权限标签转化为线性区权限标签
STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags)
{
UINT32 regionFlags = 0;
regionFlags |= VM_MAP_REGION_FLAG_PERM_USER;
regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0;
regionFlags |= VM_MAP_REGION_FLAG_PERM_USER; //必须是用户空间区
regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0; //映射区可被读
regionFlags |= (prot & PROT_WRITE) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0;
regionFlags |= (prot & PROT_EXEC) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE) : 0;
regionFlags |= (flags & MAP_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
@ -174,86 +209,87 @@ STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned lo
return regionFlags;
}
/// 虚拟地址是否在内核空间
STATIC INLINE BOOL LOS_IsKernelAddress(VADDR_T vaddr)
{
return ((vaddr >= (VADDR_T)KERNEL_ASPACE_BASE) &&
(vaddr <= ((VADDR_T)KERNEL_ASPACE_BASE + ((VADDR_T)KERNEL_ASPACE_SIZE - 1))));
}
/// 给定地址范围是否都在内核空间中
STATIC INLINE BOOL LOS_IsKernelAddressRange(VADDR_T vaddr, size_t len)
{
return (vaddr + len > vaddr) && LOS_IsKernelAddress(vaddr) && (LOS_IsKernelAddress(vaddr + len - 1));
}
/// 获取线性区的结束地址
STATIC INLINE VADDR_T LOS_RegionEndAddr(LosVmMapRegion *region)
{
return (region->range.base + region->range.size - 1);
}
/// 获取线性区大小
STATIC INLINE size_t LOS_RegionSize(VADDR_T start, VADDR_T end)
{
return (end - start + 1);
}
/// 是否为文件映射区
STATIC INLINE BOOL LOS_IsRegionTypeFile(LosVmMapRegion* region)
{
return region->regionType == VM_MAP_REGION_TYPE_FILE;
}
/// permanent 用户进程永久/常驻区
STATIC INLINE BOOL LOS_IsRegionPermUserReadOnly(LosVmMapRegion* region)
{
return ((region->regionFlags & VM_MAP_REGION_FLAG_PROT_MASK) ==
(VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ));
}
/// 是否为私有线性区
STATIC INLINE BOOL LOS_IsRegionFlagPrivateOnly(LosVmMapRegion* region)
{
return ((region->regionFlags & VM_MAP_REGION_FLAG_FLAG_MASK) == VM_MAP_REGION_FLAG_PRIVATE);
}
/// 设置线性区为文件映射
STATIC INLINE VOID LOS_SetRegionTypeFile(LosVmMapRegion* region)
{
region->regionType = VM_MAP_REGION_TYPE_FILE;
}
/// 是否为设备映射线性区 /dev/...
STATIC INLINE BOOL LOS_IsRegionTypeDev(LosVmMapRegion* region)
{
return region->regionType == VM_MAP_REGION_TYPE_DEV;
}
/// 设为设备映射线性区
STATIC INLINE VOID LOS_SetRegionTypeDev(LosVmMapRegion* region)
{
region->regionType = VM_MAP_REGION_TYPE_DEV;
}
/// 是否为匿名swap映射线性区
STATIC INLINE BOOL LOS_IsRegionTypeAnon(LosVmMapRegion* region)
{
return region->regionType == VM_MAP_REGION_TYPE_ANON;
}
/// 设为匿名swap映射线性区
STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion* region)
{
region->regionType = VM_MAP_REGION_TYPE_ANON;
}
/// 虚拟地址是否在用户空间
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
{
return ((vaddr >= USER_ASPACE_BASE) &&
(vaddr <= (USER_ASPACE_BASE + (USER_ASPACE_SIZE - 1))));
}
/// 虚拟地址[vaddr,vaddr + len]是否在用户空间
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
{
return (vaddr + len > vaddr) && LOS_IsUserAddress(vaddr) && (LOS_IsUserAddress(vaddr + len - 1));
}
//是否是一个动态分配的地址(通过vmalloc申请的)
STATIC INLINE BOOL LOS_IsVmallocAddress(VADDR_T vaddr)
{
return ((vaddr >= VMALLOC_START) &&
(vaddr <= (VMALLOC_START + (VMALLOC_SIZE - 1))));
}
/// 是否为一个空线性区
STATIC INLINE BOOL OsIsVmRegionEmpty(LosVmSpace *vmSpace)
{
if (vmSpace->regionRbTree.ulNodes == 0) {
@ -294,7 +330,6 @@ STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace
LosMux *OsGVmSpaceMuxGet(VOID);
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size);
STATUS_T OsVmSpaceRegionFree(LosVmSpace *space);
/**
* thread safety
* it is used to malloc continuous virtual memory, no sure for continuous physical memory.

@ -44,21 +44,28 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*!
* @brief
* @attention vmPage
\n nPagesorder,5,order3,2^35
*/
typedef struct VmPage {
LOS_DL_LIST node; /**< vm object dl list */
PADDR_T physAddr; /**< vm page physical addr */
Atomic refCounts; /**< vm page ref count */
UINT32 flags; /**< vm page flags */
UINT8 order; /**< vm page in which order list */
UINT8 segID; /**< the segment id of vm page */
UINT16 nPages; /**< the vm page is used for kernel heap */
LOS_DL_LIST node; /**< vm object dl list | 物理内框节点,通过它挂/摘到全局g_vmPhysSeg[segID]->freeList[order]物理页框链表 或被使用的链表
, shmIDSource.node*/
PADDR_T physAddr; /**< vm page physical addr | 物理页框起始物理地址,只能用于计算,不会用于操作(读/写数据==)*/
Atomic refCounts; /**< vm page ref count | 被引用次数,共享内存会有多次引用*/
UINT32 flags; /**< vm page flags | 页标签,同时可以有多个标签(共享/引用/活动/被锁==*/
UINT8 order; /**< vm page in which order list | 被安置在伙伴算法的几号序列( 2^0,2^1,2^2,...,2^order)*/
UINT8 segID; /**< the segment id of vm page | 所属物理内存段编号ID*/
UINT16 nPages; /**< the vm page is used for kernel heap | 分配页数,标识从本页开始连续的几页将一块被分配*/
#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK
SPIN_LOCK_S lock; /**< lock for page table entry */
#endif
} LosVmPage;
extern LosVmPage *g_vmPageArray;
extern size_t g_vmPageArraySize;
extern LosVmPage *g_vmPageArray; ///< 物理页框(page frame)池,在g_vmPageArray中:不可能存在两个物理地址一样的物理页框,
extern size_t g_vmPageArraySize; ///< 物理总页框(page frame)数
LosVmPage *LOS_VmPageGet(PADDR_T paddr);
VOID OsVmPageStartup(VOID);

@ -43,52 +43,65 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define VM_LIST_ORDER_MAX 9
#define VM_PHYS_SEG_MAX 32
/*!
* @brief
* @verbatim
LRULeast Recently Used使
使使
LRU使
* @endverbatim
*/
#define VM_LIST_ORDER_MAX 9 ///< 伙伴算法分组数量,从 2^0,2^1,...,2^8 (256*4K)=1M
#define VM_PHYS_SEG_MAX 32 ///< 最大支持32个段
#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif
#define VM_PAGE_TO_PHYS(page) ((page)->physAddr)
#define VM_ORDER_TO_PAGES(order) (1 << (order))
#define VM_ORDER_TO_PHYS(order) (1 << (PAGE_SHIFT + (order)))
#define VM_PHYS_TO_ORDER(phys) (min(LOS_LowBitGet((phys) >> PAGE_SHIFT), VM_LIST_ORDER_MAX - 1))
#define VM_PAGE_TO_PHYS(page) ((page)->physAddr) ///< 获取物理页框的物理基地址
#define VM_ORDER_TO_PAGES(order) (1 << (order)) ///< 伙伴算法由order 定位到该块组的页面单位,例如:order=2时page[4]
#define VM_ORDER_TO_PHYS(order) (1 << (PAGE_SHIFT + (order))) ///< 通过order块组跳到物理地址
#define VM_PHYS_TO_ORDER(phys) (min(LOS_LowBitGet((phys) >> PAGE_SHIFT), VM_LIST_ORDER_MAX - 1)) ///< 通过物理地址定位到order
struct VmFreeList {
LOS_DL_LIST node;
UINT32 listCnt;
LOS_DL_LIST node; ///< 双循环链表用于挂空闲物理内框节点,通过 VmPage->node 挂上来
UINT32 listCnt; ///< 空闲物理页总数
};
enum OsLruList {
VM_LRU_INACTIVE_ANON = 0,
VM_LRU_ACTIVE_ANON,
VM_LRU_INACTIVE_FILE,
VM_LRU_ACTIVE_FILE,
VM_LRU_UNEVICTABLE,
/*!
* @brief LruLeast Recently Used使
*/
enum OsLruList {// 页属性
VM_LRU_INACTIVE_ANON = 0, ///< 非活动匿名页swap
VM_LRU_ACTIVE_ANON, ///< 活动匿名页swap
VM_LRU_INACTIVE_FILE, ///< 非活动文件页(磁盘)
VM_LRU_ACTIVE_FILE, ///< 活动文件页(磁盘)
VM_LRU_UNEVICTABLE, ///< 禁止换出的页
VM_NR_LRU_LISTS
};
/*!
* @brief
*/
typedef struct VmPhysSeg {
PADDR_T start; /* The start of physical memory area */
size_t size; /* The size of physical memory area */
LosVmPage *pageBase; /* The first page address of this area */
SPIN_LOCK_S freeListLock; /* The buddy list spinlock */
struct VmFreeList freeList[VM_LIST_ORDER_MAX]; /* The free pages in the buddy list */
SPIN_LOCK_S lruLock;
size_t lruSize[VM_NR_LRU_LISTS];
LOS_DL_LIST lruList[VM_NR_LRU_LISTS];
PADDR_T start; /* The start of physical memory area | 物理内存段的开始地址*/
size_t size; /* The size of physical memory area | 物理内存段的大小*/
LosVmPage *pageBase; /* The first page address of this area | 本段首个物理页框地址*/
SPIN_LOCK_S freeListLock; /* The buddy list spinlock | 伙伴算法自旋锁,用于操作freeList链表*/
struct VmFreeList freeList[VM_LIST_ORDER_MAX]; /* The free pages in the buddy list | 伙伴算法的分组,默认分成10组 2^0,2^1,...,2^VM_LIST_ORDER_MAX*/
SPIN_LOCK_S lruLock; ///< 用于置换的自旋锁,用于操作lruList
size_t lruSize[VM_NR_LRU_LISTS]; ///< 5个双循环链表大小如此方便得到size
LOS_DL_LIST lruList[VM_NR_LRU_LISTS]; ///< 页面置换算法,5个双循环链表头它们分别描述五中不同类型的链表
} LosVmPhysSeg;
/*!
* @brief ,使
*/
struct VmPhysArea {
PADDR_T start;
size_t size;
PADDR_T start; ///< 物理内存区基地址
size_t size; ///< 物理内存总大小
};
extern struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX];
extern INT32 g_vmPhysSegNum;
extern struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]; ///< 物理内存采用段页式管理,先切段后伙伴算法页
extern INT32 g_vmPhysSegNum; ///< 段总数
UINT32 OsVmPagesToOrder(size_t nPages);
struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page);

@ -45,12 +45,12 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//是否非匿名映射 文件映射:映射和实际文件相关联,通常是把文件的内容映射到进程地址空间,这样应用程序就可以像操作进程地址空间一样读写文件。
STATIC INLINE BOOL LOS_IsNamedMapping(unsigned long flags)
{
return ((flags & MAP_ANONYMOUS) == 0);
}
///是否匿名映射 匿名映射没有映射对应的相关文件这种映射的内存区域的内容会被初始化为0
STATIC INLINE BOOL LOS_IsAnonymousMapping(unsigned long flags)
{
return ((flags & MAP_ANONYMOUS) == MAP_ANONYMOUS);

@ -1,3 +1,91 @@
/*!
* @file los_vm_zone.h
* @brief
* @link
@verbatim
0x00000000U 0xFFFFFFFFU , @note_pic
鸿: http://weharmonyos.com | https://my.oschina.net/weharmony
+----------------------------+ 0xFFFFFFFFU
| IO |
| PERIPH_PMM_SIZE |
+----------------------------+ PERIPH_UNCACHED_BASE
| IO |
| PERIPH_PMM_SIZE |
+----------------------------+ PERIPH_CACHED_BASE
| IO |
| PERIPH_PMM_SIZE |
+----------------------------+ PERIPH_DEVICE_BASE
| Vmalloc |
| |
| 128M |
| |
+----------------------------+ VMALLOC_START
| DDR_MEM_SIZE |
| Uncached |
+----------------------------+ UNCACHED_VMM_BASE = KERNEL_VMM_BASE + KERNEL_VMM_SIZE
| |
| mmu table |
| .bss |Block Started by Symbol : , g_firstPageTable,
| .data |
| .rodata |
| .text |
| vectors |
+----------------------------+ KERNEL_ASPACE_BASE = KERNEL_VMM_BASE
| 16M |
+----------------------------+ USER_ASPACE_TOP_MAX = USER_ASPACE_BASE + USER_ASPACE_SIZE
| |
| |
| USER_ASPACE_SIZE |
| (stack) |
| (map) |
| (heap) |
| .bss |
| .data .text |
+----------------------------+ USER_ASPACE_BASE
| 16M |
+----------------------------+ 0x00000000U
..\vendor\hi3516dv300\config\board\include\board.h
liteos_a, KERNEL_VADDR_BASE ,
liteos_aboard.h
#ifdef LOSCFG_KERNEL_MMU
#ifdef LOSCFG_TEE_ENABLE
#define KERNEL_VADDR_BASE 0x41000000
#else
#define KERNEL_VADDR_BASE 0x40000000
#endif
#else
#define KERNEL_VADDR_BASE DDR_MEM_ADDR
#endif
#define KERNEL_VADDR_SIZE DDR_MEM_SIZE
#define SYS_MEM_BASE DDR_MEM_ADDR
#define SYS_MEM_END (SYS_MEM_BASE + SYS_MEM_SIZE_DEFAULT)
#define EXC_INTERACT_MEM_SIZE 0x100000
: 0x40000000 ~ 0xFFFFFFFF
: 0x00000000 ~ 0x3FFFFFFF
cacheduncached
cached访CPUCPU
CPUCPU
unchached访CPU访
IOuncached访IOIOCPU
IOCPUIOCPU
IOIOCPU
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-30
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -40,44 +128,47 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#ifdef LOSCFG_KERNEL_MMU
#ifdef LOSCFG_KERNEL_MMU //
#ifdef LOSCFG_TEE_ENABLE
#define KERNEL_VADDR_BASE 0x41000000
#define KERNEL_VADDR_BASE 0x41000000 //用于链接器层面的宏配置 | 基地址
#else
#define KERNEL_VADDR_BASE 0x40000000
#define KERNEL_VADDR_BASE 0x40000000
#endif
#else
#define KERNEL_VADDR_BASE DDR_MEM_ADDR
#else //没有MMU时,内核运行基址 = 内存的基地址,因为没有了MMU,所以也没有了虚拟内存和物理内存的说法,统一就是物理内存.
#define KERNEL_VADDR_BASE DDR_MEM_ADDR ///< 内核运行基址 等于内存( Double Data Rate SDRAM)基地址
#endif
#define KERNEL_VADDR_SIZE DDR_MEM_SIZE
#define KERNEL_VADDR_SIZE DDR_MEM_SIZE ///< 真实主存的大小
#define SYS_MEM_BASE DDR_MEM_ADDR ///< 物理内存基地址
#define SYS_MEM_END (SYS_MEM_BASE + SYS_MEM_SIZE_DEFAULT) ///< 物理内存结束地址
#define SYS_MEM_BASE DDR_MEM_ADDR
#define SYS_MEM_END (SYS_MEM_BASE + SYS_MEM_SIZE_DEFAULT)
#define _U32_C(X) X##U
#define U32_C(X) _U32_C(X)
#define KERNEL_VMM_BASE U32_C(KERNEL_VADDR_BASE)
#define KERNEL_VMM_SIZE U32_C(KERNEL_VADDR_SIZE)
#define KERNEL_VMM_BASE U32_C(KERNEL_VADDR_BASE) ///< 内核内存管理层面的宏配置 | 基地址
#define KERNEL_VMM_SIZE U32_C(KERNEL_VADDR_SIZE) ///< 内核大小
#define KERNEL_ASPACE_BASE KERNEL_VMM_BASE
#define KERNEL_ASPACE_SIZE KERNEL_VMM_SIZE
#define KERNEL_ASPACE_BASE KERNEL_VMM_BASE ///< 内核运行空间层面的宏配置 | 基地址
#define KERNEL_ASPACE_SIZE KERNEL_VMM_SIZE ///< 内核空间大小
/* Uncached vmm aspace */
#define UNCACHED_VMM_BASE (KERNEL_VMM_BASE + KERNEL_VMM_SIZE)
#define UNCACHED_VMM_SIZE DDR_MEM_SIZE
#define VMALLOC_START (UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)
#define VMALLOC_SIZE 0x08000000
#ifdef LOSCFG_KERNEL_MMU
#define PERIPH_DEVICE_BASE (VMALLOC_START + VMALLOC_SIZE)
#define UNCACHED_VMM_BASE (KERNEL_VMM_BASE + KERNEL_VMM_SIZE) ///< 未缓存虚拟空间基地址,适用于DMA,LCD framebuf,
#define UNCACHED_VMM_SIZE DDR_MEM_SIZE ///<未缓存虚拟空间大小
#define VMALLOC_START (UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE) ///< 内核堆空间基地址
#define VMALLOC_SIZE 0x08000000 ///< 内核堆空间大小, 128M
//UART,LCD,摄像头,I2C,中断控制器统称为外部设备, 统一编址
#ifdef LOSCFG_KERNEL_MMU //使用MMU时,只是虚拟地址不一样,但映射的物理设备空间一致.
#define PERIPH_DEVICE_BASE (VMALLOC_START + VMALLOC_SIZE) ///< 不使用buffer,cache
#define PERIPH_DEVICE_SIZE U32_C(PERIPH_PMM_SIZE)
#define PERIPH_CACHED_BASE (PERIPH_DEVICE_BASE + PERIPH_DEVICE_SIZE)
#define PERIPH_CACHED_BASE (PERIPH_DEVICE_BASE + PERIPH_DEVICE_SIZE) ///< 使用cache但不用buffer
#define PERIPH_CACHED_SIZE U32_C(PERIPH_PMM_SIZE)
#define PERIPH_UNCACHED_BASE (PERIPH_CACHED_BASE + PERIPH_CACHED_SIZE)
#define PERIPH_UNCACHED_BASE (PERIPH_CACHED_BASE + PERIPH_CACHED_SIZE) ///< 不使用cache但使用buffer
#define PERIPH_UNCACHED_SIZE U32_C(PERIPH_PMM_SIZE)
#else
#else //不使用MMU时,外部设备空间地址一致.
#define PERIPH_DEVICE_BASE PERIPH_PMM_BASE
#define PERIPH_DEVICE_SIZE U32_C(PERIPH_PMM_SIZE)
#define PERIPH_CACHED_BASE PERIPH_PMM_BASE
@ -86,9 +177,10 @@ extern "C" {
#define PERIPH_UNCACHED_SIZE U32_C(PERIPH_PMM_SIZE)
#endif
#define IO_DEVICE_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_DEVICE_BASE)
#define IO_CACHED_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_CACHED_BASE)
#define IO_UNCACHED_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_UNCACHED_BASE)
#define IO_DEVICE_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_DEVICE_BASE) ///< 通过物理地址获取IO设备虚拟地址
#define IO_CACHED_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_CACHED_BASE) ///< 通过物理地址获取IO设备虚拟缓存地址
#define IO_UNCACHED_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_UNCACHED_BASE) ///< 通过物理地址获取IO设备虚拟未缓存地址
//DDR_MEM_ADDRDDR内存全称是DDR SDRAM(Double Data Rate SDRAM双倍速率SDRAM)
#define MEM_CACHED_ADDR(paddr) ((paddr) - DDR_MEM_ADDR + KERNEL_VMM_BASE)
#define MEM_UNCACHED_ADDR(paddr) ((paddr) - DDR_MEM_ADDR + UNCACHED_VMM_BASE)

@ -1,3 +1,54 @@
/*!
* @file los_event.c
* @brief
* @link
@verbatim
Event
322531
LOS_WAITMODE_ANDeventMask
LOS_WAITMODE_OReventMask
LOS_WAITMODE_CLR
使LOS_WAITMODE_AND | LOS_WAITMODE_CLR LOS_WAITMODE_OR | LOS_WAITMODE_CLR
LOS_EventReadeventMask
LOS_WAITMODE_CLR
LOS_EventWrite
LOS_EventClear
0
使
LOS_EventClear ~events
LOS_EventRead25使
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2022-1-15
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.

@ -1,3 +1,57 @@
/*!
* @file los_futex.c
* @brief
* @link mutex http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-mutex.html @endlink
* @link d17a6152740c https://www.jianshu.com/p/d17a6152740c @endlink
@verbatim
Futex CPU
Futex
使 futex
使
Futex(Fast userspace mutex)
mutexbarriercond
线
线Futex线
线线
线Futex线
futex (fast userspace mutex) Linux
POSIXfutex使futex
SystemV IPC(inter process communication) semaphore
semop(2)PVuser mode
kernel modeuser stackkernel stack
semaphore
semaphoresemaphore
semaphoresemop(2)semaphoresemop(2)
semaphore
futexuser space
(wait wake up)futexuser modekernel mode
futexuser spacefutexuser modekernel modeuser mode
sys_futexkernel mode
线Futex
Futex1GiB便
Futex
800~6364~79
/Futex
: futexfutex_listfutex nodefutex nodetask
nodekeykeynodequeue_listtask
@endverbatim
@image html https://gitee.com/weharmonyos/resources/raw/master/81/futex.png
* @attention Futex使POSIX
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-23
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -272,6 +326,7 @@ EXIT:
return;
}
/// 这块代码谁写的? 这种命名 ...
STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node, FutexNode **headNode, BOOL isDeleteHead)
{
FutexNode *tempNode = (FutexNode *)node;
@ -333,6 +388,7 @@ STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node)
EXIT:
return;
}
///< 从后往前插入快锁 Form写错了 @note_thinking
STATIC INT32 OsFutexInsertFindFormBackToFront(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node)
{
LOS_DL_LIST *listHead = queueList;
@ -451,6 +507,7 @@ STATIC FutexNode *OsFindFutexNode(const FutexNode *node)
headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);//拿到快锁节点实体
if ((headNode->key == node->key) && (headNode->pid == node->pid)) {//已经存在这个节点,注意这里的比较
return headNode;//是key和pid 一起比较,因为只有这样才能确定唯一性
}//详细讲解请查看 鸿蒙内核源码分析(内核态锁篇) | 如何实现快锁Futex(下)
}
return NULL;
@ -709,7 +766,18 @@ STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNum
return;
}
/*!
* @brief OsFutexWakeTask
*
* @param flags
* @param futexKey
* @param newHeadNode
* @param wakeAny
* @param wakeNumber
* @return
*
* @see
*/
STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, FutexNode **newHeadNode, BOOL *wakeAny)
{
UINT32 intSave;

@ -1,3 +1,56 @@
/*!
* @file los_mux.c
* @brief
* @link kernel-mini-basic-ipc-mutex-guide http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.html @endlink
@verbatim
访
访
使
访访
访访
访
使
访访
make menuconfig
LOS_MuxCreate
LOS_MuxPend
LOS_MuxPost
LOS_MuxDelete
@endverbatim
* @image html https://gitee.com/weharmonyos/resources/raw/master/27/mux.png
* @attention
\n 使
\n LiteOS-M
\n LOS_TaskPriSet
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-18
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -435,7 +488,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex)
return ret;
}
/*!
* @brief OsMuxPostOp
* ,,
* OsMuxPostOpOsMuxUnlockUnsafe,,, ,OsMuxPostOp
* @param mutex
* @param needSched
* @param taskCB
* @return
*
* @see
*/
STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
{
if (LOS_ListEmpty(&mutex->muxList)) {//如果互斥锁列表为空

File diff suppressed because it is too large Load Diff

@ -1,3 +1,29 @@
/*!
* @file los_rwlock.c
* @brief
* @link rwlock https://weharmony.github.io/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-trans-rwlock.html @endlink
@verbatim
使
访访
访
-
访
A
A
@endverbatim
@image html
* @attention
* @version
* @author weharmonyos.com | 鸿 |
* @date 2022-02-18
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.

@ -1,3 +1,49 @@
/*!
* @file los_sem.c
* @brief
* @link kernel-mini-basic-ipc-sem-basic http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.html @endlink
@verbatim
Semaphore访
使
0
使
0使
使使0
访1使
0121ReadyRunning
NNLOSCFG_BASE_IPC_SEM_LIMIT使
使使
使
01
1
使使使
访访访
LOS_SemCreateLOS_BinarySemCreate
LOS_SemPend
LOS_SemPost
LOS_SemDelete
@endverbatim
* @image html https://gitee.com/weharmonyos/resources/raw/master/29/sem_run.png
* @attention 使
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-18
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -79,7 +125,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
return LOS_OK;
}
/*
* Description : Create a semaphore,
* Input : count --- semaphore count,
* maxCount --- Max number of available semaphores,
* semHandle --- Index of semaphore,
* Return : LOS_OK on success ,or error code on failure
*/
LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle)
{
UINT32 intSave;

@ -53,7 +53,12 @@ int raise(int sig)
#define GETUNMASKSET(procmask, pendFlag) ((~(procmask)) & (sigset_t)(pendFlag))
#define UINT64_BIT_SIZE 64
/**
* @brief signo10-1
* @param set
* @param signo
* @return int
*/
int OsSigIsMember(const sigset_t *set, int signo)
{
int ret = LOS_NOK;
@ -215,7 +220,15 @@ void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set)
}
}
/**
* @brief
* @verbatim
SIG_BLOCKset
SIG_UNBLOCKset
SIG_SETMASKset
* @endverbatim
*/
int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl)
{
LosTaskCB *spcb = NULL;
@ -463,7 +476,14 @@ int OsDispatch(pid_t pid, siginfo_t *info, int permission)
return OsSigProcessSend(spcb, info);
}
/**
* @brief
* @verbatim
shell kill 14 7kill -14 7
14SIGALRM7
* @endverbatim
*/
int OsKill(pid_t pid, int sig, int permission)
{
siginfo_t info;
@ -680,7 +700,17 @@ int OsSigSuspend(const sigset_t *set)
return -EINTR;
}
/**
* @brief
* @verbatim
,
sig:SIGKILLSIGSTOP
act:signal
oldact:
NULL
0 -1
* @endverbatim
*/
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
{
UINTPTR addr;
@ -724,7 +754,13 @@ VOID OsSigIntUnlock(VOID)
(VOID)LOS_AtomicSub((Atomic *)&sigcb->sigIntLock, 1);
}
/**
* @brief
* @verbatim
,,
PC
* @endverbatim
*/
VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
{
UINTPTR sigHandler;
@ -774,7 +810,16 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
return sp;
}
/**
* @brief
* @verbatim
,__NR_sigreturn,.
?
,使,CPU,
,,CPU
* @endverbatim
*/
VOID *OsRestorSignalContext(VOID *sp)
{
UINT32 intSave;

@ -1,22 +1,35 @@
/*!
* @file los_membox.c
* @brief
* @link
@verbatim
使
使使
使使
make menuconfig
LOS_MemboxInit
NN
LOS_MemboxAlloc
LOS_MemboxClr
LOS_MemboxFree
,使使
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2022-04-02
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CON/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
@ -52,7 +65,7 @@
#include "los_spinlock.h"
#ifdef LOSCFG_AARCH64
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 //魔法数字,@note_good 点赞,设计的很精巧,node内容从下一个节点地址变成魔法数字
#else
#define OS_MEMBOX_MAGIC 0xa55a5aa5
#endif
@ -62,7 +75,7 @@
((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK)
#define OS_MEMBOX_USER_ADDR(addr) \
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE))
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) //@note_good 使用之前要去掉节点信息,太赞了! 很艺术化!!
#define OS_MEMBOX_NODE_ADDR(addr) \
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //节块 = (节头 + 节体) addr = 节体
/* spinlock for mem module, only available on SMP mode */
@ -239,208 +252,3 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32
return LOS_OK;
}
TRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_membox.h"
#include "los_hwi.h"
#include "los_spinlock.h"
#ifdef LOSCFG_AARCH64
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5
#else
#define OS_MEMBOX_MAGIC 0xa55a5aa5
#endif
#define OS_MEMBOX_SET_MAGIC(addr) \
((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC
#define OS_MEMBOX_CHECK_MAGIC(addr) \
((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK)
#define OS_MEMBOX_USER_ADDR(addr) \
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE))
#define OS_MEMBOX_NODE_ADDR(addr) \
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE))
/* spinlock for mem module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin);
#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state))
#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))
STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node)
{
UINT32 offset;
if (boxInfo->uwBlkSize == 0) {
return LOS_NOK;
}
offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1));
if ((offset % boxInfo->uwBlkSize) != 0) {
return LOS_NOK;
}
if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) {
return LOS_NOK;
}
return OS_MEMBOX_CHECK_MAGIC(node);
}
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
LOS_MEMBOX_NODE *node = NULL;
UINT32 index;
UINT32 intSave;
if (pool == NULL) {
return LOS_NOK;
}
if (blkSize == 0) {
return LOS_NOK;
}
if (poolSize < sizeof(LOS_MEMBOX_INFO)) {
return LOS_NOK;
}
MEMBOX_LOCK(intSave);
boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE);
boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;
boxInfo->uwBlkCnt = 0;
if (boxInfo->uwBlkNum == 0) {
MEMBOX_UNLOCK(intSave);
return LOS_NOK;
}
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);
boxInfo->stFreeList.pstNext = node;
for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {
node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);
node = node->pstNext;
}
node->pstNext = NULL;
MEMBOX_UNLOCK(intSave);
return LOS_OK;
}
LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
LOS_MEMBOX_NODE *node = NULL;
LOS_MEMBOX_NODE *nodeTmp = NULL;
UINT32 intSave;
if (pool == NULL) {
return NULL;
}
MEMBOX_LOCK(intSave);
node = &(boxInfo->stFreeList);
if (node->pstNext != NULL) {
nodeTmp = node->pstNext;
node->pstNext = nodeTmp->pstNext;
OS_MEMBOX_SET_MAGIC(nodeTmp);
boxInfo->uwBlkCnt++;
}
MEMBOX_UNLOCK(intSave);
return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);
}
LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
UINT32 ret = LOS_NOK;
UINT32 intSave;
if ((pool == NULL) || (box == NULL)) {
return LOS_NOK;
}
MEMBOX_LOCK(intSave);
do {
LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);
if (OsCheckBoxMem(boxInfo, node) != LOS_OK) {
break;
}
node->pstNext = boxInfo->stFreeList.pstNext;
boxInfo->stFreeList.pstNext = node;
boxInfo->uwBlkCnt--;
ret = LOS_OK;
} while (0);
MEMBOX_UNLOCK(intSave);
return ret;
}
LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
if ((pool == NULL) || (box == NULL)) {
return;
}
(VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0,
(boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE));
}
LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool)
{
UINT32 index;
UINT32 intSave;
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
LOS_MEMBOX_NODE *node = NULL;
if (pool == NULL) {
return;
}
MEMBOX_LOCK(intSave);
PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum);
PRINT_INFO("free node list:\r\n");
for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL;
node = node->pstNext, ++index) {
PRINT_INFO("(%u,%p)\r\n", index, node);
}
PRINT_INFO("all node list:\r\n");
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);
for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) {
PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext);
}
MEMBOX_UNLOCK(intSave);
}
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk,
UINT32 *blkCnt, UINT32 *blkSize)
{
if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) {
return LOS_NOK;
}
*maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum;
*blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt;
*blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize;
return LOS_OK;
}

@ -1,3 +1,51 @@
/*!
* @file los_memory.c
* @brief
* @link tlsf http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf @endlink
@verbatim
https://www.codenong.com/cs106845116/ TLSF算法分配中的位图计算
OpenHarmony LiteOS-A
/OS使使使
使
OpenHarmony LiteOS-ATLSF
@endverbatim
* @image html https://gitee.com/weharmonyos/resources/raw/master/11/1.png
@verbatim
使[4, 127][27, 231]size class
1. [4,127]314
1
[4,127]3131
2. 1272248
Size ClassSize SubClass
24*8=192192192
40[40,43]1010
401040
580[29,29+2^6]
31+2*8=47使4758047
580
使线
线使线
fragment=100-/
@endverbatim
* @image html https://gitee.com/weharmonyos/resources/raw/master/11/2.png
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-19
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -57,7 +105,7 @@
#define OS_MEM_COLUMN_NUM 8
UINT8 *m_aucSysMem0 = NULL; ///< 异常交互动态内存池地址的起始地址当不支持异常交互特性时m_aucSysMem0等于m_aucSysMem1。
UINT8 *m_aucSysMem1 = NULL; ///< (内核态)系统动态内存池地址的起始地址
UINT8 *m_aucSysMem1 = NULL; ///< (内核态)系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
#ifdef LOSCFG_MEM_MUL_POOL
VOID *g_poolHead = NULL; ///内存池头,由它牵引多个内存池
@ -241,8 +289,8 @@ STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size)
#else
STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size)
{
(VOID)pool;
(VOID)size;
(VOID)pool; // @note_thinking 为何要这么写 ,因为格式规范吗 ? 直接啥也不写不行吗 ?
(VOID)size; // 编译器会优化掉这种代码
}
#endif

@ -48,6 +48,10 @@
#include "shell.h"
#endif
LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
{
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");
}
/*********************************************
@ -65,11 +69,6 @@ pid 进程ID [1,MAX_INT]
pid256[1-256]
*********************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
{
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");
}
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
{
#define ARG_NUM 2

@ -31,10 +31,7 @@
#include "los_task_pri.h"
// 这个函数接受两个参数一个是地址addr另一个是对齐边界boundary。它返回一个对齐后的地址。
// 这个函数首先检查地址加上边界再减去1是否大于地址如果是
// 就返回地址加上边界再减去1然后与~((UINTPTR)(boundary - 1))进行位与运算的结果,
// 否则就返回地址与~((UINTPTR)(boundary - 1))进行位与运算的结果。这实际上是在对地址进行对齐。
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
{
if ((addr + boundary - 1) > addr) {
@ -44,14 +41,13 @@ LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
}
}
LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
{
UINT32 interval;
// 这个函数接受一个参数毫秒数msecs。这个函数首先检查毫秒数是否为0如果是就将间隔设置为0。
if (msecs == 0) {
interval = 0;
// } else { 否则它将毫秒数转换为tick数可能是操作系统的时间单位如果转换后的间隔为0就将间隔设置为1。然后它调用LOS_TaskDelay函数来延迟指定的间隔。
} else {
interval = LOS_MS2Tick(msecs);
if (interval == 0) {
interval = 1;

@ -37,6 +37,7 @@
#include "shcmd.h"
#include "shell.h"
#endif
/**
* @file los_stackinfo.c
* @brief

@ -1,3 +1,32 @@
/*!
* @file los_mp.c
* @brief
* @link
* @verbatim
CPU3(SMP+AMP+BMP) 鸿 SMP
Asymmetric multiprocessingAMPCPU
instantiation
Symmetric multiprocessingSMP
CPU
Bound multiprocessingBMP
CPU
线
PIC(Programmable Interrupt ControllerPIC
线线(Inter-Processor Interrupts,IPI
SGI:(Software Generated Interrupt)arm
SGI16,ID0~ID15
* @endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-18
*
* @history
*
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -101,7 +130,17 @@ VOID OsMpCollectTasks(VOID)
}
#ifdef LOSCFG_KERNEL_SMP_CALL
/*!
* @brief OsMpFuncCall
* CPUfuncLink, ? ?
* \n CPU ab,b, ?
* @param args
* @param func
* @param target
* @return
*
* @see
*/
VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
{
UINT32 index;

@ -32,6 +32,9 @@
#include "los_err.h"
/**
* @file los_err.c
* @brief
* @verbatim
便
@ -41,6 +44,7 @@
* @endverbatim
*/
LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL;///< 错误接管钩子函数

@ -38,10 +38,15 @@
#include "los_vm_page.h"
#include "los_arch_mmu.h"
/**
* @brief , los_vm_zone.h 鸿
*/
UINTPTR g_vmBootMemBase = (UINTPTR)&__bss_end; ///< 内核空间可用于分配的区域,紧挨着.bss区
BOOL g_kHeapInited = FALSE; ///< 内核堆区初始化变量
UINTPTR g_vmBootMemBase = (UINTPTR)&__bss_end;
BOOL g_kHeapInited = FALSE;
///< 开机引导分配器分配内存,只有开机时采用的分配方式
VOID *OsVmBootMemAlloc(size_t len)
{
UINTPTR ptr;
@ -51,33 +56,33 @@ VOID *OsVmBootMemAlloc(size_t len)
return NULL;
}
ptr = LOS_Align(g_vmBootMemBase, sizeof(UINTPTR));
g_vmBootMemBase = ptr + LOS_Align(len, sizeof(UINTPTR));
ptr = LOS_Align(g_vmBootMemBase, sizeof(UINTPTR));//对齐
g_vmBootMemBase = ptr + LOS_Align(len, sizeof(UINTPTR));//通过改变 g_vmBootMemBase来获取内存
//这样也行,g_vmBootMemBase 真是野蛮粗暴
return (VOID *)ptr;
}
///整个系统内存初始化
UINT32 OsSysMemInit(VOID)
{
STATUS_T ret;
#ifdef LOSCFG_KERNEL_VM
OsKSpaceInit();
OsKSpaceInit();//内核空间初始化
#endif
ret = OsKHeapInit(OS_KHEAP_BLOCK_SIZE);
ret = OsKHeapInit(OS_KHEAP_BLOCK_SIZE);// 内核堆空间初始化 512K
if (ret != LOS_OK) {
VM_ERR("OsKHeapInit fail\n");
return LOS_NOK;
}
#ifdef LOSCFG_KERNEL_VM
OsVmPageStartup();
g_kHeapInited = TRUE;
OsInitMappingStartUp();
OsVmPageStartup();// 物理内存初始化
g_kHeapInited = TRUE; //内核堆区初始化完成
OsInitMappingStartUp();//映射初始化
#else
g_kHeapInited = TRUE;
g_kHeapInited = TRUE;//内核堆区完成初始化
#endif
return LOS_OK;
}

@ -53,7 +53,7 @@
#define FLAG_SIZE 4
#define FLAG_START 2
//获取线性区的名称或文件路径
const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region)
{
struct Vnode *vnode = NULL;
@ -64,24 +64,24 @@ const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region)
vnode = region->unTypeData.rf.vnode;
return vnode->filePath;
#endif
} else if (region->regionFlags & VM_MAP_REGION_FLAG_HEAP) {
} else if (region->regionFlags & VM_MAP_REGION_FLAG_HEAP) {//堆区
return "HEAP";
} else if (region->regionFlags & VM_MAP_REGION_FLAG_STACK) {
} else if (region->regionFlags & VM_MAP_REGION_FLAG_STACK) {//栈区
return "STACK";
} else if (region->regionFlags & VM_MAP_REGION_FLAG_TEXT) {
} else if (region->regionFlags & VM_MAP_REGION_FLAG_TEXT) {//文本区
return "Text";
} else if (region->regionFlags & VM_MAP_REGION_FLAG_VDSO) {
} else if (region->regionFlags & VM_MAP_REGION_FLAG_VDSO) {//虚拟动态链接对象区Virtual Dynamically Shared Object、VDSO
return "VDSO";
} else if (region->regionFlags & VM_MAP_REGION_FLAG_MMAP) {
} else if (region->regionFlags & VM_MAP_REGION_FLAG_MMAP) {//映射区
return "MMAP";
} else if (region->regionFlags & VM_MAP_REGION_FLAG_SHM) {
} else if (region->regionFlags & VM_MAP_REGION_FLAG_SHM) {//共享区
return "SHM";
} else {
return "";
}
return "";
}
///
INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region)
{
LosVmMapRegion *regionTemp = NULL;
@ -107,7 +107,7 @@ INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region)
return 0;
}
///shell task 进程虚拟内存的使用情况
UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space)
{
LosVmMapRegion *region = NULL;
@ -119,7 +119,7 @@ UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space)
return 0;
}
if (space == LOS_GetKVmSpace()) {
if (space == LOS_GetKVmSpace()) {//内核空间
OsShellCmdProcessPmUsage(space, NULL, &used);
return used;
}
@ -127,15 +127,14 @@ UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space)
if (ret != 0) {
return 0;
}
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
region = (LosVmMapRegion *)pstRbNode;
used += region->range.size;
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)//开始扫描红黑树
region = (LosVmMapRegion *)pstRbNode;//拿到线性区,注意LosVmMapRegion结构体的第一个变量就是pstRbNode,所以可直接(LosVmMapRegion *)转
used += region->range.size;//size叠加,算出总使用
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)//结束扫描红黑树
(VOID)LOS_MuxRelease(&space->regionMux);
return used;
}
///内核空间物理内存使用情况统计
UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm)
{
UINT32 memUsed;
@ -159,7 +158,7 @@ UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm)
/* Kernel resident memory, include default heap memory */
memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT);
spaceList = LOS_GetVmSpaceList();//获取虚拟空间链表上面挂了所有虚拟空间
spaceList = LOS_GetVmSpaceList();//获取虚拟空间链表,上面挂了所有虚拟空间
LosMux *vmSpaceListMux = OsGVmSpaceMuxGet();
(VOID)LOS_MuxAcquire(vmSpaceListMux);
LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) {//遍历链表
@ -170,9 +169,9 @@ UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm)
}
(VOID)LOS_MuxRelease(vmSpaceListMux);
/* Kernel dynamic memory, include extended heap memory */ //内核动态内存,包括扩展堆内存
/* Kernel dynamic memory, include extended heap memory */ //内核动态内存,包括扩展堆内存
memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed);
/* Remaining heap memory */ //剩余堆内存
/* Remaining heap memory */ //剩余堆内存
memUsed -= freeMem;
*actualPm = memUsed;
@ -194,7 +193,7 @@ UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actu
}
return OsUProcessPmUsage(space, sharePm, actualPm);
}
///虚拟空间物理内存的使用情况参数同时带走共享物理内存sharePm和actualPm单位是字节
///虚拟空间物理内存的使用情况,参数同时带走共享物理内存 sharePm和actualPm 单位是字节
UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
{
LosVmMapRegion *region = NULL;
@ -230,10 +229,10 @@ UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
continue;
}
shareRef = LOS_AtomicRead(&page->refCounts);//ref 大于1 说明page被其他空间也引用了
shareRef = LOS_AtomicRead(&page->refCounts);//ref 大于1 说明page被其他空间也引用了,这就是共享内存核心定义!
if (shareRef > 1) {
if (sharePm != NULL) {
*sharePm += PAGE_SIZE;//一页4K字节
*sharePm += PAGE_SIZE;//一页 4K 字节
}
pmSize += PAGE_SIZE / shareRef;
} else {
@ -250,9 +249,7 @@ UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
return pmSize;
}
/// @brief 通过虚拟空间获取进程实体
/// @param space
/// @return
///通过虚拟空间获取进程实体
LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
{
UINT32 pid;
@ -263,7 +260,7 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
for (pid = 0; pid < g_processMaxNum; ++pid) {//循环进程池,进程池本质是个数组
processCB = g_processCBArray + pid;
if (OsProcessIsUnused(processCB)) {//进程还没被分配使用
continue;
continue;//继续找呗
}
if (processCB->vmSpace == space) {//找到了
@ -274,11 +271,7 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
SCHEDULER_UNLOCK(intSave);
return NULL;
}
/// @brief 统计虚拟空间中某个线性区的页数
/// @param space
/// @param region
/// @param pssPages
/// @return
///统计虚拟空间中某个线性区的页数
UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages)
{
UINT32 regionPages = 0;
@ -307,7 +300,7 @@ UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pss
}
if (pssPages != NULL) {
*pssPages = (UINT32)(pss + 0.5); /* 0.5, for page alignment */
*pssPages = (UINT32)(pss + 0.5);
}
return regionPages;
@ -408,16 +401,16 @@ VOID OsDumpAspace(LosVmSpace *space)
if (pcb == NULL) {
return;
}
//进程ID | 进程虚拟内存控制块地址信息 | 虚拟内存起始地址 | 虚拟内存大小 | 已使用的物理页数量
//进程ID | 进程虚拟内存控制块地址信息 | 虚拟内存起始地址 | 虚拟内存大小 | 已使用的物理页数量
spacePages = OsCountAspacePages(space);//获取空间的页数
PRINTK("\r\n PID aspace name base size pages \n");
PRINTK(" ---- ------ ---- ---- ----- ----\n");
PRINTK(" %-4d %#010x %-10.10s %#010x %#010x %d\n", pcb->processID, space, pcb->processName,
space->base, space->size, spacePages);
//虚拟区间控制块地址信息 | 虚拟区间类型 | 虚拟区间起始地址 | 虚拟区间大小 | 虚拟区间mmu映射属性 | 已使用的物理页数量(包括共享内存部分 | 已使用的物理页数量
//虚拟区间控制块地址信息 | 虚拟区间类型 | 虚拟区间起始地址 | 虚拟区间大小 | 虚拟区间mmu映射属性 | 已使用的物理页数量(包括共享内存部分 | 已使用的物理页数量
PRINTK("\r\n\t region name base size mmu_flags pages pg/ref\n");
PRINTK("\r\n\t region name base size mmu_flags pages pg/ref\n");
PRINTK("\t ------ ---- ---- ---- --------- ----- -----\n");
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)//按region 轮询统计
region = (LosVmMapRegion *)pstRbNode;
@ -435,7 +428,7 @@ VOID OsDumpAllAspace(VOID)
{
LosVmSpace *space = NULL;
LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList();//获取所有空间链表
LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) {//循环取出进程虚拟
LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) {//循环取出进程虚拟空间
(VOID)LOS_MuxAcquire(&space->regionMux);
OsDumpAspace(space);//dump 空间
(VOID)LOS_MuxRelease(&space->regionMux);

@ -49,12 +49,11 @@
#include "vnode.h"
#endif
#ifdef LOSCFG_KERNEL_VM
extern char __exc_table_start[];
extern char __exc_table_end[];
//线性正确性检查
//线性正确性检查
STATIC STATUS_T OsVmRegionPermissionCheck(LosVmMapRegion *region, UINT32 flags)
{
if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_READ) != VM_MAP_REGION_FLAG_PERM_READ) {
@ -96,7 +95,7 @@ STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *statu
}
}
#ifdef LOSCFG_FS_VFS
#ifdef LOSCFG_FS_VFS
//读页时发生缺页的处理
STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//读缺页
{
@ -141,7 +140,7 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//
return LOS_ERRNO_VM_NO_MEMORY;
}
/* unmap a page when cow happened only *///仅当写时拷贝发生时取消页面映射
/* numap a page when cow happend only *///仅当写时拷贝发生时取消页面映射
STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, LosVmPgFault *vmf)
{
UINT32 intSave;
@ -287,7 +286,7 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
return LOS_OK;
}
//以下是没有映射到物理地址的处理
//以下是没有映射到物理地址的处理
(VOID)LOS_MuxAcquire(&region->unTypeData.rf.vnode->mapping.mux_lock);
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);//函数指针执行的是g_commVmOps.OsVmmFileFault
if (ret == LOS_OK) {
@ -352,7 +351,7 @@ STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, U
*/
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
{
LosVmSpace *space = LOS_SpaceGet(vaddr);
LosVmSpace *space = LOS_SpaceGet(vaddr);//获取虚拟地址所属空间
LosVmMapRegion *region = NULL;
STATUS_T status;
PADDR_T oldPaddr;
@ -404,7 +403,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
}
vaddr = ROUNDDOWN(vaddr, PAGE_SIZE);//为啥要向下圆整,因为这一页要重新使用,需找到页面基地址
#ifdef LOSCFG_FS_VFS
#ifdef LOSCFG_FS_VFS
if (LOS_IsRegionFileValid(region)) {//是否为文件线性区
if (region->unTypeData.rf.vnode == NULL) {
goto CHECK_FAILED;
@ -422,7 +421,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
goto DONE;
}
#endif
//请求调页:推迟到不能再推迟为止
//请求调页:推迟到不能再推迟为止
newPage = LOS_PhysPageAlloc();//分配一个新的物理页
if (newPage == NULL) {
status = LOS_ERRNO_VM_NO_MEMORY;
@ -432,7 +431,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
newPaddr = VM_PAGE_TO_PHYS(newPage);//获取物理地址
(VOID)memset_s(OsVmPageToVaddr(newPage), PAGE_SIZE, 0, PAGE_SIZE);//获取虚拟地址 清0
status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &oldPaddr, NULL);//通过虚拟地址查询老物理地址
if (status >= 0) {
if (status >= 0) {//已经映射过了,@note_thinking 不是缺页吗,怎么会有页的情况?
LOS_ArchMmuUnmap(&space->archMmu, vaddr, 1);//解除映射关系
OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage);//将oldPaddr的数据拷贝到newPage
/* use old page free the new one */
@ -451,7 +450,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
status = LOS_OK;
goto DONE;
} else {
} else {//
/* map all of the pages */
LOS_AtomicInc(&newPage->refCounts);//引用数自增
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);//映射新物理地址,如此下次就不会缺页了

@ -644,4 +644,4 @@ INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
}
#endif
#endif
#endif

@ -1,4 +1,8 @@
/*
/*!
* @file los_vm_iomap.c
* @brief DMA
* @link
@verbatim
访
访Direct Memory AccessDMA访
CPU
@ -34,9 +38,12 @@
Non-coherent systemDMA
DMA
DMA
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2022-04-02
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -75,7 +82,7 @@
#include "los_vm_map.h"
#include "los_memory.h"
///分配DMA空间
/// 分配DMA空间
VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type)
{
VOID *kVaddr = NULL;
@ -90,12 +97,12 @@ VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMe
}
#ifdef LOSCFG_KERNEL_VM
kVaddr = LOS_KernelMallocAlign(size, align);
kVaddr = LOS_KernelMallocAlign(size, align);//不走内存池方式, 直接申请物理页
#else
kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align);//不走内存池方式, 直接申请物理页
kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align);//从内存池中申请
#endif
if (kVaddr == NULL) {
VM_ERR("failed, size = %u, align = %u", size, align);//从内存池中申请
VM_ERR("failed, size = %u, align = %u", size, align);
return NULL;
}
@ -109,7 +116,7 @@ VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMe
return kVaddr;
}
///释放DMA指针
/// 释放 DMA指针
VOID LOS_DmaMemFree(VOID *vaddr)
{
UINTPTR addr;
@ -118,11 +125,11 @@ VOID LOS_DmaMemFree(VOID *vaddr)
return;
}
addr = (UINTPTR)vaddr;
// 未缓存区
// 未缓存区
if ((addr >= UNCACHED_VMM_BASE) && (addr < UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)) {
addr = UNCACHED_TO_VMM_ADDR(addr);//转换成未缓存区地址
addr = UNCACHED_TO_VMM_ADDR(addr); //转换成未缓存区地址
#ifdef LOSCFG_KERNEL_VM
LOS_KernelFree((VOID *)addr);
LOS_KernelFree((VOID *)addr);//
#else
LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr);//内存池方式释放
#endif
@ -137,7 +144,7 @@ VOID LOS_DmaMemFree(VOID *vaddr)
}
return;
}
/// 将DMA虚拟地址转成物理地址
DMA_ADDR_T LOS_DmaVaddrToPaddr(VOID *vaddr)
{
return (DMA_ADDR_T)LOS_PaddrQuery(vaddr);

@ -1,4 +1,8 @@
/*
/*!
* @file los_vm_map.c
* @brief
* @link vm http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-memory-virtual.html @endlink
@verbatim
CPU
320-4GiB4GiBLiteOS-A3GiB
@ -36,11 +40,15 @@
2. CPU访V2
CPU访
便访
*/
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-25
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -1281,4 +1289,6 @@ VOID LOS_KernelFree(VOID *ptr)
{
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr);//从内存池中释放
}
}
}

@ -45,12 +45,12 @@ size_t g_vmPageArraySize;//物理页框大小
//页框初始化
STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
{
LOS_ListInit(&page->node);//页节点初始化
page->flags = FILE_PAGE_FREE;//页标签,初始为空闲页
LOS_AtomicSet(&page->refCounts, 0);//引用次数0
page->physAddr = pa;//物理地址
page->segID = segID;//物理地址使用段管理段ID
page->order = VM_LIST_ORDER_MAX;//初始化值,不属于任何块组
LOS_ListInit(&page->node); //页节点初始化
page->flags = FILE_PAGE_FREE; //页标签,初始为空闲页
LOS_AtomicSet(&page->refCounts, 0); //引用次数0
page->physAddr = pa; //物理地址
page->segID = segID; //物理地址使用段管理段ID
page->order = VM_LIST_ORDER_MAX; //初始化值,不属于任何块组
page->nPages = 0;
#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK
LOS_SpinInit(&page->lock);
@ -61,7 +61,6 @@ STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
{//@note_why 此时所有页面 page->order = VM_LIST_ORDER_MAX,能挂入伙伴算法的链表吗?
OsVmPhysPagesFreeContiguous(page, nPages);//释放连续的物理页框
}
#define VMPAGEINIT(page, pa, segID) do { \
OsVmPageInit(page, pa, segID); \
(page)++; \
@ -92,7 +91,7 @@ VOID OsVmPageStartup(VOID)
g_vmPageArraySize = nPage * sizeof(LosVmPage);//页表总大小
g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);//实模式下申请内存,此时还没有初始化MMU
OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE));
OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE));//
OsVmPhysSegAdd();// 完成对段的初始化
OsVmPhysInit();// 加入空闲链表和设置置换算法,LRU(最近最久未使用)算法

@ -1,4 +1,8 @@
/*!
* @file los_vm_phys.c
* @brief -
* @link physical http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.html @endlink
@verbatim
CPU线
LiteOS-A
@ -22,8 +26,13 @@
12KiB3322111
201
1
@endverbatim
* @image html https://gitee.com/weharmonyos/resources/raw/master/17/malloc_phy.png
* @image html https://gitee.com/weharmonyos/resources/raw/master/17/free_phy.png
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-11-25
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -691,3 +700,4 @@ VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
return (VADDR_T *)DMA_TO_VMM_ADDR(paddr);
}
#endif

@ -344,4 +344,4 @@ int OsTryShrinkMemory(size_t nPage)
#endif
#endif
#endif
#endif

@ -103,6 +103,8 @@ STATUS_T OsAnonMMap(LosVmMapRegion *region)
}
/**
* @brief
@verbatim
mmap:
.
@ -135,6 +137,14 @@ STATUS_T OsAnonMMap(LosVmMapRegion *region)
offset 0offsetPAGE_SIZE
(void *)-1
@endverbatim
* @param vaddr
* @param len
* @param prot
* @param flags
* @param fd
* @param pgoff
* @return VADDR_T
*/
VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff)
{
@ -234,12 +244,17 @@ VOID *OsShrinkHeap(VOID *addr, LosVmSpace *space)
}
/**
* @brief
@verbatim
线线
线
线线线
线
@endverbatim
* @param addr
* @return VOID*
*/
VOID *LOS_DoBrk(VOID *addr)
{
@ -553,4 +568,5 @@ VOID LOS_DumpMemRegion(VADDR_T vaddr)
OsDumpPte(vaddr);//dump L1 L2
OsDumpAspace(space);//dump 空间
}
#endif
#endif

@ -248,4 +248,5 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID)
LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK);//初始化内存监控模块
#endif
#endif

@ -1,4 +1,8 @@
/*!
* @file shm.c
* @brief
* @link
@verbatim
访
@ -10,8 +14,11 @@
访
线,使线.
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-12-24
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
@ -1026,3 +1033,4 @@ DONE:
SHELLCMD_ENTRY(shm_shellcmd, CMD_TYPE_SHOW, "shm", 2, (CmdCallBackFunc)OsShellCmdShm);
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -1,3 +1,23 @@
/*!
* @file console.h
* @brief
* @link
@verbatim
https://www.cnblogs.com/sparkdev/p/11460821.html
TTY Teletype Teletypewriter ,
,
TTY (terminal)
TTY Linux TTY TTY Linux TTY
/dev/consoletty鸿dev/ttyS0(UART0)
@endverbatim
* @version
* @author weharmonyos.com | 鸿 |
* @date 2021-12-8
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -51,55 +71,83 @@ extern "C" {
#ifdef LOSCFG_FS_VFS
/* Define two fixed console id for Console ID. */
#define CONSOLE_SERIAL 1
#define CONSOLE_TELNET 2
/* Define two fixed console id for Console ID. | 默认两种固定的控制台id */
#define CONSOLE_SERIAL 1 ///< 串行方式
#define CONSOLE_TELNET 2 ///< 远程登录
//POSIX 定义了 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 来代表 0、1、2
#define LOSCFG_PLATFORM_CONSOLE
#define STDIN 0
#define STDOUT 1
#define STDERR 2
#define STDIN 0 ///< 标准输入
#define STDOUT 1 ///< 标准输出
#define STDERR 2 ///< 错误
#define CONSOLE "/dev/console"
#define CONSOLE "/dev/console"
#define CONSOLE_NAMELEN 16
#define CONSOLE_RD_BLOCK 1
#define CONSOLE_RD_NONBLOCK 0
#define CONSOLE_SHELL_KEY_EVENT 0x112
#define CONSOLE_SHELL_EXITED 0x400
#define CONSOLE_FIFO_SIZE 0x400
#define CONSOLE_SHELL_KEY_EVENT 0x112 ///< shell 键盘事件
#define CONSOLE_SHELL_EXITED 0x400 ///< shell 退出事件
#define CONSOLE_FIFO_SIZE 0x400 ///< 1K
#define CONSOLE_NUM 2
#define CONSOLE_CIRCBUF_SIZE 0x400
#define CONSOLE_CIRCBUF_SIZE 0x400 ///< 大小 1K
/**
* @brief buf,
*/
typedef struct {
CirBuf cirBufCB; /* Circular buffer CB */
EVENT_CB_S sendEvent; /* Inform telnet send task */
CirBuf cirBufCB; /* Circular buffer CB | 循环缓冲控制块 */
EVENT_CB_S sendEvent; /* Inform telnet send task | 例如: 给SendToSer任务发送事件*/
} CirBufSendCB;
/**
* @brief ()
*/
typedef struct {
UINT32 consoleID;
UINT32 consoleType;
UINT32 consoleSem;
UINT32 consoleMask;
struct Vnode *devVnode;
CHAR *name;
INT32 fd;
UINT32 refCount;
UINT32 shellEntryId;
INT32 pgrpId;
BOOL isNonBlock;
UINT32 consoleID; ///< 控制台ID 例如 : 1 | 串口 , 2 | 远程登录
UINT32 consoleType; ///< 控制台类型
UINT32 consoleSem; ///< 控制台信号量
UINT32 consoleMask; ///< 控制台掩码
struct Vnode *devVnode; ///< 索引节点
CHAR *name; ///< 名称 例如: /dev/console1
INT32 fd; ///< 系统文件句柄, 由内核分配
UINT32 refCount; ///< 引用次数,用于判断控制台是否被占用
UINT32 shellEntryId; ///< 负责接受来自终端信息的 "ShellEntry"任务,这个值在运行过程中可能会被换掉,它始终指向当前正在运行的shell客户端
INT32 pgrpId; ///< 进程组ID
BOOL isNonBlock; ///< 是否无锁方式
#ifdef LOSCFG_SHELL
VOID *shellHandle;
VOID *shellHandle; ///< shell句柄,本质是 shell控制块 ShellCB
#endif
UINT32 sendTaskID;
CirBufSendCB *cirBufSendCB;
UINT8 fifo[CONSOLE_FIFO_SIZE];
UINT32 fifoOut;
UINT32 fifoIn;
UINT32 currentLen;
struct termios consoleTermios;
UINT32 sendTaskID; ///< 创建任务通过事件接收数据, 见于OsConsoleBufInit
CirBufSendCB *cirBufSendCB; ///< 循环缓冲发送控制块
UINT8 fifo[CONSOLE_FIFO_SIZE]; ///< termios 规范模式(ICANON mode )下使用 size:1K
UINT32 fifoOut; ///< 对fifo的标记,输出位置
UINT32 fifoIn; ///< 对fifo的标记,输入位置
UINT32 currentLen; ///< 当前fifo位置
struct termios consoleTermios; ///< 行规程
} CONSOLE_CB;
/**
* @brief https://man7.org/linux/man-pages/man3/tcflow.3.html
termios POSIXtermios
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
*/
extern INT32 system_console_init(const CHAR *deviceName);
extern INT32 system_console_deinit(const CHAR *deviceName);
extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB);
@ -126,15 +174,15 @@ extern VOID OsWakeConsoleSendTask(VOID);
#endif
extern VOID KillPgrp(UINT16 consoleId);
/* console ioctl */
/* console ioctl | 控制台常见控制操作*/
#define CONSOLE_IOC_MAGIC 'c'
#define CONSOLE_CMD_RD_BLOCK_SERIAL _IO(CONSOLE_IOC_MAGIC, 1)
#define CONSOLE_CMD_RD_BLOCK_TELNET _IO(CONSOLE_IOC_MAGIC, 2)
#define CONSOLE_CONTROL_RIGHTS_CAPTURE _IO(CONSOLE_IOC_MAGIC, 3)
#define CONSOLE_CMD_RD_BLOCK_SERIAL _IO(CONSOLE_IOC_MAGIC, 1) ///< 设置串口方式
#define CONSOLE_CMD_RD_BLOCK_TELNET _IO(CONSOLE_IOC_MAGIC, 2) ///< 设置远程登录方式
#define CONSOLE_CONTROL_RIGHTS_CAPTURE _IO(CONSOLE_IOC_MAGIC, 3) ///<
#define CONSOLE_CONTROL_RIGHTS_RELEASE _IO(CONSOLE_IOC_MAGIC, 4)
#define CONSOLE_CONTROL_CAPTURE_LINE _IO(CONSOLE_IOC_MAGIC, 5)
#define CONSOLE_CONTROL_CAPTURE_CHAR _IO(CONSOLE_IOC_MAGIC, 6)
#define CONSOLE_CONTROL_REG_USERTASK _IO(CONSOLE_IOC_MAGIC, 7)
#define CONSOLE_CONTROL_REG_USERTASK _IO(CONSOLE_IOC_MAGIC, 7) ///< 注册用户任务 shell 客户端
#endif

@ -53,13 +53,13 @@
#include "los_vm_boot.h"
#include "los_smp.h"
STATIC SystemRebootFunc g_rebootHook = NULL;
STATIC SystemRebootFunc g_rebootHook = NULL;///< 系统重启钩子函数
/// 设置系统重启钩子函数
VOID OsSetRebootHook(SystemRebootFunc func)
{
g_rebootHook = func;
}
///获取系统重启钩子函数
SystemRebootFunc OsGetRebootHook(VOID)
{
return g_rebootHook;
@ -67,31 +67,31 @@ SystemRebootFunc OsGetRebootHook(VOID)
LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID)
{
/* Must be placed at the beginning of the boot process */
OsSetMainTask();
OsCurrTaskSet(OsGetMainTask());
OsSchedRunqueueInit();
/* Must be placed at the beginning of the boot process *///必须放在启动过程的开头
OsSetMainTask();//为每个CPU核设置临时主任务
OsCurrTaskSet(OsGetMainTask());//设置当前任务
OsSchedRunqueueInit();//初始化调度队列
g_sysClock = OS_SYS_CLOCK;
g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND;
g_sysClock = OS_SYS_CLOCK; //设置系统时钟
g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND; // 设置TICK间隔
return LOS_OK;
}
//硬件早期初始化
LITE_OS_SEC_TEXT_INIT STATIC UINT32 ArchEarlyInit(VOID)
{
UINT32 ret;
/* set system counter freq */
/* set system counter freq | 设置系统计数器频率*/
#ifndef LOSCFG_TEE_ENABLE
HalClockFreqWrite(OS_SYS_CLOCK);
HalClockFreqWrite(OS_SYS_CLOCK); //写寄存器 MCR p15, 0, <Rt>, c14, c0, 0 ; Write Rt to CNTFRQ
#endif
#ifdef LOSCFG_PLATFORM_HWI
OsHwiInit();
OsHwiInit(); // 硬中断初始化
#endif
OsExcInit();
OsExcInit(); // 异常初始化
ret = OsTickInit(g_sysClock, LOSCFG_BASE_CORE_TICK_PER_SECOND);
if (ret != LOS_OK) {
@ -101,11 +101,11 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 ArchEarlyInit(VOID)
return LOS_OK;
}
//平台早期初始化
LITE_OS_SEC_TEXT_INIT STATIC UINT32 PlatformEarlyInit(VOID)
{
#if defined(LOSCFG_PLATFORM_UART_WITHOUT_VFS) && defined(LOSCFG_DRIVERS)
uart_init();
uart_init(); //初始化串口
#endif /* LOSCFG_PLATFORM_UART_WITHOUT_VFS */
return LOS_OK;
@ -145,11 +145,11 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 PlatformInit(VOID)
{
return LOS_OK;
}
//内核关键模块初始化
LITE_OS_SEC_TEXT_INIT STATIC UINT32 KModInit(VOID)
{
#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE
OsSwtmrInit();
OsSwtmrInit(); //软件定时器模块 , 软定由专门的 0 级任务实现
#endif
return LOS_OK;
}
@ -179,10 +179,10 @@ LITE_OS_SEC_TEXT_INIT VOID OsSystemInfo(VOID)
#ifdef LOSCFG_KERNEL_SMP
LOSCFG_KERNEL_SMP_CORE_NUM,
#endif
HalIrqVersion(), __DATE__, __TIME__, \
HalIrqVersion(), __DATE__, __TIME__,\
KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType);
}
///由汇编调用,鸿蒙C语言层级的入口点
LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID)
{
UINT32 ret;
@ -190,19 +190,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID)
UINT64 startNsec, endNsec, durationUsec;
#endif
ret = EarliestInit();
ret = EarliestInit();//鸿蒙初开,天地混沌
if (ret != LOS_OK) {
return ret;
}
OsInitCall(LOS_INIT_LEVEL_EARLIEST);
ret = ArchEarlyInit();
ret = ArchEarlyInit(); //架构级初始化,包括硬中断
if (ret != LOS_OK) {
return ret;
}
OsInitCall(LOS_INIT_LEVEL_ARCH_EARLY);
ret = PlatformEarlyInit();
ret = PlatformEarlyInit();//平台级初始化
if (ret != LOS_OK) {
return ret;
}
@ -224,24 +224,24 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID)
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;
}
ret = OsSystemProcessCreate();
ret = OsSystemProcessCreate();//创建系统进程
if (ret != LOS_OK) {
return ret;
}
ret = ArchInit();
ret = ArchInit(); //MMU架构初始化
if (ret != LOS_OK) {
return ret;
}
@ -285,8 +285,8 @@ STATIC VOID SystemInit(VOID)
#else
extern VOID SystemInit(VOID);
#endif
#ifndef LOSCFG_ENABLE_KERNEL_TEST
///创建系统初始任务并申请调度
STATIC UINT32 OsSystemInitTaskCreate(VOID)
{
UINT32 taskID;
@ -304,6 +304,7 @@ STATIC UINT32 OsSystemInitTaskCreate(VOID)
return LOS_TaskCreate(&taskID, &sysTask);
}
//系统任务初始化
STATIC UINT32 OsSystemInit(VOID)
{
UINT32 ret;
@ -316,5 +317,5 @@ STATIC UINT32 OsSystemInit(VOID)
return 0;
}
LOS_MODULE_INIT(OsSystemInit, LOS_INIT_LEVEL_KMOD_TASK);
LOS_MODULE_INIT(OsSystemInit, LOS_INIT_LEVEL_KMOD_TASK);//模块初始化
#endif

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -46,35 +46,35 @@ extern "C" {
#endif /* __cplusplus */
/**
* @ingroup los_config
* int stack start addr
* @ingroup los_config
* int stack start addr | ,liteos.ld
*/
extern CHAR __int_stack_start;
extern CHAR __rodata_start;
extern CHAR __rodata_end;
extern CHAR __bss_start;
extern CHAR __bss_end;
extern CHAR __text_start;
extern CHAR __text_end;
extern CHAR __ram_data_start;
extern CHAR __ram_data_end;
extern UINT32 __heap_start;
extern UINT32 __heap_end;
extern CHAR __int_stack_start; ///< 运行系统函数栈的开始地址 值来自于 liteos.ld中的 __int_stack_start = .;
extern CHAR __rodata_start; ///< ROM开始地址 只读
extern CHAR __rodata_end; ///< ROM结束地址
extern CHAR __bss_start; ///< bss开始地址 __attribute__((section(".__bss_start")));
extern CHAR __bss_end; ///< bss结束地址 __attribute__((section(".__bss_end")));
extern CHAR __text_start; ///< 代码区开始地址
extern CHAR __text_end; ///< 代码区结束地址
extern CHAR __ram_data_start; ///< RAM开始地址 可读可写
extern CHAR __ram_data_end; ///< RAM结束地址
extern UINT32 __heap_start; ///< 堆区开始地址
extern UINT32 __heap_end; ///< 堆区结束地址
/****************************** System clock module configuration ****************************/
/**
* @ingroup los_config
* System clock (unit: HZ)
*/
#ifndef OS_SYS_CLOCK
#define OS_SYS_CLOCK (get_bus_clk())
#ifndef OS_SYS_CLOCK ///< HZ:是每秒中的周期性变动重复次数的计量
#define OS_SYS_CLOCK (get_bus_clk()) ///< 系统主时钟频率 例如:50000000 即20纳秒
#endif
/**
* @ingroup los_config
* time timer clock (unit: HZ)
*/
#ifndef OS_TIME_TIMER_CLOCK
#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK
#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK ///< 定时器频率
#endif
/**
@ -82,10 +82,10 @@ extern UINT32 __heap_end;
* limit addr range when search for 'func local(frame pointer)' or 'func name'
*/
#ifndef OS_SYS_FUNC_ADDR_START
#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start)
#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start) //
#endif
#ifndef OS_SYS_FUNC_ADDR_END
#define OS_SYS_FUNC_ADDR_END (KERNEL_VMM_BASE + SYS_MEM_SIZE_DEFAULT)
#define OS_SYS_FUNC_ADDR_END (KERNEL_VMM_BASE + SYS_MEM_SIZE_DEFAULT)
#endif
/**
@ -93,7 +93,7 @@ extern UINT32 __heap_end;
* Number of Ticks in one second
*/
#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND
#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */
#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick | 每秒节拍数*/
#endif
/**
@ -131,14 +131,15 @@ extern UINT32 __heap_end;
* External configuration item for timer tailoring
*/
#if defined(LOSCFG_BASE_CORE_TICK_HW_TIME) && (LOSCFG_BASE_CORE_TICK_HW_TIME == 0)
#undef LOSCFG_BASE_CORE_TICK_HW_TIME
#undef LOSCFG_BASE_CORE_TICK_HW_TIME ///< 定时器裁剪的外部配置项
#endif
/****************************** Hardware interrupt module configuration ******************************/
/**
* @ingroup los_config
* Configuration item for hardware interrupt tailoring
* Configuration item for hardware interrupt tailoring
*/
#ifndef LOSCFG_PLATFORM_HWI
#ifndef LOSCFG_PLATFORM_HWI ///< 硬件中断裁剪配置项
#define LOSCFG_PLATFORM_HWI
#endif
@ -147,7 +148,7 @@ extern UINT32 __heap_end;
* Maximum number of used hardware interrupts, including Tick timer interrupts.
*/
#ifndef LOSCFG_PLATFORM_HWI_LIMIT
#define LOSCFG_PLATFORM_HWI_LIMIT 96
#define LOSCFG_PLATFORM_HWI_LIMIT 96 ///< 硬件中断最大数量
#endif
/**
@ -167,8 +168,8 @@ extern UINT32 __heap_end;
* @ingroup los_config
* Minimum stack size.
*
* 0x800 bytes, aligned on a boundary of 8.
* 0x800 bytes, aligned on a boundary of 4.
* 0x600 bytes, aligned on a boundary of 8.
* 0x600 bytes, aligned on a boundary of 4.
*/
#ifndef LOS_TASK_MIN_STACK_SIZE
#ifdef __LP64__
@ -182,7 +183,7 @@ extern UINT32 __heap_end;
* @ingroup los_config
* Default task priority
*/
#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO
#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO ///< 内核任务默认优先级
#define LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO 10
#endif
@ -190,7 +191,7 @@ extern UINT32 __heap_end;
* @ingroup los_config
* Maximum supported number of tasks except the idle task rather than the number of usable tasks
*/
#ifndef LOSCFG_BASE_CORE_TSK_LIMIT
#ifndef LOSCFG_BASE_CORE_TSK_LIMIT ///< 支持的最大任务数(空闲任务除外,而不是可用任务数)
#define LOSCFG_BASE_CORE_TSK_LIMIT 128
#endif
@ -198,7 +199,7 @@ extern UINT32 __heap_end;
* @ingroup los_config
* Maximum supported number of process rather than the number of usable processes.
*/
#ifndef LOSCFG_BASE_CORE_PROCESS_LIMIT
#ifndef LOSCFG_BASE_CORE_PROCESS_LIMIT ///< 支持的最大进程数,而不是可用进程数
#define LOSCFG_BASE_CORE_PROCESS_LIMIT 64
#endif
@ -210,23 +211,23 @@ extern UINT32 __heap_end;
* @ingroup los_config
* Size of the idle task stack
*/
#ifndef LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE
#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE SIZE(0x800)
#ifndef LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE ///< 空闲任务栈大小
#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE SIZE(0x800) ///< 2K
#endif
/**
* @ingroup los_config
* Default task stack size
*/
#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0x4000)
#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE //内核默认任务栈大小
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0x4000) ///< 16K
#endif
/**
* @ingroup los_config
* Longest execution time of tasks with the same priorities
*/
#ifndef LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT
#ifndef LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT //相同优先级任务的最长执行时间,时间片
#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 20000 /* 20ms */
#endif
@ -234,7 +235,7 @@ extern UINT32 __heap_end;
* @ingroup los_config
* Configuration item for task (stack) monitoring module tailoring
*/
#ifndef LOSCFG_BASE_CORE_TSK_MONITOR
#ifndef LOSCFG_BASE_CORE_TSK_MONITOR //任务(栈)监控模块裁剪配置项
#define LOSCFG_BASE_CORE_TSK_MONITOR
#endif
@ -244,7 +245,7 @@ extern UINT32 __heap_end;
* Configuration item for semaphore module tailoring
*/
#ifndef LOSCFG_BASE_IPC_SEM
#define LOSCFG_BASE_IPC_SEM
#define LOSCFG_BASE_IPC_SEM //信号量支持
#endif
/**
@ -252,7 +253,7 @@ extern UINT32 __heap_end;
* Maximum supported number of semaphores
*/
#ifndef LOSCFG_BASE_IPC_SEM_LIMIT
#define LOSCFG_BASE_IPC_SEM_LIMIT 1024
#define LOSCFG_BASE_IPC_SEM_LIMIT 1024 //信号量的最大个数
#endif
/**
@ -262,7 +263,6 @@ extern UINT32 __heap_end;
#ifndef OS_SEM_COUNT_MAX
#define OS_SEM_COUNT_MAX 0xFFFE
#endif
/****************************** Mutex module configuration ******************************/
/**
* @ingroup los_config
@ -295,7 +295,7 @@ extern UINT32 __heap_end;
* Maximum supported number of queues rather than the number of usable queues
*/
#ifndef LOSCFG_BASE_IPC_QUEUE_LIMIT
#define LOSCFG_BASE_IPC_QUEUE_LIMIT 1024
#define LOSCFG_BASE_IPC_QUEUE_LIMIT 1024 //队列个数
#endif
/****************************** Software timer module configuration **************************/
#ifdef LOSCFG_BASE_IPC_QUEUE
@ -319,23 +319,23 @@ extern UINT32 __heap_end;
* Maximum supported number of software timers rather than the number of usable software timers
*/
#ifndef LOSCFG_BASE_CORE_SWTMR_LIMIT
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 1024
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 1024 // 最大支持的软件定时器数
#endif
/**
* @ingroup los_config
* Max number of software timers ID
*
* 0xFFFF: max number of all software timers
* 0xFFFF: max number of all software timers |
*/
#ifndef OS_SWTMR_MAX_TIMERID
#define OS_SWTMR_MAX_TIMERID ((0xFFFF / LOSCFG_BASE_CORE_SWTMR_LIMIT) * LOSCFG_BASE_CORE_SWTMR_LIMIT)
#define OS_SWTMR_MAX_TIMERID ((0xFFFF / LOSCFG_BASE_CORE_SWTMR_LIMIT) * LOSCFG_BASE_CORE_SWTMR_LIMIT) ///< 65535
#endif
/**
* @ingroup los_config
* Maximum size of a software timer queue
*/
#ifndef OS_SWTMR_HANDLE_QUEUE_SIZE
#define OS_SWTMR_HANDLE_QUEUE_SIZE LOSCFG_BASE_CORE_SWTMR_LIMIT
#define OS_SWTMR_HANDLE_QUEUE_SIZE LOSCFG_BASE_CORE_SWTMR_LIMIT ///< 软时钟队列的大小
#endif
#endif
@ -346,26 +346,27 @@ extern UINT32 __heap_end;
* Starting address of the system memory
*/
#ifndef OS_SYS_MEM_ADDR
#define OS_SYS_MEM_ADDR (&m_aucSysMem1[0])
#define OS_SYS_MEM_ADDR (&m_aucSysMem1[0])//系统内存起始地址(指虚拟地址)
#endif
/**
* @ingroup los_config
* Memory size
*/
#ifndef OS_SYS_MEM_SIZE
#ifndef OS_SYS_MEM_SIZE //系统动态内存池的大小DDR自适应配置以byte为单位,从bss段末尾至系统DDR末尾
#define OS_SYS_MEM_SIZE \
((OS_SYS_FUNC_ADDR_END) - (((UINTPTR)&__bss_end + (64 - 1)) & ~(64 - 1)))
#endif
/****************************** SMP module configuration **************************/
//http://www.gotw.ca/publications/concurrency-ddj.htm 免费午餐结束了:软件并发的根本转变
#ifdef LOSCFG_KERNEL_SMP
#define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM
#define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM //多核情况下支持的CPU核数
#else
#define LOSCFG_KERNEL_CORE_NUM 1
#define LOSCFG_KERNEL_CORE_NUM 1 //单核配置
#endif
#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1)
#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1) //CPU掩码,每一个核占用一个位,用于计算和定位具体CPU核
/**
* @ingroup los_config
@ -379,11 +380,11 @@ extern UINT32 __heap_end;
/**
* @ingroup los_config
* The Version number of Public
* The Version number of Public //Public的版本号 ,每个占8位,刚好一个字节
*/
#define KERNEL_MAJOR 2
#define KERNEL_MINOR 0
#define KERNEL_PATCH 0
#define KERNEL_MAJOR 2 //主版本号
#define KERNEL_MINOR 0 //小版本号
#define KERNEL_PATCH 0 //补丁版本号
#define KERNEL_ITRE 37
#define VERSION_NUM(a, b, c, d) (((a) << 24) | ((b) << 16) | (c) << 8 | (d))
@ -403,7 +404,7 @@ extern UINT32 __heap_end;
* @ingroup los_config
* the size of space for recording exception information
*/
#define EXCINFO_RECORD_BUF_SIZE (16 * 1024)
#define EXCINFO_RECORD_BUF_SIZE (16 * 1024) //记录异常信息缓存大小 16K
/**
* @ingroup los_config
@ -411,11 +412,11 @@ extern UINT32 __heap_end;
* @attention
* <ul>
* <li> if uses, the address must be valid in flash, and it should not overlap with other addresses
* used to store valid information. </li>
* used to store valid information. </li>
* </ul>
*
*/
#define EXCINFO_RECORD_ADDR (0xffffffff)
#define EXCINFO_RECORD_ADDR (0xffffffff) //记录异常信息的空间地址
/**
* @ingroup los_config
@ -423,7 +424,7 @@ extern UINT32 __heap_end;
*
* @par Description:
* <ul>
* <li>This definition is used to declare the type of functions for reading or writing exception information</li>
* <li>This defination is used to declare the type of functions for reading or writing exception information</li>
* </ul>
* @attention
* <ul>
@ -437,9 +438,9 @@ extern UINT32 __heap_end;
*
* @retval none.
* @par Dependency:
* <ul><li>los_config.h: the header file that contains the type definition.</li></ul>
* <ul><li>los_config.h: the header file that contains the type defination.</li></ul>
* @see
*/
*/ //定义用于读取或写入异常信息的指针函数类型
typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf);
/**
@ -468,6 +469,13 @@ typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag,
* <ul><li>los_config.h: the header file that contains the API declaration.</li></ul>
* @see
*/
/**
* API
* startAddr:
* space: buf
* buf:
* hook:
*/
VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook);
#endif
@ -476,7 +484,6 @@ extern UINT32 OsMain(VOID);
typedef VOID (*SystemRebootFunc)(VOID);
VOID OsSetRebootHook(SystemRebootFunc func);
SystemRebootFunc OsGetRebootHook(VOID);
#ifdef __cplusplus
#if __cplusplus
}

@ -40,37 +40,37 @@
#endif
#ifdef LOSCFG_SAVE_EXCINFO
STATIC log_read_write_fn g_excInfoRW = NULL; /* the hook of read-writing exception information */
STATIC CHAR *g_excInfoBuf = NULL; /* pointer to the buffer for storing the exception information */
STATIC UINT32 g_excInfoIndex = 0xFFFFFFFF; /* the index of the buffer for storing the exception information */
STATIC UINT32 g_recordAddr = 0; /* the address of storing the exception information */
STATIC UINT32 g_recordSpace = 0; /* the size of storing the exception information */
STATIC log_read_write_fn g_excInfoRW = NULL; /* the hook of read-writing exception information */ //读写异常信息的钩子函数
STATIC CHAR *g_excInfoBuf = NULL; /* pointer to the buffer for storing the exception information */ //指向存储异常信息的缓冲区的指针
STATIC UINT32 g_excInfoIndex = 0xFFFFFFFF; /* the index of the buffer for storing the exception information */ //用于存储异常信息的缓冲区的索引
STATIC UINT32 g_recordAddr = 0; /* the address of storing the exception information */ //存储异常信息的地址
STATIC UINT32 g_recordSpace = 0; /* the size of storing the exception information */ //存储异常信息的大小
//设置异常信息的读写函数
VOID SetExcInfoRW(log_read_write_fn func)
{
g_excInfoRW = func;
}
///获取异常信息读写函数
log_read_write_fn GetExcInfoRW(VOID)
{
return g_excInfoRW;
}
///设置异常信息的缓存
VOID SetExcInfoBuf(CHAR *buf)
{
g_excInfoBuf = buf;
}
///获取异常信息的缓存
CHAR *GetExcInfoBuf(VOID)
{
return g_excInfoBuf;
}
///设置异常信息索引位
VOID SetExcInfoIndex(UINT32 index)
{
g_excInfoIndex = index;
}
///获取异常信息索引位
UINT32 GetExcInfoIndex(VOID)
{
return g_excInfoIndex;
@ -95,7 +95,7 @@ UINT32 GetRecordSpace(VOID)
{
return g_recordSpace;
}
///vsnprintf 为C标准库可变参数的实现函数 见于 ..\third_party\musl\kernel\src\stdio\vsnprintf.c
VOID WriteExcBufVa(const CHAR *format, va_list arglist)
{
errno_t ret;
@ -110,16 +110,15 @@ VOID WriteExcBufVa(const CHAR *format, va_list arglist)
g_excInfoIndex += ret;
}
}
///写异常信息到系统异常信息中心
VOID WriteExcInfoToBuf(const CHAR *format, ...)
{
va_list arglist;
va_start(arglist, format);
WriteExcBufVa(format, arglist);
va_end(arglist);
va_list arglist;//va_arg
va_start(arglist, format);//从任务栈中取出入栈参数
WriteExcBufVa(format, arglist);//入栈参数列表作为实参传入交由vsnprintf处理
va_end(arglist);//释放资源
}
///用于注册记录异常信息函数,并指定位置、空间和大小
VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook)
{
if ((hook == NULL) || (buf == NULL)) {
@ -133,11 +132,11 @@ VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_writ
g_excInfoRW = hook;
#ifdef LOSCFG_FS_VFS
los_vfs_init();
los_vfs_init();//初始化虚拟文件系统
#endif
}
/* Be called in the exception. */
/* Be called in the exception. */ //异常发生时回调这里
VOID OsReadWriteExceptionInfo(UINT32 startAddr, UINT32 space, UINT32 flag, CHAR *buf)
{
if ((buf == NULL) || (space == 0)) {
@ -146,7 +145,7 @@ VOID OsReadWriteExceptionInfo(UINT32 startAddr, UINT32 space, UINT32 flag, CHAR
}
// user can write exception information to files here
}
///记录异常信息产生的时间
VOID OsRecordExcInfoTime(VOID)
{
#ifdef LOSCFG_FS_VFS
@ -156,12 +155,12 @@ VOID OsRecordExcInfoTime(VOID)
CHAR nowTime[NOW_TIME_LENGTH];
(VOID)time(&t);
tmTime = localtime(&t);
tmTime = localtime(&t);//获取本地时间的标准C库函数
if (tmTime == NULL) {
return;
}
(VOID)memset_s(nowTime, sizeof(nowTime), 0, sizeof(nowTime));
(VOID)strftime(nowTime, NOW_TIME_LENGTH, "%Y-%m-%d %H:%M:%S", tmTime);
(VOID)strftime(nowTime, NOW_TIME_LENGTH, "%Y-%m-%d %H:%M:%S", tmTime);//生成时间格式
#undef NOW_TIME_LENGTH
WriteExcInfoToBuf("%s \n", nowTime);
#endif

@ -43,17 +43,18 @@
#endif
/**
* Register kernel init level labels.
* Register kernel init level labels. |
*/
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.
*
*/
STATIC VOID InitLevelCall(const CHAR *name, const UINT32 level, struct ModuleInitInfo *initLevelList[])
{
@ -65,13 +66,13 @@ 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
g_initCurrentLevel = level;
g_initCurrentModule = initLevelList[level];
} else {
} else {
while (g_initCurrentLevel < level) {
}
}
@ -116,6 +117,12 @@ STATIC VOID InitLevelCall(const CHAR *name, const UINT32 level, struct ModuleIni
#endif
}
/**
* @brief ,..
.
* @param level
* @return VOID
*/
VOID OsInitCall(const UINT32 level)
{
if (level >= LOS_INIT_LEVEL_FINISH) {

@ -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,
@ -162,7 +162,7 @@ struct ModuleInitInfo {
*/
#define OS_INIT_LEVEL_REG(_type, _num, _list) \
INIT_LABEL_REG_##_num(EXTERN_LABEL, _type) \
STATIC struct ModuleInitInfo *_list[] = { \
STATIC struct ModuleInitInfo* _list [] = { \
INIT_LABEL_REG_##_num(GET_LABEL, _type) \
}

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -34,36 +34,39 @@
#include "los_task_pri.h"
#include "los_process_pri.h"
/// 魔法键依赖于宏LOSCFG_ENABLE_MAGICKEY使用时通过menuconfig在配置项中开启“Enable MAGIC KEY”
/// Debug ---> Enable MAGIC KEY若关闭该选项则魔法键失效。
#ifdef LOSCFG_ENABLE_MAGICKEY
#define MAGIC_KEY_NUM 5
STATIC VOID OsMagicHelp(VOID);
STATIC VOID OsMagicTaskShow(VOID);
STATIC VOID OsMagicPanic(VOID);
STATIC VOID OsMagicMemCheck(VOID);
STATIC MagicKeyOp g_magicMemCheckOp = {
.opHandler = OsMagicMemCheck,
STATIC MagicKeyOp g_magicMemCheckOp = {//快捷键内存检查
.opHandler = OsMagicMemCheck, //等于执行了一次 shell memcheck
.helpMsg = "Check system memory(ctrl+e) ",
.magicKey = 0x05 /* ctrl + e */
.magicKey = 0x05 /* ctrl + e */ //系统进行简单完整性内存池检查检查出错会输出相关错误信息检查正常会输出“system memcheck over, all passed!”
};
STATIC MagicKeyOp g_magicPanicOp = {
.opHandler = OsMagicPanic,
STATIC MagicKeyOp g_magicPanicOp = {//panic 表示kernel走到了一个不知道该怎么走下一步的状况
.opHandler = OsMagicPanic, //一旦到这个情况kernel就尽可能把它此时能获取的全部信息都打印出来.
.helpMsg = "System panic(ctrl+p) ",
.magicKey = 0x10 /* ctrl + p */
.magicKey = 0x10 /* ctrl + p */ //系统主动进入panic输出panic相关信息后系统会挂住
};
STATIC MagicKeyOp g_magicTaskShowOp = {
.opHandler = OsMagicTaskShow,
STATIC MagicKeyOp g_magicTaskShowOp = { //快捷键显示任务操作
.opHandler = OsMagicTaskShow, //等于执行了一次 shell task -a
.helpMsg = "Show task information(ctrl+t) ",
.magicKey = 0x14 /* ctrl + t */
.magicKey = 0x14 /* ctrl + t */ //输出任务相关信息;
};
STATIC MagicKeyOp g_magicHelpOp = {
STATIC MagicKeyOp g_magicHelpOp = { //快捷键帮助操作
.opHandler = OsMagicHelp,
.helpMsg = "Show all magic op key(ctrl+z) ",
.magicKey = 0x1a /* ctrl + z */
.magicKey = 0x1a /* ctrl + z */ //帮助键,输出相关魔法键简单介绍;
};
/*
@ -74,7 +77,7 @@ STATIC MagicKeyOp g_magicHelpOp = {
* ctrl+n/shift out=0xe,
* ctrl+o/shift in=0xf,
* ctrl+[/esc=0x1b,
* ctrl+] used for telnet command mode;
* ctrl+] used for telnet commond mode;
*/
STATIC MagicKeyOp *g_magicOpTable[MAGIC_KEY_NUM] = {
&g_magicMemCheckOp, /* ctrl + e */
@ -84,7 +87,7 @@ STATIC MagicKeyOp *g_magicOpTable[MAGIC_KEY_NUM] = {
NULL
};
STATIC VOID OsMagicHelp(VOID)
STATIC VOID OsMagicHelp(VOID)//遍历一下 g_magicOpTable
{
INT32 i;
PRINTK("HELP: ");
@ -94,7 +97,7 @@ STATIC VOID OsMagicHelp(VOID)
PRINTK("\n");
return;
}
///执行 shell task -a 命令
STATIC VOID OsMagicTaskShow(VOID)
{
(VOID)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, NULL, OS_PROCESS_INFO_ALL);
@ -106,7 +109,7 @@ STATIC VOID OsMagicPanic(VOID)
LOS_Panic("Magic key :\n");
return;
}
///快捷键触发内存检查
STATIC VOID OsMagicMemCheck(VOID)
{
if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) {
@ -115,10 +118,10 @@ STATIC VOID OsMagicMemCheck(VOID)
return;
}
#endif
///检查魔法键
INT32 CheckMagicKey(CHAR key, UINT16 consoleId)
{
#ifdef LOSCFG_ENABLE_MAGICKEY
#ifdef LOSCFG_ENABLE_MAGICKEY //魔法键开关
INT32 i;
STATIC UINT32 magicKeySwitch = 0;
@ -126,6 +129,8 @@ INT32 CheckMagicKey(CHAR key, UINT16 consoleId)
KillPgrp(consoleId);
return 0;
} else if (key == 0x12) { /* ctrl + r */
// 在连接UART或者USB转虚拟串口的情况下输入“ctrl + r” 键,打开魔法键检测功能,输出 “Magic key on”再输入一次后
// 则关闭魔法键检测功能输出“Magic key off”。
magicKeySwitch = ~magicKeySwitch;
if (magicKeySwitch != 0) {
PrintExcInfo("Magic key on\n");
@ -134,10 +139,10 @@ INT32 CheckMagicKey(CHAR key, UINT16 consoleId)
}
return 1;
}
if (magicKeySwitch != 0) {
if (magicKeySwitch != 0) {//打开情况下,输出魔法键各回调函数
for (i = 0; i < MAGIC_KEY_NUM; i++) {
if (g_magicOpTable[i] != NULL && key == g_magicOpTable[i]->magicKey) {
(g_magicOpTable[i])->opHandler();
(g_magicOpTable[i])->opHandler();//执行回调函数 OsMagicHelp OsMagicTaskShow ==
return 1;
}
}

@ -40,10 +40,10 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
typedef struct {
VOID (*opHandler)(VOID);
CHAR *helpMsg;
CHAR magicKey;
typedef struct { //魔法键处理结构体
VOID (*opHandler)(VOID); //触发执行函数
CHAR *helpMsg; //消息提示
CHAR magicKey; //魔法键
} MagicKeyOp;
extern INT32 CheckMagicKey(CHAR key, UINT16 consoleId);

@ -51,14 +51,14 @@
#define SIZEBUF 256
const CHAR *g_logString[] = {
"EMG",
"COMMON",
"ERR",
"WARN",
"INFO",
"DEBUG",
"TRACE"
const CHAR *g_logString[] = {//日志等级
"EMG", //紧急
"COMMON", //普通
"ERR", //错误日志
"WARN", //警告
"INFO", //信息
"DEBUG", //调试
"TRACE" //跟踪
};
const CHAR *OsLogLvGet(INT32 level)
@ -71,54 +71,54 @@ STATIC VOID ErrorMsg(VOID)
const CHAR *p = "Output illegal string! vsnprintf_s failed!\n";
UartPuts(p, (UINT32)strlen(p), UART_WITH_LOCK);
}
///串口输出,打印消息的本质就是向串口输出buf
STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock)
{
#ifdef LOSCFG_SHELL_DMESG
if (!OsCheckUartLock()) {
UartPuts(str, len, isLock);
#ifdef LOSCFG_SHELL_DMESG //是否打开了 dmesg开关,打开了会写到文件中 var/log/dmesg 文件中
if (!OsCheckUartLock()) {//是否被锁
UartPuts(str, len, isLock);//直接写串口
}
if (isLock != UART_WITHOUT_LOCK) {
(VOID)OsLogMemcpyRecord(str, len);
(VOID)OsLogMemcpyRecord(str, len);//写入dmesg缓存区
}
#else
UartPuts(str, len, isLock);
UartPuts(str, len, isLock);//没有打开dmesg开关时,直接写串口
#endif
}
///控制台输出
#ifdef LOSCFG_PLATFORM_CONSOLE
STATIC VOID ConsoleOutput(const CHAR *str, UINT32 len)
{
ssize_t written = 0;
ssize_t cnt;
ssize_t toWrite = len;
ssize_t toWrite = len;//每次写入的数量
for (;;) {
cnt = write(STDOUT_FILENO, str + written, (size_t)toWrite);
cnt = write(STDOUT_FILENO, str + written, (size_t)toWrite);//向控制台写入数据,STDOUT_FILENO = 1
if ((cnt < 0) || ((cnt == 0) && ((!OsPreemptable()) || (OS_INT_ACTIVE))) || (toWrite == cnt)) {
break;
}
written += cnt;
toWrite -= cnt;
written += cnt; //已写入数量增加
toWrite -= cnt; //要写入数量减少
}
}
#endif
VOID OutputControl(const CHAR *str, UINT32 len, OutputType type)
{
switch (type) {
case CONSOLE_OUTPUT:
switch (type) {//输出类型
case CONSOLE_OUTPUT://控制台输出
#ifdef LOSCFG_PLATFORM_CONSOLE
if (ConsoleEnable() == TRUE) {
ConsoleOutput(str, len);
if (ConsoleEnable() == TRUE) {//POSIX 定义了 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 来代替 0、1、2
ConsoleOutput(str, len);//输出到控制台
break;
}
#endif
/* fall-through */
case UART_OUTPUT:
UartOutput(str, len, UART_WITH_LOCK);
/* fall-through */ //落空的情况下,会接着向串口打印数据
case UART_OUTPUT: //串口输出
UartOutput(str, len, UART_WITH_LOCK);//向串口发送数据
break;
case EXC_OUTPUT:
case EXC_OUTPUT: //异常输出
UartPuts(str, len, UART_WITH_LOCK);
break;
default:
@ -133,41 +133,42 @@ STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen)
(VOID)LOS_MemFree(m_aucSysMem0, buf);
}
}
///printf由 print 和 format 两个单词构成,格式化输出函数, 一般用于向标准输出设备按规定格式输出信息
//鸿蒙由OsVprintf 来实现可变参数日志格式的输入
VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
{
INT32 len;
const CHAR *errMsgMalloc = "OsVprintf, malloc failed!\n";
const CHAR *errMsgLen = "OsVprintf, length overflow!\n";
const CHAR *errMsgMalloc = "OsVprintf, malloc failed!\n";//内存分配失败的错误日志,注意这是在打印函数里分配内存失败的情况
const CHAR *errMsgLen = "OsVprintf, length overflow!\n";//所以要直接向串口发送字符串,不能再调用 printK(...)打印日志了.
CHAR aBuf[SIZEBUF] = {0};
CHAR *bBuf = NULL;
UINT32 bufLen = SIZEBUF;
UINT32 systemStatus;
bBuf = aBuf;
len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);
if ((len == -1) && (*bBuf == '\0')) {
/* parameter is illegal or some features in fmt dont support */
len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);//C语言库函数之一属于可变参数。用于向字符串中打印数据、数据格式用户自定义。
if ((len == -1) && (*bBuf == '\0')) {//直接碰到字符串结束符或长度异常
/* parameter is illegal or some features in fmt dont support */ //参数非法或fmt中的某些功能不支持
ErrorMsg();
return;
}
while (len == -1) {
while (len == -1) {//处理((len == -1) && (*bBuf != '\0'))的情况
/* bBuf is not enough */
OsVprintfFree(bBuf, bufLen);
bufLen = bufLen << 1;
if ((INT32)bufLen <= 0) {
if ((INT32)bufLen <= 0) {//异常情况下 向串口发送
UartPuts(errMsgLen, (UINT32)strlen(errMsgLen), UART_WITH_LOCK);
return;
}
bBuf = (CHAR *)LOS_MemAlloc(m_aucSysMem0, bufLen);
if (bBuf == NULL) {
if (bBuf == NULL) {//分配内存失败,直接向串口发送错误信息
UartPuts(errMsgMalloc, (UINT32)strlen(errMsgMalloc), UART_WITH_LOCK);
return;
}
len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);
if (*bBuf == '\0') {
len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);//将ap按格式输出到buf中
if (*bBuf == '\0') {//字符串结束符
/* parameter is illegal or some features in fmt dont support */
(VOID)LOS_MemFree(m_aucSysMem0, bBuf);
ErrorMsg();
@ -176,20 +177,20 @@ VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
}
*(bBuf + len) = '\0';
systemStatus = OsGetSystemStatus();
if ((systemStatus == OS_SYSTEM_NORMAL) || (systemStatus == OS_SYSTEM_EXC_OTHER_CPU)) {
OutputControl(bBuf, len, type);
} else if (systemStatus == OS_SYSTEM_EXC_CURR_CPU) {
OutputControl(bBuf, len, EXC_OUTPUT);
systemStatus = OsGetSystemStatus();//获取系统的状态
if ((systemStatus == OS_SYSTEM_NORMAL) || (systemStatus == OS_SYSTEM_EXC_OTHER_CPU)) {//当前CPU正常或其他CPU出现异常时
OutputControl(bBuf, len, type);//输出到终端
} else if (systemStatus == OS_SYSTEM_EXC_CURR_CPU) {//当前CPU出现异常
OutputControl(bBuf, len, EXC_OUTPUT);//串口以无锁的方式输出
}
OsVprintfFree(bBuf, bufLen);
}
///串口方式输入printf内容
VOID UartVprintf(const CHAR *fmt, va_list ap)
{
OsVprintf(fmt, ap, UART_OUTPUT);
}
///__attribute__((noinline)) 意思是告诉编译器 这是非内联函数
__attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...)
{
va_list ap;
@ -197,9 +198,9 @@ __attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...)
OsVprintf(fmt, ap, UART_OUTPUT);
va_end(ap);
}
///可变参数,输出到控制台
#ifndef LOSCFG_LIBC_NEWLIB
__attribute__((noinline)) VOID dprintf(const CHAR *fmt, ...)
__attribute__ ((noinline)) VOID dprintf(const CHAR *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@ -212,7 +213,7 @@ __attribute__((noinline)) VOID dprintf(const CHAR *fmt, ...)
va_end(ap);
}
#endif
///LK 注者的理解是 log kernel(内核日志)
VOID LkDprintf(const CHAR *fmt, va_list ap)
{
OsVprintf(fmt, ap, CONSOLE_OUTPUT);
@ -231,7 +232,7 @@ VOID DmesgPrintf(const CHAR *fmt, va_list ap)
#endif
#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS
__attribute__((noinline)) INT32 printf(const CHAR *fmt, ...)
__attribute__ ((noinline)) INT32 printf(const CHAR *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@ -240,7 +241,7 @@ __attribute__((noinline)) INT32 printf(const CHAR *fmt, ...)
return 0;
}
#endif
//系统日志的输出
__attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...)
{
va_list ap;
@ -249,7 +250,7 @@ __attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...)
va_end(ap);
(VOID)level;
}
///异常信息的输出
__attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...)
{
va_list ap;
@ -258,20 +259,20 @@ __attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...)
OsVprintf(fmt, ap, EXC_OUTPUT);
va_end(ap);
}
///打印异常信息
VOID PrintExcInfo(const CHAR *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
/* uart output without print-spinlock */
OsVprintf(fmt, ap, EXC_OUTPUT);
OsVprintf(fmt, ap, EXC_OUTPUT);//异常信息打印主体函数
#ifdef LOSCFG_SAVE_EXCINFO
WriteExcBufVa(fmt, ap);
#endif
va_end(ap);
}
#ifndef LOSCFG_SHELL_LK
#ifndef LOSCFG_SHELL_LK //log kernel 内核日志
VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...)
{
va_list ap;
@ -287,7 +288,7 @@ VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...
}
va_start(ap, fmt);
OsVprintf(fmt, ap, CONSOLE_OUTPUT);
OsVprintf(fmt, ap, CONSOLE_OUTPUT);//控制台打印
#ifdef LOSCFG_SAVE_EXCINFO
if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
WriteExcBufVa(fmt, ap);

@ -32,17 +32,24 @@
#include "los_config.h"
#include "los_sched_pri.h"
LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
/**
* @brief
* ,,reset_vector_up.S reset_vector_mp.S
* upCPU, mpCPU bl main
* @return LITE_OS_SEC_TEXT_INIT
*/
LITE_OS_SEC_TEXT_INIT INT32 main(VOID)//由主CPU执行,默认0号CPU 为主CPU
{
UINT32 ret = OsMain();
if (ret != LOS_OK) {
return (INT32)LOS_NOK;
}
CPU_MAP_SET(0, OsHwIDGet());
OsSchedStart();
CPU_MAP_SET(0, OsHwIDGet());//设置主CPU映射信息
OsSchedStart();//调度开始
while (1) {
__asm volatile("wfi");
__asm volatile("wfi");//WFI: wait for Interrupt 等待中断即下一次中断发生前都在此hold住不干活
}
}

@ -39,24 +39,42 @@
#include "fs/driver.h"
#endif
STATIC volatile UINT32 g_serialType = 0;
STATIC struct file g_serialFilep;
/*
UART
UARTUniversal Asynchronous Receiver/TransmitterUART
使线
UART 2 线线线
UART 使 UART
-----------------------------------------------------------------
+ + (D0-D7) + + +
-----------------------------------------------------------------
0
56789 bit 8 ASCII 8
1 ()()使
1
(bit) bit/s(bps) 480096001440038400115200 115200 115200
*/
STATIC volatile UINT32 g_serialType = 0;
STATIC struct file g_serialFilep;// COM0 /dev/uartdev-0 在内核层的表述 属于 .bbs段
//获取串口类型
UINT32 SerialTypeGet(VOID)
{
return g_serialType;
}
///设置串口类型,从这里看鸿蒙暂时支持两种串口
STATIC VOID SerialTypeSet(const CHAR *deviceName)
{
{///dev/uartdev-0
if (!strncmp(deviceName, SERIAL_UARTDEV, strlen(SERIAL_UARTDEV))) {
g_serialType = SERIAL_TYPE_UART_DEV;
} else if (!strncmp(deviceName, SERIAL_TTYGS0, strlen(SERIAL_TTYGS0))) {
g_serialType = SERIAL_TYPE_USBTTY_DEV;
}
}
///打开串口设备
STATIC INT32 SerialOpen(struct file *filep)
{
INT32 ret;
@ -84,36 +102,42 @@ ERROUT:
set_errno(ret);
return VFS_ERROR;
}
///关闭串口设备
STATIC INT32 SerialClose(struct file *filep)
{
(VOID)filep;
if (g_serialType == SERIAL_TYPE_UART_DEV) {
HalIrqMask(NUM_HAL_INTERRUPT_UART);
if (g_serialType == SERIAL_TYPE_UART_DEV) {//如果是UART驱动
HalIrqMask(NUM_HAL_INTERRUPT_UART);//设置中断屏蔽
}
#if defined(LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined(LOSCFG_DRIVERS_USB_ETH_SER_GADGET)
else if (g_serialType == SERIAL_TYPE_USBTTY_DEV) {
userial_mask_set(0);
else if (g_serialType == SERIAL_TYPE_USBTTY_DEV) {//如果是USB驱动
userial_mask_set(0);//设置USB掩码为 0
}
#endif
return ENOERR;
}
///读取串口数据,参数 filep 是由 /dev/serial 打开获得的文件
STATIC ssize_t SerialRead(struct file *filep, CHAR *buffer, size_t bufLen)
{
INT32 ret;
struct file *privFilep = NULL;
const struct file_operations_vfs *fileOps = NULL;
ret = GetFilepOps(filep, &privFilep, &fileOps);
ret = GetFilepOps(filep, &privFilep, &fileOps);//通过文件获取更底层设备的文件和驱动,例如 /dev/serial ---> /dev/uart
/*以 register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep);为例
privFilep = g_serialFilep
fileOps = g_serialDevOps
*/
if (ret != ENOERR) {
ret = -EINVAL;
goto ERROUT;
}
ret = FilepRead(privFilep, fileOps, buffer, bufLen);
//@note_thinking 觉得这里实现的有点饶,容易把人看懵逼,里面存在一个再次调用SerialRead的问题
//privFilep 可能是由 /dev/uartdev-0 或者 /dev/ttyGS0 打开的文件
ret = FilepRead(privFilep, fileOps, buffer, bufLen);//从USB或者UART 读buf
if (ret < 0) {
goto ERROUT;
}
@ -123,21 +147,21 @@ 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;
struct file *privFilep = NULL;
const struct file_operations_vfs *fileOps = NULL;
ret = GetFilepOps(filep, &privFilep, &fileOps);
ret = GetFilepOps(filep, &privFilep, &fileOps);//获取COM口在内核的file实例
if (ret != ENOERR) {
ret = -EINVAL;
goto ERROUT;
}
ret = FilepWrite(privFilep, fileOps, buffer, bufLen);
ret = FilepWrite(privFilep, fileOps, buffer, bufLen);//向控制台文件写入数据
if (ret < 0) {
goto ERROUT;
}
@ -147,14 +171,14 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
///控制串口设备
STATIC INT32 SerialIoctl(struct file *filep, INT32 cmd, unsigned long arg)
{
INT32 ret;
struct file *privFilep = NULL;
const struct file_operations_vfs *fileOps = NULL;
ret = GetFilepOps(filep, &privFilep, &fileOps);
ret = GetFilepOps(filep, &privFilep, &fileOps);//获取操作文件的驱动程序
if (ret != ENOERR) {
ret = -EINVAL;
goto ERROUT;
@ -170,7 +194,7 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
/// 事件查询, UartHostPollEvent(Uart) --> Hi35xxPollEvent --> poll_wait
STATIC INT32 SerialPoll(struct file *filep, poll_table *fds)
{
INT32 ret;
@ -192,21 +216,69 @@ ERROUT:
set_errno(-ret);
return VFS_ERROR;
}
STATIC const struct file_operations_vfs g_serialDevOps = {
/*!
VFS, hi35xx,
/,UART
g_consoleDevOps()
g_serialDevOps()
g_uartDevFops
g_uartHostMethod
Pl011Read ()
memcpy_s(buf,rxTransfer->data, ... )
g_pl011Uops ()
Pl011StartTx
UartPutsReg
static int32_t UartDevIoctl(struct file *filep, int32_t cmd, unsigned long arg)
{
int32_t ret = HDF_FAILURE;
struct UartHost *host = NULL;
if (filep == NULL || filep->f_vnode == NULL) {
return HDF_ERR_INVALID_PARAM;
}
struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
host = (struct UartHost *)drv->priv;
switch (cmd) {
case UART_CFG_BAUDRATE:
ret = UartHostSetBaud(host, arg);
break;
case UART_CFG_RD_BLOCK:
if (arg == UART_RD_BLOCK) {
ret = UartHostSetTransMode(host, UART_MODE_RD_BLOCK);
} else if (arg == UART_RD_NONBLOCK) {
ret = UartHostSetTransMode(host, UART_MODE_RD_NONBLOCK);
}
break;
case UART_CFG_ATTR:
ret = UartCfgAttr(host, arg);
break;
case TIOCGWINSZ:
/* Simply support ioctl(f->fd, TIOCGWINSZ, &wsz) system call, and the detailed design will be done later * /
ret = LOS_OK;
break;
default:
HDF_LOGE("%s cmd %d not support", __func__, cmd);
ret = HDF_ERR_NOT_SUPPORT;
break;
}
return ret;
}
*/
STATIC const struct file_operations_vfs g_serialDevOps = {
SerialOpen, /* open */
SerialClose, /* close */
SerialRead, /* read */
SerialWrite,
SerialWrite, ///< 写串口
NULL,
SerialIoctl,
SerialIoctl, ///< 设置波特率,设置转换模式,各种配置 ==
NULL,
#ifndef CONFIG_DISABLE_POLL
SerialPoll,
#endif
NULL,
};
/// 虚拟串口初始化,注册驱动程序 ,例如 : deviceName = "/dev/uartdev-0"
INT32 virtual_serial_init(const CHAR *deviceName)
{
INT32 ret;
@ -217,29 +289,29 @@ INT32 virtual_serial_init(const CHAR *deviceName)
goto ERROUT;
}
SerialTypeSet(deviceName);
SerialTypeSet(deviceName);//例如: /dev/uartdev-0 为 UART串口
VnodeHold();
ret = VnodeLookup(deviceName, &vnode, V_DUMMY);
ret = VnodeLookup(deviceName, &vnode, V_DUMMY);//由deviceName查询vnode节点
if (ret != LOS_OK) {
ret = EACCES;
goto ERROUT;
}
(VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file));
g_serialFilep.f_oflags = O_RDWR;
g_serialFilep.f_vnode = vnode;
g_serialFilep.ops = ((struct drv_data *)vnode->data)->ops;
if (g_serialFilep.ops->open != NULL) {
//接着是 vnode < -- > file 的绑定操作
(VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file));//文件的内核层表现file为fd背后的内容
g_serialFilep.f_oflags = O_RDWR;//可读可写
g_serialFilep.f_vnode = vnode; //绑定索引节点
g_serialFilep.ops = ((struct drv_data *)vnode->data)->ops;//这里代表 访问 /dev/serial 意味着是访问 /dev/uartdev-0
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);
(VOID)register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep);//注册虚拟串口驱动程序
//g_serialFilep作为私有数据给了 (drv_data)data->priv = g_serialFilep
VnodeDrop();
return ENOERR;
@ -248,9 +320,9 @@ ERROUT:
set_errno(ret);
return VFS_ERROR;
}
///串口设备去初始化,其实就是注销驱动程序
INT32 virtual_serial_deinit(VOID)
{
return unregister_driver(SERIAL);
return unregister_driver(SERIAL);//注销驱动程序
}

@ -43,14 +43,23 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*
鸿 PINI2CSPIUSBUART
访 API 访
*/
#ifdef LOSCFG_FS_VFS //将设备虚拟为文件统一来操作,对鸿蒙来说一切皆为文件
#define SERIAL "/dev/serial" ///< 虚拟串口设备
#define SERIAL_TTYGS0 "/dev/ttyGS0" ///< USB类型的串口
#define SERIAL_UARTDEV "/dev/uartdev" ///< Uart类型的串口
#ifdef LOSCFG_FS_VFS
#define SERIAL "/dev/serial"
#define SERIAL_TTYGS0 "/dev/ttyGS0"
#define SERIAL_UARTDEV "/dev/uartdev"
//UARTUniversal Asynchronous Receiver/Transmitter通用异步收发传输器UART 作为异步串口通信协议的一种,
//工作原理是将传输数据的每个字符一位接一位地传输。是在应用程序开发过程中使用频率最高的数据总线。
#define SERIAL_TYPE_UART_DEV 1
#define SERIAL_TYPE_USBTTY_DEV 2
#define SERIAL_TYPE_UART_DEV 1 ///< 两种串口类型之 UART
#define SERIAL_TYPE_USBTTY_DEV 2 ///< 两种串口类型之 USB
extern INT32 virtual_serial_init(const CHAR *deviceName);
extern INT32 virtual_serial_deinit(VOID);

@ -217,4 +217,4 @@ int CreateLogDir(const char *dirPath)
(void)dirPath;
return -1;
}
#endif
#endif

@ -33,13 +33,13 @@
#include "los_process_pri.h"
#include "internal.h"
STATIC Container g_rootContainer;
STATIC ContainerLimit g_containerLimit;
STATIC Atomic g_containerCount = 0xF0000000U;
STATIC Container g_rootContainer;//根容器
STATIC ContainerLimit g_containerLimit;//所有类型容器上限
STATIC Atomic g_containerCount = 0xF0000000U;//容器总数量
#ifdef LOSCFG_USER_CONTAINER
STATIC Credentials *g_rootCredentials = NULL;
#endif
//分配一个容器
UINT32 OsAllocContainerID(VOID)
{
return LOS_AtomicIncRet(&g_containerCount);
@ -57,7 +57,7 @@ VOID OsContainerInitSystemProcess(LosProcessCB *processCB)
#endif
return;
}
//获取指定容器上限值
UINT32 OsGetContainerLimit(ContainerType type)
{
switch (type) {
@ -108,7 +108,7 @@ UINT32 OsContainerLimitCheck(ContainerType type, UINT32 *containerCount)
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
//设置容器上限
UINT32 OsSetContainerLimit(ContainerType type, UINT32 value)
{
UINT32 intSave;
@ -368,7 +368,7 @@ CREATE_CONTAINER:
COPY_CONTAINERS:
return CopyContainers(flags, child, parent, processID);
}
//释放进程容器
VOID OsContainerFree(LosProcessCB *processCB)
{
LOS_AtomicDec(&processCB->container->rc);

@ -36,9 +36,9 @@
#ifdef LOSCFG_PID_CONTAINER
STATIC UINT32 g_currentPidContainerNum;
STATIC LosProcessCB *g_defaultProcessCB = NULL;
STATIC LosTaskCB *g_defaultTaskCB = NULL;
STATIC UINT32 g_currentPidContainerNum;//进程类容器当前数量
STATIC LosProcessCB *g_defaultProcessCB = NULL;//默认进程控制块 由OsInitRootPidContainer赋初值
STATIC LosTaskCB *g_defaultTaskCB = NULL;//默认任务控制块 由OsInitRootPidContainer赋初值
STATIC VOID FreeVpid(LosProcessCB *processCB)
{
@ -252,46 +252,46 @@ VOID OsPidContainerDestroyAllProcess(LosProcessCB *curr)
}
}
}
//创建一个新的进程容器
STATIC PidContainer *CreateNewPidContainer(PidContainer *parent)
{
UINT32 index;
PidContainer *newPidContainer = (PidContainer *)LOS_MemAlloc(m_aucSysMem1, sizeof(PidContainer));
PidContainer *newPidContainer = (PidContainer *)LOS_MemAlloc(m_aucSysMem1, sizeof(PidContainer));//从内核动态内存分配
if (newPidContainer == NULL) {
return NULL;
}
(VOID)memset_s(newPidContainer, sizeof(PidContainer), 0, sizeof(PidContainer));
(VOID)memset_s(newPidContainer, sizeof(PidContainer), 0, sizeof(PidContainer));//初始化内存块
newPidContainer->containerID = OsAllocContainerID();
LOS_ListInit(&newPidContainer->pidFreeList);
for (index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) {
newPidContainer->containerID = OsAllocContainerID();//分配一个容器ID
LOS_ListInit(&newPidContainer->pidFreeList);//初始化虚拟进程池空闲链表
for (index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) {//初始化容器的虚拟进程池
ProcessVid *vpid = &newPidContainer->pidArray[index];
vpid->vid = index;
vpid->vid = index;//进程ID序号
vpid->vpid = OS_INVALID_VALUE;
vpid->cb = (UINTPTR)g_defaultProcessCB;
LOS_ListTailInsert(&newPidContainer->pidFreeList, &vpid->node);
vpid->cb = (UINTPTR)g_defaultProcessCB;//默认进程控制块
LOS_ListTailInsert(&newPidContainer->pidFreeList, &vpid->node);//挂入链表
}
LOS_ListInit(&newPidContainer->tidFreeList);
LOS_ListInit(&newPidContainer->tidFreeList);//初始化虚拟任务池空闲链表
for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) {
ProcessVid *vtid = &newPidContainer->tidArray[index];
vtid->vid = index;
vtid->vid = index;//任务ID序号
vtid->vpid = OS_INVALID_VALUE;
vtid->cb = (UINTPTR)g_defaultTaskCB;
LOS_ListTailInsert(&newPidContainer->tidFreeList, &vtid->node);
LOS_ListTailInsert(&newPidContainer->tidFreeList, &vtid->node);//挂入链表
}
newPidContainer->parent = parent;
newPidContainer->parent = parent;//指定父容器
if (parent != NULL) {
LOS_AtomicSet(&newPidContainer->level, parent->level + 1);
LOS_AtomicSet(&newPidContainer->level, parent->level + 1);//子比父优先级低一级
newPidContainer->referenced = FALSE;
} else {
LOS_AtomicSet(&newPidContainer->level, 0);
LOS_AtomicSet(&newPidContainer->level, 0);//此处说明0位最高优先级
newPidContainer->referenced = TRUE;
}
return newPidContainer;
}
//销毁容器
VOID OsPidContainerDestroy(Container *container, LosProcessCB *processCB)
{
if (container == NULL) {
@ -321,21 +321,21 @@ VOID OsPidContainerDestroy(Container *container, LosProcessCB *processCB)
container->pidContainer = NULL;
container->pidForChildContainer = NULL;
(VOID)LOS_MemFree(m_aucSysMem1, pidContainer->rootPGroup);
(VOID)LOS_MemFree(m_aucSysMem1, pidContainer);
(VOID)LOS_MemFree(m_aucSysMem1, pidContainer);//释放结构体内存块
}
if (processCB != NULL) {
OsContainerFree(processCB);
}
}
/// 创建进程容器
STATIC UINT32 CreatePidContainer(LosProcessCB *child, LosProcessCB *parent)
{
UINT32 ret;
UINT32 intSave;
PidContainer *parentContainer = parent->container->pidContainer;
PidContainer *newPidContainer = CreateNewPidContainer(parentContainer);
PidContainer *parentContainer = parent->container->pidContainer;//先获取父进程容器
PidContainer *newPidContainer = CreateNewPidContainer(parentContainer);//从父进程容器中创建一个新容器
if (newPidContainer == NULL) {
return ENOMEM;
}
@ -508,25 +508,25 @@ UINT32 OsSetNsPidContainer(UINT32 flags, Container *container, Container *newCon
}
return LOS_OK;
}
///初始化进程根容器
UINT32 OsInitRootPidContainer(PidContainer **pidContainer)
{
UINT32 intSave;
g_defaultTaskCB = OsGetDefaultTaskCB();
g_defaultProcessCB = OsGetDefaultProcessCB();
PidContainer *newPidContainer = CreateNewPidContainer(NULL);
PidContainer *newPidContainer = CreateNewPidContainer(NULL);//无父进程
if (newPidContainer == NULL) {
return ENOMEM;
}
SCHEDULER_LOCK(intSave);
g_currentPidContainerNum++;
*pidContainer = newPidContainer;
g_currentPidContainerNum++;//当前进程容器数量增加
*pidContainer = newPidContainer;//成为根进程容器,由参数带回
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
//从当前容器中获取父进程ID
UINT32 OsGetVpidFromCurrContainer(const LosProcessCB *processCB)
{
UINT32 vpid = processCB->processID;

@ -68,7 +68,7 @@ STATIC UtsContainer *CreateNewUtsContainer(UtsContainer *parent)
{
UINT32 ret;
UINT32 size = sizeof(UtsContainer);
UtsContainer *utsContainer = (UtsContainer *)LOS_MemAlloc(m_aucSysMem1, size);
UtsContainer *utsContainer = (UtsContainer *)LOS_MemAlloc(m_aucSysMem1, size);//从内核动态内存分配
if (utsContainer == NULL) {
return NULL;
}
@ -105,7 +105,7 @@ STATIC UINT32 CreateUtsContainer(LosProcessCB *child, LosProcessCB *parent)
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
//初始化uts容器
UINT32 OsInitRootUtsContainer(UtsContainer **utsContainer)
{
UINT32 intSave;

@ -31,10 +31,45 @@
#include "los_cppsupport.h"
#include "los_printf.h"
/**
* @brief @file los_cppsupport.c
* @verbatim
C++使广C
STLStandard Template Library
使使
make menuconfig使C++
使C++LOS_CppSystemInitC++
CC++C++CC++
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus * /
#endif /* __cplusplus * /
/* code * /
...
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus * /
#endif /* __cplusplus * /
* @endverbatim
*/
typedef VOID (*InitFunc)(VOID);
/**
* @brief 使C++ C++
* @param initArrayStart init_array
* @param initArrayEnd init_array
* @param flag C++
* @return LITE_OS_SEC_TEXT_MINOR
*/
LITE_OS_SEC_TEXT_MINOR INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd, INT32 flag)
{
UINTPTR *start = (UINTPTR *)initArrayStart;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save