diff --git a/README.md b/README.md index 6820815690b7ff2a932fd4318d19db2e5411ff35..441166558f3461c723b74b475c62397a979f42d0 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,7 @@ ### 关注不迷路.代码即人生 -图片替换文本 +![](https://gitee.com/weharmonyos/resources/raw/master/common/so1so.png) + **QQ群 790015635 | 入群密码 666 | 存放重要文档资料** diff --git a/arch/arm/arm/include/los_hw_cpu.h b/arch/arm/arm/include/los_hw_cpu.h index b52e59f8be531a6e0b83f9171b73d73d3bbb0d49..30d02adbe568fde251f54e1aa5200411bbe5706b 100644 --- a/arch/arm/arm/include/los_hw_cpu.h +++ b/arch/arm/arm/include/los_hw_cpu.h @@ -47,10 +47,27 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +/*! + * @brief 内存屏障(英语:Memory barrier),也称内存栅栏,内存栅障,屏障指令等,是一类同步屏障指令, + \n 它使得 CPU 或编译器在对内存进行操作的时候, 严格按照一定的顺序来执行, 也就是说在memory barrier 之前的指令 + \n 和memory barrier之后的指令不会由于系统优化等原因而导致乱序。 + \n 大多数现代计算机为了提高性能而采取乱序执行,这使得内存屏障成为必须。 + + \n 语义上,内存屏障之前的所有写操作都要写入内存;内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。 + \n 因此,对于敏感的程序块,写操作之后、读操作之前可以插入内存屏障。 + * + * @param index + * @return + * + * @see + */ + + +// https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/memory-access-ordering---an-introduction /* ARM System Registers */ -#define DSB __asm__ volatile("dsb" ::: "memory") -#define DMB __asm__ volatile("dmb" ::: "memory") -#define ISB __asm__ volatile("isb" ::: "memory") +#define DSB __asm__ volatile("dsb" ::: "memory") ///< Data Synchronization Barrier(DSB) 数据同步隔离。DSB 比 DMB 管得更宽, DSB 屏障之后的所有得指令不可越过屏障乱序执行 +#define DMB __asm__ volatile("dmb" ::: "memory") ///< Data Memory Barrier(DMB) 数据存储器隔离。保证该指令前的所有内存访问结束,而该指令之后引起的内存访问只能在该指令执行结束后开始,其它数据处理指令等可以越过 DMB 屏障乱序执行 +#define ISB __asm__ volatile("isb" ::: "memory") ///< Instruction Synchronization Barrier(ISB) 指令同步隔离。ISB 比 DSB 管的更宽, ISB 屏障之前的指令保证执行完,屏障之后的指令直接flush 掉再重新从 Memroy 中取指 #define WFI __asm__ volatile("wfi" ::: "memory") #define BARRIER __asm__ volatile("":::"memory") #define WFE __asm__ volatile("wfe" ::: "memory") @@ -225,7 +242,7 @@ STATIC INLINE UINT32 ArchIntLock(VOID) : :"memory"); return intSave; } - +/// 打开当前处理器所有中断响应 STATIC INLINE UINT32 ArchIntUnlock(VOID) { UINT32 intSave; @@ -239,7 +256,7 @@ STATIC INLINE UINT32 ArchIntUnlock(VOID) } #endif - +/// 恢复到使用LOS_IntLock关闭所有中断之前的状态 STATIC INLINE VOID ArchIntRestore(UINT32 intSave) { __asm__ __volatile__( @@ -250,7 +267,7 @@ STATIC INLINE VOID ArchIntRestore(UINT32 intSave) } #define PSR_I_BIT 0x00000080U - +/// 关闭当前处理器所有中断响应 STATIC INLINE UINT32 OsIntLocked(VOID) { UINT32 intSave; diff --git a/arch/arm/arm/src/los_hwi.c b/arch/arm/arm/src/los_hwi.c index 58f2cd1c17f3dbc330781a089f66ba89fa4aad2d..f7adc97f657d23d78fade1ad9c23dabab98a7db5 100644 --- a/arch/arm/arm/src/los_hwi.c +++ b/arch/arm/arm/src/los_hwi.c @@ -4,13 +4,23 @@ * @link * @verbatim 基本概念 - 中断是指出现需要时,CPU暂停执行当前程序,转而执行新程序的过程。即在程序运行过程中, - 出现了一个必须由CPU立即处理的事务。此时,CPU暂时中止当前程序的执行转而处理这个事务, - 这个过程就叫做中断。 - 外设可以在没有CPU介入的情况下完成一定的工作,但某些情况下也需要CPU为其执行一定的工作。 - 通过中断机制,在外设不需要CPU介入时,CPU可以执行其它任务,而当外设需要CPU时,将通过产生 - 中断信号使CPU立即中断当前任务来响应中断请求。这样可以使CPU避免把大量时间耗费在等待、 - 查询外设状态的操作上,大大提高系统实时性以及执行效率。 + 中断是指出现需要时,CPU暂停执行当前程序,转而执行新程序的过程。即在程序运行过程中, + 出现了一个必须由CPU立即处理的事务。此时,CPU暂时中止当前程序的执行转而处理这个事务, + 这个过程就叫做中断。通过中断机制,可以使CPU避免把大量时间耗费在等待、查询外设状态的操作上, + 大大提高系统实时性以及执行效率。 + + 异常处理是操作系统对运行期间发生的异常情况(芯片硬件异常)进行处理的一系列动作, + 例如虚拟内存缺页异常、打印异常发生时函数的调用栈信息、CPU现场信息、任务的堆栈情况等。 + + 外设可以在没有CPU介入的情况下完成一定的工作,但某些情况下也需要CPU为其执行一定的工作。 + 通过中断机制,在外设不需要CPU介入时,CPU可以执行其它任务,而当外设需要CPU时,产生一个中断信号, + 该信号连接至中断控制器。中断控制器是一方面接收其它外设中断引脚的输入,另一方面它会发出中断信号给CPU。 + 可以通过对中断控制器编程来打开和关闭中断源、设置中断源的优先级和触发方式。 + 常用的中断控制器有VIC(Vector Interrupt Controller)和GIC(General Interrupt Controller)。 + 在ARM Cortex-A7中使用的中断控制器是GIC。CPU收到中断控制器发送的中断信号后,中断当前任务来响应中断请求。 + + 异常处理就是可以打断CPU正常运行流程的一些事情,如未定义指令异常、试图修改只读的数据异常、不对齐的地址访问异常等。 + 当异常发生时,CPU暂停当前的程序,先处理异常事件,然后再继续执行被异常打断的程序。 中断特性: 中断共享,且可配置。 @@ -82,8 +92,11 @@ 中断处理程序耗时不能过长,否则会影响CPU对中断的及时响应。 中断响应过程中不能执行引起调度的函数。 中断恢复LOS_IntRestore()的入参必须是与之对应的LOS_IntLock()的返回值(即关中断之前的CPSR值)。 - Cortex-M系列处理器中0-15中断为内部使用,Cortex-A7中0-31中断为内部使用,因此不建议用户去申请和创建。 + Cortex-M系列处理器中0-15中断为内部使用,Cortex-A7中0-31中断为内部使用,因此不建议用户去申请和创建。 + + 以ARMv7-a架构为例,中断和异常处理的入口为中断向量表,中断向量表包含各个中断和异常处理的入口函数。 * @endverbatim + * @image html https://gitee.com/weharmonyos/resources/raw/master/44/vector.png * @version * @author weharmonyos.com * @date 2021-11-16 @@ -166,7 +179,7 @@ CHAR *OsGetHwiFormName(UINT32 index)//获取某个中断的名称 { return g_hwiFormName[index]; } - +/// 获取系统支持的最大中断数 UINT32 LOS_GetSystemHwiMaximum(VOID) { return OS_HWI_MAX_NUM; diff --git a/arch/arm/include/los_hwi.h b/arch/arm/include/los_hwi.h index 62efa2072b9aa8d1301e55127b0f69eccc859394..9197db19840cb43393be9fe41bbd53316fbb7233 100644 --- a/arch/arm/include/los_hwi.h +++ b/arch/arm/include/los_hwi.h @@ -250,22 +250,22 @@ typedef VOID (*HWI_PROC_FUNC)(VOID); #define IRQF_SHARED 0x8000U //IRQF_SHARED-允许在多个设备之间共享irq typedef struct tagHwiHandleForm { - HWI_PROC_FUNC pfnHook; //中断处理函数 - HWI_ARG_T uwParam; //中断处理函数参数 - struct tagHwiHandleForm *pstNext; //节点,指向下一个中断,用于共享中断的情况 + HWI_PROC_FUNC pfnHook; ///< 中断处理函数 + HWI_ARG_T uwParam; ///< 中断处理函数参数 + struct tagHwiHandleForm *pstNext; ///< 节点,指向下一个中断,用于共享中断的情况 } HwiHandleForm; typedef struct tagIrqParam { //中断参数 - int swIrq; // 软件中断 - VOID *pDevId; // 设备ID - const CHAR *pName; //名称 + int swIrq; ///< 软件中断 + VOID *pDevId; ///< 设备ID + const CHAR *pName; ///< 名称 } HwiIrqParam; extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM];//中断注册表 /** * @ingroup los_hwi - * @brief Disable all interrupts. + * @brief Disable all interrupts. | 关闭当前处理器所有中断响应 * * @par Description: *