线程上下文 中断和向量
位索引
HAL_LSBIT_INDEX( mask, index )
HAL_MSBIT_INDEX( mask, index )
这些宏把mask参数中的最低(高)有效位的位索引存放在index参数中。一些CPU结构提供指令持这几种操作,要不然,这些宏要调用C函数完成这项工作。
空闲线程行为
HAL_IDLE_THREAD_ACTION( count )
在一些情形下,需要在内核空闲线程的循环中完成特定动作。执行处理机halt指令就是其中一个例子。这个宏提供一种可移植的方法在内核空闲线程的循环中完成这些特定动作。count参数是空闲线程循环次数的一个拷贝,它可以用来触发事件。
Reorder barrier
HAL_REORDER_BARRIER()
在代码优化时,编译器会调整代码次序。但多线程系统中一些部位的代码次序很重要,调整它们次序有时会产生问题。把这个宏插在不允许进行次序调整的语句之间。
断点支持
HAL_BREAKPOINT( label )
HAL_BREAKINST
HAL_BREAKINST_SIZE
这些宏提供了对断点的支持。
HAL_BREAKPOINT()执行一条断点指令。为这条断点指令定义了这个标签,这样exception代码可以检测到执行了哪个断点。
HAL_BREAKINST包含了这条断点指令的整数形式。
HAL_BREAKINST_SIZE是这条断点指令的字节大小。
结合使用这三个宏可以在任何地方设置断点
GDB支持
HAL_THREAD_GET_SAVED_REGISTERS( sp, regs )
HAL_GET_GDB_REGISTERS( regval, regs )
HAL_SET_GDB_REGISTERS( regs, regval )
这些宏提供了interface??GDB到HAL的支持。
AL_THREAD_GET_SAVED_REGISTERS()从堆栈指针sp抽取出指向HAL_SavedRegistersh结构的指针,并把它赋值给参数regs。这个堆栈指针sp必须为线程上下文切换时被保护起来的值。
HAL_GET_GDB_REGISTERS()把一个寄存器的状态转换成GDB期望的格式并把它存放在寄存器dump中。regs参数是指向HAL_SavedRegisters结构的指针,而regval是指向包含GDB寄存器dump的内存块指针。
HAL_SET_GDB_REGISTERS()把GDB寄存器dump转换成HAL期望的格式。
Setjmp and longjmp 支持
CYGARC_JMP_BUF_SIZE
hal_jmp_buf[CYGARC_JMP_BUF_SIZE]
hal_setjmp( hal_jmp_buf env )
hal_longjmp( hal_jmp_buf env, int val )
这些函数提供了对C函数setjmp() and longjmp()的支持。
hal/ARCH/arch/v1_2_1/include/hal_intr.h
hal_intr.h定义了有关中断处理的操作。
向量数目
CYGNUM_HAL_VECTOR_XXX
CYGNUM_HAL_VSR_MIN
CYGNUM_HAL_VSR_MAX
CYGNUM_HAL_ISR_MIN
CYGNUM_HAL_ISR_MAX
CYGNUM_HAL_EXCEPTION_MIN
CYGNUM_HAL_EXCEPTION_MAX
CYGNUM_HAL_ISR_COUNT
CYGNUM_HAL_VSR_COUNT
CYGNUM_HAL_EXCEPTION_COUNT
这里说明了所有可能的中断和exception向量,同时给出向量数目的最大和最小值用来进行范围检查。
对应于向量服务例程和中断服务例程,分别有两组向量数目范围。这两组数目范围大小之间没有必然关系。
VSR向量对应于一组exception向量。这些exception向量由CPU递送,它们很多属于内部exception陷阱(trap)。而ISR向量对应于一组外部中断,VSR通过对中断控制器额外进行解码来决定这些中断。
当CPU支持同步exceptions时,允许的同步exceptions范围由CYGNUM_HAL_EXCEPTION_MIN和CYGNUM_HAL_EXCEPTION_MAX决定。而实际exceptions数目一般与VSR exceptions范围一致。将来可能会添加一些由系统软件产生的exception,如栈溢出。
CYGNUM_HAL_ISR_COUNT, CYGNUM_HAL_VSR_COUNT 和CYGNUM_HAL_EXCEPTION_COUNT分别定义了ISRs,VSRs和EXCEPTIONs数目,它们用来定义向量数组。向量号到数组偏移量之间可能要进行转换,因此CYGNUM_HAL_XXX_COUNT可能不是简单的CYGNUM_HAL_XXX_MAX - CYGNUM_HAL_XXX_MIN或CYGNUM_HAL_XXX_MAX+1。
中断状态控制
HAL_DISABLE_INTERRUPTS( old )
HAL_RESTORE_INTERRUPTS( old )
HAL_ENABLE_INTERRUPTS()
HAL_QUERY_INTERRUPTS( state )
这些宏提供了CPU中断屏蔽机制。通常它们只应当操作CPU状态寄存器,enable和disable中断递送,而不应当访问中断控制器。
HAL_DISABLE_INTERRUPTS() disable中断递送并把中断屏蔽字的最初状态存放在old参数里。
HAL_RESTORE_INTERRUPTS()恢复记录在old参数里的中断屏蔽状态。
HAL_ENABLE_INTERRUPTS()只是enable中断递送而不考虑屏蔽字的当前状态。
HAL_QUERY_INTERRUPTS()把中断屏蔽状态存放在state参数里。
管理ISR 和 VSR
HAL_INTERRUPT_ATTACH( vector, isr, data, object )
HAL_INTERRUPT_DETACH( vector, isr )
HAL_VSR_SET( vector, vsr, poldvsr )
HAL_VSR_GET( vector, pvsr )
这些宏管理如何把中断服务例程和向量服务例程attach到对应的中断向量表和exception向量表上。
HAL_INTERRUPT_ATTACH()把中断服务例程,数据指针和对象指针attach到给出的向量上。当这个向量上的中断产生时,根据c函数的调用约定调用这个中断服务例程,同时把向量号和数据指针分别做为它的第一和第二个参数。
HAL_INTERRUPT_DETACH()从这个向量上分离中断服务例程。
HAL_VSR_SET()用vsr参数替换附带在这个向量上的向量服务例程,旧的向量服务例程通过pvsr参数被返回。
HAL_VSR_GET()把一份向量服务例程的拷贝赋值给pvsr。
中断控制器管理
HAL_INTERRUPT_MASK( vector )
HAL_INTERRUPT_UNMASK( vector )
HAL_INTERRUPT_ACKNOWLEDGE( vector )
HAL_INTERRUPT_CONFIGURE( vector, level, up )
HAL_INTERRUPT_SET_LEVEL( vector, level )
这些宏控制现有的任何分级的中断控制器。如果不存在分级的中断控制器,这些宏必须为空。
HAL_INTERRUPT_MASK()使得与给出的向量相关联的中断被阻塞。
HAL_INTERRUPT_UNMASK()使得与给出的向量相关联的中断不会被阻塞。
HAL_INTERRUPT_ACKNOWLEDGE()对给出向量里的当前中断进行确认,一般是这个向量的中断服务例程执行这段代码如果它准备接受(allow)更多的中断。在发送下一个中断之前,大多数中断控制器需要某种形式的确认动作。执行这个宏可能导致另一个中断被发送出去。这是否会中断当前的代码依赖于CPU中断屏弊字的状态。
HAL_INTERRUPT_CONFIGURE()提供了控制手段来控制一个中断信号如何被检测到,它的参数分别是:
vector
将要被配置的中断。
level
如果是等级方式,则置为真;如果是边缘触发方式,则为假。
up
如果是等级方式,那么up被置为真如果通过高等级信号中断被检测到,为假如果通过低等级信号中断被检测到。
如果是边缘触发方式,那么up被置为真如果中断被上升边缘触发,为假如果中断被下降边缘触发。
HAL_INTERRUPT_SET_LEVEL()提供了控制手段来控制硬件中断的优先级,它的参数是:
vector
将要被设置级别的中断
level
优先级别。在有些CPU结构中,设定中断优先级也用来enable和disable中断,因此这个函数可能会与HAL_INTERRUPT_MASK()和HAL_INTERRUPT_UNMASK()互相冲突。
返回
时钟控制
HAL_CLOCK_INITIALIZE( period )
HAL_CLOCK_RESET( vector, period )
HAL_CLOCK_READ( pvalue )
这些宏控制了时钟或定时器设备,它们被用在内核中以提供超时设定,延迟和调度服务。时钟是用某种形式的计数器实现的。一些外部源增加或减少计数器的值,当它的值为0时,便产生一个中断。
HAL_CLOCK_INITIALIZE()初始化时钟设备,使它在给定的周期内产生中断。这个周期是用来初始化时钟计数器,必须根据时钟频率和期望的中断产生频率计算它的值。
HAL_CLOCK_RESET()重新初始化这个时钟以引发下一个中断。只有当每次中断产生后时钟设备需要以某种方式重新设定时,这个宏才真正有用。
HAL_CLOCK_READ()读出时钟计数器的当前值并把它赋值给pvalue指向的地址。自从前一次中断产生后,这个值将会是时钟滴答的次数,因此它介于零和初始周期值之间。
hal/ARCH/arch/v1_2_1/include/hal_io.h
hal_io.h包含一些定义用来支持以一种与CPU结构无关的方式对设备控制寄存器进行访问。
寄存器地址
HAL_IO_REGISTER
这个类型用来存储I/O寄存器的地址。它一般是一个内存地址,一个整数端口地址或一个I/O空间的偏移量。
寄存器读
HAL_READ_XXX( register, value )
HAL_READ_XXX_VECTOR( register, buffer, count, stride )
这些宏支持读各种大小的I/O寄存器。宏名中的XXX部分可能是UINT8, UINT16, UINT32。
HAL_READ_XXX()从寄存器读出适当大小的值并把它存放在第二个参数指向的变量中。
HAL_READ_XXX_VECTOR()读出count个适当大小的值并把它们存放在buffer中。stride参数控制了指针在寄存器空间中前进的步伐。stride为0意味着重复地读同一个寄存器。stride为1意味着读出count个连续的寄存器。使用更大的stride是考虑到稀疏分布的寄存器。
寄存器写
HAL_WRITE_XXX( register, value )
HAL_WRITE_XXX_VECTOR( register, buffer, count, stride )
这些宏支持写各种大小的I/O寄存器。宏名中的XXX部分可能是UINT8, UINT16, UINT32。
HAL_READ_XXX()把第二个参数指向的变量的值写到寄存器。
HAL_READ_XXX_VECTOR()从buffer读出count个适当大小的值并把它们写到寄存器。stride参数控制了指针在寄存器空间中前进的步伐。stride为0意味着重复地写同一个寄存器。stride为1意味着写count个连续的寄存器。使用更大的stride是考虑到稀疏分布的寄存器。
hal/ARCH/arch/v1_2_1/include/hal_cache.h
hal_cache.h定义了对CPU上cache控制的支持
对于数据和指令cache,这里定义了不同版本的宏,通过在宏名中DCACHE 或 ICACHE的使用区分它们。XCACHE则表示这个宏适用于数据cache和指令cache。
使用一些宏时,用户有责认遵循有关它们的约束,hal_cache.h文件说明了这些约束。
注意到应当小心使用一些破坏性的cache宏。在cache invalidation之前同步cache本身就不安全,因为在同步之后但在invalidation之前中断可能发生。这可能导致丢失在中断处理时产生的脏数据线的状态。
依赖于CPU结构的能力,也许可以通过在同步和invalidation时暂时disable cache来解决这个问题(中断处理时没有新的数据会被缓存)。要不然就必须在操作cache时disable中断。这可能需要比较长的时间。
Cache dimensions
HAL_XCACHE_SIZE
HAL_XCACHE_LINE_SIZE
HAL_XCACHE_WAYS
HAL_XCACHE_SETS
这些宏定义了数据和指令cache的大小和dimension。
HAL_XCACHE_SIZE
整个cache的大小,以字节为单位。
HAL_XCACHE_LINE_SIZE
Caceh线的大小,以字节为单位。
HAL_XCACHE_WAYS
gives the number of ways in each set and defines its level of associativity.
This would be 1 for a direct mapped cache.
HAL_XCACHE_SETS
gives the number of sets in the cache, and is derived from the previous values.
全局cache控制
HAL_XCACHE_ENABLE()
HAL_XCACHE_DISABLE()
HAL_XCACHE_INVALIDATE_ALL()
HAL_XCACHE_SYNC()
HAL_XCACHE_BURST_SIZE( size )
HAL_DCACHE_WRITE_MODE( mode )
HAL_XCACHE_LOCK( base, size )
HAL_XCACHE_UNLOCK( base, size )
HAL_XCACHE_UNLOCK_ALL()
这些宏影响整个或大部分cache的状态,
HAL_XCACHE_ENABLE() and HAL_XCACHE_DISABLE()
enable and disable the cache.
HAL_XCACHE_INVALIDATE_ALL()
使得cache所有内容失效。
HAL_XCACHE_SYNC()
同步cache的内容和内存的内容。在一些实现中它可能等同于HAL_XCACHE_INVALIDATE_ALL()。
HAL_XCACHE_BURST_SIZE()
allows the size of cache to/from memory bursts to be controlled. This macro will only be defined if this functionality is available.
HAL_DCACHE_WRITE_MODE()
控制数据cache线写回内存的方式。定义了所有可能的模式,典型的定义模式有HAL_DCACHE_WRITEBACK_MODE和HAL_DCACHE_WRITETHRU_MODE。只有存在这个功能,这个宏才能被定义。
HAL_XCACHE_LOCK()锁住cache中的数据。base和size参数定义了将要锁在cache中的内存区域。是否任何时候允许多个被锁住的区域以及在这块数据被锁住的过程中,这个操作是否会导致cache对区域外的地址不再有cache的功能,这些问题与CPU结构有关。只有存在这个功能,这个宏才能被定义。
HAL_XCACHE_UNLOCK()
cancels the locking of the memory region given. This should normally correspond to a region supplied in a matching lock call. This macro will only be defined if this functionality is available.
HAL_XCACHE_UNLOCK_ALL()
cancels all existing locked memory regions. This may be required as part of the cache initialization on some architectures. This macro will only be defined if this functionality is available.
Cache线控制
HAL_DCACHE_ALLOCATE( base , size )
HAL_DCACHE_FLUSH( base , size )
HAL_XCACHE_INVALIDATE( base , size )
HAL_DCACHE_STORE( base , size )
HAL_DCACHE_READ_HINT( base , size )
HAL_DCACHE_WRITE_HINT( base , size )
HAL_DCACHE_ZERO( base , size )
All of these macros apply a cache operation to all cache lines that match the memory address region defined by the base and size arguments. These macros will only be defined if the described functionality is available. Also, it is not guaranteed that the cache function will only be applied to just the described regions, in some architectures it may be applied to the whole cache.
HAL_DCACHE_ALLOCATE()
allocates lines in the cache for the given region without reading their contents from memory, hence the contents of the lines is undefined. This is useful for preallocating lines which are to be completely overwritten, for example in a block copy operation.
HAL_DCACHE_FLUSH()
invalidates all cache lines in the region after writing any dirty lines to memory.
HAL_XCACHE_INVALIDATE()
invalidates all cache lines in the region. Any dirty lines are invalidated without being written to memory.
HAL_DCACHE_STORE()
writes all dirty lines in the region to memory, but does not invalidate any lines.
HAL_DCACHE_READ_HINT()
hints to the cache that the region is going to be read from in the near future. This may cause the region to be speculatively read into the cache.
HAL_DCACHE_WRITE_HINT()
hints to the cache that the region is going to be written to in the near future. This may have the identical behavior to HAL_DCACHE_READ_HINT().
HAL_DCACHE_ZERO()
allocates and zeroes lines in the cache for the given region without reading memory. This is useful if a large area of memory is to be cleared.
hal/ARCH/arch/v1_2_1/src/ARCH.ld
ARCH.ld是一个CPU结构特有的 linker script文件。它定义了这个CPU结构所需要的section类型。不同的平台(板)和启动类型,有不同内存布局。在预处理过程中,定义了内存布局中这些section的区域,alignment和位置参数。
hal/ARCH/arch/v1_2_1/src/vectors.S
vectors.S包含了处理exception和中断向量的代码。因为通常把系统重启入口点实现为其中的一个向量,它同时也包含了处理系统启动的代码。
这段代码的实现方式由HAL实现者决定的,只要它能够与定义在hal_intr.h的宏正确地打交道,它可以采取任何形式。当然,当前所有的实现方式都遵循相同模式,除非有非常好的理由,你可以采用别的模式。下面的章节描述了标准的HAL实现模式。
这个文件一般包含下列几段代码:
启动和初始化代码。
递交exception
同步exception的缺省处理
中断的缺省处理
文章评论(0条评论)
登录后参与讨论