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

同步官方代码

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    鸿蒙研究站 | http://weharmonyos.com (国内)
              | https://weharmony.github.io (国外)
    oschina | https://my.oschina.net/weharmony
    博客园 | https://www.cnblogs.com/weharmony/
    知乎 | https://www.zhihu.com/people/weharmonyos
    csdn | https://blog.csdn.net/kuangyufei
    51cto | https://harmonyos.51cto.com/column/34
    掘金 | https://juejin.cn/user/756888642000808
    公众号 | 鸿蒙研究站 (weharmonyos)
上级 801efb18
......@@ -162,7 +162,7 @@
### 四大码仓发布 | 源码同步官方
内核注解同时在 [gitee](https://gitee.com/weharmony/kernel_liteos_a_note) | [github](https://github.com/kuangyufei/kernel_liteos_a_note) | [coding](https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files) | [codechina](https://codechina.csdn.net/kuangyufei/kernel_liteos_a_note) 发布,并与官方源码按月保持同步,同步历史如下:
* `2021/12/11` -- 增加LMS模块,完善PM
* `2021/12/20` -- 增加LMS模块,完善PM,Fat Cache
* `2021/11/12` -- 加入epoll支持,对shell模块有较大调整,微调process,task,更正单词拼写错误
* `2021/10/21` -- 增加性能优化模块`perf`,优化了文件映射模块
* `2021/09/14` -- common,extended等几个目录结构和Makefile调整
......
......@@ -165,6 +165,10 @@ extern "C" {
#define DISK_ATA_GET_MODEL 21 /* Get model name */
#define DISK_ATA_GET_SN 22 /* Get serial number */
#ifdef LOSCFG_FS_FAT_CACHE
#define DISK_DIRECT_BUFFER_SIZE 4 /* los_disk direct io buffer when bcache is off */
#endif
typedef enum _disk_status_ {
STAT_UNUSED,
STAT_INUSED,
......@@ -187,6 +191,9 @@ typedef struct _los_disk_ {
CHAR *disk_name;
LOS_DL_LIST head; /* link head of all the partitions */
struct pthread_mutex disk_mutex;
#ifndef LOSCFG_FS_FAT_CACHE
UINT8 *buff;
#endif
} los_disk;
typedef struct _los_part_ {
......
......@@ -36,6 +36,10 @@
#include "sys/mount.h"
#include "linux/spinlock.h"
#include "path_cache.h"
#ifndef LOSCFG_FS_FAT_CACHE
#include "los_vm_common.h"
#include "user_copy.h"
#endif
/**
* @file disk.c
......@@ -832,6 +836,77 @@ INT32 DiskPartitionRegister(los_disk *disk)
return ENOERR;
}
#ifndef LOSCFG_FS_FAT_CACHE
static INT32 disk_read_directly(los_disk *disk, VOID *buf, UINT64 sector, UINT32 count)
{
INT32 result = VFS_ERROR;
struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
if ((bops == NULL) || (bops->read == NULL)) {
return VFS_ERROR;
}
if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
UINT32 cnt = 0;
UINT8 *buffer = disk->buff;
for (; count != 0; count -= cnt) {
cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
result = bops->read(disk->dev, buffer, sector, cnt);
if (result == (INT32)cnt) {
result = ENOERR;
} else {
break;
}
if (LOS_CopyFromKernel(buf, disk->sector_size * cnt, buffer, disk->sector_size * cnt)) {
result = VFS_ERROR;
break;
}
buf = (UINT8 *)buf + disk->sector_size * cnt;
sector += cnt;
}
} else {
result = bops->read(disk->dev, buf, sector, count);
if (result == count) {
result = ENOERR;
}
}
return result;
}
static INT32 disk_write_directly(los_disk *disk, const VOID *buf, UINT64 sector, UINT32 count)
{
struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
INT32 result = VFS_ERROR;
if ((bops == NULL) || (bops->read == NULL)) {
return VFS_ERROR;
}
if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
UINT32 cnt = 0;
UINT8 *buffer = disk->buff;
for (; count != 0; count -= cnt) {
cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
if (LOS_CopyToKernel(buffer, disk->sector_size * cnt, buf, disk->sector_size * cnt)) {
result = VFS_ERROR;
break;
}
result = bops->write(disk->dev, buffer, sector, cnt);
if (result == (INT32)cnt) {
result = ENOERR;
} else {
break;
}
buf = (UINT8 *)buf + disk->sector_size * cnt;
sector += cnt;
}
} else {
result = bops->write(disk->dev, buf, sector, count);
if (result == count) {
result = ENOERR;
}
}
return result;
}
#endif
///读磁盘数据
INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
{
......@@ -871,19 +946,13 @@ INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL us
PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len);
}
} else {
#endif
result = VFS_ERROR;
}
#else
if (disk->dev == NULL) {
goto ERROR_HANDLE;
}
struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;//获取块操作数据方式
if ((bops != NULL) && (bops->read != NULL)) {
result = bops->read(disk->dev, (UINT8 *)buf, sector, count);//读取绝对扇区内容至buf
if (result == (INT32)count) {
result = ENOERR;
}
}
#ifdef LOSCFG_FS_FAT_CACHE
}
result = disk_read_directly(disk, buf, sector, count);
#endif
if (result != ENOERR) {
......@@ -934,16 +1003,13 @@ INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count)
PRINT_ERR("los_disk_write write err = %d, sector = %llu, len = %u\n", result, sector, len);
}
} else {
#endif//无缓存情况下获取操作块实现函数指针结构体
struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
if ((bops != NULL) && (bops->write != NULL)) {
result = bops->write(disk->dev, (UINT8 *)buf, sector, count);//真正的写磁盘
if (result == (INT32)count) {
result = ENOERR;
}
result = VFS_ERROR;
}
#ifdef LOSCFG_FS_FAT_CACHE
#else
if (disk->dev == NULL) {
goto ERROR_HANDLE;
}
result = disk_write_directly(disk, buf, sector, count);
#endif
if (result != ENOERR) {
......@@ -1187,7 +1253,8 @@ ERROR_HANDLE:
INT32 los_disk_cache_clear(INT32 drvID)
{
INT32 result;
INT32 result = ENOERR;
#ifdef LOSCFG_FS_FAT_CACHE
los_part *part = get_part(drvID);
los_disk *disk = NULL;
......@@ -1195,7 +1262,7 @@ INT32 los_disk_cache_clear(INT32 drvID)
return VFS_ERROR;
}
result = OsSdSync(part->disk_id);
if (result != 0) {
if (result != ENOERR) {
PRINTK("[ERROR]disk_cache_clear SD sync failed!\n");
return result;
}
......@@ -1208,7 +1275,7 @@ INT32 los_disk_cache_clear(INT32 drvID)
DISK_LOCK(&disk->disk_mutex);
result = BcacheClearCache(disk->bcache);
DISK_UNLOCK(&disk->disk_mutex);
#endif
return result;
}
......@@ -1358,6 +1425,10 @@ static INT32 DiskDeinit(los_disk *disk)
#ifdef LOSCFG_FS_FAT_CACHE
DiskCacheDeinit(disk);
#else
if (disk->buff != NULL) {
free(disk->buff);
}
#endif
disk->dev = NULL;
......@@ -1378,12 +1449,15 @@ static INT32 DiskDeinit(los_disk *disk)
return ENOERR;
}
///磁盘初始化
static VOID OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk,
struct geometry *diskInfo, struct Vnode *blkDriver)
static UINT32 OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk,
struct geometry *diskInfo, struct Vnode *blkDriver)
{
pthread_mutexattr_t attr;
#ifdef LOSCFG_FS_FAT_CACHE //使能FAT缓存
#ifdef LOSCFG_FS_FAT_CACHE
OsBcache *bc = DiskCacheInit((UINT32)diskID, diskInfo, blkDriver);
if (bc == NULL) {
return VFS_ERROR;
}
disk->bcache = bc;
#endif
......@@ -1392,6 +1466,16 @@ static VOID OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk,
(VOID)pthread_mutex_init(&disk->disk_mutex, &attr);
DiskStructInit(diskName, diskID, diskInfo, blkDriver, disk);
#ifndef LOSCFG_FS_FAT_CACHE
disk->buff = malloc(diskInfo->geo_sectorsize * DISK_DIRECT_BUFFER_SIZE);
if (disk->buff == NULL) {
PRINT_ERR("OsDiskInitSub: direct buffer of disk init failed\n");
return VFS_ERROR;
}
#endif
return ENOERR;
}
///磁盘初始化
INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
......@@ -1416,22 +1500,25 @@ INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
ret = VnodeLookup(diskName, &blkDriver, 0);
if (ret < 0) {
VnodeDrop();
PRINT_ERR("disk_init : find %s fail!\n", diskName);
ret = ENOENT;
goto DISK_FIND_ERROR;
}
struct block_operations *bops2 = (struct block_operations *)((struct drv_data *)blkDriver->data)->ops;
//块操作,块是文件系统层面的概念,块(Block)是文件系统存取数据的最小单位,一般大小是4KB
if ((bops2 == NULL) || (bops2->geometry == NULL) ||
(bops2->geometry(blkDriver, &diskInfo) != 0)) {//geometry 就是 CHS
if ((bops2 == NULL) || (bops2->geometry == NULL) || (bops2->geometry(blkDriver, &diskInfo) != 0)) {
goto DISK_BLKDRIVER_ERROR;
}
if (diskInfo.geo_sectorsize < DISK_MAX_SECTOR_SIZE) {//验证扇区大小
if (diskInfo.geo_sectorsize < DISK_MAX_SECTOR_SIZE) {
goto DISK_BLKDRIVER_ERROR;
}
OsDiskInitSub(diskName, diskID, disk, &diskInfo, blkDriver);//初始化磁盘描述符
ret = OsDiskInitSub(diskName, diskID, disk, &diskInfo, blkDriver);
if (ret != ENOERR) {
(VOID)DiskDeinit(disk);
VnodeDrop();
return VFS_ERROR;
}
VnodeDrop();
if (DiskDivideAndPartitionRegister(info, disk) != ENOERR) {
(VOID)DiskDeinit(disk);
......
......@@ -2074,45 +2074,18 @@ static UINT get_oldest_time(DIR_FILE df[], DWORD *oldest_time, UINT len)
return index;
}
int fatfs_fscheck(struct Vnode* vp, struct fs_dirent_s *dir)
static FRESULT fscheck(DIR *dp)
{
FATFS *fs = (FATFS *)vp->originMount->data;
DIR_FILE df[CHECK_FILE_NUM] = {0};
DIR *dp = NULL;
FILINFO *finfo = &(((DIR_FILE *)(vp->data))->fno);
FILINFO fno;
DWORD old_time = -1;
DWORD time;
UINT count;
UINT index = 0;
los_part *part = NULL;
UINT count;
DWORD time;
DWORD old_time = -1;
FRESULT result;
int ret;
if (fs->fs_type != FS_FAT32) {
return -EINVAL;
}
if ((finfo->fattrib & AM_DIR) == 0) {
return -ENOTDIR;
}
ret = fatfs_opendir(vp, dir);
if (ret < 0) {
return ret;
}
ret = lock_fs(fs);
if (ret == FALSE) {
result = FR_TIMEOUT;
goto ERROR_WITH_DIR;
}
dp = (DIR *)dir->u.fs_dir;
dp->obj.id = fs->id;
for (count = 0; count < CHECK_FILE_NUM; count++) {
if ((result = f_readdir(dp, &fno)) != FR_OK) {
goto ERROR_UNLOCK;
return result;
} else {
if (fno.fname[0] == 0 || fno.fname[0] == (TCHAR)0xFF) {
break;
......@@ -2137,15 +2110,50 @@ int fatfs_fscheck(struct Vnode* vp, struct fs_dirent_s *dir)
index = get_oldest_time(df, &old_time, CHECK_FILE_NUM);
}
}
if (result != FR_OK) {
goto ERROR_UNLOCK;
index = 0;
while (result == FR_OK && index < count) {
result = f_fcheckfat(&df[index]);
++index;
}
for (index = 0; index < count; index++) {
result = f_fcheckfat(&df[index]);
if (result != FR_OK) {
goto ERROR_UNLOCK;
}
return result;
}
int fatfs_fscheck(struct Vnode* vp, struct fs_dirent_s *dir)
{
FATFS *fs = (FATFS *)vp->originMount->data;
DIR *dp = NULL;
FILINFO *finfo = &(((DIR_FILE *)(vp->data))->fno);
#ifdef LOSCFG_FS_FAT_CACHE
los_part *part = NULL;
#endif
FRESULT result;
int ret;
if (fs->fs_type != FS_FAT32) {
return -EINVAL;
}
if ((finfo->fattrib & AM_DIR) == 0) {
return -ENOTDIR;
}
ret = fatfs_opendir(vp, dir);
if (ret < 0) {
return ret;
}
ret = lock_fs(fs);
if (ret == FALSE) {
result = FR_TIMEOUT;
goto ERROR_WITH_DIR;
}
dp = (DIR *)dir->u.fs_dir;
dp->obj.id = fs->id;
result = fscheck(dp);
if (result != FR_OK) {
goto ERROR_UNLOCK;
}
unlock_fs(fs, FR_OK);
......
......@@ -56,11 +56,15 @@ STATIC DevHandle g_wdHandle;
STATIC void StartWatchdog(void)
{
int32_t ret;
if (g_wdStarted) {
return;
}
g_wdHandle = WatchdogOpen(0);
ret = WatchdogOpen(0, &g_wdHandle);
if (ret != HDF_SUCCESS) {
return;
}
WatchdogSetTimeout(g_wdHandle, WATCHDOG_TIMER_INTERVAL);
if (LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND * WATCHDOG_TIMER_INTERVAL_HALF, LOS_SWTMR_MODE_PERIOD,
......
......@@ -67,6 +67,7 @@ STATIC UINT32 ConsoleSendTask(UINTPTR param);
STATIC UINT8 g_taskConsoleIDArray[LOSCFG_BASE_CORE_TSK_LIMIT];///< task 控制台ID池,同步task数量,理论上每个task都可以有一个自己的控制台
STATIC SPIN_LOCK_INIT(g_consoleSpin);///< 初始化控制台自旋锁
STATIC SPIN_LOCK_INIT(g_consoleWriteSpinLock);
#define SHELL_ENTRYID_INVALID 0xFFFFFFFF ///< 默认值,SHELL_ENTRYID 一般为 任务ID
#define SHELL_TASK_PRIORITY 9 ///< shell 的优先级为 9
......@@ -165,20 +166,13 @@ STATIC UINT32 ConsoleRefcountGet(const CONSOLE_CB *consoleCB)
///设置控制台引用次数,也表示占用控制台的数量
STATIC VOID ConsoleRefcountSet(CONSOLE_CB *consoleCB, BOOL flag)
{
if (flag == TRUE) {
++(consoleCB->refCount);
} else {
--(consoleCB->refCount);
}
(consoleCB->refCount) += flag ? 1 : -1;
}
///控制台是否被占用
BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB)
{
if (ConsoleRefcountGet(consoleCB) != FALSE) {
return TRUE;
} else {
return FALSE;
}
return ConsoleRefcountGet(consoleCB);
}
STATIC INT32 ConsoleCtrlCaptureLine(CONSOLE_CB *consoleCB)
......@@ -306,10 +300,7 @@ STATIC INT32 OsConsoleFullpathToID(const CHAR *fullpath)
STATIC BOOL ConsoleFifoEmpty(const CONSOLE_CB *console)
{
if (console->fifoOut == console->fifoIn) {
return TRUE;
}
return FALSE;
return console->fifoOut == console->fifoIn;
}
STATIC VOID ConsoleFifoClearup(CONSOLE_CB *console)
......@@ -355,11 +346,9 @@ INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops)
* corresponding to filep of /dev/console)
*/
ret = fops->open(filep);
if (ret < 0) {
return -EPERM;
}
return ret;
return (ret < 0) ? -EPERM : ret;
}
///向控制台buf中写入结束字符
STATIC INLINE VOID UserEndOfRead(CONSOLE_CB *consoleCB, struct file *filep,
const struct file_operations_vfs *fops)
......@@ -478,10 +467,7 @@ STATIC INT32 UserFilepRead(CONSOLE_CB *consoleCB, struct file *filep, const stru
/* Non-ICANON mode | 非规范模式 所有的输入即时有效,用户不需要另外输入行结束符,不能进行行编辑*/
if ((consoleCB->consoleTermios.c_lflag & ICANON) == 0) {
ret = fops->read(filep, buffer, bufLen);
if (ret < 0) {
return -EPERM;
}
return ret;
return (ret < 0) ? -EPERM : ret;
}
/**
在规范模式下,输入数据基于行进行处理。
......@@ -540,11 +526,9 @@ INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR
* corresponding to filep of /dev/console)
*///采用uart read函数从文件中读取数据,将数据写入缓冲区(文件对应/dev/console的filep)
ret = fops->read(filep, buffer, bufLen);
if (ret < 0) {
return -EPERM;
}
return ret;
return (ret < 0) ? -EPERM : ret;
}
///写数据到串口或远程登录
INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen)
{
......@@ -554,11 +538,9 @@ INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, con
}
ret = fops->write(filep, buffer, bufLen);
if (ret < 0) {
return -EPERM;
}
return ret;
return (ret < 0) ? -EPERM : ret;
}
///关闭串口或远程登录
INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops)
{
......@@ -572,10 +554,7 @@ INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops)
* corresponding to filep of /dev/console)
*/
ret = fops->close(filep);
if (ret < 0) {
return -EPERM;
}
return ret;
return ret < 0 ? -EPERM : ret;
}
INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg)
......@@ -586,10 +565,7 @@ INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT
}
ret = fops->ioctl(filep, cmd, arg);
if (ret < 0) {
return -EPERM;
}
return ret;
return (ret < 0) ? -EPERM : ret;
}
INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds)
......@@ -604,11 +580,9 @@ INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll
* corresponding to filep of /dev/serial)
*/
ret = fops->poll(filep, fds);
if (ret < 0) {
return -EPERM;
}
return ret;
return (ret < 0) ? -EPERM : ret;
}
///对 file_operations_vfs->open 的实现函数,也就是说这是 打开控制台的实体函数.
STATIC INT32 ConsoleOpen(struct file *filep)
{
......@@ -765,7 +739,8 @@ STATIC ssize_t DoWrite(CirBufSendCB *cirBufSendCB, CHAR *buffer, size_t bufLen)
return 0;
}
#endif
LOS_CirBufLock(&cirBufSendCB->cirBufCB, &intSave);
LOS_SpinLockSave(&g_consoleWriteSpinLock, &intSave);
while (written < (INT32)bufLen) {
/* Transform for CR/LR mode | 回车(CR, ASCII 13, \r) 换行(LF, ASCII 10, \n)*/
if ((buffer[written] == '\n') || (buffer[written] == '\r')) {
......@@ -779,7 +754,8 @@ STATIC ssize_t DoWrite(CirBufSendCB *cirBufSendCB, CHAR *buffer, size_t bufLen)
toWrite -= cnt;
written += cnt;
}
LOS_CirBufUnlock(&cirBufSendCB->cirBufCB, intSave);
LOS_SpinUnlockRestore(&g_consoleWriteSpinLock, intSave);
/* Log is cached but not printed when a system exception occurs */
if (OsGetSystemStatus() == OS_SYSTEM_NORMAL) {
(VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT);//发送数据事件
......@@ -871,10 +847,8 @@ STATIC INT32 ConsoleGetWinSize(unsigned long arg)
.ws_row = DEFAULT_WINDOW_SIZE_ROW
};
if (LOS_CopyFromKernel((VOID *)arg, sizeof(struct winsize), &kws, sizeof(struct winsize)) != 0) {
return -EFAULT;
}
return LOS_OK;
return (LOS_CopyFromKernel((VOID *)arg, sizeof(struct winsize), &kws, sizeof(struct winsize)) != 0) ?
-EFAULT : LOS_OK;
}
STATIC INT32 ConsoleGetTermios(unsigned long arg)
......@@ -892,11 +866,8 @@ STATIC INT32 ConsoleGetTermios(unsigned long arg)
return -EFAULT;
}
if(LOS_ArchCopyToUser((VOID *)arg, &consoleCB->consoleTermios, sizeof(struct termios)) != 0) {
return -EFAULT;
} else {
return LOS_OK;
}
return (LOS_ArchCopyToUser((VOID *)arg, &consoleCB->consoleTermios, sizeof(struct termios)) != 0) ?
-EFAULT : LOS_OK;
}
INT32 ConsoleSetPgrp(CONSOLE_CB *consoleCB, unsigned long arg)
......@@ -909,11 +880,9 @@ INT32 ConsoleSetPgrp(CONSOLE_CB *consoleCB, unsigned long arg)
INT32 ConsoleGetPgrp(CONSOLE_CB *consoleCB, unsigned long arg)
{
if (LOS_ArchCopyToUser((VOID *)arg, &consoleCB->pgrpId, sizeof(INT32)) != 0) {
return -EFAULT;
}
return LOS_OK;
return (LOS_ArchCopyToUser((VOID *)arg, &consoleCB->pgrpId, sizeof(INT32)) != 0) ? -EFAULT : LOS_OK;
}
///< 对控制台i/o操作
STATIC INT32 ConsoleIoctl(struct file *filep, INT32 cmd, unsigned long arg)
{
......@@ -1231,11 +1200,7 @@ STATIC UINT32 OsConsoleBufInit(CONSOLE_CB *consoleCB)
initParam.usTaskPrio = SHELL_TASK_PRIORITY; //优先级9
initParam.auwArgs[0] = (UINTPTR)consoleCB; //入口函数的参数
initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; //16K
if (consoleCB->consoleID == CONSOLE_SERIAL) {//控制台的两种方式
initParam.pcName = "SendToSer"; //发送数据到串口
} else {
initParam.pcName = "SendToTelnet";//发送数据到远程登录
}
initParam.pcName = (consoleCB->consoleID == CONSOLE_SERIAL) ? "SendToSer" : "SendToTelnet"; //控制台的两种方式
initParam.uwResved = LOS_TASK_STATUS_DETACHED; //使用任务分离模式
ret = LOS_TaskCreate(&consoleCB->sendTaskID, &initParam);//创建task 并加入就绪队列,申请立即调度
......@@ -1460,10 +1425,7 @@ BOOL ConsoleEnable(VOID)
if (consoleID == 0) {
return FALSE;
} else if ((consoleID == CONSOLE_TELNET) || (consoleID == CONSOLE_SERIAL)) {
if ((OsGetSystemStatus() == OS_SYSTEM_NORMAL) && !OsPreemptable()) {
return FALSE;
}
return TRUE;
return ((OsGetSystemStatus() == OS_SYSTEM_NORMAL) && !OsPreemptable()) ? FALSE : TRUE;
}
#if defined (LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined (LOSCFG_DRIVERS_USB_ETH_SER_GADGET)
else if ((SerialTypeGet() == SERIAL_TYPE_USBTTY_DEV) && (userial_mask_get() == 1)) {
......@@ -1499,69 +1461,46 @@ INT32 ConsoleTaskReg(INT32 consoleID, UINT32 taskID)
return LOS_OK;
}
LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
return g_console[consoleID - 1]->shellEntryId == taskID ? LOS_OK : LOS_NOK;
return (g_console[consoleID - 1]->shellEntryId == taskID) ? LOS_OK : LOS_NOK;
}
///无锁方式设置串口
BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB)
{
INT32 ret;
if (consoleCB == NULL) {
PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
return FALSE;
}
ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_NONBLOCK);
if (ret != 0) {
return FALSE;
}
return TRUE;
return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_NONBLOCK) == 0;
}
///锁方式设置串口
BOOL SetSerialBlock(const CONSOLE_CB *consoleCB)
{
INT32 ret;
if (consoleCB == NULL) {
PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
return TRUE;
}
ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_BLOCK);
if (ret != 0) {
return TRUE;
}
return FALSE;
return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_BLOCK) != 0;
}
///无锁方式设置远程登录
BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB)
{
INT32 ret;
if (consoleCB == NULL) {
PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
return FALSE;
}
ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_NONBLOCK);
if (ret != 0) {
return FALSE;
}
return TRUE;
return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_NONBLOCK) == 0;
}
///锁方式设置远程登录
BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB)
{
INT32 ret;
if (consoleCB == NULL) {
PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__);
return TRUE;
}
ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_BLOCK);
if (ret != 0) {
return TRUE;
}
return FALSE;
return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_BLOCK) != 0;
}
BOOL is_nonblock(const CONSOLE_CB *consoleCB)
......@@ -1598,12 +1537,9 @@ INT32 ConsoleUpdateFd(VOID)
}
}
if (g_console[consoleID - 1] == NULL) {
return -1;
}
return g_console[consoleID - 1]->fd;
return (g_console[consoleID - 1] != NULL) ? g_console[consoleID - 1]->fd : -1;
}
///获取参数控制台ID 获取对应的控制台控制块(描述符)
CONSOLE_CB *OsGetConsoleByID(INT32 consoleID)
{
......@@ -1660,7 +1596,6 @@ STATIC UINT32 ConsoleSendTask(UINTPTR param)
CirBufSendCB *cirBufSendCB = consoleCB->cirBufSendCB;
CirBuf *cirBufCB = &cirBufSendCB->cirBufCB;
UINT32 ret, size;
UINT32 intSave;
CHAR *buf = NULL;
(VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_RUNNING);//发送一个控制台任务正在运行的事件
......@@ -1679,9 +1614,7 @@ STATIC UINT32 ConsoleSendTask(UINTPTR param)
}
(VOID)memset_s(buf, size + 1, 0, size + 1);//清0
LOS_CirBufLock(cirBufCB, &intSave);
(VOID)LOS_CirBufRead(cirBufCB, buf, size);//读取循环cirBufCB至 buf
LOS_CirBufUnlock(cirBufCB, intSave);
(VOID)WriteToTerminal(consoleCB, buf, size);//将buf数据写到控制台终端设备
(VOID)LOS_MemFree(m_aucSysMem1, buf);//清除buf
......
......@@ -102,3 +102,6 @@ source "kernel/extended/perf/Kconfig"
######################### config options of lms #########################
source "kernel/extended/lms/Kconfig"
######################### config options of hilog #########################
source "kernel/extended/hilog/Kconfig"
config HILOG
tristate "Hilog support"
default y
help
hilog buffer manager.
Hilog is a simple log manager for OpenHarmonyOS.
log string write to /dev/hilog, and the hilog driver copy it
to the ring buffer. Ring buffer can be read from userspace.
config HILOG_BUFFER_SIZE
int "hilog buffer size"
default 4096
help
Define the default ring buffer size of hilog
\ No newline at end of file
......@@ -41,7 +41,7 @@
#include "los_vm_lock.h"
#include "user_copy.h"
//hilog是鸿蒙的一个用于输出的功能模块
#define HILOG_BUFFER 4096// 4K缓存, ring buf 方式管理
#define HILOG_BUFFER LOSCFG_HILOG_BUFFER_SIZE// 4K缓存, ring buf 方式管理
#define DRIVER_MODE 0666 //权限 chmod 666
#define HILOG_DRIVER "/dev/hilog" // 可以看出hilog是当一种字符设备来实现
......@@ -256,6 +256,7 @@ static void HiLogCoverOldLog(size_t bufLen)
int retval;
struct HiLogEntry header;
size_t totalSize = bufLen + sizeof(struct HiLogEntry);
int dropLogLines = 0;
while (totalSize + g_hiLogDev.size > HILOG_BUFFER) {
retval = HiLogReadRingBuffer((unsigned char *)&header, sizeof(header));
......@@ -263,9 +264,13 @@ static void HiLogCoverOldLog(size_t bufLen)
break;
}
dropLogLines++;
HiLogBufferDec(sizeof(header));
HiLogBufferDec(header.len);
}
if (dropLogLines > 0) {
dprintf("hilog ringbuffer full, drop %d line(s) log", dropLogLines);
}
}
///将外部buf写入hilog设备分两步完成
int HiLogWriteInternal(const char *buffer, size_t bufLen)
......
......@@ -56,22 +56,6 @@ typedef struct {
CirBufStatus status;//两种状态
CHAR *fifo; //顺序buffer ,1K
} CirBuf;
//锁循环buf
STATIC INLINE VOID LOS_CirBufLock(CirBuf *cirbufCB, UINT32 *intSave)
{
if (cirbufCB == NULL) {
return;
}
LOS_SpinLockSave(&cirbufCB->lock, intSave);
}
///解锁循环buf
STATIC INLINE VOID LOS_CirBufUnlock(CirBuf *cirbufCB, UINT32 intSave)
{
if (cirbufCB == NULL) {
return;
}
LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
}
extern UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size);
extern VOID LOS_CirBufDeinit(CirBuf *cirbufCB);
......
......@@ -30,6 +30,7 @@
*/
#include "los_cir_buf.h"
#include "los_spinlock.h"
/// 返回循环buf已使用的大小
......@@ -110,14 +111,17 @@ STATIC UINT32 OsCirBufWriteLoop(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
///写入数据到循环buf区
UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
{
UINT32 cpSize;
UINT32 cpSize = 0;
UINT32 intSave;
if ((cirbufCB == NULL) || (buf == NULL) || (size == 0)) {
if ((cirbufCB == NULL) || (buf == NULL) || (size == 0) || (cirbufCB->status != CBUF_USED)) {
return 0;
}
LOS_SpinLockSave(&cirbufCB->lock, &intSave);
if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == 0)) {
return 0;
goto EXIT;;
}
if (cirbufCB->startIdx <= cirbufCB->endIdx) {//开始位置在前面
......@@ -126,6 +130,8 @@ UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
cpSize = OsCirBufWriteLinear(cirbufCB, buf, size);//线性方式写入,分一次拷贝
}
EXIT:
LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
return cpSize;
}
/* 图形表示读线性buf linear 模式 ,图表示 读之前的样子 @note_pic
......@@ -192,14 +198,17 @@ STATIC UINT32 OsCirBufReadLoop(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
///读取循环buf的数据
UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
{
UINT32 cpSize;
UINT32 cpSize = 0;
UINT32 intSave;
if ((cirbufCB == NULL) || (buf == NULL) || (size == 0)) {
if ((cirbufCB == NULL) || (buf == NULL) || (size == 0) || (cirbufCB->status != CBUF_USED)) {
return 0;
}
LOS_SpinLockSave(&cirbufCB->lock, &intSave);
if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == cirbufCB->size)) {
return 0;
goto EXIT;
}
if (cirbufCB->startIdx >= cirbufCB->endIdx) {//开始位置大于结束位置的情况怎么读
......@@ -208,6 +217,8 @@ UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
cpSize = OsCirBufReadLinear(cirbufCB, buf, size);//线性读取,读取 endIdx - startIdx 部分就行了,所以是线性读取
}
EXIT:
LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
return cpSize;
}
///初始化循环buf
......
......@@ -30,10 +30,16 @@
*/
#include "los_vm_zone.h"
#define TEXT_BASE KERNEL_VADDR_BASE //代码区为内核起始地址
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
/***********************************************
本文件经过
python build.py ipcamera_hi3516dv300
编译后生成 board.ld,内容如下:
#define TEXT_BASE KERNEL_VADDR_BASE //代码区为内核起始地址
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
......@@ -57,10 +63,6 @@ SECTIONS
USER_INIT_VM_START = 0x1000000;
***********************************************/
#define TEXT_BASE KERNEL_VADDR_BASE //代码区为内核起始地址
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
/*
https://www.jianshu.com/p/42823b3b7c8e
MEMORY:内存布局,描述板上的存储器位置
......
git add -A
git commit -m ' 更新 readme
git commit -m ' 同步官方代码
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册