RTEMS目录梳理Sparc

介绍RTEMS BSP和Driver的文档:https://docs.rtems.org/branches/master/bsp-howto.pdf

目标相关的文件包括三部分,其中每一部分的sparc相关的会在sparc目录下,此外,有一个文件夹no_cpu里有例子,用于如果没有例子的目标为模板;此外,还有shared,这里是公共的部分:

(1)CPU相关,rtems-4.6.0\cpukit\score\cpu

(2)板子相关,bsp,rtems-4.6.0\c\src\lib\libbsp

(3)外设相关,

 

和sparc有关的目录有三个:

rtems-4.6.0\cpukit\score\cpu\sparc\cpu.c

rtems-4.6.0\c\src\lib\libbsp\sparc\shared\bspstart.c

rtems-4.6.0\c\src\lib\libcpu\sparc\cache\cache.c

 

https://devel.rtems.org/wiki/TBR/UserManual/SparcBSPStartup

SparcBSPStartup
The startup procedure for the SPARC Erc32 and Leon BSPs is complicated. Jiri Gaisler provided this explanation in response to a user's questions. See ​http://www.rtems.com/ml/rtems-users/2005/september/msg00024.html for the original.

The SPARC port of RTEMS generates binaries that do not perform any board initialisation, and that are linked to the beginning of the RAM. The idea behind this is to avoid having a separate bsp for every possible board around. Instead, a boot-prom builder (mkprom) is used to create a self-extracting prom image that initialises all board registers, loads the application to ram, and the starts it. The parameters to mkprom defines memory sizes, waitstates, frequency stack pointer and so on. So far so good...
When running on a (recent) ERC32 simulator, the RTEMS image is loaded into the emulated ram and started from there. The simulator detects that the start address is not 0 (SPARC reset vector) and perform the necessary board init routines that would have been make by mkprom on real hardware.
An issue with the 3-chip version of ERC32 is that the timer scaling register can not be read, only written (!). The RTEMS application can therefore not read the timer scaler to figure out which frequency the board is running at. To solve this, both the mkprom loader and the simulator writes a copy of the scaler value to trap entry 0x7e in the sparc trap table, because this trap can never occur anyway. The RTEMS application picks up the value from there and now knows the frequency and can generate proper timer events etc.
Possible cause of the problem: Fabrício could be running rdbmon debug monitor on his board, using it to download and start applications. rdbmon is an application on its own, and needs to insert its trap vectors into the RTEMS applications trap table. This is done by starting the application in user mode. The first priviledged instruction that occurs is a write to %tbr (trap base register). This instruction will trap and control is transfered to rdbmon. The monitor can read out the value of the new %tbr, insert its trap entries there, write the scaler value in 0x7e of the new trap table, and re-start the application is supervisor mode. What can not be done (and this is also mentioned in the leccs/rdbmon manual) is to single step through this procedure. What can also not be done is to use a custom loader that does not write 0x7e, or custom start up code that re-allocates the trap table.
Note that these issues are commented in start.S and spurious.c of the sparc/erc32 bsp.

start.S
/*
   This is a sad patch to make sure that we know where the
   MEC timer control register mirror is so we can stop the timers
   from an external debugger. It is needed because the control
   register is write-only. Trap 0x7C cannot occur in ERC32...


   We also use this location to store the last location of the
   usable RAM in order not to overwrite the remote debugger with
   the RTEMS work-space area.


 * /


    .global SYM(_ERC32_MEC_Timer_Control_Mirror), SYM(rdb_start), SYM(CLOCK_SPEED)
    .global SYM(Configuration)


SYM(rdb_start):
SYM(_ERC32_MEC_Timer_Control_Mirror):


  BAD_TRAP; BAD_TRAP;                           ! 7C - 7D undefined


SYM(CLOCK_SPEED):


  .word    0x0a, 0, 0, 0                ! 7E (10 MHz default)
spurious.c
  for ( trap=0 ; trap<256 ; trap++ ) {


    /*
     *  Skip window overflow, underflow, and flush as well as software
     *  trap 0 which we will use as a shutdown. Also avoid trap 0x70 - 0x7f
     *  which cannot happen and where some of the space is used to pass
     *  paramaters to the program.
     */


     if (( trap == 5 || trap == 6 ) ||
         (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
         (( trap >= 0x70 ) && ( trap <= 0x83 )))
      continue;


    set_vector( (rtems_isr_entry) bsp_spurious_handler,
         SPARC_SYNCHRONOUS_TRAP( trap ), 1 );
  }
View Code

 

 

rtems-4.6.0\cpukit\score\include\rtems\score\isr.h

11 #define _ISR_Install_vector( _vector, _new_handler, _old_handler ) \
12   _CPU_ISR_install_vector( _vector, _new_handler, _old_handler )

rtems-4.6.0\cpukit\score\cpu\sparc\cpu.c

 1 /*PAGE
 2  *
 3  *  _CPU_ISR_install_vector
 4  *
 5  *  This kernel routine installs the RTEMS handler for the
 6  *  specified vector.
 7  *
 8  *  Input parameters:
 9  *    vector       - interrupt vector number
10  *    new_handler  - replacement ISR for this vector number
11  *    old_handler  - pointer to former ISR for this vector number
12  *
13  *  Output parameters: 
14  *    *old_handler - former ISR for this vector number
15  *
16  */
17 
18 void _CPU_ISR_install_vector(
19   unsigned32  vector,
20   proc_ptr    new_handler,
21   proc_ptr   *old_handler
22 )
23 {
24    unsigned32 real_vector;
25    proc_ptr   ignored;
26 
27   /*
28    *  Get the "real" trap number for this vector ignoring the synchronous
29    *  versus asynchronous indicator included with our vector numbers.
30    */
31 
32    real_vector = SPARC_REAL_TRAP_NUMBER( vector );
33 
34    /*
35     *  Return the previous ISR handler.
36     */
37 
38    *old_handler = _ISR_Vector_table[ real_vector ];
39 
40    /*
41     *  Install the wrapper so this ISR can be invoked properly.
42     */
43 
44    _CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
45 
46    /*
47     *  We put the actual user ISR address in '_ISR_vector_table'.  This will
48     *  be used by the _ISR_Handler so the user gets control.
49     */
50 
51     _ISR_Vector_table[ real_vector ] = new_handler;
52 }
View Code

 

系统初始化包括底层初始化start.o和高层初始化boot_card()

 

 

E:\project\obsw\rtems-4.6.0\c\src\lib\libbsp\shared\bootcard.c

E:\project\obsw\rtems-4.6.0\c\src\lib\libbsp\unix\posix\startup\bspstart.c

boot_card调用bsp_start 

 

4.11.2,rtems-4.11.2\c\src\lib\libbsp\shared\bootcard.c中提到汇编的start.S调用boot_card,boot_card是C语言入口。但是没有找到一个start.S.

 1 /**
 2  * @file
 3  *
 4  * @ingroup bsp_bootcard
 5  *
 6  * @brief Standard system startup.
 7  *
 8  *  This is the C entry point for ALL RTEMS BSPs.  It is invoked
 9  *  from the assembly language initialization file usually called
10  *  start.S.  It provides the framework for the BSP initialization
11  *  sequence.  The basic flow of initialization is:
12  *
13  *  + start.S: basic CPU setup (stack, zero BSS)
14  *    + boot_card
15  *      + bspstart.c: bsp_start - more advanced initialization
16  *      + obtain information on BSP memory and allocate RTEMS Workspace
17  *      + rtems_initialize_data_structures
18  *      + allocate memory to C Program Heap
19  *      + initialize C Library and C Program Heap
20  *      + bsp_pretasking_hook
21  *      + if defined( RTEMS_DEBUG )
22  *        - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
23  *      + rtems_initialize_before_drivers
24  *      + bsp_predriver_hook
25  *      + rtems_initialize_device_drivers
26  *        - all device drivers
27  *      + bsp_postdriver_hook
28  *      + rtems_initialize_start_multitasking
29  *        - 1st task executes C++ global constructors
30  *          .... appplication runs ...
31  *          - exit
32  *      + will not return to here
33  *
34  *  This style of initialization ensures that the C++ global
35  *  constructors are executed after RTEMS is initialized.
36  *  Thanks to Chris Johns <cjohns@plessey.com.au> for the idea
37  *  to move C++ global constructors into the first task.
38  */

 

 rtems 3.6.0

object.h c\src\exec\score\headers

对象相关,rtems把定时器、任务、信号量、队列等都作为对象来管理,下面是对象的class枚举量

 1 typedef enum {
 2   OBJECTS_NO_CLASS                  =  0,
 3   OBJECTS_INTERNAL_THREADS          =  1,
 4   OBJECTS_RTEMS_TASKS               =  2,
 5   OBJECTS_POSIX_THREADS             =  3,
 6   OBJECTS_RTEMS_TIMERS              =  4,
 7   OBJECTS_RTEMS_SEMAPHORES          =  5,
 8   OBJECTS_RTEMS_MESSAGE_QUEUES      =  6,
 9   OBJECTS_RTEMS_PARTITIONS          =  7,
10   OBJECTS_RTEMS_REGIONS             =  8,
11   OBJECTS_RTEMS_PORTS               =  9,
12   OBJECTS_RTEMS_PERIODS             = 10,
13   OBJECTS_RTEMS_EXTENSIONS          = 11,
14   OBJECTS_POSIX_KEYS                = 12,
15   OBJECTS_POSIX_INTERRUPTS          = 13,
16   OBJECTS_POSIX_MESSAGE_QUEUES      = 14,
17   OBJECTS_POSIX_MUTEXES             = 15,
18   OBJECTS_POSIX_SEMAPHORES          = 16,
19   OBJECTS_POSIX_CONDITION_VARIABLES = 17
20 } Objects_Classes;

 

 

 

地方大幅度

posted on 2020-04-10 21:46  yanhc  阅读(422)  评论(0编辑  收藏  举报

导航