首页 文章 精选 留言 我的

精选列表

搜索[实时etl],共10000篇文章
优秀的个人博客,低调大师

gofs v0.8.0 已经发布,基于 Go 的跨平台实时文件同步工具

Fixed 新增init-env.sh脚本来修复UDP缓冲区大小问题 Enhancements 移除ssh_key命令行参数,通过在source和dest命令行参数中新增一些参数来配置SFTP的认证信息 新增copy_link和copy_unsafe_link命令行参数来控制软链接在本地磁盘模式下的同步 更新scripts/build-release.sh脚本,新增linux arm64和macOS arm64发布 更新release脚本,从HEAD中获取最近一次git提交的哈希值 移除CBool结构并进行代码重构 移除未使用的全局变量 新增docker和release工作流 新增govulncheck工作流 将minio.statDirEntry和sftp.statDirEntry替换为fs.FileInfoToDirEntry 将全局日志替换为本地的局部日志 重构build-release.sh和build-docker.sh脚本,使其更加通用化 更新install-minio.sh脚本,使用-q命令行参数来避免打印进度日志 将函数NewDecryptReader重命名为newDecryptReader 更新依赖包,github.com/quic-go/quic-go v0.38.0 => v0.39.0 更新依赖包,github.com/minio/minio-go/v7 v7.0.62 => v7.0.63 更新依赖包,github.com/no-src/log v0.3.0 => v0.3.1 更新依赖包,golang.org/x/oauth2 v0.11.0 => v0.12.0 更新依赖包,google.golang.org/grpc v1.57.0 => v1.58.2 详情查看:https://github.com/no-src/gofs/releases/tag/v0.8.0

优秀的个人博客,低调大师

gofs v0.7.2 已经发布,基于 Go 的跨平台实时文件同步工具

Fixed 修复特定字符可能会破坏文件路径的问题 Enhancements 为SFTP新增一些集成测试 支持软链接本身的同步 实现通过文件查询接口获取链接信息 新增go1.21支持 移除go1.19支持 新增symlink动作 为FileInfo结构新增LinkTo字段 新增fs.IsSymlink函数 在Driver接口中新增Symlink,Lstat和ReadLink方法 更新README文档,将bat替换为bash来识别Run in Terminal快捷按钮 更新README文档,新增Web UI小节 更新依赖包,github.com/quic-go/quic-go v0.36.0 => v0.38.0 更新依赖包,github.com/minio/minio-go/v7 v7.0.58 => v7.0.62 更新依赖包,google.golang.org/grpc v1.56.0 => v1.57.0 更新依赖包,github.com/no-src/log v0.2.3 => v0.3.0 更新依赖包,golang.org/x/oauth2 v0.9.0 => v0.11.0 更新依赖包,github.com/pkg/sftp v1.13.5 => v1.13.6 更新依赖包,github.com/no-src/fsctl v0.1.1 => v0.1.2 更新依赖包,golang.org/x/crypto v0.10.0 => v0.11.0 详情查看:https://github.com/no-src/gofs/releases/tag/v0.7.2

优秀的个人博客,低调大师

gofs v0.7.1 已经发布,基于 Go 的跨平台实时文件同步工具

Fixed 修复中继文档中的示例 修复停止grpc客户端导致panic的问题 修复同步文件到服务端场景的测试用例 Enhancements 新增dry_run命令行参数来支持启动gofs但是不真正执行同步操作 新增一些MinIO的集成测试 更新gofs程序的描述信息 在parseRedisConnection函数中返回int类型的db字段 在Loader接口中新增一些保存函数 更新构建脚本,在构建之前先切换到main分支 更新依赖包,github.com/gin-gonic/gin v1.9.0 => v1.9.1 更新依赖包,github.com/quic-go/quic-go v0.34.0 => v0.36.0 更新依赖包,github.com/minio/minio-go/v7 v7.0.55 => v7.0.58 更新依赖包,google.golang.org/grpc v1.55.0 => v1.56.0 更新依赖包,github.com/no-src/log v0.1.10 => v0.2.3 更新依赖包,github.com/no-src/nscache v0.1.0 => v0.1.1 更新依赖包,golang.org/x/oauth2 v0.8.0 => v0.9.0 更新依赖包,google.golang.org/protobuf v1.30.0 => v1.31.0 详情查看:https://github.com/no-src/gofs/releases/tag/v0.7.1

优秀的个人博客,低调大师

中断 Hwi:提高鸿蒙轻内核系统实时性及执行效率的秘密武器

摘要:本文带领大家一起剖析了鸿蒙轻内核的中断模块的源代码,掌握中断相关的概念,中断初始化操作,中断创建、删除,开关中断操作等。 本文分享自华为云社区《鸿蒙轻内核M核源码分析系列五 中断Hwi》,原文作者:zhushy。 本文,我们讲述一下中断,会给读者介绍中断的概念,鸿蒙轻内核的中断模块的源代码。本文中所涉及的源码,以 OpenHarmony LiteOS-M 内核为例,均可以在开源站点gitee.com/openharmony… 获取。 1、中断概念介绍 中断是指出现需要时,CPU 暂停执行当前程序,转而执行新程序的过程。当外设需要 CPU 时,将通过产生中断信号使 CPU 立即中断当前任务来响应中断请求。在剖析中断源代码之前,下面介绍些中断相关的硬件、中断相关的概念。 1.1 中断相关的硬件介绍 与中断相关的硬件可以划分为三类:设备、中断控制器、CPU 本身。 设备 发起中断的源,当设备需要请求 CPU 时,产生一个中断信号,该信号连接至中断控制器。 中断控制器 中断控制器是 CPU 众多外设中的一个,它一方面接收其它外设中断引脚的输入。另一方面,它会发出中断信号给 CPU。可以通过对中断控制器编程来打开和关闭中断源、设置中断源的优先级和触发方式。 CPU CPU 会响应中断源的请求,中断当前正在执行的任务,转而执行中断处理程序。 1.2 中断相关的概念 中断号 每个中断请求信号都会有特定的标志,使得计算机能够判断是哪个设备提出的中断请求,这个标志就是中断号。 中断优先级 为使系统能够及时响应并处理所有中断,系统根据中断时间的重要性和紧迫程度,将中断源分为若干个级别,称作中断优先级。 中断处理程序 当外设产生中断请求后,CPU 暂停当前的任务,转而响应中断申请,即执行中断处理程序。产生中断的每个设备都有相应的中断处理程序。 中断向量 中断服务程序的入口地址。 中断向量表 存储中断向量的存储区,中断向量与中断号对应,中断向量在中断向量表中按照中断号顺序存储。 中断共享 当外设较少时,可以实现一个外设对应一个中断号,但为了支持更多的硬件设备,可以让多个设备共享一个中断号,共享同一个中断号的中断处理程序形成一个链表。当外部设备产生中断申请时,系统会遍历中断号对应的中断处理程序链表,直到找到对应设备的中断处理程序。在遍历执行过程中,各中断处理程序可以通过检测设备 ID,判断是否是这个中断处理程序对应的设备产生的中断。 接下来,我们再看看鸿蒙轻内核中断源代码。 2、鸿蒙轻内核中断源代码 2.1 中断相关的声明和定义 在文件 kernel\arch\arm\cortex-m7\gcc\los_interrupt.c 中定义了一些结构体、全局变量、内联函数,在分析源码之前,我们先看下这些定义和声明。全部变量 g_intCount 表示正在处理的中断数量,每次进入中断处理程序时,都会把该变量数值加 1,完成中断处理退出时,该数值减 1。对应的内联函数 HalIsIntActive()用于获取是否正在处理中断,返回值大于 0,则表示正在处理中断。 UINT32g_intCount=0; inlineUINT32HalIsIntActive(VOID) { return(g_intCount>0); } 我们在再看看中断向量表定义。⑴处代码为系统支持的中断定义了数组 g_hwiForm[OS_VECTOR_CNT],对于每一个中断号 hwiNum,对应的数组元素 g_hwiForm[hwiNum]表示每一个中断对应的中断处理执行入口程序。⑵处的宏 OS_HWI_WITH_ARG 表示中断处理程序是否支持参数传入,默认关闭。如果支持传参,定义⑶处的结构体 HWI_HANDLER_FUNC 来维护中断处理函数及其参数,还需要定义⑷处 g_hwiHandlerForm 数组。如果不支持传参,使用⑹处定义的 g_hwiHandlerForm 数组。对于每一个中断号 hwiNum,对应的数组元素 g_hwiHandlerForm[hwiNum]表示每一个中断对应的中断处理程序。⑸、⑺处定义个函数 OsSetVector()用于设置指定中断号对应的中断处理执行入口程序和中断处理程序。中断处理执行入口程序和中断处理程序的关系是,当中断发生时,会执行中断处理执行入口程序,这个函数会进一步调用中断处理程序。 ⑴STATICHWI_PROC_FUNC__attribute__((aligned(0x100)))g_hwiForm[OS_VECTOR_CNT]={0}; ⑵#if(OS_HWI_WITH_ARG==1) ⑶typedefstruct{ HWI_PROC_FUNCpfnHandler; VOID*pParm; }HWI_HANDLER_FUNC; ⑷STATICHWI_HANDLER_FUNCg_hwiHandlerForm[OS_VECTOR_CNT]={{(HWI_PROC_FUNC)0,(HWI_ARG_T)0}}; ⑸VOIDOsSetVector(UINT32num,HWI_PROC_FUNCvector,VOID*arg) { if((num+OS_SYS_VECTOR_CNT)<OS_VECTOR_CNT){ g_hwiForm[num+OS_SYS_VECTOR_CNT]=(HWI_PROC_FUNC)HalInterrupt; g_hwiHandlerForm[num+OS_SYS_VECTOR_CNT].pfnHandler=vector; g_hwiHandlerForm[num+OS_SYS_VECTOR_CNT].pParm=arg; } } #else ⑹STATICHWI_PROC_FUNCg_hwiHandlerForm[OS_VECTOR_CNT]={0}; ⑺VOIDOsSetVector(UINT32num,HWI_PROC_FUNCvector) { if((num+OS_SYS_VECTOR_CNT)<OS_VECTOR_CNT){ g_hwiForm[num+OS_SYS_VECTOR_CNT]=HalInterrupt; g_hwiHandlerForm[num+OS_SYS_VECTOR_CNT]=vector; } } #endif 2.2 中断初始化 HalHwiInit() 在系统启动时,在 kernel\src\los_init.c 中调用 HalArchInit()进行中断初始化。这个函数定义在 kernel\arch\arm\cortex-m7\gcc\los_context.c,然后进一步调用定义在 kernel\arch\arm\cortex-m7\gcc\los_interrupt.c 文件中 HalHwiInit()函数完成中断向量初始化。我们分析下代码。 宏LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 表示是否使用系统预定义的向量基地址和中断处理程序,默认开启。⑴处开始,中断向量表的 0 号中断设置为空,1 号中断对应复位处理程序 Reset_Handler。⑵处把其余的中断设置为默认的中断处理执行入口程序 HalHwiDefaultHandler()。⑶处设置系统中断(异常是中断的一种,系统中断也称为异常),系统中断的执行入口函数定义在 kernel\arch\arm\cortex-m7\gcc\los_exc.S,使用汇编语言实现。系统中断中,14 号中断对应 HalPendSV 处理程序,用于任务上下文切换,15 号中断是 tick 中断。 执行⑷处代码把中断向量表赋值给 SCB->VTOR。对于 Cortex-M3 及以上的 CPU 核,还需要执行⑸设置优先级组。⑹处代码使能指定的异常。 LITE_OS_SEC_TEXT_INITVOIDHalHwiInit() { #if(LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT==1) UINT32index; ⑴g_hwiForm[0]=0;/*[0]TopofStack*/ g_hwiForm[1]=Reset_Handler;/*[1]reset*/ ⑵for(index=2;index<OS_VECTOR_CNT;index++){/*2:Thestartingpositionoftheinterrupt*/ g_hwiForm[index]=(HWI_PROC_FUNC)HalHwiDefaultHandler; } /*Exceptionhandlerregister*/ ⑶g_hwiForm[NonMaskableInt_IRQn+OS_SYS_VECTOR_CNT]=HalExcNMI; g_hwiForm[HARDFAULT_IRQN+OS_SYS_VECTOR_CNT]=HalExcHardFault; g_hwiForm[MemoryManagement_IRQn+OS_SYS_VECTOR_CNT]=HalExcMemFault; g_hwiForm[BusFault_IRQn+OS_SYS_VECTOR_CNT]=HalExcBusFault; g_hwiForm[UsageFault_IRQn+OS_SYS_VECTOR_CNT]=HalExcUsageFault; g_hwiForm[SVCall_IRQn+OS_SYS_VECTOR_CNT]=HalExcSvcCall; g_hwiForm[PendSV_IRQn+OS_SYS_VECTOR_CNT]=HalPendSV; g_hwiForm[SysTick_IRQn+OS_SYS_VECTOR_CNT]=SysTick_Handler; /*Interruptvectortablelocation*/ ⑷SCB->VTOR=(UINT32)(UINTPTR)g_hwiForm; #endif #if(__CORTEX_M>=0x03U)/*onlyforCortex-M3andabove*/ ⑸NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); #endif /*EnableUSGFAULT,BUSFAULT,MEMFAULT*/ ⑹*(volatileUINT32*)OS_NVIC_SHCSR|=(USGFAULT|BUSFAULT|MEMFAULT); /*EnableDIV0andunalignedexception*/ *(volatileUINT32*)OS_NVIC_CCR|=DIV0FAULT; return; } 2.3 创建中断 UINT32 HalHwiCreate() 开发者可以调用函数 UINT32HalHwiCreate()创建中断,注册中断处理程序。我们先看看这个函数的参数,HWI_HANDLE_T hwiNum 是硬件中断号,HWI_PRIOR_ThwiPrio 中断的优先级,HWI_MODE_T mode 中断模式,保留暂时没有使用。HWI_PROC_FUNC handler 是需要注册的中断处理程序,中断被触发后会调用这个函数。HWI_ARG_T arg 是中断处理程序的参数。 一起剖析下这个函数的源代码,⑴处代码开始,对入参进行校验,中断处理程序不能为空,中断号不能大于支持的最大中断号,中断优先级不能超过指定优先级的大小。如果待创建的中断号对应的中断执行入口程序不等于 HalHwiDefaultHandler,说明已经创建过,返回错误码。关中断,然后执行⑵处的 OsSetVector()函数设置指定中断号的中断处理程序。⑶处调用 CMSIS 函数使能中断、设置中断的优先级,打开中断,完成中断的创建。 LITE_OS_SEC_TEXT_INITUINT32HalHwiCreate(HWI_HANDLE_ThwiNum, HWI_PRIOR_ThwiPrio, HWI_MODE_Tmode, HWI_PROC_FUNChandler, HWI_ARG_Targ) { UINTPTRintSave; ⑴if(handler==NULL){ returnOS_ERRNO_HWI_PROC_FUNC_NULL; } if(hwiNum>=OS_HWI_MAX_NUM){ returnOS_ERRNO_HWI_NUM_INVALID; } if(g_hwiForm[hwiNum+OS_SYS_VECTOR_CNT]!=(HWI_PROC_FUNC)HalHwiDefaultHandler){ returnOS_ERRNO_HWI_ALREADY_CREATED; } if(hwiPrio>OS_HWI_PRIO_LOWEST){ returnOS_ERRNO_HWI_PRIO_INVALID; } intSave=LOS_IntLock(); #if(OS_HWI_WITH_ARG==1) OsSetVector(hwiNum,handler,arg); #else ⑵OsSetVector(hwiNum,handler); #endif ⑶NVIC_EnableIRQ((IRQn_Type)hwiNum); NVIC_SetPriority((IRQn_Type)hwiNum,hwiPrio); LOS_IntRestore(intSave); returnLOS_OK; } 2.4 删除中断 UINT32 HalHwiDelete() 中断删除操作是创建操作的反向操作,也比较好理解。开发者可以调用函数 UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum)来删除中断。函数需要指定中断号参数 HWI_HANDLE_T hwiNum。一起剖析下这个函数的源代码,⑴处代码对入参进行校验,不能大于支持的最大中断号。⑵处调用 CMSIS 函数来失能中断,然后锁中断,执行⑶把中断向量表指定中断号的中断执行入口程序设置为默认程序 HalHwiDefaultHandler。 LITE_OS_SEC_TEXT_INITUINT32HalHwiDelete(HWI_HANDLE_ThwiNum) { UINT32intSave; ⑴if(hwiNum>=OS_HWI_MAX_NUM){ returnOS_ERRNO_HWI_NUM_INVALID; } ⑵NVIC_DisableIRQ((IRQn_Type)hwiNum); intSave=LOS_IntLock(); ⑶g_hwiForm[hwiNum+OS_SYS_VECTOR_CNT]=(HWI_PROC_FUNC)HalHwiDefaultHandler; LOS_IntRestore(intSave); returnLOS_OK; } 2.5 中断处理执行入口程序 我们再来看看中断处理执行入口程序。默认的函数 HalHwiDefaultHandler()如下,调用函数 HalIntNumGet()获取中断号,打印输出,然后进行死循环。其中函数 HalIntNumGet()读取寄存器 ipsr 来获取触发的中断的中断号。 LITE_OS_SEC_TEXT_MINORVOIDHalHwiDefaultHandler(VOID) { UINT32irqNum=HalIntNumGet(); PRINT_ERR("%sirqNum:%d\n",__FUNCTION__,irqNum); while(1){} } 继续来看中断处理执行入口程序 HalInterrupt(),源码如下。 ⑴处把全局变量 g_intCount 表示的正在处理的中断数量加 1,在中断执行完毕后,在⑹处再把正在处理的中断数量减 1。⑵处调用函数 HalIntNumGet()获取中断号,⑶、⑸处调用的函数 HalPreInterruptHandler(),HalAftInterruptHandler()在执行中断处理程序前、后可以处理些其他操作,当前默认为空函数。⑷处根据中断号从中断处理程序数组中获取中断处理程序,不为空就调用执行。 LITE_OS_SEC_TEXTVOIDHalInterrupt(VOID) { UINT32hwiIndex; UINT32intSave; #if(LOSCFG_KERNEL_RUNSTOP==1) SCB->SCR&=(UINT32)~((UINT32)SCB_SCR_SLEEPDEEP_Msk); #endif intSave=LOS_IntLock(); ⑴g_intCount++; LOS_IntRestore(intSave); ⑵hwiIndex=HalIntNumGet(); OsHookCall(LOS_HOOK_TYPE_ISR_ENTER,hwiIndex); ⑶HalPreInterruptHandler(hwiIndex); #if(OS_HWI_WITH_ARG==1) if(g_hwiHandlerForm[hwiIndex].pfnHandler!=0){ g_hwiHandlerForm[hwiIndex].pfnHandler((VOID*)g_hwiHandlerForm[hwiIndex].pParm); } #else if(g_hwiHandlerForm[hwiIndex]!=0){ ⑷g_hwiHandlerForm[hwiIndex](); } #endif ⑸HalAftInterruptHandler(hwiIndex); OsHookCall(LOS_HOOK_TYPE_ISR_EXIT,hwiIndex); intSave=LOS_IntLock(); ⑹g_intCount--; LOS_IntRestore(intSave); } 3、开关中断 最后,分享下开、关中断的相关知识,开、关中断分别指的是: 开中断 执行完毕特定的短暂的程序,打开中断,可以响应中断。 关中断 为了保护执行的程序不被打断,关闭相应外部的中断。 对应的开、关中断的函数定义在文件 kernel\arch\include\los_context.h 中,代码如下。⑴处的 UINT32 LOS_IntLock(VOID)会关闭中断,暂停响应中断。⑵处的函数 VOID LOS_IntRestore(UINT32 intSave)可以用来恢复 UINT32LOS_IntLock(VOID)函数关闭的中断,UINT32 LOS_IntLock(VOID)的返回值作为 VOIDLOS_IntRestore(UINT32 intSave)的参数进行恢复中断。⑶处的函数 UINT32 LOS_IntUnLock(VOID)会使能中断,可以响应中断。 UINTPTRHalIntLock(VOID); ⑴#defineLOS_IntLockHalIntLock VOIDHalIntRestore(UINTPTRintSave); ⑵#defineLOS_IntRestoreHalIntRestore UINTPTRHalIntUnLock(VOID); ⑶#defineLOS_IntUnLockHalIntUnLock 可以看出,LOS_IntLock、LOS_IntRestore 和 LOS_IntUnLock 是定义的宏,他们对应定义在文件kernel\arch\arm\cortex-m7\gcc\los_dispatch.S 中的汇编函数,源码如下。我们分析下这些汇编函数。寄存器 PRIMASK 是单一 bit 位的寄存器,置为 1 后,就关掉所有可屏蔽异常,只剩下 NMI 和硬故障 HardFault 异常可以响应。默认值是 0,表示没有关闭中断。汇编指令 CPSID I 会设置 PRIMASK=1,关闭中断,指令 CPSIEI 设置 PRIMASK=0,开启中断。 ⑴处 HalIntLock 函数把寄存器 PRIMASK 数值写入寄存器 R0 返回,并执行 CPSIDI 关闭中断。⑵处 HalIntUnLock 函数把寄存器 PRIMASK 数值写入寄存器 R0 返回,并执行指令 CPSIEI 开启中断。两个函数的返回结果可以传递给⑶处 HalIntRestore 函数,把寄存器状态数值写入寄存器 PRIMASK,用于恢复之前的中断状态。不管是 HalIntLock 还是 HalIntUnLock,都可以和 ArchIntRestore 配对使用。 .typeHalIntLock,%function .globalHalIntLock HalIntLock: .fnstart .cantunwind ⑴MRSR0,PRIMASK CPSIDI BXLR .fnend .typeHalIntUnLock,%function .globalHalIntUnLock HalIntUnLock: .fnstart .cantunwind ⑵MRSR0,PRIMASK CPSIEI BXLR .fnend .typeHalIntRestore,%function .globalHalIntRestore HalIntRestore: .fnstart .cantunwind ⑶MSRPRIMASK,R0 BXLR .fnend 小结 本文带领大家一起剖析了鸿蒙轻内核的中断模块的源代码,掌握中断相关的概念,中断初始化操作,中断创建、删除,开关中断操作等。后续也会陆续推出更多的分享文章,敬请期待,也欢迎大家分享学习、使用鸿蒙轻内核的心得,有任何问题、建议,都可以留言给我们:gitee.com/openharmony… 。为了更容易找到鸿蒙轻内核代码仓,建议访问 gitee.com/openharmony… ,关注 Watch、点赞 Star、并 Fork 到自己账户下,谢谢。 点击关注,第一时间了解华为云新鲜技术~

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册