📄 hal.sgml
字号:
thread will be stored. </PARA> </LISTITEM> </VARLISTENTRY> <VARLISTENTRY> <TERM>to</TERM> <LISTITEM> <PARA> A pointer to a location from where the stack pointer of the next thread will be read. </PARA> </LISTITEM> </VARLISTENTRY></VARIABLELIST><para>For <function>HAL_THREAD_LOAD_CONTEXT()</function> the current CPUstate is discarded and the state of the destination thread isloaded. This is only used once, to load the first thread when thescheduler is started.</para><PARA>For <function>HAL_THREAD_SWITCH_CONTEXT()</function> the state of thecurrent thread is saved onto its stack, using the current value of thestack pointer, and the address of the saved state placed in<parameter>*from</parameter>. The value in<parameter>*to</parameter> is then read and the state of the newthread is loaded from it.</PARA><para>While these two operations may be implemented with inline assembler,they are normally implemented as calls to assembly code functions inthe HAL. There are two advantages to doing it this way. First, thereturn link of the call provides a convenient PC value to be used inthe saved context. Second, the calling conventions mean that thecompiler will have already saved the caller-saved registers before thecall, so the HAL need only save the callee-saved registers.</para><para>The implementation of <function>HAL_THREAD_SWITCH_CONTEXT()</function>saves the current CPU state on the stack, including the currentinterrupt state (or at least the register that contains it). Fordebugging purposes it is useful to save the entire register set, butfor performance only the ABI-defined callee-saved registers need besaved. If it is implemented, the option<literal>CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM</literal> controlshow many registers are saved.</para><para>The implementation of <function>HAL_THREAD_LOAD_CONTEXT()</function>loads a thread context, destroying the current context. With a littlecare this can be implemented by sharing code with<function>HAL_THREAD_SWITCH_CONTEXT()</function>. To load a threadcontext simply requires the saved registers to be restored from thestack and a jump or return made back to the saved PC.</para><PARA>Note that interrupts are not disabled during this process, anyinterrupts that occur will be delivered onto the stack to which thecurrent CPU stack pointer points. Hence the stack pointershould never be invalid, or loaded with a value that might cause thesaved state to become corrupted by an interrupt. However, the currentinterrupt state is saved and restored as part of the threadcontext. If a thread disables interrupts and does something to cause acontext switch, interrupts may be re-enabled on switching to anotherthread. Interrupts will be disabled again when the original threadregains control.</PARA></SECTION><!-- =================================================================== --><SECTION><TITLE>Bit indexing</TITLE><PROGRAMLISTING>HAL_LSBIT_INDEX( index, mask )HAL_MSBIT_INDEX( index, mask )</PROGRAMLISTING><PARA>These macros place in <parameter>index</parameter> the bit index ofthe least significant bit in <parameter>mask</parameter>. Somearchitectures have instruction level support for one or other of theseoperations. If no architectural support is available, then thesemacros may call C functions to do the job.</PARA></SECTION><!-- =================================================================== --><SECTION><TITLE>Idle thread activity</TITLE><PROGRAMLISTING>HAL_IDLE_THREAD_ACTION( count )</PROGRAMLISTING><PARA>It may be necessary under some circumstances for the HAL to executecode in the kernel idle thread's loop. An example might be to executea processor halt instruction. This macro provides a portable way ofdoing this. The argument is a copy of the idle thread's loop counter,and may be used to trigger actions at longer intervals than everyloop.</PARA></SECTION><!-- =================================================================== --><SECTION><TITLE>Reorder barrier</TITLE><PROGRAMLISTING>HAL_REORDER_BARRIER()</PROGRAMLISTING><PARA>When optimizing the compiler can reorder code. In some parts ofmulti-threaded systems, where the order of actions is vital, this cansometimes cause problems. This macro may be inserted into places wherereordering should not happen and prevents code being migrated acrossit by the compiler optimizer. It should be placed between statementsthat must be executed in the order written in the code.</PARA></SECTION><!-- =================================================================== --><SECTION><TITLE>Breakpoint support</TITLE><PROGRAMLISTING>HAL_BREAKPOINT( label )HAL_BREAKINSTHAL_BREAKINST_SIZE</PROGRAMLISTING><PARA>These macros provide support for breakpoints.</PARA><PARA><FUNCTION>HAL_BREAKPOINT()</FUNCTION> executes a breakpointinstruction. The label is defined at the breakpoint instruction sothat exception code can detect which breakpoint was executed.</PARA><PARA><literal>HAL_BREAKINST</literal> contains the breakpoint instructioncode as an integer value. <literal>HAL_BREAKINST_SIZE</literal> isthe size of that breakpoint instruction in bytes. Together thesemay be used to place a breakpoint in any code.</PARA></SECTION><!-- =================================================================== --><SECTION><TITLE>GDB support</TITLE><PROGRAMLISTING>HAL_THREAD_GET_SAVED_REGISTERS( sp, regs )HAL_GET_GDB_REGISTERS( regval, regs )HAL_SET_GDB_REGISTERS( regs, regval )</PROGRAMLISTING><PARA>These macros provide support for interfacing GDB to the HAL.</PARA><PARA><FUNCTION>HAL_THREAD_GET_SAVED_REGISTERS()</FUNCTION> extracts apointer to a <STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structurefrom a stack pointer value. The stack pointer passed in should be thevalue saved by the thread context macros. The macro will assign apointer to the <STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structureto the variable passed as the second argument.</PARA><PARA><FUNCTION>HAL_GET_GDB_REGISTERS()</FUNCTION> translates a registerstate as saved by the HAL and into a register dump in the formatexpected by GDB. It takes a pointer to a<STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structure in the<parameter>regs</parameter> argument and a pointer to the memory tocontain the GDB register dump in the <parameter>regval</parameter>argument.</PARA><PARA><FUNCTION>HAL_SET_GDB_REGISTERS()</FUNCTION> translates a GDB formatregister dump into a the format expected by the HAL. It takes apointer to the memory containing the GDB register dump in the<parameter>regval</parameter> argument and a pointer to a<STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structurein the <parameter>regs</parameter> argument.</PARA></SECTION><!-- =================================================================== --><SECTION><TITLE>Setjmp and longjmp support</TITLE><PROGRAMLISTING>CYGARC_JMP_BUF_SIZEhal_jmp_buf[CYGARC_JMP_BUF_SIZE]hal_setjmp( hal_jmp_buf env )hal_longjmp( hal_jmp_buf env, int val )</PROGRAMLISTING><PARA>These functions provide support for the C<FUNCTION>setjmp()</FUNCTION> and <FUNCTION>longjmp()</FUNCTION>functions. Refer to the C library for further information.</PARA></SECTION><!-- =================================================================== --><section><title>Stack Sizes</title><programlisting>CYGNUM_HAL_STACK_SIZE_MINIMUMCYGNUM_HAL_STACK_SIZE_TYPICAL</programlisting><para>The values of these macros define the minimum and typical sizes ofthread stacks.</para><para><literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal> defines the minimumsize of a thread stack. This is enough for the thread to functioncorrectly within eCos and allows it to take interrupts and contextswitches. There should also be enough space for a simple thread entryfunction to execute and call basic kernel operations on objects likemutexes and semaphores. However there will not be enough room for muchmore than this. When creating stacks for their own threads,applications should determine the stack usage needed for applicationpurposes and then add<literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal>.</para><para><literal>CYGNUM_HAL_STACK_SIZE_TYPICAL</literal> is a reasonable increment over<literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal>, usually about 1kB. This should beadequate for most modest thread needs. Only threads that need todefine significant amounts of local data, or have very deep call treesshould need to use a larger stack size.</para></section><!-- =================================================================== --><section><title>Address Translation</title><programlisting>CYGARC_CACHED_ADDRESS(addr)CYGARC_UNCACHED_ADDRESS(addr)CYGARC_PHYSICAL_ADDRESS(addr)</programlisting><para>These macros provide address translation between different views ofmemory. In many architectures a given memory location may be visibleat different addresses in both cached and uncached forms. It is alsopossible that the MMU or some other address translation unit in theCPU presents memory to the program at a different virtual address toits physical address on the bus.</para><para><function>CYGARC_CACHED_ADDRESS()</function> translates the givenaddress to its location in cached memory. This is typically where theapplication will access the memory.</para><para><function>CYGARC_UNCACHED_ADDRESS()</function> translates the givenaddress to its location in uncached memory. This is typically wheredevice drivers will access the memory to avoid cache problems. It mayadditionally be necessary for the cache to be flushed before thecontents of this location is fully valid.</para><para><function>CYGARC_PHYSICAL_ADDRESS()</function> translates the givenaddress to its location in the physical address space. This istypically the address that needs to be passed to device hardware suchas a DMA engine, ethernet device or PCI bus bridge. The physicaladdress may not be directly accessible to the program, it may bere-mapped by address translation.</para></section><!-- =================================================================== --><section><title>Global Pointer</title><programlisting>CYGARC_HAL_SAVE_GP()CYGARC_HAL_RESTORE_GP()</programlisting><para>These macros insert code to save and restore any global data pointerthat the ABI uses. These are necessary when switching context betweentwo eCos instances - for example between an eCos application andRedBoot.</para></section></SECTION><!-- }}} --><!-- {{{ Interrupt Handling --><SECTION id="hal-interrupt-handling"><TITLE>Interrupt Handling</TITLE><para>These interfaces contain definitions related to interrupthandling. They include definitions of exception and interrupt numbers,interrupt enabling and masking, and realtime clock operations.</para><PARA>These definitions are normally found in<FILENAME>cyg/hal/hal_intr.h</FILENAME>. This file is supplied by thearchitecture HAL. Any variant or platform specific definitions willbe found in <filename>cyg/hal/var_intr.h</filename>,<filename>cyg/hal/plf_intr.h</filename> or<filename>cyg/hal/hal_platform_ints.h</filename> in the variant or platformHAL, depending on the exact target. These files are includeautomatically by this header, so need not be included explicitly.</PARA><!-- =================================================================== --><SECTION><TITLE>Vector numbers</TITLE><PROGRAMLISTING>CYGNUM_HAL_VECTOR_XXXXCYGNUM_HAL_VSR_MINCYGNUM_HAL_VSR_MAXCYGNUM_HAL_VSR_COUNTCYGNUM_HAL_INTERRUPT_XXXXCYGNUM_HAL_ISR_MINCYGNUM_HAL_ISR_MAXCYGNUM_HAL_ISR_COUNTCYGNUM_HAL_EXCEPTION_XXXXCYGNUM_HAL_EXCEPTION_MINCYGNUM_HAL_EXCEPTION_MAXCYGNUM_HAL_EXCEPTION_COUNT</PROGRAMLISTING><PARA>All possible VSR, interrupt and exception vectors are specified here,together with maximum and minimum values for range checking. While theVSR and exception numbers will be defined in this file, the interruptnumbers will normally be defined in the variant or platform HAL filethat is included by this header. </PARA><PARA>There are two ranges of numbers, those for the vector serviceroutines and those for the interrupt service routines. The relationshipbetween these two ranges is undefined, and no equivalence shouldbe assumed if vectors from the two ranges coincide.</PARA><PARA>The VSR vectors correspond to the set of exception vectors that can bedelivered by the CPU architecture, many of these will be internalexception traps. The ISR vectors correspond to the set of externalinterrupts that can be delivered and are usually determined by extradecoding of the interrupt controller by the interrupt VSR.</PARA><PARA>Where a CPU supports synchronous exceptions, the range of suchexceptions allowed are defined by <literal>CYGNUM_HAL_EXCEPTION_MIN</literal> and<literal>CYGNUM_HAL_EXCEPTION_MAX</literal>. The<literal>CYGNUM_HAL_EXCEPTION_XXXX</literal> definitions arestandard names used by target independent code to test for thepresence of particular exceptions in the architecture. The actualexception numbers will normally correspond to the VSR exception
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -