Changeset 6d7a4d2 in rtems-docs
- Timestamp:
- 06/17/16 05:05:41 (7 years ago)
- Branches:
- 4.11, 5, am, master
- Children:
- 86518bd
- Parents:
- 54514fe
- Location:
- bsp_howto
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
bsp_howto/ada95_interrupt.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2008. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Ada95 Interrupt Support … … 7 11 ============ 8 12 9 This chapter describes what is required to enable Ada interrupt 10 and errorexception handling when using GNAT over RTEMS.13 This chapter describes what is required to enable Ada interrupt and error 14 exception handling when using GNAT over RTEMS. 11 15 12 The GNAT Ada95 interrupt support RTEMS was developed by 13 Jiri Gaisler <jgais@ws.estec.esa.nl> who also wrote this 14 chapter. 16 The GNAT Ada95 interrupt support RTEMS was developed by Jiri Gaisler 17 <jgais@ws.estec.esa.nl> who also wrote this chapter. 15 18 16 19 Mapping Interrupts to POSIX Signals 17 20 =================================== 18 21 19 In Ada95, interrupts can be attached with the interrupt_attach pragma. 20 For most systems, the gnat run-time will use POSIX signal to implement 21 the interrupt handling, mapping one signal per interrupt. For interrupts 22 to be propagated to the attached Ada handler, the corresponding signal 23 must be raisedwhen the interrupt occurs.22 In Ada95, interrupts can be attached with the interrupt_attach pragma. For 23 most systems, the gnat run-time will use POSIX signal to implement the 24 interrupt handling, mapping one signal per interrupt. For interrupts to be 25 propagated to the attached Ada handler, the corresponding signal must be raised 26 when the interrupt occurs. 24 27 25 The same mechanism is used to generate Ada error exceptions. 26 Three error exceptions are defined: program, constraint and storage 27 error. These are generated by raising the predefined signals: SIGILL, 28 SIGFPE and SIGSEGV. These signals should be raised when a spurious 29 or erroneous trap occurs. 28 The same mechanism is used to generate Ada error exceptions. Three error 29 exceptions are defined: program, constraint and storage error. These are 30 generated by raising the predefined signals: SIGILL, SIGFPE and SIGSEGV. These 31 signals should be raised when a spurious or erroneous trap occurs. 30 32 31 To enable gnat interrupt and error exception support for a particular 32 BSP, thefollowing has to be done:33 To enable gnat interrupt and error exception support for a particular BSP, the 34 following has to be done: 33 35 34 # Write an interrupt/trap handler that will raise the corresponding 35 signaldepending on the interrupt/trap number.36 - Write an interrupt/trap handler that will raise the corresponding signal 37 depending on the interrupt/trap number. 36 38 37 # Install the interrupt handler for all interrupts/traps that will be 38 handledby gnat (including spurious).39 - Install the interrupt handler for all interrupts/traps that will be handled 40 by gnat (including spurious). 39 41 40 # At startup, gnat calls ``__gnat_install_handler()``. The BSP 41 must providethis function which installs the interrupt/trap handlers.42 - At startup, gnat calls ``__gnat_install_handler()``. The BSP must provide 43 this function which installs the interrupt/trap handlers. 42 44 43 Which CPU-interrupt will generate which signal is implementation 44 defined. There are 32 POSIX signals (1 - 32), and all except the 45 three error signals (SIGILL, SIGFPE and SIGSEGV) can be used. I 46 would suggest to use the upper 16 (17 - 32) which do not 47 have an assigned POSIX name. 45 Which CPU-interrupt will generate which signal is implementation defined. There 46 are 32 POSIX signals (1 - 32), and all except the three error signals (SIGILL, 47 SIGFPE and SIGSEGV) can be used. I would suggest to use the upper 16 (17 - 32) 48 which do not have an assigned POSIX name. 48 49 49 Note that the pragma interrupt_attach will only bind a signal 50 to a particular Ada handler - it will not unmask the51 i nterrupt or do any other things to enable it. This have to be52 done separately, typically by writing various deviceregister.50 Note that the pragma interrupt_attach will only bind a signal to a particular 51 Ada handler - it will not unmask the interrupt or do any other things to enable 52 it. This have to be done separately, typically by writing various device 53 register. 53 54 54 55 Example Ada95 Interrupt Program 55 56 =============================== 56 57 57 An example program (``irq_test``) is included in the 58 Ada examples package to show how interrupts can be handled 59 in Ada95. Note that generation of the test interrupt 60 (``irqforce.c``) is BSP specific and must be edited. 58 An example program (``irq_test``) is included in the Ada examples package to 59 show how interrupts can be handled in Ada95. Note that generation of the test 60 interrupt (``irqforce.c``) is BSP specific and must be edited. 61 61 62 NOTE: The ``irq_test`` example was written for the SPARC/ERC32 63 BSP. 62 .. note:: 63 64 The ``irq_test`` example was written for the SPARC/ERC32 BSP. 64 65 65 66 Version Requirements 66 67 ==================== 67 68 68 With RTEMS 4.0, a patch was required to psignal.c in RTEMS 69 sources (to correct a bug associated to the default action of 70 signals 15-32). The SPARC/ERC32RTEMS BSP includes the``gnatsupp`` subdirectory that can be used as an example69 With RTEMS 4.0, a patch was required to psignal.c in RTEMS sources (to correct 70 a bug associated to the default action of signals 15-32). The SPARC/ERC32 71 RTEMS BSP includes the``gnatsupp`` subdirectory that can be used as an example 71 72 for other BSPs. 72 73 73 With GNAT 3.11p, a patch is required for ``a-init.c`` to invoke 74 the BSP specific routine that installs the exception handlers. 75 76 .. COMMENT: COPYRIGHT (c) 1988-2008. 77 78 .. COMMENT: On-Line Applications Research Corporation (OAR). 79 80 .. COMMENT: All rights reserved. 81 74 With GNAT 3.11p, a patch is required for ``a-init.c`` to invoke the BSP 75 specific routine that installs the exception handlers. -
bsp_howto/analog.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Analog Driver 4 8 ############# 5 9 6 The Analog driver is responsible for providing an 7 interface to Digital to Analog Converters (DACs) and 8 Analog to Digital Converters (ADCs). The capabilities provided 9 by this class of device driver are: 10 The Analog driver is responsible for providing an interface to Digital to 11 Analog Converters (DACs) and Analog to Digital Converters (ADCs). The 12 capabilities provided by this class of device driver are: 10 13 11 14 - Initialize an Analog Board … … 23 26 - Reinitialize DACS 24 27 25 Most analog devices are found on I/O cards that support multiple 26 DACs or ADCson a single card.28 Most analog devices are found on I/O cards that support multiple DACs or ADCs 29 on a single card. 27 30 28 There are currently no analog device drivers included in the 29 RTEMS source tree. The information provided in this chapter 30 is based on drivers developed for applications using RTEMS. 31 It is hoped that this driver model information can form the 32 basis for a standard analog driver model that can be supported 33 in future RTEMS distribution. 31 There are currently no analog device drivers included in the RTEMS source tree. 32 The information provided in this chapter is based on drivers developed for 33 applications using RTEMS. It is hoped that this driver model information can 34 form the basis for a standard analog driver model that can be supported in 35 future RTEMS distribution. 34 36 35 37 Major and Minor Numbers 36 38 ======================= 37 39 38 The *major* number of a device driver is its index in the39 RTEMS DeviceAddress Table.40 The ``major`` number of a device driver is its index in the RTEMS Device 41 Address Table. 40 42 41 A *minor* number is associated with each device instance 42 managed by a particular device driver. An RTEMS minor number 43 is an ``unsigned32`` entity. Convention calls for 44 dividing the bits in the minor number down into categories 43 A ``minor`` number is associated with each device instance managed by a 44 particular device driver. An RTEMS minor number is an ``unsigned32`` entity. 45 Convention calls for dividing the bits in the minor number down into categories 45 46 like the following: 46 47 47 - *board*- indicates the board a particular device is located on48 - ``board`` - indicates the board a particular device is located on 48 49 49 - *port*- indicates the particular device on a board.50 - ``port`` - indicates the particular device on a board. 50 51 51 From the above, it should be clear that a single device driver 52 can support multiple copies of the same board in a single system. 53 The minor number is usedto distinguish the devices.52 From the above, it should be clear that a single device driver can support 53 multiple copies of the same board in a single system. The minor number is used 54 to distinguish the devices. 54 55 55 56 Analog Driver Configuration 56 57 =========================== 57 58 58 There is not a standard analog driver configuration table but some 59 fields are common across different drivers. The analog driver 60 configuration table is typically an array of structures with each 61 structure containing the information for a particular board. 62 The following is a list of the type of information normally required 63 to configure an analog board: 59 There is not a standard analog driver configuration table but some fields are 60 common across different drivers. The analog driver configuration table is 61 typically an array of structures with each structure containing the information 62 for a particular board. The following is a list of the type of information 63 normally required to configure an analog board: 64 64 65 *board_offset* 65 ``board_offset`` 66 66 is the base address of a board. 67 67 68 *DAC_initial_values* 69 is an array of the voltages that should be written to each DAC 70 during initialization. This allows the driver to start the board71 in a knownstate.68 ``DAC_initial_values`` 69 is an array of the voltages that should be written to each DAC during 70 initialization. This allows the driver to start the board in a known 71 state. 72 72 73 73 Initialize an Analog Board 74 74 ========================== 75 75 76 At system initialization, the analog driver's initialization entry point 77 will be invoked. As part of initialization, the driver will perform 78 whatever board initialization is required and then set all79 outputs to their configured initialstate.76 At system initialization, the analog driver's initialization entry point will 77 be invoked. As part of initialization, the driver will perform whatever board 78 initialization is required and then set all outputs to their configured initial 79 state. 80 80 81 The analog driver may register a device name for each DAC and ADC in 82 thesystem.81 The analog driver may register a device name for each DAC and ADC in the 82 system. 83 83 84 84 Open a Particular Analog … … 89 89 90 90 With some drivers, it may be necessary to allocate memory when a particular 91 device is opened. If that is the case, then this is often the place 92 to do thisoperation.91 device is opened. If that is the case, then this is often the place to do this 92 operation. 93 93 94 94 Close a Particular Analog … … 98 98 99 99 With some drivers, it may be necessary to allocate memory when a particular 100 device is opened. If that is the case, then this is the place 101 where thatmemory should be deallocated.100 device is opened. If that is the case, then this is the place where that 101 memory should be deallocated. 102 102 103 103 Read from a Particular Analog 104 104 ============================= 105 105 106 This corresponds to the driver read call. After validating the minor 107 number and arguments, this call reads the indicated device. Most analog 108 devices store the last value written to a DAC. Since DACs are output 109 only devices, saving the last written value gives the appearance that 110 DACs can be read from also.If the device is an ADC, then it is sampled.106 This corresponds to the driver read call. After validating the minor number 107 and arguments, this call reads the indicated device. Most analog devices store 108 the last value written to a DAC. Since DACs are output only devices, saving 109 the last written value gives the appearance that DACs can be read from also. 110 If the device is an ADC, then it is sampled. 111 111 112 *NOTE:* Many boards have multiple analog inputs but only one ADC. On 113 these boards, it will be necessary to provide some type of mutual exclusion 114 during reads. On these boards, there is a MUX which must be switched 115 before sampling the ADC. After the MUX is switched, the driver must 116 delay some short period of time (usually microseconds) before the 117 signal is stable and can be sampled. To make matters worse, some ADCs 118 cannot respond to wide voltage swings in a single sample. On these 119 ADCs, one must do two samples when the voltage swing is too large. 120 On a practical basis, this means that the driver usually ends up 121 double sampling the ADC on these systems. 112 .. note:: 122 113 123 The value returned is a single precision floating point number 124 representing the voltage read. This value is stored in the``argument_block`` passed in to the call. By returning the 125 voltage, the caller is freed from having to know the number of 126 bits in the analog and board dependent conversion algorithm. 114 Many boards have multiple analog inputs but only one ADC. On these boards, 115 it will be necessary to provide some type of mutual exclusion during reads. 116 On these boards, there is a MUX which must be switched before sampling the 117 ADC. After the MUX is switched, the driver must delay some short period of 118 time (usually microseconds) before the signal is stable and can be sampled. 119 To make matters worse, some ADCs cannot respond to wide voltage swings in a 120 single sample. On these ADCs, one must do two samples when the voltage 121 swing is too large. On a practical basis, this means that the driver 122 usually ends up double sampling the ADC on these systems. 123 124 The value returned is a single precision floating point number representing the 125 voltage read. This value is stored in the ``argument_block`` passed in to the 126 call. By returning the voltage, the caller is freed from having to know the 127 number of bits in the analog and board dependent conversion algorithm. 127 128 128 129 Write to a Particular Analog 129 130 ============================ 130 131 131 This corresponds to the driver write call. After validating the minor 132 number and arguments, this call writes the indicated device. If the133 specified deviceis an ADC, then an error is usually returned.132 This corresponds to the driver write call. After validating the minor number 133 and arguments, this call writes the indicated device. If the specified device 134 is an ADC, then an error is usually returned. 134 135 135 The value written is a single precision floating point number 136 representing the voltage to be written to the specified DAC. 137 This value is stored in the ``argument_block`` passed in to the 138 call. By passing the voltage to the device driver, the caller is 139 freed from having to know the number of bits in the analog 140 and board dependent conversion algorithm. 136 The value written is a single precision floating point number representing the 137 voltage to be written to the specified DAC. This value is stored in the 138 ``argument_block`` passed in to the call. By passing the voltage to the device 139 driver, the caller is freed from having to know the number of bits in the 140 analog and board dependent conversion algorithm. 141 141 142 142 Reset DACs 143 143 ========== 144 144 145 This is one of the IOCTL functions supported by the I/O control 146 device driver entry point. When this IOCTL function is invoked, 147 all of the DACs are writtento 0.0 volts.145 This is one of the IOCTL functions supported by the I/O control device driver 146 entry point. When this IOCTL function is invoked, all of the DACs are written 147 to 0.0 volts. 148 148 149 149 Reinitialize DACS 150 150 ================= 151 151 152 This is one of the IOCTL functions supported by the I/O control 153 device driver entry point. When this IOCTL function is invoked, 154 all of the DACs are written with the initial value configured 155 for this device. 152 This is one of the IOCTL functions supported by the I/O control device driver 153 entry point. When this IOCTL function is invoked, all of the DACs are written 154 with the initial value configured for this device. 156 155 157 156 Get Last Written Values 158 157 ======================= 159 158 160 This is one of the IOCTL functions supported by the I/O control 161 device driver entry point. When this IOCTL function is invoked, 162 the following information isreturned to the caller:159 This is one of the IOCTL functions supported by the I/O control device driver 160 entry point. When this IOCTL function is invoked, the following information is 161 returned to the caller: 163 162 164 163 - last value written to the specified DAC 165 164 166 165 - timestamp of when the last write was performed 167 168 .. COMMENT: COPYRIGHT (c) 1988-2002.169 170 .. COMMENT: On-Line Applications Research Corporation (OAR).171 172 .. COMMENT: All rights reserved.173 -
bsp_howto/ata.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 ATA Driver … … 12 16 ============ 13 17 14 ATA driver provides generic interface to an ATA device. ATA driver is 15 hardware independent implementation of ATA standard defined in working draft 16 "AT Attachment Interface with Extensions (ATA-2)" X3T10/0948D revision 4c, 17 March18, 1996. ATA Driver based on IDE Controller Driver and may be used for18 ATA driver provides generic interface to an ATA device. ATA driver is hardware 19 independent implementation of ATA standard defined in working draft "AT 20 Attachment Interface with Extensions (ATA-2)" X3T10/0948D revision 4c, March 21 18, 1996. ATA Driver based on IDE Controller Driver and may be used for 18 22 computer systems with single IDE controller and with multiple as well. Although 19 23 current implementation has several restrictions detailed below ATA driver … … 25 29 - Only PIO mode is supported but both poll and interrupt driven 26 30 27 The reference implementation for ATA driver can be found in``cpukit/libblock/src/ata.c``. 31 The reference implementation for ATA driver can be found in 32 ``cpukit/libblock/src/ata.c``. 28 33 29 34 Initialization … … 31 36 32 37 The ``ata_initialize`` routine is responsible for ATA driver 33 initialization. The main goal of the initialization is to detect and 34 register in the system all ATA devices attached to IDE controllers 35 successfullyinitialized by the IDE Controller driver.38 initialization. The main goal of the initialization is to detect and register 39 in the system all ATA devices attached to IDE controllers successfully 40 initialized by the IDE Controller driver. 36 41 37 42 In the implementation of the driver, the following actions are performed: 38 .. code:: c 43 44 .. code-block:: c 39 45 40 46 rtems_device_driver ata_initialize( 41 rtems_device_major_number major,42 rtems_device_minor_number minor,43 void \*arg47 rtems_device_major_number major, 48 rtems_device_minor_number minor, 49 void *arg 44 50 ) 45 51 { 46 initialize internal ATA driver data structure 47 for each IDE controller successfully initialized by the IDE Controller 48 driver 49 if the controller is interrupt driven 50 set up interrupt handler 51 obtain information about ATA devices attached to the controller 52 with help of EXECUTE DEVICE DIAGNOSTIC command 53 for each ATA device detected on the controller 54 obtain device parameters with help of DEVICE IDENTIFY command 55 register new ATA device as new block device in the system 52 initialize internal ATA driver data structure 53 54 for each IDE controller successfully initialized by the IDE Controller driver 55 if the controller is interrupt driven 56 set up interrupt handler 57 58 obtain information about ATA devices attached to the controller 59 with help of EXECUTE DEVICE DIAGNOSTIC command 60 61 for each ATA device detected on the controller 62 obtain device parameters with help of DEVICE IDENTIFY command 63 64 register new ATA device as new block device in the system 56 65 } 57 66 … … 62 71 (see libblock library description). Device names are formed based on IDE 63 72 controller minor number device is attached to and device number on the 64 controller (0 - Master, 1 - Slave). In current implementation 64 minor 65 numbers are reserved for each ATA device which allows to support up to 63 66 logical partitions per device. 67 .. code:: c 73 controller (0 - Master, 1 - Slave). In current implementation 64 minor numbers 74 are reserved for each ATA device which allows to support up to 63 logical 75 partitions per device. 68 76 69 controller minor device number device name ata device minor 70 0 0 hda 0 71 0 1 hdb 64 72 1 0 hdc 128 73 1 1 hdd 172 74 ... ... ... 77 ================ ============= =========== ================ 78 controller minor device number device name ata device minor 79 ================ ============= =========== ================ 80 0 0 hda 0 81 0 1 hdb 64 82 1 0 hdc 128 83 1 1 hdd 172 84 ... ... ... ... 85 ================ ============= =========== ================ 75 86 76 87 ATA Driver Architecture … … 80 91 ---------------------------------------- 81 92 82 ATA driver works with ATA requests. ATA request is described by the 83 following structure: 84 .. code:: c 93 ATA driver works with ATA requests. ATA request is described by the following 94 structure: 85 95 86 /* ATA request \*/ 96 .. code-block:: c 97 98 /* ATA request */ 87 99 typedef struct ata_req_s { 88 Chain_Node link; /* link in requests chain \*/ 89 char type; /* request type \*/ 90 ata_registers_t regs; /* ATA command \*/ 91 uint32_t cnt; /* Number of sectors to be exchanged \*/ 92 uint32_t cbuf; /* number of current buffer from breq in use \*/ 93 uint32_t pos; /* current position in 'cbuf' \*/ 94 blkdev_request \*breq; /* blkdev_request which corresponds to the 95 * ata request 96 \*/ 97 rtems_id sema; /* semaphore which is used if synchronous 98 * processing of the ata request is required 99 \*/ 100 rtems_status_code status; /* status of ata request processing \*/ 101 int error; /* error code \*/ 100 Chain_Node link; /* link in requests chain */ 101 char type; /* request type */ 102 ata_registers_t regs; /* ATA command */ 103 uint32_t cnt; /* Number of sectors to be exchanged */ 104 uint32_t cbuf; /* number of current buffer from breq in use */ 105 uint32_t pos; /* current position in 'cbuf' */ 106 blkdev_request *breq; /* blkdev_request which corresponds to the ata request */ 107 rtems_id sema; /* semaphore which is used if synchronous 108 * processing of the ata request is required */ 109 rtems_status_code status; /* status of ata request processing */ 110 int error; /* error code */ 102 111 } ata_req_t; 103 112 104 ATA driver supports separate ATA requests queues for each IDE 105 controller (one queue per controller). The following structure contains 106 information about controller's queue and devices attached to the controller: 107 .. code:: c 113 ATA driver supports separate ATA requests queues for each IDE controller (one 114 queue per controller). The following structure contains information about 115 controller's queue and devices attached to the controller: 116 117 .. code-block:: c 108 118 109 119 /* 110 * This structure describes controller state, devices configuration on the111 * controller and chain of ATA requests to the controller.112 \*/120 * This structure describes controller state, devices configuration on the 121 * controller and chain of ATA requests to the controller. 122 */ 113 123 typedef struct ata_ide_ctrl_s { 114 bool present; /* controller state \*/115 ata_dev_t device[2]; /* ata devices description \*/116 Chain_Control reqs; /* requests chain \*/124 bool present; /* controller state */ 125 ata_dev_t device[2]; /* ata devices description */ 126 Chain_Control reqs; /* requests chain */ 117 127 } ata_ide_ctrl_t; 118 128 119 Driver uses array of the structures indexed by the controllers minor 120 number. 129 Driver uses array of the structures indexed by the controllers minor number. 121 130 122 The following structure allows to map an ATA device to the pair (IDE 123 controller minor number device is attached to, device number 124 on the controller): 125 .. code :: c131 The following structure allows to map an ATA device to the pair (IDE controller 132 minor number device is attached to, device number on the controller): 133 134 .. code-block:: c 126 135 127 136 /* 128 * Mapping of rtems ATA devices to the following pairs:129 * (IDE controller number served the device, device number on the controller)130 \*/137 * Mapping of rtems ATA devices to the following pairs: 138 * (IDE controller number served the device, device number on the controller) 139 */ 131 140 typedef struct ata_ide_dev_s { 132 int ctrl_minor;/* minor number of IDE controller serves rtems ATA device \*/133 int device; /* device number on IDE controller (0 or 1) \*/141 int ctrl_minor;/* minor number of IDE controller serves rtems ATA device */ 142 int device; /* device number on IDE controller (0 or 1) */ 134 143 } ata_ide_dev_t; 135 144 136 Driver uses array of the structures indexed by the ATA devices minor 137 number. 145 Driver uses array of the structures indexed by the ATA devices minor number. 138 146 139 147 ATA driver defines the following internal events: 140 .. code:: c141 148 142 /* ATA driver events \*/ 149 .. code-block:: c 150 151 /* ATA driver events */ 143 152 typedef enum ata_msg_type_s { 144 ATA_MSG_GEN_EVT = 1, /* general event \*/145 ATA_MSG_SUCCESS_EVT, /* success event \*/146 ATA_MSG_ERROR_EVT, /* error event \*/147 ATA_MSG_PROCESS_NEXT_EVT /* process next ata request event \*/153 ATA_MSG_GEN_EVT = 1, /* general event */ 154 ATA_MSG_SUCCESS_EVT, /* success event */ 155 ATA_MSG_ERROR_EVT, /* error event */ 156 ATA_MSG_PROCESS_NEXT_EVT /* process next ata request event */ 148 157 } ata_msg_type_t; 149 158 … … 152 161 153 162 All ATA driver functionality is available via ATA driver ioctl. Current 154 implementation supports only two ioctls: BLKIO_REQUESTand155 ATAIO_SET_MULTIPLE_MODE. Each ATA driver ioctl() call generates an 156 ATA request which is appended to the appropriate controller queue depending 157 on ATA device the request belongs to. If appended request is single request in 158 thecontroller's queue then ATA driver event is generated.163 implementation supports only two ioctls: ``BLKIO_REQUEST`` and 164 ``ATAIO_SET_MULTIPLE_MODE``. Each ATA driver ``ioctl()`` call generates an ATA 165 request which is appended to the appropriate controller queue depending on ATA 166 device the request belongs to. If appended request is single request in the 167 controller's queue then ATA driver event is generated. 159 168 160 169 ATA driver task which manages queue of ATA driver events is core of ATA 161 driver. In current driver version queue of ATA driver events implemented 162 as RTEMS message queue. Each message contains event type, IDE controller 163 minor number on which event happened and error if an error occurred. Events 164 may be generated either by ATA driver ioctl call or by ATA driver task itself. 165 Each time ATA driver task receives an event it gets controller minor number 166 from event, takes first ATA request from controller queue and processes it 167 depending on request and event types. An ATA request processing may also 168 includes sending of several events. If ATA request processing is finished 169 the ATA request is removed from the controller queue. Note, that in current 170 implementation maximum one event per controller may be queued at any moment 171 of the time. 170 driver. In current driver version queue of ATA driver events implemented as 171 RTEMS message queue. Each message contains event type, IDE controller minor 172 number on which event happened and error if an error occurred. Events may be 173 generated either by ATA driver ioctl call or by ATA driver task itself. Each 174 time ATA driver task receives an event it gets controller minor number from 175 event, takes first ATA request from controller queue and processes it depending 176 on request and event types. An ATA request processing may also includes sending 177 of several events. If ATA request processing is finished the ATA request is 178 removed from the controller queue. Note, that in current implementation maximum 179 one event per controller may be queued at any moment of the time. 172 180 173 181 (This part seems not very clear, hope I rewrite it soon) 174 175 .. COMMENT: COPYRIGHT (c) 1988-2002.176 177 .. COMMENT: On-Line Applications Research Corporation (OAR).178 179 .. COMMENT: All rights reserved.180 -
bsp_howto/clock.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Clock Driver … … 10 14 system. 11 15 12 - A steady time basis to the kernel, so that the RTEMS primitives that need 13 a clock tick work properly. See the *Clock Manager* chapter of the*RTEMS Application C User's Guide* for more details. 14 15 - An optional time counter to generate timestamps of the uptime and wall 16 clock time. 16 - A steady time basis to the kernel, so that the RTEMS primitives that need a 17 clock tick work properly. See the *Clock Manager* chapter of the *RTEMS 18 Application C User's Guide* for more details. 19 20 - An optional time counter to generate timestamps of the uptime and wall clock 21 time. 17 22 18 23 The clock driver is usually located in the :file:`clock` directory of the BSP. 19 Clock drivers should use the :dfn:`Clock Driver Shell` available via the:file:`clockdrv_shell.h` include file. 24 Clock drivers should use the :dfn:`Clock Driver Shell` available via the 25 :file:`clockdrv_shell.h` include file. 20 26 21 27 Clock Driver Shell … … 30 36 functions, defines and macros for the :dfn:`Clock Driver Shell` which are 31 37 explained here step by step. A clock driver file looks in general like this. 32 .. code:: c 38 39 .. code-block:: c 33 40 34 41 /* 35 * A section with functions, defines and macros to provide hardware specific36 * functions for the Clock Driver Shell.37 \*/42 * A section with functions, defines and macros to provide hardware specific 43 * functions for the Clock Driver Shell. 44 */ 38 45 #include "../../../shared/clockdrv_shell.h" 39 46 … … 46 53 - The most basic clock driver provides only a periodic interrupt service 47 54 routine which calls ``rtems_clock_tick()``. The interval is determined by 48 the application configuration via ``#define 49 CONFIGURE_MICROSECONDS_PER_TICK`` and can be obtained via``rtems_configuration_get_microseconds_per_tick()``. The timestamp50 resolution is limited to the clock tick interval.55 the application configuration via ``#define CONFIGURE_MICROSECONDS_PER_TICK`` 56 and can be obtained via ``rtems_configuration_get_microseconds_per_tick()``. 57 The timestamp resolution is limited to the clock tick interval. 51 58 52 59 - In case the hardware lacks support for a free running counter, then the … … 61 68 ~~~~~~~~~~~~~~~~~~~~~~~ 62 69 63 .. code :: c70 .. code-block:: c 64 71 65 72 static void some_support_initialize_hardware( void ) 66 73 { 67 /* Initialize hardware \*/ 68 } 69 #define Clock_driver_support_initialize_hardware() \\ 70 some_support_initialize_hardware() 71 /* Indicate that this clock driver lacks a proper timecounter in hardware \*/ 74 /* Initialize hardware */ 75 } 76 77 #define Clock_driver_support_initialize_hardware() \ 78 some_support_initialize_hardware() 79 80 /* Indicate that this clock driver lacks a proper timecounter in hardware */ 81 72 82 #define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER 83 73 84 #include "../../../shared/clockdrv_shell.h" 74 85 … … 76 87 ~~~~~~~~~~~~~~~~~~~~~~~~~~ 77 88 78 .. code :: c89 .. code-block:: c 79 90 80 91 #include <rtems/timecounter.h> 92 81 93 static rtems_timecounter_simple some_tc; 82 static uint32_t some_tc_get( rtems_timecounter_simple \*tc ) 83 { 84 return some.counter; 85 } 86 static bool some_tc_is_pending( rtems_timecounter_simple \*tc ) 87 { 88 return some.is_pending; 89 } 90 static uint32_t some_tc_get_timecount( struct timecounter \*tc ) 91 { 92 return rtems_timecounter_simple_downcounter_get( 93 tc, 94 some_tc_get, 95 some_tc_is_pending 96 ); 97 } 94 95 static uint32_t some_tc_get( rtems_timecounter_simple *tc ) 96 { 97 return some.counter; 98 } 99 100 static bool some_tc_is_pending( rtems_timecounter_simple *tc ) 101 { 102 return some.is_pending; 103 } 104 105 static uint32_t some_tc_get_timecount( struct timecounter *tc ) 106 { 107 return rtems_timecounter_simple_downcounter_get( 108 tc, 109 some_tc_get, 110 some_tc_is_pending 111 ); 112 } 113 98 114 static void some_tc_tick( void ) 99 115 { 100 rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get ); 101 } 116 rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get ); 117 } 118 102 119 static void some_support_initialize_hardware( void ) 103 120 { 104 uint32_t frequency = 123456; 105 uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); 106 uint32_t timecounter_ticks_per_clock_tick = 107 ( frequency * us_per_tick ) / 1000000; 108 /* Initialize hardware \*/ 109 rtems_timecounter_simple_install( 110 &some_tc, 111 frequency, 112 timecounter_ticks_per_clock_tick, 113 some_tc_get_timecount 114 ); 115 } 116 #define Clock_driver_support_initialize_hardware() \\ 117 some_support_initialize_hardware() 118 #define Clock_driver_timecounter_tick() \\ 119 some_tc_tick() 121 uint32_t frequency = 123456; 122 uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); 123 uint32_t timecounter_ticks_per_clock_tick = 124 ( frequency * us_per_tick ) / 1000000; 125 126 /* Initialize hardware */ 127 rtems_timecounter_simple_install( 128 &some_tc, 129 frequency, 130 timecounter_ticks_per_clock_tick, 131 some_tc_get_timecount 132 ); 133 } 134 135 #define Clock_driver_support_initialize_hardware() \ 136 some_support_initialize_hardware() 137 #define Clock_driver_timecounter_tick() \ 138 some_tc_tick() 139 120 140 #include "../../../shared/clockdrv_shell.h" 121 141 … … 127 147 valid timestamps. The hardware must provide a periodic interrupt to service 128 148 the clock tick and a free running counter for the timecounter. The free 129 running counter must have a power of two period. The ``tc_counter_mask`` 130 must be initialized to the free running counter period minus one, e.g. for a 131 32-bit counter this is 0xffffffff. The ``tc_get_timecount`` function must 132 return the current counter value (the counter values must increase, so if the 133 counter counts down, a conversion is necessary). Use``RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER`` for the ``tc_quality``. Set``tc_frequency`` to the frequency of the free running counter in Hz. All 134 other fields of the ``struct timecounter`` must be zero initialized. 135 Install the initialized timecounter via ``rtems_timecounter_install()``. 136 .. code:: c 149 running counter must have a power of two period. The ``tc_counter_mask`` must 150 be initialized to the free running counter period minus one, e.g. for a 32-bit 151 counter this is 0xffffffff. The ``tc_get_timecount`` function must return the 152 current counter value (the counter values must increase, so if the counter 153 counts down, a conversion is necessary). Use 154 ``RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER`` for the ``tc_quality``. Set 155 ``tc_frequency`` to the frequency of the free running counter in Hz. All other 156 fields of the ``struct timecounter`` must be zero initialized. Install the 157 initialized timecounter via ``rtems_timecounter_install()``. 158 159 .. code-block:: c 137 160 138 161 #include <rtems/timecounter.h> 162 139 163 static struct timecounter some_tc; 140 static uint32_t some_tc_get_timecount( struct timecounter \*tc ) 141 { 142 some.free_running_counter; 143 } 164 165 static uint32_t some_tc_get_timecount( struct timecounter *tc ) 166 { 167 some.free_running_counter; 168 } 169 144 170 static void some_support_initialize_hardware( void ) 145 171 { 146 uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); 147 uint32_t frequency = 123456; 148 /* 149 * The multiplication must be done in 64-bit arithmetic to avoid an integer 150 * overflow on targets with a high enough counter frequency. 151 \*/ 152 uint32_t interval = (uint32_t) ( ( frequency * us_per_tick ) / 1000000 ); 153 /* 154 * Initialize hardware and set up a periodic interrupt for the configuration 155 * based interval. 156 \*/ 157 some_tc.tc_get_timecount = some_tc_get_timecount; 158 some_tc.tc_counter_mask = 0xffffffff; 159 some_tc.tc_frequency = frequency; 160 some_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; 161 rtems_timecounter_install( &some_tc ); 162 } 163 #define Clock_driver_support_initialize_hardware() \\ 164 some_support_initialize_hardware() 172 uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); 173 uint32_t frequency = 123456; 174 175 /* 176 * The multiplication must be done in 64-bit arithmetic to avoid an integer 177 * overflow on targets with a high enough counter frequency. 178 */ 179 uint32_t interval = (uint32_t) ( ( frequency * us_per_tick ) / 1000000 ); 180 181 /* 182 * Initialize hardware and set up a periodic interrupt for the configuration 183 * based interval. 184 */ 185 some_tc.tc_get_timecount = some_tc_get_timecount; 186 some_tc.tc_counter_mask = 0xffffffff; 187 some_tc.tc_frequency = frequency; 188 some_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; 189 rtems_timecounter_install( &some_tc ); 190 } 191 192 #define Clock_driver_support_initialize_hardware() \ 193 some_support_initialize_hardware() 194 165 195 #include "../../../shared/clockdrv_shell.h" 166 196 … … 170 200 The clock driver must provide a function to install the clock tick interrupt 171 201 service routine via ``Clock_driver_support_install_isr()``. 172 .. code:: c 202 203 .. code-block:: c 173 204 174 205 #include <bsp/irq.h> 175 206 #include <bsp/fatal.h> 207 176 208 static void some_support_install_isr( rtems_interrupt_handler isr ) 177 209 { 178 rtems_status_code sc; 179 sc = rtems_interrupt_handler_install( 180 SOME_IRQ, 181 "Clock", 182 RTEMS_INTERRUPT_UNIQUE, 183 isr, 184 NULL 185 ); 186 if ( sc != RTEMS_SUCCESSFUL ) { 187 bsp_fatal( SOME_FATAL_IRQ_INSTALL ); 188 } 189 } 190 #define Clock_driver_support_install_isr( isr, old ) \\ 191 some_support_install_isr( isr ) 210 rtems_status_code sc; 211 sc = rtems_interrupt_handler_install( 212 SOME_IRQ, 213 "Clock", 214 RTEMS_INTERRUPT_UNIQUE, 215 isr, 216 NULL 217 ); 218 if ( sc != RTEMS_SUCCESSFUL ) { 219 bsp_fatal( SOME_FATAL_IRQ_INSTALL ); 220 } 221 } 222 223 #define Clock_driver_support_install_isr( isr, old ) \ 224 some_support_install_isr( isr ) 225 192 226 #include "../../../shared/clockdrv_shell.h" 193 227 … … 195 229 --------------- 196 230 197 The hardware specific support at tick is specified by``Clock_driver_support_at_tick()``. 198 .. code:: c 231 The hardware specific support at tick is specified by 232 ``Clock_driver_support_at_tick()``. 233 234 .. code-block:: c 199 235 200 236 static void some_support_at_tick( void ) 201 237 { 202 /* Clear interrupt \*/ 203 } 204 #define Clock_driver_support_at_tick() \\ 205 some_support_at_tick() 238 /* Clear interrupt */ 239 } 240 241 #define Clock_driver_support_at_tick() \ 242 some_support_at_tick() 243 206 244 #include "../../../shared/clockdrv_shell.h" 207 245 … … 210 248 211 249 The :dfn:`Clock Driver Shell` provides the routine ``Clock_exit()`` that is 212 scheduled to be run during system shutdown via the ``atexit()`` routine. 213 The hardware specific shutdown support is specified by``Clock_driver_support_shutdown_hardware()`` which is used by``Clock_exit()``. It should disable the clock tick source if it was 214 enabled. This can be used to prevent clock ticks after the system is shutdown. 215 .. code:: c 250 scheduled to be run during system shutdown via the ``atexit()`` routine. The 251 hardware specific shutdown support is specified by 252 ``Clock_driver_support_shutdown_hardware()`` which is used by ``Clock_exit()``. 253 It should disable the clock tick source if it was enabled. This can be used to 254 prevent clock ticks after the system is shutdown. 255 256 .. code-block:: c 216 257 217 258 static void some_support_shutdown_hardware( void ) 218 259 { 219 /* Shutdown hardware \*/ 220 } 221 #define Clock_driver_support_shutdown_hardware() \\ 222 some_support_shutdown_hardware() 260 /* Shutdown hardware */ 261 } 262 263 #define Clock_driver_support_shutdown_hardware() \ 264 some_support_shutdown_hardware() 265 223 266 #include "../../../shared/clockdrv_shell.h" 224 267 … … 229 272 due to a limited range of the hardware timer), then this can be specified with 230 273 the optional ``#define CLOCK_DRIVER_ISRS_PER_TICK`` and ``#define 231 CLOCK_DRIVER_ISRS_PER_TICK_VALUE`` defines. This is currently used only for x86 232 and it hopefully remains that way. 233 .. code:: c 234 235 /* Enable multiple clock driver ticks per clock tick \*/ 274 CLOCK_DRIVER_ISRS_PER_TICK_VALUE`` defines. This is currently used only for 275 x86 and it hopefully remains that way. 276 277 .. code-block:: c 278 279 /* Enable multiple clock driver ticks per clock tick */ 236 280 #define CLOCK_DRIVER_ISRS_PER_TICK 1 237 /* Specifiy the clock driver ticks per clock tick value \*/ 281 282 /* Specifiy the clock driver ticks per clock tick value */ 238 283 #define CLOCK_DRIVER_ISRS_PER_TICK_VALUE 123 284 239 285 #include "../../../shared/clockdrv_shell.h" 240 286 … … 246 292 This information is valuable when debugging a system. This variable is 247 293 declared as follows: 248 .. code:: c 294 295 .. code-block:: c 249 296 250 297 volatile uint32_t Clock_driver_ticks; 251 252 .. COMMENT: COPYRIGHT (c) 1988-2002.253 254 .. COMMENT: On-Line Applications Research Corporation (OAR).255 256 .. COMMENT: All rights reserved.257 -
bsp_howto/conf.py
r54514fe r6d7a4d2 4 4 from conf import * 5 5 6 version = '1.0' 7 release = '5.0' 6 version = '4.11.0' 7 release = '4.11.0' 8 9 project = "RTEMS BSP and Device Driver Development Guide" 8 10 9 11 latex_documents = [ 10 ('index', 'bsp_howto.tex', u'RTEMS BSP Howto Documentation', u'RTEMS Documentation Project', 'manual'),12 ('index', 'bsp_howto.tex', u'RTEMS BSP and Device Driver Development Guide', u'RTEMS Documentation Project', 'manual'), 11 13 ] 12 -
bsp_howto/console.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Console Driver … … 7 11 ============ 8 12 9 This chapter describes the operation of a console driver using 10 the RTEMS POSIX Termios support. Traditionally RTEMS has referred 11 to all serial device drivers as console device drivers. A 12 console driver can be used to do raw data processing in addition 13 to the "normal" standard input and output device functions required 14 of a console. 15 16 The serial driver may be called as the consequence of a C Library 17 call such as ``printf`` or ``scanf`` or directly via the``read`` or ``write`` system calls. 13 This chapter describes the operation of a console driver using the RTEMS POSIX 14 Termios support. Traditionally RTEMS has referred to all serial device drivers 15 as console device drivers. A console driver can be used to do raw data 16 processing in addition to the "normal" standard input and output device 17 functions required of a console. 18 19 The serial driver may be called as the consequence of a C Library call such as 20 ``printf`` or ``scanf`` or directly via the``read`` or ``write`` system calls. 18 21 There are two main functioning modes: 19 22 20 - console: formatted input/output, with special characters (end of 21 line,tabulations, etc.) recognition and processing,23 - console: formatted input/output, with special characters (end of line, 24 tabulations, etc.) recognition and processing, 22 25 23 26 - raw: permits raw data processing. 24 27 25 One may think that two serial drivers are needed to handle these two types 26 ofdata, but Termios permits having only one driver.28 One may think that two serial drivers are needed to handle these two types of 29 data, but Termios permits having only one driver. 27 30 28 31 Termios 29 32 ======= 30 33 31 Termios is a standard for terminal management, included in the POSIX 32 1003.1b standard. As part of the POSIX and Open Group Single UNIX 33 Specification, is commonly provided on UNIX implementations. The 34 Open Group has the termios portion of the POSIX standard online 35 at http://opengroup.org/onlinepubs/007908775/xbd/termios.html. 36 The requirements for the ``<termios.h>`` file are also provided 37 and are athttp://opengroup.org/onlinepubs/007908775/xsh/termios.h.html.34 Termios is a standard for terminal management, included in the POSIX 1003.1b 35 standard. As part of the POSIX and Open Group Single UNIX Specification, is 36 commonly provided on UNIX implementations. The Open Group has the termios 37 portion of the POSIX standard online at 38 http://opengroup.org/onlinepubs/007908775/xbd/termios.html. The requirements 39 for the ``<termios.h>`` file are also provided and are at 40 http://opengroup.org/onlinepubs/007908775/xsh/termios.h.html. 38 41 39 42 Having RTEMS support for Termios is beneficial because: 40 43 41 - from the user's side because it provides standard primitive operations 42 to access the terminal and change configuration settings. These operations 43 are the same under UNIX and RTEMS. 44 45 - from the BSP developer's side because it frees the 46 developer from dealing with buffer states and mutual exclusions on them. 47 Early RTEMS console device drivers also did their own special 48 character processing. 44 - from the user's side because it provides standard primitive operations to 45 access the terminal and change configuration settings. These operations are 46 the same under UNIX and RTEMS. 47 48 - from the BSP developer's side because it frees the developer from dealing 49 with buffer states and mutual exclusions on them. Early RTEMS console device 50 drivers also did their own special character processing. 49 51 50 52 - it is part of an internationally recognized standard. … … 56 58 - raw and console handling, 57 59 58 - blocking or non-blocking characters receive, with or without 59 Timeout. 60 61 At this time, RTEMS documentation does not include a thorough discussion 62 of the Termios functionality. For more information on Termios, 63 type ``man termios`` on a Unix box or point a web browser 64 athttp://www.freebsd.org/cgi/man.cgi. 60 - blocking or non-blocking characters receive, with or without Timeout. 61 62 At this time, RTEMS documentation does not include a thorough discussion of the 63 Termios functionality. For more information on Termios, type ``man termios`` 64 on a Unix box or point a web browser athttp://www.freebsd.org/cgi/man.cgi. 65 65 66 66 Driver Functioning Modes … … 76 76 - task driven mode 77 77 78 In polled mode, the processor blocks on sending/receiving characters. 79 This mode is not the most efficient way to utilize the UART. But 80 polled mode is usually necessary when one wants to print an 81 error message in the event of a fatal error such as a fatal error 82 in the BSP. This is also the simplest mode to 83 program. Polled mode is generally preferred if the serial port is 84 to be used primarily as a debug console. In a simple polled driver, 85 the software will continuously check the status of the UART when 86 it is reading or writing to the UART. Termios improves on this 87 by delaying the caller for 1 clock tick between successive checks 88 of the UART on a read operation. 78 In polled mode, the processor blocks on sending/receiving characters. This 79 mode is not the most efficient way to utilize the UART. But polled mode is 80 usually necessary when one wants to print an error message in the event of a 81 fatal error such as a fatal error in the BSP. This is also the simplest mode 82 to program. Polled mode is generally preferred if the serial port is to be 83 used primarily as a debug console. In a simple polled driver, the software 84 will continuously check the status of the UART when it is reading or writing to 85 the UART. Termios improves on this by delaying the caller for 1 clock tick 86 between successive checks of the UART on a read operation. 89 87 90 88 In interrupt driven mode, the processor does not block on sending/receiving 91 characters. Data is buffered between the interrupt service routine 92 and application code. Two buffers are used to insulate the application 93 from the relative slowness of the serial device. One of the buffers is 94 used for incoming characters, while the other is used for outgoing characters. 95 96 An interrupt is raised when a character is received by the UART. 97 The interrupt subroutine places the incoming character at the end 98 of the input buffer. When an application asks for input, 99 the characters at the front of the buffer are returned. 100 101 When the application prints to the serial device, the outgoing characters 102 are placed at the end of the output buffer. The driver will place 103 one or more characters in the UART (the exact number depends on the UART) 104 An interrupt will be raised when all the characters have been transmitted. 105 The interrupt service routine has to send the characters 106 remaining in the output buffer the same way. When the transmitting side 107 of the UART is idle, it is typically necessary to prime the transmitter 108 before the first interrupt will occur. 89 characters. Data is buffered between the interrupt service routine and 90 application code. Two buffers are used to insulate the application from the 91 relative slowness of the serial device. One of the buffers is used for 92 incoming characters, while the other is used for outgoing characters. 93 94 An interrupt is raised when a character is received by the UART. The interrupt 95 subroutine places the incoming character at the end of the input buffer. When 96 an application asks for input, the characters at the front of the buffer are 97 returned. 98 99 When the application prints to the serial device, the outgoing characters are 100 placed at the end of the output buffer. The driver will place one or more 101 characters in the UART (the exact number depends on the UART) An interrupt will 102 be raised when all the characters have been transmitted. The interrupt service 103 routine has to send the characters remaining in the output buffer the same way. 104 When the transmitting side of the UART is idle, it is typically necessary to 105 prime the transmitter before the first interrupt will occur. 109 106 110 107 The task driven mode is similar to interrupt driven mode, but the actual data … … 114 111 ================================== 115 112 116 The following Figure shows how a Termios driven serial driver works: 117 Figure notincluded in ASCII version113 The following Figure shows how a Termios driven serial driver works: Figure not 114 included in ASCII version 118 115 119 116 The following list describes the basic flow. 120 117 121 - the application programmer uses standard C library call (printf, 122 scanf, read, write, etc.), 123 124 - C library (ctx.g. RedHat (formerly Cygnus) Newlib) calls 125 the RTEMS system call interface. This code can be found in the:file:`cpukit/libcsupport/src` directory. 118 - the application programmer uses standard C library call (printf, scanf, read, 119 write, etc.), 120 121 - C library (ctx.g. RedHat (formerly Cygnus) Newlib) calls the RTEMS system 122 call interface. This code can be found in the:file:`cpukit/libcsupport/src` 123 directory. 126 124 127 125 - Glue code calls the serial driver entry routines. … … 134 132 functions are deprecated: 135 133 136 - ``rtems_termios_open()`` - use ``rtems_termios_device_open()`` in 137 combination with ``rtems_termios_device_install()`` instead. 138 139 - ``rtems_termios_close()`` - use ``rtems_termios_device_close()`` 140 instead. 134 - ``rtems_termios_open()`` - use ``rtems_termios_device_open()`` in combination 135 with ``rtems_termios_device_install()`` instead. 136 137 - ``rtems_termios_close()`` - use ``rtems_termios_device_close()`` instead. 141 138 142 139 This manual describes the new API. A new console driver should consist of 143 140 three parts. 144 141 145 # The basic console driver functions using the Termios support. Add this 146 theBSPs Makefile.am:147 148 .. code:: c 142 - The basic console driver functions using the Termios support. Add this the 143 BSPs Makefile.am: 144 145 .. code-block:: makefile 149 146 150 147 [...] 151 148 libbsp_a_SOURCES += ../../shared/console-termios.c 152 \[...]153 154 # A general serial module specific low-level driver providing the handler 155 table for the Termios ``rtems_termios_device_install()`` function. This156 low-leveldriver could be used for more than one BSP.157 158 # A BSP specific initialization routine ``console_initialize()``, that 159 calls ``rtems_termios_device_install()`` providing a low-level driver160 context foreach installed device.149 [...] 150 151 - A general serial module specific low-level driver providing the handler table 152 for the Termios ``rtems_termios_device_install()`` function. This low-level 153 driver could be used for more than one BSP. 154 155 - A BSP specific initialization routine ``console_initialize()``, that calls 156 ``rtems_termios_device_install()`` providing a low-level driver context for 157 each installed device. 161 158 162 159 You need to provide a device handler structure for the Termios device … … 168 165 If you want to use polled IO it should look like the following. Termios must 169 166 be told the addresses of the handler that are to be used for simple character 170 IO, i.e. pointers to the ``my_driver_poll_read()`` and``my_driver_poll_write()`` functions described later in `Termios and Polled IO`_. 171 172 .. code:: c 167 IO, i.e. pointers to the ``my_driver_poll_read()`` and 168 ``my_driver_poll_write()`` functions described later in `Termios and Polled 169 IO`_. 170 171 .. code-block:: c 173 172 174 173 const rtems_termios_handler my_driver_handler_polled = { 175 .first_open = my_driver_first_open,176 .last_close = my_driver_last_close,177 .poll_read = my_driver_poll_read,178 .write = my_driver_poll_write,179 .set_attributes = my_driver_set_attributes,180 .stop_remote_tx = NULL,181 .start_remote_tx = NULL,182 .mode = TERMIOS_POLLED174 .first_open = my_driver_first_open, 175 .last_close = my_driver_last_close, 176 .poll_read = my_driver_poll_read, 177 .write = my_driver_poll_write, 178 .set_attributes = my_driver_set_attributes, 179 .stop_remote_tx = NULL, 180 .start_remote_tx = NULL, 181 .mode = TERMIOS_POLLED 183 182 } 184 183 … … 187 186 handler to be passed to Termios. Indeed a ``console_read()`` call returns the 188 187 contents of Termios input buffer. This buffer is filled in the driver 189 interrupt subroutine, see also `Termios and Interrupt Driven IO`_. The driver 190 is responsible for providing a pointer to the``my_driver_interrupt_write()`` function. 191 192 .. code:: c 188 interrupt subroutine, see also `Termios and Interrupt Driven IO`_. The driver 189 is responsible for providing a pointer to the``my_driver_interrupt_write()`` 190 function. 191 192 .. code-block:: c 193 193 194 194 const rtems_termios_handler my_driver_handler_interrupt = { 195 .first_open = my_driver_first_open,196 .last_close = my_driver_last_close,197 .poll_read = NULL,198 .write = my_driver_interrupt_write,199 .set_attributes = my_driver_set_attributes,200 .stopRemoteTx = NULL,201 .stop_remote_tx = NULL,202 .start_remote_tx = NULL,203 .mode = TERMIOS_IRQ_DRIVEN195 .first_open = my_driver_first_open, 196 .last_close = my_driver_last_close, 197 .poll_read = NULL, 198 .write = my_driver_interrupt_write, 199 .set_attributes = my_driver_set_attributes, 200 .stopRemoteTx = NULL, 201 .stop_remote_tx = NULL, 202 .start_remote_tx = NULL, 203 .mode = TERMIOS_IRQ_DRIVEN 204 204 }; 205 205 206 You can also provide hander for remote transmission control. This 207 is not covered in this manual, so they are set to ``NULL`` in the above 208 examples. 206 You can also provide hander for remote transmission control. This is not 207 covered in this manual, so they are set to ``NULL`` in the above examples. 209 208 210 209 The low-level driver should provide a data structure for its device context. 211 The initialization routine must provide a context for each installed device via``rtems_termios_device_install()``. For simplicity of the console 212 initialization example the device name is also present. Her is an example header file. 213 .. code:: c 210 The initialization routine must provide a context for each installed device via 211 ``rtems_termios_device_install()``. For simplicity of the console 212 initialization example the device name is also present. Here is an example 213 header file. 214 215 .. code-block:: c 214 216 215 217 #ifndef MY_DRIVER_H 216 218 #define MY_DRIVER_H 219 217 220 #include <rtems/termiostypes.h> 218 221 #include <some-chip-header.h> 222 219 223 /* Low-level driver specific data structure \*/ 220 224 typedef struct { 221 rtems_termios_device_context base;222 const char \*device_name;223 volatile module_register_block \*regs;224 /* More stuff \*/225 rtems_termios_device_context base; 226 const char \*device_name; 227 volatile module_register_block \*regs; 228 /* More stuff \*/ 225 229 } my_driver_context; 230 226 231 extern const rtems_termios_handler my_driver_handler_polled; 227 232 extern const rtems_termios_handler my_driver_handler_interrupt; 233 228 234 #endif /* MY_DRIVER_H \*/ 229 230 235 231 236 Termios and Polled IO … … 237 242 The ``my_driver_poll_write()`` routine is responsible for writing ``n`` 238 243 characters from ``buf`` to the serial device specified by ``tty``. 239 .. code:: c 244 245 .. code-block:: c 240 246 241 247 static void my_driver_poll_write( 242 rtems_termios_device_context \*base,243 const char \*buf,244 size_t n245 ) 246 { 247 my_driver_context \*ctx = (my_driver_context \*) base;248 size_t i;249 /* Write \*/250 for (i = 0; i < n; ++i) {251 my_driver_write_char(ctx, buf[i]);252 }248 rtems_termios_device_context *base, 249 const char *buf, 250 size_t n 251 ) 252 { 253 my_driver_context *ctx = (my_driver_context *) base; 254 size_t i; 255 /* Write */ 256 for (i = 0; i < n; ++i) { 257 my_driver_write_char(ctx, buf[i]); 258 } 253 259 } 254 260 … … 256 262 character from the serial device specified by ``tty``. If no character is 257 263 available, then the routine should return minus one. 258 .. code:: c 259 260 static int my_driver_poll_read(rtems_termios_device_context \*base) 261 { 262 my_driver_context \*ctx = (my_driver_context \*) base; 263 /* Check if a character is available \*/ 264 if (my_driver_can_read_char(ctx)) { 265 /* Return the character \*/ 266 return my_driver_read_char(ctx); 267 } else { 268 /* Return an error status \*/ 269 return -1; 270 } 264 265 .. code-block:: c 266 267 static int my_driver_poll_read(rtems_termios_device_context *base) 268 { 269 my_driver_context *ctx = (my_driver_context *) base; 270 /* Check if a character is available */ 271 if (my_driver_can_read_char(ctx)) { 272 /* Return the character */ 273 return my_driver_read_char(ctx); 274 } else { 275 /* Return an error status */ 276 return -1; 277 } 271 278 } 272 279 … … 286 293 In the simplest case, the ``my_driver_interrupt_handler()`` will have to check 287 294 the status of the UART and determine what caused the interrupt. The following 288 describes the operation of an ``my_driver_interrupt_handler`` which has to 289 do this: 290 .. code:: c 295 describes the operation of an ``my_driver_interrupt_handler`` which has to do 296 this: 297 298 .. code-block:: c 291 299 292 300 static void my_driver_interrupt_handler( 293 rtems_vector_number vector, 294 void \*arg 295 ) 296 { 297 rtems_termios_tty \*tty = arg; 298 my_driver_context \*ctx = rtems_termios_get_device_context(tty); 299 char buf[N]; 300 size_t n; 301 /* 302 * Check if we have received something. The function reads the 303 * received characters from the device and stores them in the 304 * buffer. It returns the number of read characters. 305 \*/ 306 n = my_driver_read_received_chars(ctx, buf, N); 307 if (n > 0) { 308 /* Hand the data over to the Termios infrastructure \*/ 309 rtems_termios_enqueue_raw_characters(tty, buf, n); 310 } 311 /* 312 * Check if we have something transmitted. The functions returns 313 * the number of transmitted characters since the last write to the 314 * device. 315 \*/ 316 n = my_driver_transmitted_chars(ctx); 317 if (n > 0) { 318 /* 319 * Notify Termios that we have transmitted some characters. It 320 * will call now the interrupt write function if more characters 321 * are ready for transmission. 322 \*/ 323 rtems_termios_dequeue_characters(tty, n); 324 } 301 rtems_vector_number vector, 302 void *arg 303 ) 304 { 305 rtems_termios_tty *tty = arg; 306 my_driver_context *ctx = rtems_termios_get_device_context(tty); 307 char buf[N]; 308 size_t n; 309 310 /* 311 * Check if we have received something. The function reads the 312 * received characters from the device and stores them in the 313 * buffer. It returns the number of read characters. 314 */ 315 n = my_driver_read_received_chars(ctx, buf, N); 316 if (n > 0) { 317 /* Hand the data over to the Termios infrastructure */ 318 rtems_termios_enqueue_raw_characters(tty, buf, n); 319 } 320 321 /* 322 * Check if we have something transmitted. The functions returns 323 * the number of transmitted characters since the last write to the 324 * device. 325 */ 326 n = my_driver_transmitted_chars(ctx); 327 if (n > 0) { 328 /* 329 * Notify Termios that we have transmitted some characters. It 330 * will call now the interrupt write function if more characters 331 * are ready for transmission. 332 */ 333 rtems_termios_dequeue_characters(tty, n); 334 } 325 335 } 326 336 327 337 The ``my_driver_interrupt_write()`` function is responsible for telling the 328 device that the ``n`` characters at ``buf`` are to be transmitted. It 329 the value ``n`` is zero to indicate that no more characters are to send. 330 The driver can disable the transmit interrupts now. This routine is invoked 331 either from task context with disabled interrupts to start a new transmission 332 processwith exactly one character in case of an idle output state or from the338 device that the ``n`` characters at ``buf`` are to be transmitted. It the 339 value ``n`` is zero to indicate that no more characters are to send. The 340 driver can disable the transmit interrupts now. This routine is invoked either 341 from task context with disabled interrupts to start a new transmission process 342 with exactly one character in case of an idle output state or from the 333 343 interrupt handler to refill the transmitter. If the routine is invoked to 334 344 start the transmit process the output state will become busy and Termios starts … … 336 346 able to fill the transmit buffer you will end up with one interrupt per 337 347 character. 338 .. code:: c 348 349 .. code-block:: c 339 350 340 351 static void my_driver_interrupt_write( 341 rtems_termios_device_context \*base, 342 const char \*buf, 343 size_t n 344 ) 345 { 346 my_driver_context \*ctx = (my_driver_context \*) base; 347 /* 348 * Tell the device to transmit some characters from buf (less than 349 * or equal to n). When the device is finished it should raise an 350 * interrupt. The interrupt handler will notify Termios that these 351 * characters have been transmitted and this may trigger this write 352 * function again. You may have to store the number of outstanding 353 * characters in the device data structure. 354 \*/ 355 /* 356 * Termios will set n to zero to indicate that the transmitter is 357 * now inactive. The output buffer is empty in this case. The 358 * driver may disable the transmit interrupts now. 359 \*/ 352 rtems_termios_device_context *base, 353 const char *buf, 354 size_t n 355 ) 356 { 357 my_driver_context *ctx = (my_driver_context *) base; 358 359 /* 360 * Tell the device to transmit some characters from buf (less than 361 * or equal to n). When the device is finished it should raise an 362 * interrupt. The interrupt handler will notify Termios that these 363 * characters have been transmitted and this may trigger this write 364 * function again. You may have to store the number of outstanding 365 * characters in the device data structure. 366 */ 367 /* 368 * Termios will set n to zero to indicate that the transmitter is 369 * now inactive. The output buffer is empty in this case. The 370 * driver may disable the transmit interrupts now. 371 */ 360 372 } 361 373 … … 367 379 368 380 The ``console_initialize()`` function may look like this: 369 .. code:: c 381 382 .. code-block:: c 370 383 371 384 #include <my-driver.h> … … 373 386 #include <bsp.h> 374 387 #include <bsp/fatal.h> 375 static my_driver_context driver_context_table[M] = { /* Some values \*/ }; 388 389 static my_driver_context driver_context_table[M] = { /* Some values */ }; 390 376 391 rtems_device_driver console_initialize( 377 rtems_device_major_number major, 378 rtems_device_minor_number minor, 379 void \*arg 380 ) 381 { 382 rtems_status_code sc; 383 #ifdef SOME_BSP_USE_INTERRUPTS 384 const rtems_termios_handler \*handler = &my_driver_handler_interrupt; 385 #else 386 const rtems_termios_handler \*handler = &my_driver_handler_polled; 387 #endif 388 /* 389 * Initialize the Termios infrastructure. If Termios has already 390 * been initialized by another device driver, then this call will 391 * have no effect. 392 \*/ 393 rtems_termios_initialize(); 394 /* Initialize each device \*/ 395 for ( 396 minor = 0; 397 minor < RTEMS_ARRAY_SIZE(driver_context_table); 398 ++minor 399 ) { 400 my_driver_context \*ctx = &driver_context_table[minor]; 401 /* 402 * Install this device in the file system and Termios. In order 403 * to use the console (i.e. being able to do printf, scanf etc. 404 * on stdin, stdout and stderr), one device must be registered as 405 * "/dev/console" (CONSOLE_DEVICE_NAME). 406 \*/ 407 sc = rtems_termios_device_install( 408 ctx->device_name, 409 major, 410 minor, 411 handler, 412 NULL, 413 ctx 414 ); 415 if (sc != RTEMS_SUCCESSFUL) { 416 bsp_fatal(SOME_BSP_FATAL_CONSOLE_DEVICE_INSTALL); 417 } 418 } 419 return RTEMS_SUCCESSFUL; 392 rtems_device_major_number major, 393 rtems_device_minor_number minor, 394 void *arg 395 ) 396 { 397 rtems_status_code sc; 398 #ifdef SOME_BSP_USE_INTERRUPTS 399 const rtems_termios_handler *handler = &my_driver_handler_interrupt; 400 #else 401 const rtems_termios_handler *handler = &my_driver_handler_polled; 402 #endif 403 404 /* 405 * Initialize the Termios infrastructure. If Termios has already 406 * been initialized by another device driver, then this call will 407 * have no effect. 408 */ 409 rtems_termios_initialize(); 410 411 /* Initialize each device */ 412 for ( 413 minor = 0; 414 minor < RTEMS_ARRAY_SIZE(driver_context_table); 415 ++minor 416 ) { 417 my_driver_context *ctx = &driver_context_table[minor]; 418 419 /* 420 * Install this device in the file system and Termios. In order 421 * to use the console (i.e. being able to do printf, scanf etc. 422 * on stdin, stdout and stderr), one device must be registered as 423 * "/dev/console" (CONSOLE_DEVICE_NAME). 424 */ 425 sc = rtems_termios_device_install( 426 ctx->device_name, 427 major, 428 minor, 429 handler, 430 NULL, 431 ctx 432 ); 433 if (sc != RTEMS_SUCCESSFUL) { 434 bsp_fatal(SOME_BSP_FATAL_CONSOLE_DEVICE_INSTALL); 435 } 436 } 437 438 return RTEMS_SUCCESSFUL; 420 439 } 421 440 … … 423 442 ----------------------- 424 443 425 The ``console_open()`` function provided by :file:`console-termios.c` is 426 called whenever a serial device is opened. The device registered as``"/dev/console"`` (``CONSOLE_DEVICE_NAME``) is opened automatically 427 during RTEMS initialization. For instance, if UART channel 2 is registered as``"/dev/tty1"``, the ``console_open()`` entry point will be called as the 444 The ``console_open()`` function provided by :file:`console-termios.c` is called 445 whenever a serial device is opened. The device registered as 446 ``"/dev/console"`` (``CONSOLE_DEVICE_NAME``) is opened automatically during 447 RTEMS initialization. For instance, if UART channel 2 is registered as 448 ``"/dev/tty1"``, the ``console_open()`` entry point will be called as the 428 449 result of an ``fopen("/dev/tty1", mode)`` in the application. 429 450 430 During the first open of the device Termios will call the``my_driver_first_open()`` handler. 431 .. code:: c 451 During the first open of the device Termios will call the 452 ``my_driver_first_open()`` handler. 453 454 .. code-block:: c 432 455 433 456 static bool my_driver_first_open( 434 rtems_termios_tty \*tty, 435 rtems_termios_device_context \*base, 436 struct termios \*term, 437 rtems_libio_open_close_args_t \*args 438 ) 439 { 440 my_driver_context \*ctx = (my_driver_context \*) base; 441 rtems_status_code sc; 442 bool ok; 443 /* 444 * You may add some initialization code here. 445 \*/ 446 /* 447 * Sets the initial baud rate. This should be set to the value of 448 * the boot loader. This function accepts only exact Termios baud 449 * values. 450 \*/ 451 sc = rtems_termios_set_initial_baud(tty, MY_DRIVER_BAUD_RATE); 452 if (sc != RTEMS_SUCCESSFUL) { 453 /* Not a valid Termios baud \*/ 454 } 455 /* 456 * Alternatively you can set the best baud. 457 \*/ 458 rtems_termios_set_best_baud(term, MY_DRIVER_BAUD_RATE); 459 /* 460 * To propagate the initial Termios attributes to the device use 461 * this. 462 \*/ 463 ok = my_driver_set_attributes(base, term); 464 if (!ok) { 465 /* This is bad \*/ 466 } 467 /* 468 * Return true to indicate a successful set attributes, and false 469 * otherwise. 470 \*/ 471 return true; 457 rtems_termios_tty *tty, 458 rtems_termios_device_context *base, 459 struct termios *term, 460 rtems_libio_open_close_args_t *args 461 ) 462 { 463 my_driver_context *ctx = (my_driver_context *) base; 464 rtems_status_code sc; 465 bool ok; 466 467 /* 468 * You may add some initialization code here. 469 */ 470 471 /* 472 * Sets the initial baud rate. This should be set to the value of 473 * the boot loader. This function accepts only exact Termios baud 474 * values. 475 */ 476 sc = rtems_termios_set_initial_baud(tty, MY_DRIVER_BAUD_RATE); 477 if (sc != RTEMS_SUCCESSFUL) { 478 /* Not a valid Termios baud */ 479 } 480 481 /* 482 * Alternatively you can set the best baud. 483 */ 484 rtems_termios_set_best_baud(term, MY_DRIVER_BAUD_RATE); 485 486 /* 487 * To propagate the initial Termios attributes to the device use 488 * this. 489 */ 490 ok = my_driver_set_attributes(base, term); 491 if (!ok) { 492 /* This is bad */ 493 } 494 495 /* 496 * Return true to indicate a successful set attributes, and false 497 * otherwise. 498 */ 499 return true; 472 500 } 473 501 … … 481 509 Termios will call the ``my_driver_last_close()`` handler if the last close 482 510 happens on the device. 483 .. code:: c 511 512 .. code-block:: c 484 513 485 514 static void my_driver_last_close( 486 rtems_termios_tty \*tty, 487 rtems_termios_device_context \*base, 488 rtems_libio_open_close_args_t \*args 489 ) 490 { 491 my_driver_context \*ctx = (my_driver_context \*) base; 492 /* 493 * The driver may do some cleanup here. 494 \*/ 515 rtems_termios_tty *tty, 516 rtems_termios_device_context *base, 517 rtems_libio_open_close_args_t *args 518 ) 519 { 520 my_driver_context *ctx = (my_driver_context *) base; 521 522 /* 523 * The driver may do some cleanup here. 524 */ 495 525 } 496 526 … … 512 542 ------------------------------- 513 543 514 The ``console_control()`` provided by :file:`console-termios.c` is invoked 515 when the line parameters for a particular serial device are to be changed. 516 Thisentry point corresponds to the device driver IO control entry point.544 The ``console_control()`` provided by :file:`console-termios.c` is invoked when 545 the line parameters for a particular serial device are to be changed. This 546 entry point corresponds to the device driver IO control entry point. 517 547 518 548 The application writer is able to control the serial line configuration with 519 Termios calls (such as the ``ioctl()`` command, see the Termios 520 documentation for more details). If the driver is to support dynamic 521 configuration, then it must have the ``console_control()`` piece of code. 522 Basically ``ioctl()`` commands call ``console_control()`` with the serial 523 line configuration in aTermios defined data structure.549 Termios calls (such as the ``ioctl()`` command, see the Termios documentation 550 for more details). If the driver is to support dynamic configuration, then it 551 must have the ``console_control()`` piece of code. Basically ``ioctl()`` 552 commands call ``console_control()`` with the serial line configuration in a 553 Termios defined data structure. 524 554 525 555 The driver is responsible for reinitializing the device with the correct 526 556 settings. For this purpose Termios calls the ``my_driver_set_attributes()`` 527 557 handler. 528 .. code:: c 558 559 .. code-block:: c 529 560 530 561 static bool my_driver_set_attributes( 531 rtems_termios_device_context \*base, 532 const struct termios \*term 533 ) 534 { 535 my_driver_context \*ctx = (my_driver_context \*) base; 536 /* 537 * Inspect the termios data structure and configure the device 538 * appropriately. The driver should only be concerned with the 539 * parts of the structure that specify hardware setting for the 540 * communications channel such as baud, character size, etc. 541 \*/ 542 /* 543 * Return true to indicate a successful set attributes, and false 544 * otherwise. 545 \*/ 546 return true; 547 } 548 549 .. COMMENT: COPYRIGHT (c) 1988-2002. 550 551 .. COMMENT: On-Line Applications Research Corporation (OAR). 552 553 .. COMMENT: All rights reserved. 554 562 rtems_termios_device_context *base, 563 const struct termios *term 564 ) 565 { 566 my_driver_context *ctx = (my_driver_context *) base; 567 568 /* 569 * Inspect the termios data structure and configure the device 570 * appropriately. The driver should only be concerned with the 571 * parts of the structure that specify hardware setting for the 572 * communications channel such as baud, character size, etc. 573 */ 574 /* 575 * Return true to indicate a successful set attributes, and false 576 * otherwise. 577 */ 578 return true; 579 } -
bsp_howto/discrete.rst
r54514fe r6d7a4d2 4 4 ############### 5 5 6 The Discrete driver is responsible for providing an 7 interface to Discrete Input/Outputs. The capabilities provided 8 by this class of device driver are: 6 The Discrete driver is responsible for providing an interface to Discrete 7 Input/Outputs. The capabilities provided by this class of device driver are: 9 8 10 9 - Initialize a Discrete I/O Board … … 22 21 - Reinitialize DACS 23 22 24 Most discrete I/O devices are found on I/O cards that support many 25 bits of discrete I/O on a single card. This driver model is centered 26 on the notion ofreading bitfields from the card.23 Most discrete I/O devices are found on I/O cards that support many bits of 24 discrete I/O on a single card. This driver model is centered on the notion of 25 reading bitfields from the card. 27 26 28 There are currently no discrete I/O device drivers included in the 29 RTEMS source tree. The information provided in this chapter 30 is based on drivers developed for applications using RTEMS. 31 It is hoped that this driver model information can form the 32 discrete I/O driver model that can be supported in future RTEMS 27 There are currently no discrete I/O device drivers included in the RTEMS source 28 tree. The information provided in this chapter is based on drivers developed 29 for applications using RTEMS. It is hoped that this driver model information 30 can form the discrete I/O driver model that can be supported in future RTEMS 33 31 distribution. 34 32 … … 36 34 ======================= 37 35 38 The *major* number of a device driver is its index in the39 RTEMS DeviceAddress Table.36 The ``major`` number of a device driver is its index in the RTEMS Device 37 Address Table. 40 38 41 A *minor* number is associated with each device instance 42 managed by a particular device driver. An RTEMS minor number 43 is an ``unsigned32`` entity. Convention calls for 44 dividing the bits in the minor number down into categories 45 that specify a particular bitfield. This results in categories 46 like the following: 39 A ``minor`` number is associated with each device instance managed by a 40 particular device driver. An RTEMS minor number is an ``unsigned32`` entity. 41 Convention calls for dividing the bits in the minor number down into categories 42 that specify a particular bitfield. This results in categories like the 43 following: 47 44 48 - *board*- indicates the board a particular bitfield is located on45 - ``board`` - indicates the board a particular bitfield is located on 49 46 50 - *word* - indicates the particular word of discrete bits the51 bitfield islocated within47 - ``word`` - indicates the particular word of discrete bits the bitfield is 48 located within 52 49 53 - *start*- indicates the starting bit of the bitfield50 - ``start`` - indicates the starting bit of the bitfield 54 51 55 - *width*- indicates the width of the bitfield52 - ``width`` - indicates the width of the bitfield 56 53 57 From the above, it should be clear that a single device driver 58 can support multiple copies of the same board in a single system. 59 The minor number is usedto distinguish the devices.54 From the above, it should be clear that a single device driver can support 55 multiple copies of the same board in a single system. The minor number is used 56 to distinguish the devices. 60 57 61 By providing a way to easily access a particular bitfield from 62 the device driver, the application is insulated with knowing how 63 to mask fields in and outof a discrete I/O.58 By providing a way to easily access a particular bitfield from the device 59 driver, the application is insulated with knowing how to mask fields in and out 60 of a discrete I/O. 64 61 65 62 Discrete I/O Driver Configuration 66 63 ================================= 67 64 68 There is not a standard discrete I/O driver configuration table but some 69 fields are common across different drivers. The discrete I/O driver 70 configuration table is typically an array of structures with each 71 structure containing the information for a particular board. 72 The following is a list of the type of information normally required 73 to configure an discrete I/O board: 65 There is not a standard discrete I/O driver configuration table but some fields 66 are common across different drivers. The discrete I/O driver configuration 67 table is typically an array of structures with each structure containing the 68 information for a particular board. The following is a list of the type of 69 information normally required to configure an discrete I/O board: 74 70 75 *board_offset* 71 ``board_offset`` 76 72 is the base address of a board. 77 73 78 *relay_initial_values* 79 is an array of the values that should be written to each output 80 word on the board during initialization. This allows the driver81 to start with the board's outputin a known state.74 ``relay_initial_values`` 75 is an array of the values that should be written to each output word on the 76 board during initialization. This allows the driver to start with the 77 board's output in a known state. 82 78 83 79 Initialize a Discrete I/O Board … … 85 81 86 82 At system initialization, the discrete I/O driver's initialization entry point 87 will be invoked. As part of initialization, the driver will perform 88 whatever board initializatin is required and then set all 89 outputs to their configuredinitial state.83 will be invoked. As part of initialization, the driver will perform whatever 84 board initializatin is required and then set all outputs to their configured 85 initial state. 90 86 91 The discrete I/O driver may register a device name for bitfields of 92 particular interest to the system. Normally this will be restricted 93 to the names of eachword and, if the driver supports it, an "all words".87 The discrete I/O driver may register a device name for bitfields of particular 88 interest to the system. Normally this will be restricted to the names of each 89 word and, if the driver supports it, an "all words". 94 90 95 91 Open a Particular Discrete Bitfield … … 100 96 101 97 With some drivers, it may be necessary to allocate memory when a particular 102 device is opened. If that is the case, then this is often the place 103 to do thisoperation.98 device is opened. If that is the case, then this is often the place to do this 99 operation. 104 100 105 101 Close a Particular Discrete Bitfield … … 109 105 110 106 With some drivers, it may be necessary to allocate memory when a particular 111 device is opened. If that is the case, then this is the place 112 where thatmemory should be deallocated.107 device is opened. If that is the case, then this is the place where that 108 memory should be deallocated. 113 109 114 110 Read from a Particular Discrete Bitfield 115 111 ======================================== 116 112 117 This corresponds to the driver read call. After validating the minor 118 number and arguments, this call reads the indicated bitfield. A 119 discrete I/O devices may have to store the last value written to 120 a discrete output. If the bitfield is output only, saving the last 121 written value gives the appearance that it can be read from also. 122 If the bitfield is input, then it is sampled. 113 This corresponds to the driver read call. After validating the minor number 114 and arguments, this call reads the indicated bitfield. A discrete I/O devices 115 may have to store the last value written to a discrete output. If the bitfield 116 is output only, saving the last written value gives the appearance that it can 117 be read from also. If the bitfield is input, then it is sampled. 123 118 124 *NOTE:* Many discrete inputs have a tendency to bounce. The application 125 may have to take account for bounces. 119 .. note:: 126 120 127 The value returned is an ``unsigned32`` number 128 representing the bitfield read. This value is stored in the``argument_block`` passed in to the call.121 Many discrete inputs have a tendency to bounce. The application may have to 122 take account for bounces. 129 123 130 *NOTE:* Some discrete I/O drivers have a special minor number 131 used to access all discrete I/O bits on the board. If this special 132 minor is used, then the area pointed to by ``argument_block`` must 133 be the correct size. 124 The value returned is an ``unsigned32`` number representing the bitfield read. 125 This value is stored in the ``argument_block`` passed in to the call. 126 127 .. note:: 128 129 Some discrete I/O drivers have a special minor number used to access all 130 discrete I/O bits on the board. If this special minor is used, then the 131 area pointed to by ``argument_block`` must be the correct size. 134 132 135 133 Write to a Particular Discrete Bitfield 136 134 ======================================= 137 135 138 This corresponds to the driver write call. After validating the minor 139 number and arguments, this call writes the indicated device. If the140 specified deviceis an ADC, then an error is usually returned.136 This corresponds to the driver write call. After validating the minor number 137 and arguments, this call writes the indicated device. If the specified device 138 is an ADC, then an error is usually returned. 141 139 142 The value written is an ``unsigned32`` number 143 representing the value to be written to the specified 144 bitfield. This value is stored in the``argument_block`` passed in to the call.140 The value written is an ``unsigned32`` number representing the value to be 141 written to the specified bitfield. This value is stored in the 142 ``argument_block`` passed in to the call. 145 143 146 *NOTE:* Some discrete I/O drivers have a special minor number 147 used to access all discrete I/O bits on the board. If this special 148 minor is used, then the area pointed to by ``argument_block`` must 149 be the correct size. 144 .. note:: 145 146 Some discrete I/O drivers have a special minor number used to access all 147 discrete I/O bits on the board. If this special minor is used, then the 148 area pointed to by ``argument_block`` must be the correct size. 150 149 151 150 Disable Discrete Outputs 152 151 ======================== 153 152 154 This is one of the IOCTL functions supported by the I/O control 155 device driver entry point. When this IOCTL function is invoked, 156 the discrete outputs aredisabled.153 This is one of the IOCTL functions supported by the I/O control device driver 154 entry point. When this IOCTL function is invoked, the discrete outputs are 155 disabled. 157 156 158 *NOTE:* It may not be possible to disable/enable discrete output on all 159 discrete I/O boards. 157 .. note:: 158 159 It may not be possible to disable/enable discrete output on all discrete I/O 160 boards. 160 161 161 162 Enable Discrete Outputs 162 163 ======================= 163 164 164 This is one of the IOCTL functions supported by the I/O control 165 device driver entry point. When this IOCTL function is invoked, 166 the discrete outputs areenabled.165 This is one of the IOCTL functions supported by the I/O control device driver 166 entry point. When this IOCTL function is invoked, the discrete outputs are 167 enabled. 167 168 168 *NOTE:* It may not be possible to disable/enable discrete output on all 169 discrete I/O boards. 169 .. note:: 170 171 It may not be possible to disable/enable discrete output on all discrete 172 I/O boards. 170 173 171 174 Reinitialize Outputs 172 175 ==================== 173 176 174 This is one of the IOCTL functions supported by the I/O control 175 device driver entry point. When this IOCTL function is invoked, 176 the discrete outputs are rewritten with the configured initial 177 output values. 177 This is one of the IOCTL functions supported by the I/O control device driver 178 entry point. When this IOCTL function is invoked, the discrete outputs are 179 rewritten with the configured initial output values. 178 180 179 181 Get Last Written Values 180 182 ======================= 181 183 182 This is one of the IOCTL functions supported by the I/O control 183 device driver entry point. When this IOCTL function is invoked, 184 the following information isreturned to the caller:184 This is one of the IOCTL functions supported by the I/O control device driver 185 entry point. When this IOCTL function is invoked, the following information is 186 returned to the caller: 185 187 186 188 - last value written to the specified output word 187 189 188 190 - timestamp of when the last write was performed 189 -
bsp_howto/frame_buffer.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Frame Buffer Driver 4 8 ################### 5 9 6 In this chapter, we present the basic functionality implemented by a 7 frame buffer driver: ``frame_buffer_initialize()``, ``frame_buffer_open()``,``frame_buffer_close()``, ``frame_buffer_read()``, ``frame_buffer_write()`` 8 and ``frame_buffer_control()``. 10 In this chapter, we present the basic functionality implemented by a frame 11 buffer driver: 12 13 - ``frame_buffer_initialize()`` 14 - ``frame_buffer_open()`` 15 - ``frame_buffer_close()`` 16 - ``frame_buffer_read()`` 17 - ``frame_buffer_write()`` 18 - ``frame_buffer_control()`` 9 19 10 20 Introduction … … 12 22 13 23 The purpose of the frame buffer driver is to provide an abstraction for 14 graphics hardware. 15 By using the frame buffer interface, an application can display graphics 16 without knowing anything about the low-level details of interfacing to a 17 particular graphics adapter. The parameters governing the mapping of 18 memory to displayed pixels (planar or linear, bit depth, etc) is still 19 implementation-specific, but device-independent methods are provided to 24 graphics hardware. By using the frame buffer interface, an application can 25 display graphics without knowing anything about the low-level details of 26 interfacing to a particular graphics adapter. The parameters governing the 27 mapping of memory to displayed pixels (planar or linear, bit depth, etc) is 28 still implementation-specific, but device-independent methods are provided to 20 29 determine and potentially modify these parameters. 21 30 22 The frame buffer driver is commonly located in the ``console`` 23 directory of the BSP and registered by the name */dev/fb0*. 24 Additional frame buffers (if available) are named */dev/fb1*,*/dev/fb2*, etc. 25 26 To work with the frame buffer, the following operation sequence is used:``open()``, ``ioctls()`` to get the frame buffer info, ``read()`` and/or``write()``, and ``close()``. 31 The frame buffer driver is commonly located in the ``console`` directory of the 32 BSP and registered by the name :file:`/dev/fb0`. Additional frame buffers (if 33 available) are named :file:`/dev/fb1*,*/dev/fb2`, etc. 34 35 To work with the frame buffer, the following operation sequence is 36 used:``open()``, ``ioctls()`` to get the frame buffer info, ``read()`` 37 and/or ``write()``, and ``close()``. 27 38 28 39 Driver Function Overview … … 33 44 34 45 The driver initialization is called once during the RTEMS initialization 35 process and returns RTEMS_SUCCESSFULwhen the device driver is successfully36 initialized. During the initialization, a name is assigned to the frame 37 buffer device. If the graphics hardware supports console text output, 38 as is the case with the pc386 VGA hardware, initialization into graphics 39 mode may be deferreduntil the device is ``open()`` ed.46 process and returns ``RTEMS_SUCCESSFUL`` when the device driver is successfully 47 initialized. During the initialization, a name is assigned to the frame buffer 48 device. If the graphics hardware supports console text output, as is the case 49 with the pc386 VGA hardware, initialization into graphics mode may be deferred 50 until the device is ``open()`` ed. 40 51 41 52 The ``frame_buffer_initialize()`` function may look like this: 42 53 43 .. code :: c54 .. code-block:: c 44 55 45 56 rtems_device_driver frame_buffer_initialize( 46 rtems_device_major_number major, 47 rtems_device_minor_number minor, 48 void \*arg) 49 { 50 rtems_status_code status; 51 printk( "frame buffer driver initializing..\\n" ); 52 /* 53 * Register the device 54 \*/ 55 status = rtems_io_register_name("/dev/fb0", major, 0); 56 if (status != RTEMS_SUCCESSFUL) 57 { 58 printk("Error registering frame buffer device!\\n"); 59 rtems_fatal_error_occurred( status ); 60 } 61 /* 62 * graphics hardware initialization goes here for non-console 63 * devices 64 \*/ 65 return RTEMS_SUCCESSFUL; 57 rtems_device_major_number major, 58 rtems_device_minor_number minor, 59 void *arg) 60 { 61 rtems_status_code status; 62 63 printk( "frame buffer driver initializing..\n" ); 64 65 /* 66 * Register the device 67 */ 68 status = rtems_io_register_name("/dev/fb0", major, 0); 69 if (status != RTEMS_SUCCESSFUL) 70 { 71 printk("Error registering frame buffer device!\n"); 72 rtems_fatal_error_occurred( status ); 73 } 74 75 /* 76 * graphics hardware initialization goes here for non-console 77 * devices 78 */ 79 80 return RTEMS_SUCCESSFUL; 66 81 } 67 82 … … 69 84 ------------------------------- 70 85 71 The ``frame_buffer_open()`` function is called whenever a frame buffer device is opened. 72 If the frame buffer is registered as "/dev/fb0", the ``frame_buffer_open`` entry point 73 will be called as the result of an ``open("/dev/fb0", mode)`` in the application. 74 75 Thread safety of the frame buffer driver is implementation-dependent. 76 The VGA driver shown below uses a mutex to prevent multiple open() 77 operations of the frame buffer device. 78 79 The ``frame_buffer_open()`` function returns RTEMS_SUCCESSFUL when the device driver 80 is successfully opened, and RTEMS_UNSATISFIED if the device is already open: 81 .. code:: c 86 The ``frame_buffer_open()`` function is called whenever a frame buffer device 87 is opened. If the frame buffer is registered as :file:`/dev/fb0`, the 88 ``frame_buffer_open`` entry point will be called as the result of an 89 ``open("/dev/fb0", mode)`` in the application. 90 91 Thread safety of the frame buffer driver is implementation-dependent. The VGA 92 driver shown below uses a mutex to prevent multiple open() operations of the 93 frame buffer device. 94 95 The ``frame_buffer_open()`` function returns ``RTEMS_SUCCESSFUL`` when the 96 device driver is successfully opened, and ``RTEMS_UNSATISFIED`` if the device 97 is already open: 98 99 .. code-block:: c 82 100 83 101 rtems_device_driver frame_buffer_close( 84 rtems_device_major_number major, 85 rtems_device_minor_number minor, 86 void \*arg 87 ) 88 { 89 if (pthread_mutex_unlock(&mutex) == 0){ 90 /* restore previous state. for VGA this means return to text mode. 91 * leave out if graphics hardware has been initialized in 92 * frame_buffer_initialize() \*/ 93 ega_hwterm(); 94 printk( "FBVGA close called.\\n" ); 95 return RTEMS_SUCCESSFUL; 96 } 97 return RTEMS_UNSATISFIED; 102 rtems_device_major_number major, 103 rtems_device_minor_number minor, 104 void *arg 105 ) 106 { 107 if (pthread_mutex_unlock(&mutex) == 0) { 108 /* restore previous state. for VGA this means return to text mode. 109 * leave out if graphics hardware has been initialized in 110 * frame_buffer_initialize() 111 */ 112 ega_hwterm(); 113 printk( "FBVGA close called.\n" ); 114 return RTEMS_SUCCESSFUL; 115 } 116 return RTEMS_UNSATISFIED; 98 117 } 99 118 … … 104 123 ------------------------------- 105 124 106 The ``frame_buffer_close()`` is invoked when the frame buffer device 107 is closed. It frees up any resources allocated in``frame_buffer_open()``, and should restore previous hardware state. 108 The entry point corresponds to the device driver close entry point. 109 110 Returns RTEMS_SUCCESSFUL when the device driver is successfully closed: 111 .. code:: c 125 The ``frame_buffer_close()`` is invoked when the frame buffer device is closed. 126 It frees up any resources allocated in ``frame_buffer_open()``, and should 127 restore previous hardware state. The entry point corresponds to the device 128 driver close entry point. 129 130 Returns ``RTEMS_SUCCESSFUL`` when the device driver is successfully closed: 131 132 .. code-block:: c 112 133 113 134 rtems_device_driver frame_buffer_close( 114 rtems_device_major_number major, 115 rtems_device_minor_number minor, 116 void \*arg) 117 { 118 pthread_mutex_unlock(&mutex); 119 /* TODO check mutex return value, RTEMS_UNSATISFIED if it failed. we 120 * don't want to unconditionally call ega_hwterm()... \*/ 121 /* restore previous state. for VGA this means return to text mode. 122 * leave out if graphics hardware has been initialized in 123 * frame_buffer_initialize() \*/ 124 ega_hwterm(); 125 printk( "frame buffer close called.\\n" ); 126 return RTEMS_SUCCESSFUL; 135 rtems_device_major_number major, 136 rtems_device_minor_number minor, 137 void *arg) 138 { 139 pthread_mutex_unlock(&mutex); 140 141 /* TODO check mutex return value, RTEMS_UNSATISFIED if it failed. we 142 * don't want to unconditionally call ega_hwterm()... */ 143 /* restore previous state. for VGA this means return to text mode. 144 * leave out if graphics hardware has been initialized in 145 * frame_buffer_initialize() */ 146 ega_hwterm(); 147 printk( "frame buffer close called.\n" ); 148 return RTEMS_SUCCESSFUL; 127 149 } 128 150 … … 130 152 ------------------------------------ 131 153 132 The ``frame_buffer_read()`` is invoked from a ``read()`` operation 133 on the frame buffer device. 134 Read functions should allow normal and partial reading at the end of frame buffer memory. 135 This method returns RTEMS_SUCCESSFUL when the device is successfully read from: 136 .. code:: c 154 The ``frame_buffer_read()`` is invoked from a ``read()`` operation on the frame 155 buffer device. Read functions should allow normal and partial reading at the 156 end of frame buffer memory. This method returns ``RTEMS_SUCCESSFUL`` when the 157 device is successfully read from: 158 159 .. code-block:: c 137 160 138 161 rtems_device_driver frame_buffer_read( 139 rtems_device_major_number major, 140 rtems_device_minor_number minor, 141 void \*arg 142 ) 143 { 144 rtems_libio_rw_args_t \*rw_args = (rtems_libio_rw_args_t \*)arg; 145 rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; 146 memcpy(rw_args->buffer, (const void \*) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); 147 return RTEMS_SUCCESSFUL; 162 rtems_device_major_number major, 163 rtems_device_minor_number minor, 164 void *arg 165 ) 166 { 167 rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; 168 rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? 169 (fb_fix.smem_len - rw_args->offset) : rw_args->count; 170 memcpy(rw_args->buffer, 171 (const void *) (fb_fix.smem_start + rw_args->offset), 172 rw_args->bytes_moved); 173 return RTEMS_SUCCESSFUL; 148 174 } 149 175 … … 151 177 ---------------------------------- 152 178 153 The ``frame_buffer_write()`` is invoked from a ``write()`` 154 operation on the frame buffer device. 155 The frame buffer write function is similar to the read function, and 156 should handle similar cases involving partial writes. 157 158 This method returns RTEMS_SUCCESSFUL when the device is successfully 179 The ``frame_buffer_write()`` is invoked from a ``write()`` operation on the 180 frame buffer device. The frame buffer write function is similar to the read 181 function, and should handle similar cases involving partial writes. 182 183 This method returns ``RTEMS_SUCCESSFUL`` when the device is successfully 159 184 written to: 160 .. code:: c 185 186 .. code-block:: c 161 187 162 188 rtems_device_driver frame_buffer_write( 163 rtems_device_major_number major, 164 rtems_device_minor_number minor, 165 void \*arg 166 ) 167 { 168 rtems_libio_rw_args_t \*rw_args = (rtems_libio_rw_args_t \*)arg; 169 rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; 170 memcpy( (void \*) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved); 171 return RTEMS_SUCCESSFUL; 189 rtems_device_major_number major, 190 rtems_device_minor_number minor, 191 void *arg 192 ) 193 { 194 rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; 195 rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? 196 (fb_fix.smem_len - rw_args->offset) : rw_args->count; 197 memcpy((void *) (fb_fix.smem_start + rw_args->offset), 198 rw_args->buffer, 199 rw_args->bytes_moved); 200 return RTEMS_SUCCESSFUL; 172 201 } 173 202 … … 175 204 ----------------------- 176 205 177 The frame buffer driver allows several ioctls, partially compatible with 178 the Linux kernel, 179 to obtain information about the hardware. 180 181 All ``ioctl()`` operations on the frame buffer device invoke``frame_buffer_control()``.206 The frame buffer driver allows several ioctls, partially compatible with the 207 Linux kernel, to obtain information about the hardware. 208 209 All ``ioctl()`` operations on the frame buffer device invoke 210 ``frame_buffer_control()``. 182 211 183 212 Ioctls supported: … … 187 216 - ioctl to set and get palette. 188 217 189 .. code :: c218 .. code-block:: c 190 219 191 220 rtems_device_driver frame_buffer_control( 192 rtems_device_major_number major, 193 rtems_device_minor_number minor, 194 void \*arg 195 ) 196 { 197 rtems_libio_ioctl_args_t \*args = arg; 198 printk( "FBVGA ioctl called, cmd=%x\\n", args->command ); 199 switch( args->command ) { 200 case FBIOGET_FSCREENINFO: 201 args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); 202 break; 203 case FBIOGET_VSCREENINFO: 204 args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); 205 break; 206 case FBIOPUT_VSCREENINFO: 207 /* not implemented yet*/ 208 args->ioctl_return = -1; 209 return RTEMS_UNSATISFIED; 210 case FBIOGETCMAP: 211 args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer ); 212 break; 213 case FBIOPUTCMAP: 214 args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer ); 215 break; 216 default: 217 args->ioctl_return = 0; 218 break; 219 } 220 return RTEMS_SUCCESSFUL; 221 } 222 223 See ``rtems/fb.h`` for more information on the list of ioctls and 224 data structures they work with. 225 226 .. COMMENT: COPYRIGHT (c) 1988-2002. 227 228 .. COMMENT: On-Line Applications Research Corporation (OAR). 229 230 .. COMMENT: All rights reserved. 231 221 rtems_device_major_number major, 222 rtems_device_minor_number minor, 223 void *arg 224 ) 225 { 226 rtems_libio_ioctl_args_t *args = arg; 227 228 printk( "FBVGA ioctl called, cmd=%x\n", args->command ); 229 230 switch( args->command ) { 231 case FBIOGET_FSCREENINFO: 232 args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); 233 break; 234 case FBIOGET_VSCREENINFO: 235 args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); 236 break; 237 case FBIOPUT_VSCREENINFO: 238 /* not implemented yet*/ 239 args->ioctl_return = -1; 240 return RTEMS_UNSATISFIED; 241 case FBIOGETCMAP: 242 args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer ); 243 break; 244 case FBIOPUTCMAP: 245 args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer ); 246 break; 247 default: 248 args->ioctl_return = 0; 249 break; 250 } 251 252 return RTEMS_SUCCESSFUL; 253 } 254 255 See ``rtems/fb.h`` for more information on the list of ioctls and data 256 structures they work with. -
bsp_howto/ide_controller.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 IDE Controller Driver … … 7 11 ============ 8 12 9 The IDE Controller driver is responsible for providing an 10 interface to an IDE Controller. The capabilities provided by this 11 driver are: 13 The IDE Controller driver is responsible for providing an interface to an IDE 14 Controller. The capabilities provided by this driver are: 12 15 13 16 - Read IDE Controller register … … 19 22 - Write data block through IDE Controller Data Register 20 23 21 The reference implementation for an IDE Controller driver can 22 be found in ``$RTEMS_SRC_ROOT/c/src/libchip/ide``. This driver 23 is based on the libchip concept and allows to work with any of the IDE 24 Controller chips simply by appropriate configuration of BSP. Drivers for a 25 particular IDE Controller chips locate in the following directories: drivers 26 for well-known IDE Controller chips locate into``$RTEMS_SRC_ROOT/c/src/libchip/ide``, drivers for IDE Controller chips 27 integrated with CPU locate into``$RTEMS_SRC_ROOT/c/src/lib/libcpu/myCPU`` and 28 drivers for custom IDE Controller chips (for example, implemented on FPGA) 29 locate into ``$RTEMS_SRC_ROOT/c/src/lib/libbsp/myBSP``. 30 There is a README file in these directories for each supported 31 IDE Controller chip. Each of these README explains how to configure a BSP 32 for that particular IDE Controller chip.24 The reference implementation for an IDE Controller driver can be found in 25 ``$RTEMS_SRC_ROOT/c/src/libchip/ide``. This driver is based on the libchip 26 concept and allows to work with any of the IDE Controller chips simply by 27 appropriate configuration of BSP. Drivers for a particular IDE Controller chips 28 locate in the following directories: drivers for well-known IDE Controller 29 chips locate into ``$RTEMS_SRC_ROOT/c/src/libchip/ide``, drivers for IDE 30 Controller chips integrated with CPU locate into 31 ``$RTEMS_SRC_ROOT/c/src/lib/libcpu/myCPU`` and drivers for custom IDE 32 Controller chips (for example, implemented on FPGA) locate into 33 ``$RTEMS_SRC_ROOT/c/src/lib/libbsp/myBSP``. There is a README file in these 34 directories for each supported IDE Controller chip. Each of these README 35 explains how to configure a BSP for that particular IDE Controller chip. 33 36 34 37 Initialization 35 38 ============== 36 39 37 IDE Controller chips used by a BSP are statically configured into``IDE_Controller_Table``. The ``ide_controller_initialize`` routine is 40 IDE Controller chips used by a BSP are statically configured into 41 ``IDE_Controller_Table``. The ``ide_controller_initialize`` routine is 38 42 responsible for initialization of all configured IDE controller chips. 39 43 Initialization order of the chips based on the order the chips are defined in 40 44 the ``IDE_Controller_Table``. 41 45 42 The following actions are performed by the IDE Controller driver 43 initialization routine: 44 .. code:: c 46 The following actions are performed by the IDE Controller driver initialization 47 routine: 48 49 .. code-block:: c 45 50 46 51 rtems_device_driver ide_controller_initialize( 47 rtems_device_major_number major,48 rtems_device_minor_number minor_arg,49 void \*arg52 rtems_device_major_number major, 53 rtems_device_minor_number minor_arg, 54 void *arg 50 55 ) 51 56 { 52 for each IDE Controller chip configured in IDE_Controller_Table53 if (BSP dependent probe(if exists) AND device probe for this IDE chip54 indicates it is present)55 perform initialization of the particular chip56 register device with configured name for this chip57 for each IDE Controller chip configured in IDE_Controller_Table 58 if (BSP dependent probe(if exists) AND device probe for this IDE chip 59 indicates it is present) 60 perform initialization of the particular chip 61 register device with configured name for this chip 57 62 } 58 63 … … 63 68 Controller chip register. IDE Controller chip is selected via the minor 64 69 number. This routine is not allowed to be called from an application. 65 .. code:: c66 70 67 void ide_controller_read_register(rtems_device_minor_number minor, 68 unsigned32 reg, unsigned32 \*value) 71 .. code-block:: c 72 73 void ide_controller_read_register( 74 rtems_device_minor_number minor, 75 unsigned32 reg, 76 unsigned32 *value 77 ) 69 78 { 70 get IDE Controller chip configuration information from 71 IDE_Controller_Table by minor number 72 invoke read register routine for the chip 79 get IDE Controller chip configuration information from 80 IDE_Controller_Table by minor number 81 82 invoke read register routine for the chip 73 83 } 74 84 … … 79 89 register with specified value. IDE Controller chip is selected via the minor 80 90 number. This routine is not allowed to be called from an application. 81 .. code:: c82 91 83 void ide_controller_write_register(rtems_device_minor_number minor, 84 unsigned32 reg, unsigned32 value) 92 .. code-block:: c 93 94 void ide_controller_write_register( 95 rtems_device_minor_number minor, 96 unsigned32 reg, 97 unsigned32 value 98 ) 85 99 { 86 get IDE Controller chip configuration information from 87 IDE_Controller_Table by minor number 88 invoke write register routine for the chip 100 get IDE Controller chip configuration information from 101 IDE_Controller_Table by minor number 102 103 invoke write register routine for the chip 89 104 } 90 105 … … 92 107 ==================================================== 93 108 94 The ``ide_controller_read_data_block`` provides multiple consequent read 95 of the IDE Controller Data Register. IDE Controller chip is selected via the 96 minor number. The same functionality may be achieved via separate multiple 97 calls of ``ide_controller_read_register`` routine but``ide_controller_read_data_block`` allows to escape functions call 98 overhead. This routine is not allowed to be called from an application. 99 .. code:: c 109 The ``ide_controller_read_data_block`` provides multiple consequent read of the 110 IDE Controller Data Register. IDE Controller chip is selected via the minor 111 number. The same functionality may be achieved via separate multiple calls of 112 ``ide_controller_read_register`` routine but ``ide_controller_read_data_block`` 113 allows to escape functions call overhead. This routine is not allowed to be 114 called from an application. 115 116 .. code-block:: c 100 117 101 118 void ide_controller_read_data_block( 102 rtems_device_minor_number minor,103 unsigned16 block_size,104 blkdev_sg_buffer \*bufs,105 uint32_t \*cbuf,106 uint32_t \*pos119 rtems_device_minor_number minor, 120 unsigned16 block_size, 121 blkdev_sg_buffer *bufs, 122 uint32_t *cbuf, 123 uint32_t *pos 107 124 ) 108 125 { 109 get IDE Controller chip configuration information from 110 IDE_Controller_Table by minor number 111 invoke read data block routine for the chip 126 get IDE Controller chip configuration information from 127 IDE_Controller_Table by minor number 128 129 invoke read data block routine for the chip 112 130 } 113 131 … … 115 133 ===================================================== 116 134 117 The ``ide_controller_write_data_block`` provides multiple consequent write 118 into the IDE Controller Data Register. IDE Controller chip is selected via the 119 minor number. The same functionality may be achieved via separate multiple 120 calls of ``ide_controller_write_register`` routine but``ide_controller_write_data_block`` allows to escape functions call 135 The ``ide_controller_write_data_block`` provides multiple consequent write into 136 the IDE Controller Data Register. IDE Controller chip is selected via the minor 137 number. The same functionality may be achieved via separate multiple calls of 138 ``ide_controller_write_register`` routine but 139 ``ide_controller_write_data_block`` allows to escape functions call 121 140 overhead. This routine is not allowed to be called from an application. 122 .. code:: c 141 142 .. code-block:: c 123 143 124 144 void ide_controller_write_data_block( 125 rtems_device_minor_number minor,126 unsigned16 block_size,127 blkdev_sg_buffer \*bufs,128 uint32_t \*cbuf,129 uint32_t \*pos145 rtems_device_minor_number minor, 146 unsigned16 block_size, 147 blkdev_sg_buffer *bufs, 148 uint32_t *cbuf, 149 uint32_t *pos 130 150 ) 131 151 { 132 get IDE Controller chip configuration information from 133 IDE_Controller_Table by minor number 134 invoke write data block routine for the chip 152 get IDE Controller chip configuration information from 153 IDE_Controller_Table by minor number 154 155 invoke write data block routine for the chip 135 156 } 136 137 .. COMMENT: COPYRIGHT (c) 1988-2002.138 139 .. COMMENT: On-Line Applications Research Corporation (OAR).140 141 .. COMMENT: All rights reserved.142 -
bsp_howto/index.rst
r54514fe r6d7a4d2 5 5 ======================================= 6 6 7 COPYRIGHT (c) 1988 - 2015. 7 BSP and Device Driver Development Guide 8 --------------------------------------- 8 9 9 On-Line Applications Research Corporation (OAR). 10 | COPYRIGHT (c) 1988 - 2015. 11 | On-Line Applications Research Corporation (OAR). 10 12 11 The authors have used their best efforts in preparing 12 this material. These efforts include the development, research, 13 and testing of the theories and programs to determine their 14 effectiveness. No warranty of any kind, expressed or implied, 15 with regard to the software or the material contained in this 16 document is provided. No liability arising out of the 17 application or use of any product described in this document is 18 assumed. The authors reserve the right to revise this material 19 and to make changes from time to time in the content hereof 20 without obligation to notify anyone of such revision or changes. 13 The authors have used their best efforts in preparing this material. These 14 efforts include the development, research, and testing of the theories and 15 programs to determine their effectiveness. No warranty of any kind, expressed 16 or implied, with regard to the software or the material contained in this 17 document is provided. No liability arising out of the application or use of 18 any product described in this document is assumed. The authors reserve the 19 right to revise this material and to make changes from time to time in the 20 content hereof without obligation to notify anyone of such revision or changes. 21 21 22 The RTEMS Project is hosted at http://www.rtems.org. Any 23 inquiries concerning RTEMS, its related support components, or its 24 documentation should be directed to the Community Project hosted athttp://www.rtems.org.22 The RTEMS Project is hosted at http://www.rtems.org. Any inquiries concerning 23 RTEMS, its related support components, or its documentation should be directed 24 to the Community Project hosted at http://www.rtems.org. 25 25 26 Any inquiries for commercial services including training, support, custom 27 development, application development assistance should be directed tohttp://www.rtems.com. 26 .. topic:: RTEMS Online Resources 28 27 29 30 Table of Contents 31 ----------------- 32 33 .. toctree:: 34 35 preface 36 28 ================ ============================= 29 Home https://www.rtems.org/ 30 Developers https://devel.rtems.org/ 31 Documentation https://docs.rtems.org/ 32 Bug Reporting https://devel.rtems.org/query 33 Mailing Lists https://lists.rtems.org/ 34 Git Repositories https://git.rtems.org/ 35 ================ ============================= 37 36 38 37 .. toctree:: … … 40 39 :numbered: 41 40 41 preface 42 42 target_dependant_files 43 43 makefiles … … 60 60 command 61 61 62 63 64 62 * :ref:`genindex` 65 63 * :ref:`search` 66 -
bsp_howto/initilization_code.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2008. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Initialization Code … … 8 12 9 13 The initialization code is the first piece of code executed when there's a 10 reset/reboot. Its purpose is to initialize the board for the application. 11 This chapter contains a narrative description of the initialization 12 process followed by a description of each of the files and routines 13 commonly found in the BSP related to initialization. The remainder of 14 this chapter covers special issues which require attention such 15 as interrupt vector table and chip selectinitialization.14 reset/reboot. Its purpose is to initialize the board for the application. This 15 chapter contains a narrative description of the initialization process followed 16 by a description of each of the files and routines commonly found in the BSP 17 related to initialization. The remainder of this chapter covers special issues 18 which require attention such as interrupt vector table and chip select 19 initialization. 16 20 17 21 Most of the examples in this chapter will be based on the SPARC/ERC32 and 18 m68k/gen68340 BSP initialization code. Like most BSPs, the initialization 19 for these BSP is divided into two subdirectories under the BSP source 20 directory. The BSP source code for these BSPs is in the following 21 directories: 22 m68k/gen68340 BSP initialization code. Like most BSPs, the initialization for 23 these BSP is divided into two subdirectories under the BSP source directory. 24 The BSP source code for these BSPs is in the following directories: 25 22 26 .. code:: c 23 27 … … 25 29 c/src/lib/libbsp/sparc/erc32 26 30 27 Both BSPs contain startup code written in assembly language and C. 28 The gen68340 BSP has its early initialization start code in the``start340`` subdirectory and its C startup code in the ``startup`` 29 directory. In the ``start340`` directory are two source files. 30 The file ``startfor340only.s`` is the simpler of these files as it only 31 has initialization code for a MC68340 board. The file ``start340.s`` 32 contains initialization for a 68349 based board as well. 33 34 Similarly, the ERC32 BSP has startup code written in assembly language 35 and C. However, this BSP shares this code with other SPARC BSPs. 36 Thus the ``Makefile.am`` explicitly references the following files 37 for this functionality. 31 Both BSPs contain startup code written in assembly language and C. The 32 gen68340 BSP has its early initialization start code in the ``start340`` 33 subdirectory and its C startup code in the ``startup`` directory. In the 34 ``start340`` directory are two source files. The file ``startfor340only.s`` is 35 the simpler of these files as it only has initialization code for a MC68340 36 board. The file ``start340.s`` contains initialization for a 68349 based board 37 as well. 38 39 Similarly, the ERC32 BSP has startup code written in assembly language and C. 40 However, this BSP shares this code with other SPARC BSPs. Thus the 41 ``Makefile.am`` explicitly references the following files for this 42 functionality. 43 38 44 .. code:: c 39 45 40 46 ../../sparc/shared/start.S 41 47 42 *NOTE:* In most BSPs, the directory named ``start340`` in the 43 gen68340 BSP would be simply named ``start`` or start followed by a 44 BSP designation. 48 .. note:: 49 50 In most BSPs, the directory named ``start340`` in the gen68340 BSP would be 51 simply named ``start`` or start followed by a BSP designation. 45 52 46 53 Required Global Variables 47 54 ========================= 48 55 49 Although not strictly part of initialization, there are a few global 50 variables assumed to exist by reusable device drivers. These global 51 variables should only defined by the BSP when using one of these device 52 drivers. 53 54 The BSP author probably should be aware of the ``Configuration`` 55 Table structure generated by ``<rtems/confdefs.h>`` during debug but 56 should not explicitly reference it in the source code. There are helper 57 routines provided by RTEMS to access individual fields. 56 Although not strictly part of initialization, there are a few global variables 57 assumed to exist by reusable device drivers. These global variables should 58 only defined by the BSP when using one of these device drivers. 59 60 The BSP author probably should be aware of the ``Configuration`` Table 61 structure generated by ``<rtems/confdefs.h>`` during debug but should not 62 explicitly reference it in the source code. There are helper routines provided 63 by RTEMS to access individual fields. 58 64 59 65 In older RTEMS versions, the BSP included a number of required global 60 variables. We have made every attempt to eliminate these in the interest 61 ofsimplicity.66 variables. We have made every attempt to eliminate these in the interest of 67 simplicity. 62 68 63 69 Board Initialization 64 70 ==================== 65 71 66 This section describes the steps an application goes through from the 67 time the first BSP code is executed until the first application task 68 executes. The following figure illustrates the program flow during 69 this sequence: 70 71 IMAGE NOT AVAILABLE IN ASCII VERSION 72 73 The above figure illustrates the flow from assembly language start code 74 to the shared ``bootcard.c`` framework then through the C Library, 75 RTEMS, device driver initialization phases, and the context switch 76 to the first application task. After this, the application executes 77 until it calls ``exit``, ``rtems_shutdown_executive``, or some 78 other normal termination initiating routine and a fatal system state is 79 reached. The optional ``bsp_fatal_extension`` initial extension can perform 80 BSP specific system termination. 81 82 The routines invoked during this will be discussed and their location 83 in the RTEMS source tree pointed out as we discuss each. 72 This section describes the steps an application goes through from the time the 73 first BSP code is executed until the first application task executes. 74 75 The initialization flows from assembly language start code to the shared 76 ``bootcard.c`` framework then through the C Library, RTEMS, device driver 77 initialization phases, and the context switch to the first application task. 78 After this, the application executes until it calls ``exit``, 79 ``rtems_shutdown_executive``, or some other normal termination initiating 80 routine and a fatal system state is reached. The optional 81 ``bsp_fatal_extension`` initial extension can perform BSP specific system 82 termination. 83 84 The routines invoked during this will be discussed and their location in the 85 RTEMS source tree pointed out as we discuss each. 84 86 85 87 Start Code - Assembly Language Initialization 86 88 --------------------------------------------- 87 89 88 The assembly language code in the directory ``start`` is the first part 89 of the application to execute. It is responsible for initializing the 90 processor andboard enough to execute the rest of the BSP. This includes:90 The assembly language code in the directory ``start`` is the first part of the 91 application to execute. It is responsible for initializing the processor and 92 board enough to execute the rest of the BSP. This includes: 91 93 92 94 - initializing the stack … … 98 100 - copy the initialized data from ROM to RAM 99 101 100 The general rule of thumb is that the start code in assembly should 101 do the minimum necessary to allow C code to execute to complete the 102 initialization sequence. 103 104 The initial assembly language start code completes its execution by 105 invoking the shared routine ``boot_card()``. 106 107 The label (symbolic name) associated with the starting address of the 108 program is typically called ``start``. The start object file is the 109 first object file linked into the program image so it is ensured that 110 the start code is at offset 0 in the ``.text`` section. It is the 111 responsibility of the linker script in conjunction with the compiler 112 specifications file to put the start code in the correct location in 113 the application image. 102 The general rule of thumb is that the start code in assembly should do the 103 minimum necessary to allow C code to execute to complete the initialization 104 sequence. 105 106 The initial assembly language start code completes its execution by invoking 107 the shared routine ``boot_card()``. 108 109 The label (symbolic name) associated with the starting address of the program 110 is typically called ``start``. The start object file is the first object file 111 linked into the program image so it is ensured that the start code is at offset 112 0 in the ``.text`` section. It is the responsibility of the linker script in 113 conjunction with the compiler specifications file to put the start code in the 114 correct location in the application image. 114 115 115 116 boot_card() - Boot the Card 116 117 --------------------------- 117 118 118 The ``boot_card()`` is the first C code invoked. This file is the 119 core component in the RTEMS BSP Initialization Framework and provides 120 the proper sequencing of initialization steps for the BSP, RTEMS and 121 device drivers. All BSPs use the same shared version of ``boot_card()`` 122 which is located in the following file: 119 The ``boot_card()`` is the first C code invoked. This file is the core 120 component in the RTEMS BSP Initialization Framework and provides the proper 121 sequencing of initialization steps for the BSP, RTEMS and device drivers. All 122 BSPs use the same shared version of ``boot_card()`` which is located in the 123 following file: 124 123 125 .. code:: c 124 126 … … 132 134 for later use by the application. 133 135 134 - It invokes the BSP specific routine ``bsp_work_area_initialize()`` 135 which is supposed to initialize the RTEMS Workspace and the C Program Heap. 136 Usually the default implementation in``c/src/lib/libbsp/shared/bspgetworkarea.c`` should be sufficient. Custom 137 implementations can use ``bsp_work_area_initialize_default()`` or``bsp_work_area_initialize_with_table()`` available as inline functions from``#include <bsp/bootcard.h>``. 138 139 - It invokes the BSP specific routine ``bsp_start()`` which is 140 written in C and thus able to perform more advanced initialization. 141 Often MMU, bus and interrupt controller initialization occurs here. Since the 142 RTEMS Workspace and the C Program Heap was already initialized by``bsp_work_area_initialize()``, this routine may use ``malloc()``, etc. 143 144 - It invokes the RTEMS directive``rtems_initialize_data_structures()`` to initialize the RTEMS 145 executive to a state where objects can be created but tasking is not 146 enabled. 147 148 - It invokes the BSP specific routine ``bsp_libc_init()`` to initialize 149 the C Library. Usually the default implementation in``c/src/lib/libbsp/shared/bsplibc.c`` should be sufficient. 150 151 - It invokes the RTEMS directive``rtems_initialize_before_drivers()`` to initialize the MPCI Server 152 thread in a multiprocessor configuration and execute API specific 153 extensions. 154 155 - It invokes the BSP specific routine ``bsp_predriver_hook``. For 156 most BSPs, the implementation of this routine does nothing. 157 158 - It invokes the RTEMS directive``rtems_initialize_device_drivers()`` to initialize the statically 159 configured set of device drivers in the order they were specified in 160 the Configuration Table. 136 - It invokes the BSP specific routine ``bsp_work_area_initialize()`` which is 137 supposed to initialize the RTEMS Workspace and the C Program Heap. Usually 138 the default implementation in ``c/src/lib/libbsp/shared/bspgetworkarea.c`` 139 should be sufficient. Custom implementations can use 140 ``bsp_work_area_initialize_default()`` or 141 ``bsp_work_area_initialize_with_table()`` available as inline functions 142 from``#include <bsp/bootcard.h>``. 143 144 - It invokes the BSP specific routine ``bsp_start()`` which is written in C and 145 thus able to perform more advanced initialization. Often MMU, bus and 146 interrupt controller initialization occurs here. Since the RTEMS Workspace 147 and the C Program Heap was already initialized by 148 ``bsp_work_area_initialize()``, this routine may use ``malloc()``, etc. 149 150 - It invokes the RTEMS directive ``rtems_initialize_data_structures()`` to 151 initialize the RTEMS executive to a state where objects can be created but 152 tasking is not enabled. 153 154 - It invokes the BSP specific routine ``bsp_libc_init()`` to initialize the C 155 Library. Usually the default implementation in 156 ``c/src/lib/libbsp/shared/bsplibc.c`` should be sufficient. 157 158 - It invokes the RTEMS directive ``rtems_initialize_before_drivers()`` to 159 initialize the MPCI Server thread in a multiprocessor configuration and 160 execute API specific extensions. 161 162 - It invokes the BSP specific routine ``bsp_predriver_hook``. For most BSPs, 163 the implementation of this routine does nothing. 164 165 - It invokes the RTEMS directive ``rtems_initialize_device_drivers()`` to 166 initialize the statically configured set of device drivers in the order they 167 were specified in the Configuration Table. 161 168 162 169 - It invokes the BSP specific routine ``bsp_postdriver_hook``. For … … 166 173 for the BSP to insert BSP specific code into the initialization sequence. 167 174 168 - It invokes the RTEMS directive ``rtems_initialize_start_multitasking()``169 which initiates multitasking and performs a context switch to the 170 first user application task and may enable interrupts as a side-effect of171 that context switch. The context switch saves the executing context. The172 application runs now. The directive rtems_shutdown_executive() will return173 to the saved context. The exit() function will use this directive.174 After a return to the saved context a fatal system state is reached. The175 fatal source is RTEMS_FATAL_SOURCE_EXITwith a fatal code set to the value176 passed to rtems_shutdown_executive(). 177 The enabling of interrupts during the first context switch is often the source178 for fatal errors during BSP development because the BSP did not clear and/or179 disable all interrupt sources and a spurious interrupt will occur.180 When in the context of the first task but before its body has been181 entered, any C++ Global Constructorswill be invoked.175 - It invokes the RTEMS directive ``rtems_initialize_start_multitasking()`` 176 which initiates multitasking and performs a context switch to the first user 177 application task and may enable interrupts as a side-effect of that context 178 switch. The context switch saves the executing context. The application 179 runs now. The directive ``rtems_shutdown_executive()`` will return to the 180 saved context. The ``exit()`` function will use this directive. After a 181 return to the saved context a fatal system state is reached. The fatal 182 source is ``RTEMS_FATAL_SOURCE_EXIT`` with a fatal code set to the value 183 passed to rtems_shutdown_executive(). The enabling of interrupts during the 184 first context switch is often the source for fatal errors during BSP 185 development because the BSP did not clear and/or disable all interrupt 186 sources and a spurious interrupt will occur. When in the context of the 187 first task but before its body has been entered, any C++ Global Constructors 188 will be invoked. 182 189 183 190 That's it. We just went through the entire sequence. … … 190 197 C Program Heap and RTEMS Workspace commonly referred to as the work areas. 191 198 Many BSPs place the work areas at the end of RAM although this is certainly not 192 a requirement. Usually the default implementation in:file:`c/src/lib/libbsp/shared/bspgetworkarea.c` should be sufficient. Custom 193 implementations can use ``bsp_work_area_initialize_default()`` or``bsp_work_area_initialize_with_table()`` available as inline functions from``#include <bsp/bootcard.h>``. 199 a requirement. Usually the default implementation 200 in:file:`c/src/lib/libbsp/shared/bspgetworkarea.c` should be sufficient. 201 Custom implementations can use ``bsp_work_area_initialize_default()`` 202 or``bsp_work_area_initialize_with_table()`` available as inline functions from 203 ``#include <bsp/bootcard.h>``. 194 204 195 205 bsp_start() - BSP Specific Initialization … … 197 207 198 208 This is the second BSP specific C routine to execute during system 199 initialization. It is called right after ``bsp_work_area_initialize()``. 200 The``bsp_start()`` routine often performs required fundamental hardware209 initialization. It is called right after ``bsp_work_area_initialize()``. The 210 ``bsp_start()`` routine often performs required fundamental hardware 201 211 initialization such as setting bus controller registers that do not have a 202 212 direct impact on whether or not C code can execute. The interrupt controllers … … 207 217 208 218 After completing execution, this routine returns to the ``boot_card()`` 209 routine. In case of errors, the initialization should be terminated via``bsp_fatal()``. 219 routine. In case of errors, the initialization should be terminated via 220 ``bsp_fatal()``. 210 221 211 222 bsp_predriver_hook() - BSP Specific Predriver Hook 212 223 -------------------------------------------------- 213 224 214 The ``bsp_predriver_hook()`` method is the BSP specific routine that is 215 i nvoked immediately before the the device drivers are initialized. RTEMS216 i nitialization is complete but interrupts and tasking are disabled.217 218 The BSP may use the shared version of this routine which is empty. 219 Most BSPsdo not provide a specific implementation of this callback.225 The ``bsp_predriver_hook()`` method is the BSP specific routine that is invoked 226 immediately before the the device drivers are initialized. RTEMS initialization 227 is complete but interrupts and tasking are disabled. 228 229 The BSP may use the shared version of this routine which is empty. Most BSPs 230 do not provide a specific implementation of this callback. 220 231 221 232 Device Driver Initialization 222 233 ---------------------------- 223 234 224 At this point in the initialization sequence, the initialization 225 routines for all of the device drivers specified in the Device 226 Driver Table are invoked. The initialization routines are invoked 227 in the order they appear in the DeviceDriver Table.228 229 The Driver Address Table is part of the RTEMS Configuration Table. It 230 de fines device drivers entry points (initialization, open, close, read,231 write, and control). For more information about this table, please232 refer to the *Configuring a System* chapter in the*RTEMS Application C User's Guide*.233 234 The RTEMS initialization procedure calls the initialization function for 235 every driver defined in the RTEMS Configuration Table (this allows 236 on e to include only the drivers needed by the application).235 At this point in the initialization sequence, the initialization routines for 236 all of the device drivers specified in the Device Driver Table are invoked. 237 The initialization routines are invoked in the order they appear in the Device 238 Driver Table. 239 240 The Driver Address Table is part of the RTEMS Configuration Table. It defines 241 device drivers entry points (initialization, open, close, read, write, and 242 control). For more information about this table, please refer to the 243 *Configuring a System* chapter in the *RTEMS Application C User's Guide*. 244 245 The RTEMS initialization procedure calls the initialization function for every 246 driver defined in the RTEMS Configuration Table (this allows one to include 247 only the drivers needed by the application). 237 248 238 249 All these primitives have a major and a minor number as arguments: … … 240 251 - the major number refers to the driver type, 241 252 242 - the minor number is used to control two peripherals with the same 243 driver (for instance, we define only one major number for the serial 244 driver, but two minor numbers for channel A and B if there are two 245 channels in the UART). 253 - the minor number is used to control two peripherals with the same driver (for 254 instance, we define only one major number for the serial driver, but two 255 minor numbers for channel A and B if there are two channels in the UART). 246 256 247 257 RTEMS Postdriver Callback 248 258 ------------------------- 249 259 250 The ``bsp_postdriver_hook()`` BSP specific routine is invoked 251 immediately after the the device drivers and MPCI are initialized. 252 Interrupts and tasking are disabled. 253 254 Most BSPs use the shared implementation of this routine which is responsible for opening the device ``/dev/console`` for standard input, output and error if the application has configured the Console Device Driver. This file is located at: 260 The ``bsp_postdriver_hook()`` BSP specific routine is invoked immediately after 261 the the device drivers and MPCI are initialized. Interrupts and tasking are 262 disabled. 263 264 Most BSPs use the shared implementation of this routine which is responsible 265 for opening the device ``/dev/console`` for standard input, output and error if 266 the application has configured the Console Device Driver. This file is located 267 at: 268 255 269 .. code:: c 256 270 … … 260 274 ========================== 261 275 262 The Interrupt Vector Table is called different things on different 263 processor families but the basic functionality is the same. Each 264 entry in the Table corresponds to the handler routine for a particular 265 interrupt source. When an interrupt from that source occurs, the 266 specified handler routine is invoked. Some context information is 267 saved by the processor automatically when this happens. RTEMS saves 268 enough context information so that an interrupt service routine 269 can be implemented in a high level language. 270 271 On some processors, the Interrupt Vector Table is at a fixed address. If 272 this address is in RAM, then usually the BSP only has to initialize 273 it to contain pointers to default handlers. If the table is in ROM, 274 then the application developer will have to take special steps to 275 fill in the table. 276 277 If the base address of the Interrupt Vector Table can be dynamically 278 changed to an arbitrary address, then the RTEMS port to that processor 279 family will usually allocate its own table and install it. For example, 280 on some members of the Motorola MC68xxx family, the Vector Base Register 281 (``vbr``) contains this base address. 276 The Interrupt Vector Table is called different things on different processor 277 families but the basic functionality is the same. Each entry in the Table 278 corresponds to the handler routine for a particular interrupt source. When an 279 interrupt from that source occurs, the specified handler routine is invoked. 280 Some context information is saved by the processor automatically when this 281 happens. RTEMS saves enough context information so that an interrupt service 282 routine can be implemented in a high level language. 283 284 On some processors, the Interrupt Vector Table is at a fixed address. If this 285 address is in RAM, then usually the BSP only has to initialize it to contain 286 pointers to default handlers. If the table is in ROM, then the application 287 developer will have to take special steps to fill in the table. 288 289 If the base address of the Interrupt Vector Table can be dynamically changed to 290 an arbitrary address, then the RTEMS port to that processor family will usually 291 allocate its own table and install it. For example, on some members of the 292 Motorola MC68xxx family, the Vector Base Register (``vbr``) contains this base 293 address. 282 294 283 295 Interrupt Vector Table on the gen68340 BSP 284 296 ------------------------------------------ 285 297 286 The gen68340 BSP provides a default Interrupt Vector Table in the 287 file ``$BSP_ROOT/start340/start340.s``. After the ``entry`` 288 label is the definition of space reserved for the table of 289 interrupts vectors. This space is assigned the symbolic name 290 of ``__uhoh`` in the ``gen68340`` BSP. 291 292 At ``__uhoh`` label is the default interrupt handler routine. This 293 routine is only called when an unexpected interrupts is raised. One can 294 add their own routine there (in that case there's a call to a routine - 295 $BSP_ROOT/startup/dumpanic.c - that prints which address caused the 296 interrupt and the contents of the registers, stack, etc.), but this should 297 not return. 298 The gen68340 BSP provides a default Interrupt Vector Table in the file 299 ``$BSP_ROOT/start340/start340.s``. After the ``entry`` label is the definition 300 of space reserved for the table of interrupts vectors. This space is assigned 301 the symbolic name of ``__uhoh`` in the ``gen68340`` BSP. 302 303 At ``__uhoh`` label is the default interrupt handler routine. This routine is 304 only called when an unexpected interrupts is raised. One can add their own 305 routine there (in that case there's a call to a routine - 306 $BSP_ROOT/startup/dumpanic.c - that prints which address caused the interrupt 307 and the contents of the registers, stack, etc.), but this should not return. 298 308 299 309 Chip Select Initialization 300 310 ========================== 301 311 302 When the microprocessor accesses a memory area, address decoding is 303 handled by an address decoder, so that the microprocessor knows which 304 memory chip(s) to access.The following figure illustrates this:305 306 .. code:: c312 When the microprocessor accesses a memory area, address decoding is handled by 313 an address decoder, so that the microprocessor knows which memory chip(s) to 314 access. The following figure illustrates this: 315 316 .. code:: 307 317 308 318 +-------------------+ 309 319 ------------| | 310 ------------| \|------------311 ------------| Address \|------------312 ------------| Decoder \|------------313 ------------| \|------------320 ------------| |------------ 321 ------------| Address |------------ 322 ------------| Decoder |------------ 323 ------------| |------------ 314 324 ------------| | 315 325 +-------------------+ 316 326 CPU Bus Chip Select 317 327 318 The Chip Select registers must be programmed such that they match 319 the ``linkcmds`` settings. In the gen68340 BSP, ROM and RAM 320 addresses can be found in both the ``linkcmds`` and initialization 321 code, but this is not a great way to do this. It is better to 322 define addresses in the linker script. 328 The Chip Select registers must be programmed such that they match the 329 ``linkcmds`` settings. In the gen68340 BSP, ROM and RAM addresses can be found 330 in both the ``linkcmds`` and initialization code, but this is not a great way 331 to do this. It is better to define addresses in the linker script. 323 332 324 333 Integrated Processor Registers Initialization 325 334 ============================================= 326 335 327 The CPUs used in many embedded systems are highly complex devices 328 with multiple peripherals on the CPU itself. For these devices, 329 there are always some specific integrated processor registers 330 that must be initialized. Refer to the processors' manuals for 331 details on these registers and be VERY carefulprogramming them.336 The CPUs used in many embedded systems are highly complex devices with multiple 337 peripherals on the CPU itself. For these devices, there are always some 338 specific integrated processor registers that must be initialized. Refer to the 339 processors' manuals for details on these registers and be VERY careful 340 programming them. 332 341 333 342 Data Section Recopy 334 343 =================== 335 344 336 The next initialization part can be found in``$BSP340_ROOT/start340/init68340.c``. First the Interrupt 337 Vector Table is copied into RAM, then the data section recopy is initiated 338 (_CopyDataClearBSSAndStart in ``$BSP340_ROOT/start340/startfor340only.s``). 345 The next initialization part can be found in 346 ``$BSP340_ROOT/start340/init68340.c``. First the Interrupt Vector Table is 347 copied into RAM, then the data section recopy is initiated 348 (``_CopyDataClearBSSAndStart`` in ``$BSP340_ROOT/start340/startfor340only.s``). 339 349 340 350 This code performs the following actions: 341 351 342 - copies the .data section from ROM to its location reserved in RAM 343 (see `Initialized Data`_ for more details about this copy), 344 345 - clear ``.bss`` section (all the non-initialized 346 data will take value 0). 352 - copies the .data section from ROM to its location reserved in RAM (see 353 `Initialized Data`_ for more details about this copy), 354 355 - clear ``.bss`` section (all the non-initialized data will take value 0). 347 356 348 357 The RTEMS Configuration Table 349 358 ============================= 350 359 351 The RTEMS configuration table contains the maximum number of objects RTEMS 352 can handle during the application (e.g. maximum number of tasks, 353 semaphores, etc.). It's used to allocate the size for the RTEMS inner data 354 structures. 355 356 The RTEMS configuration table is application dependent, which means that 357 one has to provide one per application. It is usually defined by defining 358 macros and including the header file ``<rtems/confdefs.h>``. In simple 359 applications such as the tests provided with RTEMS, it is commonly found 360 in the main module of the application. For more complex applications, 361 it may be in a file by itself. 362 363 The header file ``<rtems/confdefs.h>`` defines a constant table 364 named ``Configuration``. With RTEMS 4.8 and older, it was accepted 365 practice for the BSP to copy this table into a modifiable copy named``BSP_Configuration``. This copy of the table was modified to define 366 the base address of the RTEMS Executive Workspace as well as to reflect 367 any BSP and device driver requirements not automatically handled by the 368 application. In 4.9 and newer, we have eliminated the BSP copies of the 369 configuration tables and are making efforts to make the configuration 370 information generated by ``<rtems/confdefs.h>`` constant and read only. 371 372 For more information on the RTEMS Configuration Table, refer to the*RTEMS Application C User's Guide*. 373 374 .. COMMENT: COPYRIGHT (c) 1988-2008. 375 376 .. COMMENT: On-Line Applications Research Corporation (OAR). 377 378 .. COMMENT: All rights reserved. 379 360 The RTEMS configuration table contains the maximum number of objects RTEMS can 361 handle during the application (e.g. maximum number of tasks, semaphores, 362 etc.). It's used to allocate the size for the RTEMS inner data structures. 363 364 The RTEMS configuration table is application dependent, which means that one 365 has to provide one per application. It is usually defined by defining macros 366 and including the header file ``<rtems/confdefs.h>``. In simple applications 367 such as the tests provided with RTEMS, it is commonly found in the main module 368 of the application. For more complex applications, it may be in a file by 369 itself. 370 371 The header file ``<rtems/confdefs.h>`` defines a constant table named 372 ``Configuration``. With RTEMS 4.8 and older, it was accepted practice for the 373 BSP to copy this table into a modifiable copy named ``BSP_Configuration``. 374 This copy of the table was modified to define the base address of the RTEMS 375 Executive Workspace as well as to reflect any BSP and device driver 376 requirements not automatically handled by the application. In 4.9 and newer, 377 we have eliminated the BSP copies of the configuration tables and are making 378 efforts to make the configuration information generated by 379 ``<rtems/confdefs.h>`` constant and read only. 380 381 For more information on the RTEMS Configuration Table, refer to the *RTEMS 382 Application C User's Guide*. -
bsp_howto/linker_script.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 4 .. COMMENT: COPYRIGHT (c) 1988-2011. 5 .. COMMENT: On-Line Applications Research Corporation (OAR). 6 .. COMMENT: All rights reserved. 2 7 3 8 Linker Script … … 8 13 9 14 The ``linkcmds`` file is a script which is passed to the linker at linking 10 time. This file describes the memory configuration of the board as needed 11 to link the program. Specifically it specifies where the code and data 12 for the application will reside in memory. 13 14 The format of the linker script is defined by the GNU Loader ``ld`` 15 which is included as a component of the GNU Binary Utilities. If you 16 are using GNU/Linux, then you probably have the documentation installed 17 already and are using these same tools configured for *native* use. 18 Please visit the Binutils project http://sourceware.org/binutils/ 19 if you need more information. 15 time. This file describes the memory configuration of the board as needed to 16 link the program. Specifically it specifies where the code and data for the 17 application will reside in memory. 18 19 The format of the linker script is defined by the GNU Loader ``ld`` which is 20 included as a component of the GNU Binary Utilities. If you are using 21 GNU/Linux, then you probably have the documentation installed already and are 22 using these same tools configured for *native* use. Please visit the Binutils 23 project http://sourceware.org/binutils/ if you need more information. 20 24 21 25 Program Sections 22 26 ================ 23 27 24 An embedded systems programmer must be much more aware of the 25 placement of their executable image in memory than the average 26 applications programmer. A program destined to be embedded as well 27 as the target system have some specific properties that must be 28 taken into account. Embedded machines often mean average performances 29 and small memory usage. It is the memory usage that concerns us 30 when examining the linker command file. 28 An embedded systems programmer must be much more aware of the placement of 29 their executable image in memory than the average applications programmer. A 30 program destined to be embedded as well as the target system have some specific 31 properties that must be taken into account. Embedded machines often mean 32 average performances and small memory usage. It is the memory usage that 33 concerns us when examining the linker command file. 31 34 32 35 Two types of memories have to be distinguished: … … 36 39 - ROM - non-volatile but read only 37 40 38 Even though RAM and ROM can be found in every personal computer, 39 one generally doesn't care about them. In a personal computer, 40 a program is nearly always stored on disk and executed in RAM. Things 41 are a bit different for embedded targets: the target will execute the 42 program each time it is rebooted or switched on. The application 43 program is stored in non-volatile memory such as ROM, PROM, EEPROM, 44 or Flash. On the other hand, data processing occurs in RAM. 45 46 This leads us to the structure of an embedded program. In rough terms, 47 an embedded program is made of sections. It is the responsibility of 48 the application programmer to place these sections in the appropriate 49 place in target memory. To make this clearer, if using the COFF 50 object file format on the Motorola m68k family of microprocessors, 51 the following sections will be present: 52 53 - *code (``.text``) section*: 54 is the program's code and it should not be modified. 55 This section may be placed in ROM. 56 57 - *non-initialized data (``.bss``) section*: 41 Even though RAM and ROM can be found in every personal computer, one generally 42 doesn't care about them. In a personal computer, a program is nearly always 43 stored on disk and executed in RAM. Things are a bit different for embedded 44 targets: the target will execute the program each time it is rebooted or 45 switched on. The application program is stored in non-volatile memory such as 46 ROM, PROM, EEPROM, or Flash. On the other hand, data processing occurs in RAM. 47 48 This leads us to the structure of an embedded program. In rough terms, an 49 embedded program is made of sections. It is the responsibility of the 50 application programmer to place these sections in the appropriate place in 51 target memory. To make this clearer, if using the COFF object file format on 52 the Motorola m68k family of microprocessors, the following sections will be 53 present: 54 55 - code (``.text``) section: 56 is the program's code and it should not be modified. This section may be 57 placed in ROM. 58 59 - non-initialized data (``.bss``) section: 58 60 holds uninitialized variables of the program. It can stay in RAM. 59 61 60 - *initialized data (``.data``) section*: 61 holds the initialized program data which may be modified during the 62 program's life. This means they have to be in RAM. 63 On the other hand, these variables must be set to predefined values, and 64 those predefined values have to be stored in ROM. 65 66 *NOTE:* Many programs and support libraries unknowingly assume that the``.bss`` section and, possibly, the application heap are initialized 67 to zero at program start. This is not required by the ISO/ANSI C Standard 68 but is such a common requirement that most BSPs do this. 69 70 That brings us up to the notion of the image of an executable: it consists 71 of the set of the sections that together constitute the application. 62 - initialized data (``.data``) section: 63 holds the initialized program data which may be modified during the program's 64 life. This means they have to be in RAM. On the other hand, these variables 65 must be set to predefined values, and those predefined values have to be 66 stored in ROM. 67 68 .. note:: 69 70 Many programs and support libraries unknowingly assume that the ``.bss`` 71 section and, possibly, the application heap are initialized to zero at 72 program start. This is not required by the ISO/ANSI C Standard but is such 73 a common requirement that most BSPs do this. 74 75 That brings us up to the notion of the image of an executable: it consists of 76 the set of the sections that together constitute the application. 72 77 73 78 Image of an Executable 74 79 ====================== 75 80 76 As a program executable has many sections (note that the user can define 77 their own, and that compilers define theirs without any notice), one has to 78 specify the placement of each section as well as the type of memory 79 (RAM or ROM) the sections will be placed into. 80 For instance, a program compiled for a Personal Computer will see all the 81 sections to go to RAM, while a program destined to be embedded will see 82 some of his sections going into the ROM. 83 84 The connection between a section and where that section is loaded into 85 memory is made at link time. One has to let the linker know where 86 the different sections are to be placed once they are in memory. 87 88 The following example shows a simple layout of program sections. With 89 some object formats, there are many more sections but the basic 90 layout is conceptually similar. 91 .. code:: c 92 93 +-----------------+-------------+ 94 | .text | RAM or ROM | 95 +-----------------+-------------+ 96 | .data | RAM | 97 +-----------------+-------------+ 98 | .bss | RAM | 99 +-----------------+-------------+ 81 As a program executable has many sections (note that the user can define their 82 own, and that compilers define theirs without any notice), one has to specify 83 the placement of each section as well as the type of memory (RAM or ROM) the 84 sections will be placed into. For instance, a program compiled for a Personal 85 Computer will see all the sections to go to RAM, while a program destined to be 86 embedded will see some of his sections going into the ROM. 87 88 The connection between a section and where that section is loaded into memory 89 is made at link time. One has to let the linker know where the different 90 sections are to be placed once they are in memory. 91 92 The following example shows a simple layout of program sections. With some 93 object formats, there are many more sections but the basic layout is 94 conceptually similar. 95 96 ============ ============= 97 .text RAM or ROM 98 .data RAM 99 .bss RAM 100 ============ ============= 100 101 101 102 Example Linker Command Script … … 103 104 104 105 The GNU linker has a command language to specify the image format. This 105 command language can be quite complicated but most of what is required 106 can be learned by careful examination of a well-documented example. 107 The following is a heavily commented version of the linker script 108 used with the the ``gen68340`` BSP This file can be found at 109 $BSP340_ROOT/startup/linkcmds. 106 command language can be quite complicated but most of what is required can be 107 learned by careful examination of a well-documented example. The following is 108 a heavily commented version of the linker script used with the the ``gen68340`` 109 BSP This file can be found at $BSP340_ROOT/startup/linkcmds. 110 110 111 .. code:: c 111 112 112 113 /* 113 * Specify that the output is to be coff-m68k regardless of what the114 * native object format is.115 \*/114 * Specify that the output is to be coff-m68k regardless of what the 115 * native object format is. 116 */ 116 117 OUTPUT_FORMAT(coff-m68k) 117 118 /* 118 * Set the amount of RAM on the target board.119 *120 * NOTE: The default may be overridden by passing an argument to ld.121 \*/119 * Set the amount of RAM on the target board. 120 * 121 * NOTE: The default may be overridden by passing an argument to ld. 122 */ 122 123 RamSize = DEFINED(RamSize) ? RamSize : 4M; 123 124 /* 124 * Set the amount of RAM to be used for the application heap. Objects125 * allocated using malloc() come from this area. Having a tight heap126 * size is somewhat difficult and multiple attempts to squeeze it may127 * be needed reducing memory usage is important. If all objects are128 * allocated from the heap at system initialization time, this eases129 * the sizing of the application heap.130 *131 * NOTE 1: The default may be overridden by passing an argument to ld.132 *133 * NOTE 2: The TCP/IP stack requires additional memory in the Heap.134 *135 * NOTE 3: The GNAT/RTEMS run-time requires additional memory in136 * the Heap.137 \*/125 * Set the amount of RAM to be used for the application heap. Objects 126 * allocated using malloc() come from this area. Having a tight heap 127 * size is somewhat difficult and multiple attempts to squeeze it may 128 * be needed reducing memory usage is important. If all objects are 129 * allocated from the heap at system initialization time, this eases 130 * the sizing of the application heap. 131 * 132 * NOTE 1: The default may be overridden by passing an argument to ld. 133 * 134 * NOTE 2: The TCP/IP stack requires additional memory in the Heap. 135 * 136 * NOTE 3: The GNAT/RTEMS run-time requires additional memory in 137 * the Heap. 138 */ 138 139 HeapSize = DEFINED(HeapSize) ? HeapSize : 0x10000; 139 140 /* 140 * Set the size of the starting stack used during BSP initialization141 * until first task switch. After that point, task stacks allocated142 * by RTEMS are used.143 *144 * NOTE: The default may be overridden by passing an argument to ld.145 \*/141 * Set the size of the starting stack used during BSP initialization 142 * until first task switch. After that point, task stacks allocated 143 * by RTEMS are used. 144 * 145 * NOTE: The default may be overridden by passing an argument to ld. 146 */ 146 147 StackSize = DEFINED(StackSize) ? StackSize : 0x1000; 147 148 /* 148 * Starting addresses and length of RAM and ROM.149 *150 * The addresses must be valid addresses on the board. The151 * Chip Selects should be initialized such that the code addresses152 * are valid.153 \*/149 * Starting addresses and length of RAM and ROM. 150 * 151 * The addresses must be valid addresses on the board. The 152 * Chip Selects should be initialized such that the code addresses 153 * are valid. 154 */ 154 155 MEMORY { 155 156 ram : ORIGIN = 0x10000000, LENGTH = 4M … … 157 158 } 158 159 /* 159 * This is for the network driver. See the Networking documentation160 * for more details.161 \*/160 * This is for the network driver. See the Networking documentation 161 * for more details. 162 */ 162 163 ETHERNET_ADDRESS = 163 164 DEFINED(ETHERNET_ADDRESS) ? ETHERNET_ADDRESS : 0xDEAD12; 164 165 /* 165 * The following defines the order in which the sections should go.166 * It also defines a number of variables which can be used by the167 * application program.168 *169 * NOTE: Each variable appears with 1 or 2 leading underscores to170 * ensure that the variable is accessible from C code with a171 * single underscore. Some object formats automatically add172 * a leading underscore to all C global symbols.173 \*/166 * The following defines the order in which the sections should go. 167 * It also defines a number of variables which can be used by the 168 * application program. 169 * 170 * NOTE: Each variable appears with 1 or 2 leading underscores to 171 * ensure that the variable is accessible from C code with a 172 * single underscore. Some object formats automatically add 173 * a leading underscore to all C global symbols. 174 */ 174 175 SECTIONS { 175 176 /* 176 * Make the RomBase variable available to the application.177 \*/177 * Make the RomBase variable available to the application. 178 */ 178 179 _RamSize = RamSize; 179 180 __RamSize = RamSize; 180 181 /* 181 * Boot PROM - Set the RomBase variable to the start of the ROM.182 \*/182 * Boot PROM - Set the RomBase variable to the start of the ROM. 183 */ 183 184 rom : { 184 _RomBase = .;185 __RomBase = .;185 _RomBase = .; 186 __RomBase = .; 186 187 } >rom 187 188 /* 188 * Dynamic RAM - set the RamBase variable to the start of the RAM.189 \*/189 * Dynamic RAM - set the RamBase variable to the start of the RAM. 190 */ 190 191 ram : { 191 _RamBase = .;192 __RamBase = .;193 } >ram 194 /* 195 * Text (code) goes into ROM196 \*/192 _RamBase = .; 193 __RamBase = .; 194 } >ram 195 /* 196 * Text (code) goes into ROM 197 */ 197 198 .text : { 198 /*199 * Create a symbol for each object (.o).200 \*/201 CREATE_OBJECT_SYMBOLS202 /*203 * Put all the object files code sections here.204 \*/205 \*(.text)206 . = ALIGN (16); /* go to a 16-byte boundary \*/207 /*208 * C++ constructors and destructors209 *210 * NOTE: See the CROSSGCC mailing-list FAQ for211 * more details about the "\[......]".212 \*/213 __CTOR_LIST__ = .;214 \[......]215 __DTOR_END__ = .;216 /*217 * Declares where the .text section ends.218 \*/219 etext = .;220 _etext = .;199 /* 200 * Create a symbol for each object (.o). 201 */ 202 CREATE_OBJECT_SYMBOLS 203 /* 204 * Put all the object files code sections here. 205 */ 206 *(.text) 207 . = ALIGN (16); /* go to a 16-byte boundary */ 208 /* 209 * C++ constructors and destructors 210 * 211 * NOTE: See the CROSSGCC mailing-list FAQ for 212 * more details about the "\[......]". 213 */ 214 __CTOR_LIST__ = .; 215 [......] 216 __DTOR_END__ = .; 217 /* 218 * Declares where the .text section ends. 219 */ 220 etext = .; 221 _etext = .; 221 222 } >rom 222 223 /* 223 * Exception Handler Frame section224 \*/224 * Exception Handler Frame section 225 */ 225 226 .eh_fram : { 226 . = ALIGN (16);227 \*(.eh_fram)228 } >ram 229 /* 230 * GCC Exception section231 \*/227 . = ALIGN (16); 228 *(.eh_fram) 229 } >ram 230 /* 231 * GCC Exception section 232 */ 232 233 .gcc_exc : { 233 . = ALIGN (16);234 \*(.gcc_exc)235 } >ram 236 /* 237 * Special variable to let application get to the dual-ported238 * memory.239 \*/234 . = ALIGN (16); 235 *(.gcc_exc) 236 } >ram 237 /* 238 * Special variable to let application get to the dual-ported 239 * memory. 240 */ 240 241 dpram : { 241 m340 = .;242 _m340 = .;243 . += (8 * 1024);244 } >ram 245 /* 246 * Initialized Data section goes in RAM247 \*/242 m340 = .; 243 _m340 = .; 244 . += (8 * 1024); 245 } >ram 246 /* 247 * Initialized Data section goes in RAM 248 */ 248 249 .data : { 249 copy_start = .;250 \*(.data)251 . = ALIGN (16);252 _edata = .;253 copy_end = .;254 } >ram 255 /* 256 * Uninitialized Data section goes in ROM257 \*/250 copy_start = .; 251 *(.data) 252 . = ALIGN (16); 253 _edata = .; 254 copy_end = .; 255 } >ram 256 /* 257 * Uninitialized Data section goes in ROM 258 */ 258 259 .bss : { 259 /* 260 * M68K specific: Reserve some room for the Vector Table 261 * (256 vectors of 4 bytes). 262 \*/ 263 M68Kvec = .; 264 _M68Kvec = .; 265 . += (256 * 4); 266 /* 267 * Start of memory to zero out at initialization time. 268 \*/ 269 clear_start = .; 270 /* 271 * Put all the object files uninitialized data sections 272 * here. 273 \*/ 274 \*(.bss) 275 \*(COMMON) 276 . = ALIGN (16); 277 _end = .; 278 /* 279 * Start of the Application Heap 280 \*/ 281 _HeapStart = .; 282 __HeapStart = .; 283 . += HeapSize; 284 /* 285 * The Starting Stack goes after the Application Heap. 286 * M68K stack grows down so start at high address. 287 \*/ 288 . += StackSize; 289 . = ALIGN (16); 290 stack_init = .; 291 clear_end = .; 292 /* 293 * The RTEMS Executive Workspace goes here. RTEMS 294 * allocates tasks, stacks, semaphores, etc. from this 295 * memory. 296 \*/ 297 _WorkspaceBase = .; 298 __WorkspaceBase = .; 299 } >ram 300 } 260 /* 261 * M68K specific: Reserve some room for the Vector Table 262 * (256 vectors of 4 bytes). 263 */ 264 M68Kvec = .; 265 _M68Kvec = .; 266 . += (256 * 4); 267 /* 268 * Start of memory to zero out at initialization time. 269 */ 270 clear_start = .; 271 /* 272 * Put all the object files uninitialized data sections 273 * here. 274 */ 275 *(.bss) 276 *(COMMON) 277 . = ALIGN (16); 278 _end = .; 279 /* 280 * Start of the Application Heap 281 */ 282 _HeapStart = .; 283 __HeapStart = .; 284 . += HeapSize; 285 /* 286 * The Starting Stack goes after the Application Heap. 287 * M68K stack grows down so start at high address. 288 */ 289 . += StackSize; 290 . = ALIGN (16); 291 stack_init = .; 292 clear_end = .; 293 /* 294 * The RTEMS Executive Workspace goes here. RTEMS 295 * allocates tasks, stacks, semaphores, etc. from this 296 * memory. 297 */ 298 _WorkspaceBase = .; 299 __WorkspaceBase = .; 300 } >ram 301 301 302 302 Initialized Data 303 303 ================ 304 304 305 Now there's a problem with the initialized data: the ``.data`` section 306 has to be in RAM as this data may be modified during the program execution. 307 But how will the values be initialized at boot time? 308 309 One approach is to place the entire program image in RAM and reload 310 the image in its entirety each time the program is run. This is fine 311 for use in a debug environment where a high-speed connection is available 312 between the development host computer and the target. But even in this 313 environment, it is cumbersome. 314 315 The solution is to place a copy of the initialized data in a separate 316 area of memory and copy it into the proper location each time the 317 program is started. It is common practice to place a copy of the initialized ``.data`` section at the end of the code (``.text``) section 318 in ROM when building a PROM image. The GNU tool ``objcopy`` 319 can be used for this purpose. 305 Now there's a problem with the initialized data: the ``.data`` section has to 306 be in RAM as this data may be modified during the program execution. But how 307 will the values be initialized at boot time? 308 309 One approach is to place the entire program image in RAM and reload the image 310 in its entirety each time the program is run. This is fine for use in a debug 311 environment where a high-speed connection is available between the development 312 host computer and the target. But even in this environment, it is cumbersome. 313 314 The solution is to place a copy of the initialized data in a separate area of 315 memory and copy it into the proper location each time the program is started. 316 It is common practice to place a copy of the initialized ``.data`` section at 317 the end of the code (``.text``) section in ROM when building a PROM image. The 318 GNU tool ``objcopy`` can be used for this purpose. 320 319 321 320 The following figure illustrates the steps a linked program goes through 322 321 to become a downloadable image. 323 322 324 325 +--------------+-----+--------------------+--------------------------+ 326 | .data RAM | | .data RAM ||327 +--------------+ +--------------------+|328 | .bss RAM | | .bss RAM | | 329 +--------------+ +--------------------+-----+--------------------+ 330 | .text ROM | | .text ROM | | .text | 331 +--------------+-----+---------+----------+-----+--------------------+ 332 | copy of .data ROM | | copy of .data | | 333 +--------------------+---------+----------------+--------------------+ 334 | Step 1 |Step 2 Step 3 | 335 +--------------------+--------------------------+--------------------+ 323 +--------------+------+--------------------------+--------------------+ 324 | .data (RAM) | | .data (RAM) | | 325 +--------------+ +--------------------------+ | 326 | .bss (RAM) | | .bss (RAM) | | 327 +--------------+ +--------------------------+--------------------+ 328 | .text (ROM) | | .text (ROM) | .text | 329 +--------------+------+---------+----------+-----+--------------------+ 330 | copy of .data (ROM) | | copy of .data | | 331 +---------------------+---------+----------------+--------------------+ 332 | Step 1 | Step 2 | Step 3 | 333 +---------------------+--------------------------+--------------------+ 334 336 335 337 336 In Step 1, the program is linked together using the BSP linker script. 338 337 339 In Step 2, a copy is made of the ``.data`` section and placed 340 after the ``.text`` section so it can be placed in PROM. This step 341 is done after the linking time. There is an example 342 of doing this in the file $RTEMS_ROOT/make/custom/gen68340.cfg: 343 .. code:: c 338 In Step 2, a copy is made of the ``.data`` section and placed after the 339 ``.text`` section so it can be placed in PROM. This step is done after the 340 linking time. There is an example of doing this in the file 341 $RTEMS_ROOT/make/custom/gen68340.cfg: 342 343 .. code-block:: shell 344 344 345 345 # make a PROM image using objcopy 346 m68k-rtems-objcopy \\ 347 --adjust-section-vma .data= \\ 348 \`m68k-rtems-objdump --section-headers \\ 349 $(basename $@).exe \\ 350 | awk '\[...]` \\ 346 m68k-rtems-objcopy --adjust-section-vma \ 347 .data=`m68k-rtems-objdump --section-headers $(basename $@).exe | awk '[...]'` \ 351 348 $(basename $@).exe 352 349 353 NOTE: The address of the "copy of ``.data`` section" is 354 created by extracting the last address in the ``.text`` 355 section with an ``awk`` script. The details of how 356 this is done are not relevant. 357 358 Step 3 shows the final executable image as it logically appears in 359 the target's non-volatile program memory. The board initialization 360 code will copy the ""copy of ``.data`` section" (which are stored in 361 ROM) to their reserved location in RAM. 362 363 .. COMMENT: COPYRIGHT (c) 1988-2011. 364 365 .. COMMENT: On-Line Applications Research Corporation (OAR). 366 367 .. COMMENT: All rights reserved. 368 350 .. note:: 351 352 The address of the "copy of ``.data`` section" is created by extracting the 353 last address in the ``.text`` section with an ``awk`` script. The details 354 of how this is done are not relevant. 355 356 Step 3 shows the final executable image as it logically appears in the target's 357 non-volatile program memory. The board initialization code will copy the 358 ""copy of ``.data`` section" (which are stored in ROM) to their reserved 359 location in RAM. -
bsp_howto/makefiles.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Makefiles … … 5 9 6 10 This chapter discusses the Makefiles associated with a BSP. It does not 7 describe the process of configuring, building, and installing RTEMS. 8 This chapter will not provide detailed information about this process. 9 Nonetheless, it is important to remember that the general process consists10 of four phases asshown here:11 describe the process of configuring, building, and installing RTEMS. This 12 chapter will not provide detailed information about this process. Nonetheless, 13 it is important to remember that the general process consists of four phases as 14 shown here: 11 15 12 - .. code:: c16 - ``bootstrap`` 13 17 14 bootstrap 18 - ``configure`` 15 19 16 - .. code:: c20 - ``build`` 17 21 18 configure 22 - ``install`` 19 23 20 - .. code:: c 24 During the bootstrap phase, you are using the ``configure.ac`` and 25 ``Makefile.am`` files as input to GNU autoconf and automake to generate a 26 variety of files. This is done by running the ``bootstrap`` script found at 27 the top of the RTEMS source tree. 21 28 22 build 29 During the configure phase, a number of files are generated. These generated 30 files are tailored for the specific host/target combination by the configure 31 script. This set of files includes the Makefiles used to actually compile and 32 install RTEMS. 23 33 24 - .. code:: c 34 During the build phase, the source files are compiled into object files and 35 libraries are built. 25 36 26 install 27 28 During the bootstrap phase, you are using the ``configure.ac`` and``Makefile.am`` files as input to GNU autoconf and automake to 29 generate a variety of files. This is done by running the ``bootstrap`` 30 script found at the top of the RTEMS source tree. 31 32 During the configure phase, a number of files are generated. These 33 generated files are tailored for the specific host/target combination 34 by the configure script. This set of files includes the Makefiles used 35 to actually compile and install RTEMS. 36 37 During the build phase, the source files are compiled into object files 38 and libraries are built. 39 40 During the install phase, the libraries, header files, and other support 41 files are copied to the BSP specific installation point. After installation 42 is successfully completed, the files generated by the configure and build 43 phases may be removed. 37 During the install phase, the libraries, header files, and other support files 38 are copied to the BSP specific installation point. After installation is 39 successfully completed, the files generated by the configure and build phases 40 may be removed. 44 41 45 42 Makefiles Used During The BSP Building Process 46 43 ============================================== 47 44 48 RTEMS uses the *GNU automake* and *GNU autoconf* automatic 49 configuration package. Consequently, there are a number of 50 automatically generated files in each directory in the RTEMS 51 source tree. The ``bootstrap`` script found in the top level 52 directory of the RTEMS source tree is executed to produce the 53 automatically generated files. That script must be run from 54 a directory with a ``configure.ac`` file in it. The ``bootstrap`` 55 command is usually invoked in one of the following manners: 45 RTEMS uses the *GNU automake* and *GNU autoconf* automatic configuration 46 package. Consequently, there are a number of automatically generated files in 47 each directory in the RTEMS source tree. The ``bootstrap`` script found in the 48 top level directory of the RTEMS source tree is executed to produce the 49 automatically generated files. That script must be run from a directory with a 50 ``configure.ac`` file in it. The ``bootstrap`` command is usually invoked in 51 one of the following manners: 56 52 57 - ``bootstrap`` to regenerate all files that are generated by 58 auto conf and automake.53 - ``bootstrap`` to regenerate all files that are generated by autoconf and 54 automake. 59 55 60 - ``bootstrap -c`` to remove all files generated by autoconf and 61 automake. 56 - ``bootstrap -c`` to remove all files generated by autoconf and automake. 62 57 63 58 - ``bootstrap -p`` to regenerate ``preinstall.am`` files. 64 59 65 There is a file named ``Makefile.am`` in each directory of 66 a BSP. This file is used by *automake* to produce the file named``Makefile.in`` which is also found in each directory of a BSP. 67 When modifying a ``Makefile.am``, you can probably find examples of 68 anything you need to do in one of the BSPs.60 There is a file named ``Makefile.am`` in each directory of a BSP. This file is 61 used by *automake* to produce the file named ``Makefile.in`` which is also 62 found in each directory of a BSP. When modifying a ``Makefile.am``, you can 63 probably find examples of anything you need to do in one of the BSPs. 69 64 70 The configure process specializes the ``Makefile.in`` files at the time that RTEMS 71 is configured for a specific development host and target. Makefiles 72 are automatically generated from the ``Makefile.in`` files. It is 73 necessary for the BSP developer to provide the ``Makefile.am`` 74 files and generate the ``Makefile.in`` files. Most of the 75 time, it is possible to copy the ``Makefile.am`` from another 76 similar directory and edit it. 65 The configure process specializes the ``Makefile.in`` files at the time that 66 RTEMS is configured for a specific development host and target. Makefiles are 67 automatically generated from the ``Makefile.in`` files. It is necessary for 68 the BSP developer to provide the ``Makefile.am`` files and generate the 69 ``Makefile.in`` files. Most of the time, it is possible to copy the 70 ``Makefile.am`` from another similar directory and edit it. 77 71 78 The ``Makefile`` files generated are processed when configuring 79 and buildingRTEMS for a given BSP.72 The ``Makefile`` files generated are processed when configuring and building 73 RTEMS for a given BSP. 80 74 81 The BSP developer is responsible for generating ``Makefile.am`` 82 files which properly build all the files associated with their BSP. 83 Most BSPs will only have a single ``Makefile.am`` which details 84 the set of source files to build to compose the BSP support library 85 along with the set of include files that are tobe installed.75 The BSP developer is responsible for generating ``Makefile.am`` files which 76 properly build all the files associated with their BSP. Most BSPs will only 77 have a single ``Makefile.am`` which details the set of source files to build to 78 compose the BSP support library along with the set of include files that are to 79 be installed. 86 80 87 This single ``Makefile.am`` at the top of the BSP tree specifies 88 the set of header files to install. This fragment from the SPARC/ERC32 89 BSP results in four header files being installed. 90 .. code:: c 81 This single ``Makefile.am`` at the top of the BSP tree specifies the set of 82 header files to install. This fragment from the SPARC/ERC32 BSP results in 83 four header files being installed. 84 85 .. code-block:: makefile 91 86 92 87 include_HEADERS = include/bsp.h … … 95 90 include_HEADERS += include/coverhd.h 96 91 97 When adding new include files, you will be adding to the set of``include_HEADERS``. When you finish editing the ``Makefile.am`` 98 file, do not forget to run ``bootstrap -p`` to regenerate the``preinstall.am``. 92 When adding new include files, you will be adding to the set of 93 ``include_HEADERS``. When you finish editing the ``Makefile.am`` file, do not 94 forget to run ``bootstrap -p`` to regenerate the ``preinstall.am``. 99 95 100 The ``Makefile.am`` also specifies which source files to build. 101 By convention, logical components within the BSP each assign their 102 source files to a unique variable. These variables which define 103 the source files are collected into a single variable which instructs 104 the GNU autotools that we are building ``libbsp.a``. This fragment 105 from the SPARC/ERC32 BSP shows how the startup related, miscellaneous 106 support code, and the console device driver source is managed 107 in the ``Makefile.am``. 108 .. code:: c 96 The ``Makefile.am`` also specifies which source files to build. By convention, 97 logical components within the BSP each assign their source files to a unique 98 variable. These variables which define the source files are collected into a 99 single variable which instructs the GNU autotools that we are building 100 ``libbsp.a``. This fragment from the SPARC/ERC32 BSP shows how the startup 101 related, miscellaneous support code, and the console device driver source is 102 managed in the ``Makefile.am``. 109 103 110 startup_SOURCES = ../../sparc/shared/bspclean.c ../../shared/bsplibc.c \\ 111 ../../shared/bsppredriverhook.c \\ 112 ../../shared/bsppost.c ../../sparc/shared/bspstart.c \\ 113 ../../shared/bootcard.c ../../shared/sbrk.c startup/setvec.c \\ 104 .. code-block:: makefile 105 106 startup_SOURCES = ../../sparc/shared/bspclean.c ../../shared/bsplibc.c \ 107 ../../shared/bsppredriverhook.c \ 108 ../../shared/bsppost.c ../../sparc/shared/bspstart.c \ 109 ../../shared/bootcard.c ../../shared/sbrk.c startup/setvec.c \ 114 110 startup/spurious.c startup/erc32mec.c startup/boardinit.S 115 111 clock_SOURCES = clock/ckinit.c … … 118 114 libbsp_a_SOURCES = $(startup_SOURCES) $(console_SOURCES) ... 119 115 120 When adding new files to an existing directory, do not forget to add 121 the new files to the list of files to be built in the corresponding``XXX_SOURCES`` variable in the ``Makefile.am`` and run``bootstrap``. 116 When adding new files to an existing directory, do not forget to add the new 117 files to the list of files to be built in the corresponding ``XXX_SOURCES`` 118 variable in the ``Makefile.am`` and run``bootstrap``. 122 119 123 Some BSPs use code that is built in ``libcpu``. If you BSP does 124 this, then you will need to make sure the objects are pulled into your 125 BSP library. The following from the SPARC/ERC32 BSP pulls in the cache, 126 register window management and system call support code from the directory 127 corresponding to its ``RTEMS_CPU`` model. 128 .. code:: c 120 Some BSPs use code that is built in ``libcpu``. If you BSP does this, then you 121 will need to make sure the objects are pulled into your BSP library. The 122 following from the SPARC/ERC32 BSP pulls in the cache, register window 123 management and system call support code from the directory corresponding to its 124 ``RTEMS_CPU`` model. 129 125 130 libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/cache.rel \\ 131 ../../../libcpu/@RTEMS_CPU@/reg_win.rel \\ 126 .. code-block:: makefile 127 128 libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/cache.rel \ 129 ../../../libcpu/@RTEMS_CPU@/reg_win.rel \ 132 130 ../../../libcpu/@RTEMS_CPU@/syscall.rel 133 131 134 *NOTE:* The ``Makefile.am`` files are ONLY processed by``bootstrap`` and the resulting ``Makefile.in`` files are only 135 processed during the configure process of a RTEMS build. Therefore, 136 when developing a BSP and adding a new file to a ``Makefile.am``, 137 the already generated ``Makefile`` will not automatically 138 include the new references unless you configured RTEMS with the``--enable-maintainer-mode`` option. Otherwise, the new file not 139 being be taken into account! 132 .. note: 133 134 The ``Makefile.am`` files are ONLY processed by ``bootstrap`` and the resulting 135 ``Makefile.in`` files are only processed during the configure process of a 136 RTEMS build. Therefore, when developing a BSP and adding a new file to a 137 ``Makefile.am``, the already generated ``Makefile`` will not automatically 138 include the new references unless you configured RTEMS with the 139 ``--enable-maintainer-mode`` option. Otherwise, the new file will not being be 140 taken into account! 140 141 141 142 Creating a New BSP Make Customization File 142 143 ========================================== 143 144 144 When building a BSP or an application using that BSP, it is necessary 145 to tailor the compilation arguments to account for compiler flags, use 146 custom linker scripts, include the RTEMS libraries, etc.. The BSP 147 must be built using this information. Later, once the BSP is installed 148 with the toolset, this same information must be used when building the 149 application. So a BSP must include a build configuration file. The 150 configuration file is ``make/custom/BSP.cfg``. 145 When building a BSP or an application using that BSP, it is necessary to tailor 146 the compilation arguments to account for compiler flags, use custom linker 147 scripts, include the RTEMS libraries, etc.. The BSP must be built using this 148 information. Later, once the BSP is installed with the toolset, this same 149 information must be used when building the application. So a BSP must include 150 a build configuration file. The configuration file is ``make/custom/BSP.cfg``. 151 151 152 The configuration file is taken into account when building one's 153 application using the RTEMS template Makefiles (``make/templates``). 154 These application template Makefiles have been included with the 155 RTEMS source distribution since the early 1990's. However there is 156 a desire in the RTEMS user community to move all provided examples to 157 GNU autoconf. They are included in the 4.9 release series and used for 158 all examples provided with RTEMS. There is no definite time table for 159 obsoleting them. You are free to use these but be warned they have 160 fallen out of favor with many in the RTEMS community and may disappear 161 in the future. 152 The configuration file is taken into account when building one's application 153 using the RTEMS template Makefiles (``make/templates``). These application 154 template Makefiles have been included with the RTEMS source distribution since 155 the early 1990's. However there is a desire in the RTEMS user community to 156 move all provided examples to GNU autoconf. They are included in the 4.9 157 release series and used for all examples provided with RTEMS. There is no 158 definite time table for obsoleting them. You are free to use these but be 159 warned they have fallen out of favor with many in the RTEMS community and may 160 disappear in the future. 162 161 163 The following is a slightly shortened version of the make customization 164 file for the gen68340 BSP. The original source for this file can be 165 found in the ``make/custom`` directory. 166 .. code:: c 162 The following is a slightly shortened version of the make customization file 163 for the gen68340 BSP. The original source for this file can be found in the 164 ``make/custom`` directory. 165 166 .. code-block:: makefile 167 167 168 168 # The RTEMS CPU Family and Model … … 178 178 CFLAGS_OPTIMIZE_V = -O2 -g -fomit-frame-pointer 179 179 180 The make customization files have generally grown simpler and simpler 181 with each RTEMS release. Beginning in the 4.9 release series, the rules 182 for linking an RTEMS application are shared by all BSPs. Only BSPs which 183 need to perform a transformation from linked ELF file to a downloadable 184 format have any additional actions for program link time. In 4.8 and 185 older, every BSP specified the "make executable" or ``make-exe`` 186 rule and duplicated the same actions. 180 The make customization files have generally grown simpler and simpler with each 181 RTEMS release. Beginning in the 4.9 release series, the rules for linking an 182 RTEMS application are shared by all BSPs. Only BSPs which need to perform a 183 transformation from linked ELF file to a downloadable format have any 184 additional actions for program link time. In 4.8 and older, every BSP specified 185 the "make executable" or ``make-exe`` rule and duplicated the same actions. 187 186 188 It is generally easier to copy a ``make/custom`` file from a 189 BSP similar to the one being developed. 190 191 .. COMMENT: COPYRIGHT (c) 1988-2002. 192 193 .. COMMENT: On-Line Applications Research Corporation (OAR). 194 195 .. COMMENT: All rights reserved. 196 187 It is generally easier to copy a ``make/custom`` file from a BSP similar to the 188 one being developed. -
bsp_howto/miscellanous_support.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 4 .. COMMENT: COPYRIGHT (c) 1988-2002. 5 .. COMMENT: On-Line Applications Research Corporation (OAR). 6 .. COMMENT: All rights reserved. 2 7 3 8 Miscellaneous Support Files … … 7 12 ================================ 8 13 9 The file ``bsp_specs`` defines the start files and libraries 10 that are always used with this BSP. The format of this file 11 is admittedly cryptic and this document will make no attempt 12 to explain it completely. Below is the ``bsp_specs`` 13 file from the PowerPC psim BSP: 14 .. code :: c14 The file ``bsp_specs`` defines the start files and libraries that are always 15 used with this BSP. The format of this file is admittedly cryptic and this 16 document will make no attempt to explain it completely. Below is the 17 ``bsp_specs`` file from the PowerPC psim BSP: 18 19 .. code-block:: c 15 20 16 21 %rename endfile old_endfile 17 22 %rename startfile old_startfile 18 23 %rename link old_link 19 \*startfile:20 %{!qrtems: %(old_startfile)} \ \24 *startfile: 25 %{!qrtems: %(old_startfile)} \ 21 26 %{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s start.o%s}} 22 \*link:27 *link: 23 28 %{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -e _start -u __vectors} 24 \*endfile:29 *endfile: 25 30 %{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s} 26 31 27 The first section of this file renames the built-in definition of 28 some specification variables so they can be augmented without 29 embedded their original definition. The subsequent sections 30 specify what behavior is expected when the ``-qrtems`` option is specified. 31 32 The ``*startfile`` section specifies that the BSP specific file``start.o`` will be used instead of ``crt0.o``. In addition, 33 various EABI support files (``ecrti.o`` etc.) will be linked in with 34 the executable. 35 36 The ``*link`` section adds some arguments to the linker when it is 37 invoked by GCC to link an application for this BSP. 38 39 The format of this file is specific to the GNU Compiler Suite. The 40 argument used to override and extend the compiler built-in specifications 41 is available in all recent GCC versions. The ``-specs`` option is 42 present in all ``egcs`` distributions and ``gcc`` distributions 43 starting with version 2.8.0. 32 The first section of this file renames the built-in definition of some 33 specification variables so they can be augmented without embedded their 34 original definition. The subsequent sections specify what behavior is expected 35 when the ``-qrtems`` option is specified. 36 37 The ``*startfile`` section specifies that the BSP specific file ``start.o`` 38 will be used instead of ``crt0.o``. In addition, various EABI support files 39 (``ecrti.o`` etc.) will be linked in with the executable. 40 41 The ``*link`` section adds some arguments to the linker when it is invoked by 42 GCC to link an application for this BSP. 43 44 The format of this file is specific to the GNU Compiler Suite. The argument 45 used to override and extend the compiler built-in specifications is available 46 in all recent GCC versions. The ``-specs`` option is present in all ``egcs`` 47 distributions and ``gcc`` distributions starting with version 2.8.0. 44 48 45 49 README Files 46 50 ============ 47 51 48 Most BSPs provide one or more ``README`` files. Generally, there 49 is a ``README`` file at the top of the BSP source. This file 50 describes the board and its hardware configuration, provides vendor 51 information, local configuration information, information on downloading 52 code to the board, debugging, etc.. The intent of this 53 file is to help someone begin to use the BSP faster. 54 55 A ``README`` file in a BSP subdirectory typically explains something 56 about the contents of that subdirectory in greater detail. For example, 57 it may list the documentation available for a particular peripheral 58 controller and how to obtain that documentation. It may also explain some 59 particularly cryptic part of the software in that directory or provide 60 rationale on the implementation. 52 Most BSPs provide one or more ``README`` files. Generally, there is a 53 ``README`` file at the top of the BSP source. This file describes the board 54 and its hardware configuration, provides vendor information, local 55 configuration information, information on downloading code to the board, 56 debugging, etc.. The intent of this file is to help someone begin to use the 57 BSP faster. 58 59 A ``README`` file in a BSP subdirectory typically explains something about the 60 contents of that subdirectory in greater detail. For example, it may list the 61 documentation available for a particular peripheral controller and how to 62 obtain that documentation. It may also explain some particularly cryptic part 63 of the software in that directory or provide rationale on the implementation. 61 64 62 65 times 63 66 ===== 64 67 65 This file contains the results of the RTEMS Timing Test Suite. It is 66 in a standard format so that results from one BSP can be easily compared 67 with thoseof another target board.68 This file contains the results of the RTEMS Timing Test Suite. It is in a 69 standard format so that results from one BSP can be easily compared with those 70 of another target board. 68 71 69 72 If a BSP supports multiple variants, then there may be multiple ``times`` … … 73 76 ================== 74 77 75 Some BSPs provide additional tools that aid in using the target board. 76 These tools run on the development host and are built as part of building 77 the BSP. Most common is a script to automate running the RTEMS Test Suites 78 on the BSP.Examples of this include:78 Some BSPs provide additional tools that aid in using the target board. These 79 tools run on the development host and are built as part of building the BSP. 80 Most common is a script to automate running the RTEMS Test Suites on the BSP. 81 Examples of this include: 79 82 80 83 - ``powerpc/psim`` includes scripts to ease use of the simulator 81 84 82 - ``m68k/mvme162`` includes a utility to download across the 83 VMEbus into target memory if the host is a VMEbus board in the same 84 chasis. 85 - ``m68k/mvme162`` includes a utility to download across the VMEbus into target 86 memory if the host is a VMEbus board in the same chasis. 85 87 86 88 bsp.h Include File 87 89 ================== 88 90 89 The file ``include/bsp.h`` contains prototypes and definitions 90 specific to this board. Every BSP is required to provide a ``bsp.h``. 91 The best approach to writing a ``bsp.h`` is copying an existing one 92 as a starting point. 93 94 Many ``bsp.h`` files provide prototypes of variables defined 95 in the linker script (``linkcmds``). 91 The file ``include/bsp.h`` contains prototypes and definitions specific to this 92 board. Every BSP is required to provide a ``bsp.h``. The best approach to 93 writing a ``bsp.h`` is copying an existing one as a starting point. 94 95 Many ``bsp.h`` files provide prototypes of variables defined in the linker 96 script (``linkcmds``). 96 97 97 98 tm27.h Include File 98 99 =================== 99 100 100 The ``tm27`` test from the RTEMS Timing Test Suite is designed to measure the length of time required to vector to and return from an interrupt handler. This test requires some help from the BSP to know how to cause and manipulate the interrupt source used for this measurement. The following is a list of these: 101 The ``tm27`` test from the RTEMS Timing Test Suite is designed to measure the 102 length of time required to vector to and return from an interrupt handler. This 103 test requires some help from the BSP to know how to cause and manipulate the 104 interrupt source used for this measurement. The following is a list of these: 101 105 102 106 - ``MUST_WAIT_FOR_INTERRUPT`` - modifies behavior of ``tm27``. 103 107 104 - ``Install_tm27_vector`` - installs the interrupt service 105 routine for the Interrupt Benchmark Test (``tm27``). 106 107 - ``Cause_tm27_intr`` - generates the interrupt source 108 used in the Interrupt Benchmark Test (``tm27``). 109 110 - ``Clear_tm27_intr`` - clears the interrupt source 111 used in the Interrupt Benchmark Test (``tm27``). 112 113 - ``Lower_tm27_intr`` - lowers the interrupt mask so the 114 interrupt source used in the Interrupt Benchmark Test (``tm27``) 115 can generate a nested interrupt. 116 117 All members of the Timing Test Suite are designed to run *WITHOUT* 118 the Clock Device Driver installed. This increases the predictability 119 of the tests' execution as well as avoids occassionally including the 120 overhead of a clock tick interrupt in the time reported. Because of 121 this it is sometimes possible to use the clock tick interrupt source 122 as the source of this test interrupt. On other architectures, it is 123 possible to directly force an interrupt to occur. 108 - ``Install_tm27_vector`` - installs the interrupt service routine for the 109 Interrupt Benchmark Test (``tm27``). 110 111 - ``Cause_tm27_intr`` - generates the interrupt source used in the Interrupt 112 Benchmark Test (``tm27``). 113 114 - ``Clear_tm27_intr`` - clears the interrupt source used in the Interrupt 115 Benchmark Test (``tm27``). 116 117 - ``Lower_tm27_intr`` - lowers the interrupt mask so the interrupt source used 118 in the Interrupt Benchmark Test (``tm27``) can generate a nested interrupt. 119 120 All members of the Timing Test Suite are designed to run *WITHOUT* the Clock 121 Device Driver installed. This increases the predictability of the tests' 122 execution as well as avoids occassionally including the overhead of a clock 123 tick interrupt in the time reported. Because of this it is sometimes possible 124 to use the clock tick interrupt source as the source of this test interrupt. 125 On other architectures, it is possible to directly force an interrupt to occur. 124 126 125 127 Calling Overhead File 126 128 ===================== 127 129 128 The file ``include/coverhd.h`` contains the overhead associated 129 with invoking each directive. This overhead consists of the execution 130 time required to package the parameters as well as to execute the "jump to 131 subroutine" and "return from subroutine" sequence. The intent of this 132 file is to help separate the calling overhead from the actual execution 133 time of a directive. This file is only used by the tests in the 134 RTEMS Timing Test Suite. 135 136 The numbers in this file are obtained by running the "Timer Overhead"``tmoverhd`` test. The numbers in this file may be 0 and no 137 overhead is subtracted from the directive execution times reported by 138 the Timing Suite. 139 140 There is a shared implementation of ``coverhd.h`` which sets all of 141 the overhead constants to 0. On faster processors, this is usually the142 best alternative for the BSP as the calling overhead is extremely small. 143 This file is located at: 130 The file ``include/coverhd.h`` contains the overhead associated with invoking 131 each directive. This overhead consists of the execution time required to 132 package the parameters as well as to execute the "jump to subroutine" and 133 "return from subroutine" sequence. The intent of this file is to help separate 134 the calling overhead from the actual execution time of a directive. This file 135 is only used by the tests in the RTEMS Timing Test Suite. 136 137 The numbers in this file are obtained by running the "Timer 138 Overhead"``tmoverhd`` test. The numbers in this file may be 0 and no overhead 139 is subtracted from the directive execution times reported by the Timing Suite. 140 141 There is a shared implementation of ``coverhd.h`` which sets all of the 142 overhead constants to 0. On faster processors, this is usually the best 143 alternative for the BSP as the calling overhead is extremely small. This file 144 is located at: 145 144 146 .. code:: c 145 147 … … 149 151 ===================== 150 152 151 Although nearly all BSPs give all possible memory to the C Program Heap 152 at initialization, it is possible for a BSP to configure the initial 153 size of the heap small and let it grow on demand. If the BSP wants 154 to dynamically extend the heap used by the C Library memory allocation 155 routines (i.e. ``malloc`` family), then the``sbrk`` routine must 156 be functional. The following is the prototype for this routine: 153 Although nearly all BSPs give all possible memory to the C Program Heap at 154 initialization, it is possible for a BSP to configure the initial size of the 155 heap small and let it grow on demand. If the BSP wants to dynamically extend 156 the heap used by the C Library memory allocation routines (i.e. ``malloc`` 157 family), then the``sbrk`` routine must be functional. The following is the 158 prototype for this routine: 159 157 160 .. code:: c 158 161 159 162 void * sbrk(size_t increment) 160 163 161 The ``increment`` amount is based upon the ``sbrk_amount`` 162 parameter passed to the ``bsp_libc_init`` during system initialization... index:: CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK 163 164 If your BSP does not want to support dynamic heap extension, then you do not have to do anything special. However, if you want to support ``sbrk``, you must provide an implementation of this method and define ``CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK`` in ``bsp.h``. This informs ``rtems/confdefs.h`` to configure the Malloc Family Extensions which support ``sbrk``. 164 The ``increment`` amount is based upon the ``sbrk_amount`` parameter passed to 165 the ``bsp_libc_init`` during system initialization. 166 167 .. index:: CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK 168 169 If your BSP does not want to support dynamic heap extension, then you do not 170 have to do anything special. However, if you want to support ``sbrk``, you 171 must provide an implementation of this method and define 172 ``CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK`` in ``bsp.h``. This informs 173 ``rtems/confdefs.h`` to configure the Malloc Family Extensions which support 174 ``sbrk``. 165 175 166 176 bsp_fatal_extension() - Cleanup the Hardware … … 171 181 shared version of ``bsp_fatal_extension()`` that does nothing or performs a 172 182 system reset. This implementation is located in the following file: 183 173 184 .. code:: c 174 185 175 186 c/src/lib/libbsp/shared/bspclean.c 176 187 177 The ``bsp_fatal_extension()`` routine can be used to return to a ROM 178 monitor, insure that interrupt sources are disabled, etc.. This routine is the 179 last place to ensure a clean shutdown of the hardware. The fatal source, 180 internal error indicator, and the fatal code arguments are available to 181 evaluate the fatal condition. All of the non-fatal shutdown sequences 182 ultimately pass their exit status to ``rtems_shutdown_executive`` and this 183 is what is passed to this routine in case the fatal source is 184 RTEMS_FATAL_SOURCE_EXIT. 185 186 On some BSPs, it prints a message indicating that the application 187 completed execution and waits for the user to press a key before 188 resetting the board. The PowerPC/gen83xx and PowerPC/gen5200 BSPs do 189 this when they are built to support the FreeScale evaluation boards. 190 This is convenient when using the boards in a development environment 191 and may be disabled for production use. 188 The ``bsp_fatal_extension()`` routine can be used to return to a ROM monitor, 189 insure that interrupt sources are disabled, etc.. This routine is the last 190 place to ensure a clean shutdown of the hardware. The fatal source, internal 191 error indicator, and the fatal code arguments are available to evaluate the 192 fatal condition. All of the non-fatal shutdown sequences ultimately pass their 193 exit status to ``rtems_shutdown_executive`` and this is what is passed to this 194 routine in case the fatal source is ``RTEMS_FATAL_SOURCE_EXIT``. 195 196 On some BSPs, it prints a message indicating that the application completed 197 execution and waits for the user to press a key before resetting the board. 198 The PowerPC/gen83xx and PowerPC/gen5200 BSPs do this when they are built to 199 support the FreeScale evaluation boards. This is convenient when using the 200 boards in a development environment and may be disabled for production use. 192 201 193 202 Configuration Macros 194 203 ==================== 195 204 196 Each BSP can define macros in bsp.h which alter some of the the default configuration parameters in ``rtems/confdefs.h``. This section describes those macros: 197 198 - .. index:: CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK 199 200 ``CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK`` must be defined if the 201 BSP has proper support for ``sbrk``. This is discussed in more detail 202 in the previous section. 203 204 - .. index:: BSP_IDLE_TASK_BODY 205 206 ``BSP_IDLE_TASK_BODY`` may be defined to the entry point of a 207 BSP specific IDLE thread implementation. This may be overridden if the 208 application provides its own IDLE task implementation. 209 210 - .. index:: BSP_IDLE_TASK_STACK_SIZE 211 212 ``BSP_IDLE_TASK_STACK_SIZE`` may be defined to the desired 213 default stack size for the IDLE task as recommended when using this BSP. 214 215 - .. index:: BSP_INTERRUPT_STACK_SIZE 216 217 ``BSP_INTERRUPT_STACK_SIZE`` may be defined to the desired default interrupt stack size as recommended when using this BSP. This is sometimes required when the BSP developer has knowledge of stack intensive interrupt handlers. 218 219 - .. index:: BSP_ZERO_WORKSPACE_AUTOMATICALLY 220 221 ``BSP_ZERO_WORKSPACE_AUTOMATICALLY`` is defined when the BSP 222 requires that RTEMS zero out the RTEMS C Program Heap at initialization. 223 If the memory is already zeroed out by a test sequence or boot ROM, 224 then the boot time can be reduced by not zeroing memory twice. 225 226 - .. index:: BSP_DEFAULT_UNIFIED_WORK_AREAS 227 228 ``BSP_DEFAULT_UNIFIED_WORK_AREAS`` is defined when the BSP 229 recommends that the unified work areas configuration should always 230 be used. This is desirable when the BSP is known to always have very 231 little RAM and thus saving memory by any means is desirable. 205 Each BSP can define macros in bsp.h which alter some of the the default 206 configuration parameters in ``rtems/confdefs.h``. This section describes those 207 macros: 208 209 .. index:: CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK 210 211 - ``CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK`` must be defined if the BSP has proper 212 support for ``sbrk``. This is discussed in more detail in the previous 213 section. 214 215 .. index:: BSP_IDLE_TASK_BODY 216 217 - ``BSP_IDLE_TASK_BODY`` may be defined to the entry point of a BSP specific 218 IDLE thread implementation. This may be overridden if the application 219 provides its own IDLE task implementation. 220 221 .. index:: BSP_IDLE_TASK_STACK_SIZE 222 223 - ``BSP_IDLE_TASK_STACK_SIZE`` may be defined to the desired default stack size 224 for the IDLE task as recommended when using this BSP. 225 226 .. index:: BSP_INTERRUPT_STACK_SIZE 227 228 - ``BSP_INTERRUPT_STACK_SIZE`` may be defined to the desired default interrupt 229 stack size as recommended when using this BSP. This is sometimes required 230 when the BSP developer has knowledge of stack intensive interrupt handlers. 231 232 .. index:: BSP_ZERO_WORKSPACE_AUTOMATICALLY 233 234 - ``BSP_ZERO_WORKSPACE_AUTOMATICALLY`` is defined when the BSP requires that 235 RTEMS zero out the RTEMS C Program Heap at initialization. If the memory is 236 already zeroed out by a test sequence or boot ROM, then the boot time can be 237 reduced by not zeroing memory twice. 238 239 .. index:: BSP_DEFAULT_UNIFIED_WORK_AREAS 240 241 - ``BSP_DEFAULT_UNIFIED_WORK_AREAS`` is defined when the BSP recommends that 242 the unified work areas configuration should always be used. This is 243 desirable when the BSP is known to always have very little RAM and thus 244 saving memory by any means is desirable. 232 245 233 246 set_vector() - Install an Interrupt Vector 234 247 ========================================== 235 248 236 On targets with Simple Vectored Interrupts, the BSP must provide 237 an implementation of the ``set_vector`` routine. This routine is 238 responsible for installing an interrupt vector. It invokes the support 239 routines necessary to install an interrupt handler as either a "raw" 240 or an RTEMS interrupt handler. Raw handlers bypass the RTEMS interrupt 241 structure and are responsible for saving and restoring all their own 242 registers. Raw handlers are useful for handling traps, debug vectors, 243 etc.. 244 245 The ``set_vector`` routine is a central place to perform interrupt 246 controller manipulation and encapsulate that information. It is usually 247 implemented as follows: 248 249 .. code:: c 250 251 rtems_isr_entry set_vector( /* returns old vector \*/ 252 rtems_isr_entry handler, /* isr routine \*/ 253 rtems_vector_number vector, /* vector number \*/ 254 int type /* RTEMS or RAW intr \*/ 249 On targets with Simple Vectored Interrupts, the BSP must provide an 250 implementation of the ``set_vector`` routine. This routine is responsible for 251 installing an interrupt vector. It invokes the support routines necessary to 252 install an interrupt handler as either a "raw" or an RTEMS interrupt handler. 253 Raw handlers bypass the RTEMS interrupt structure and are responsible for 254 saving and restoring all their own registers. Raw handlers are useful for 255 handling traps, debug vectors, etc. 256 257 The ``set_vector`` routine is a central place to perform interrupt controller 258 manipulation and encapsulate that information. It is usually implemented as 259 follows: 260 261 .. code:: c 262 263 rtems_isr_entry set_vector( /* returns old vector \*/ 264 rtems_isr_entry handler, /* isr routine \*/ 265 rtems_vector_number vector, /* vector number \*/ 266 int type /* RTEMS or RAW intr \*/ 255 267 ) 256 268 { 257 if the type is RAW 258 install the raw vector 259 else 260 use rtems_interrupt_catch to install the vector 261 perform any interrupt controller necessary to unmask 262 the interrupt source 263 return the previous handler 269 if the type is RAW 270 install the raw vector 271 else 272 use rtems_interrupt_catch to install the vector 273 perform any interrupt controller necessary to unmask the interrupt source 274 return the previous handler 264 275 } 265 276 266 *NOTE:* The i386, PowerPC and ARM ports use a Programmable 267 Interrupt Controller model which does not require the BSP to implement``set_vector``. BSPs for these architectures must provide a different 268 set of support routines. 277 .. note:: 278 279 The i386, PowerPC and ARM ports use a Programmable Interrupt Controller 280 model which does not require the BSP to implement ``set_vector``. BSPs for 281 these architectures must provide a different set of support routines. 269 282 270 283 Interrupt Delay Profiling … … 272 285 273 286 The RTEMS profiling needs support by the BSP for the interrupt delay times. In 274 case profiling is enabled via the RTEMS build configuration option``--enable-profiling`` (in this case the pre-processor symbol``RTEMS_PROFILING`` is defined) a BSP may provide data for the interrupt 275 delay times. The BSP can feed interrupt delay times with the``_Profiling_Update_max_interrupt_delay()`` function 276 (``#include <rtems/score/profiling.h>``). For an example please have a look 277 at ``c/src/lib/libbsp/sparc/leon3/clock/ckinit.c``. 287 case profiling is enabled via the RTEMS build configuration option 288 ``--enable-profiling`` (in this case the pre-processor symbol 289 ``RTEMS_PROFILING`` is defined) a BSP may provide data for the interrupt delay 290 times. The BSP can feed interrupt delay times with the 291 ``_Profiling_Update_max_interrupt_delay()`` function (``#include 292 <rtems/score/profiling.h>``). For an example please have a look at 293 ``c/src/lib/libbsp/sparc/leon3/clock/ckinit.c``. 278 294 279 295 Programmable Interrupt Controller API 280 296 ===================================== 281 297 282 A BSP can use the PIC API to install Interrupt Service Routines through 283 a setof generic methods. In order to do so, the header files284 libbsp/shared/include/irq-generic.h and libbsp/shared/include/irq-info.h298 A BSP can use the PIC API to install Interrupt Service Routines through a set 299 of generic methods. In order to do so, the header files 300 libbsp/shared/include/irq-generic.h and ``libbsp/shared/include/irq-info.h`` 285 301 must be included by the bsp specific irq.h file present in the include/ 286 302 directory. The irq.h acts as a BSP interrupt support configuration file which 287 is used to define some important MACROS. It contains the declarations for 288 any required global functions like bsp_interrupt_dispatch(). Thus later on, 289 every call to the PIC interface requires including <bsp/irq.h> 290 291 The generic interrupt handler table is intitalized by invoking the``bsp_interrupt_initialize()`` method from bsp_start() in the bspstart.c 292 file which sets up this table to store the ISR addresses, whose size is based 293 on the definition of macros, BSP_INTERRUPT_VECTOR_MIN & BSP_INTERRUPT_VECTOR_MAX 294 in include/bsp.h 303 is used to define some important MACROS. It contains the declarations for any 304 required global functions like bsp_interrupt_dispatch(). Thus later on, every 305 call to the PIC interface requires including ``<bsp/irq.h>`` 306 307 The generic interrupt handler table is intitalized by invoking the 308 ``bsp_interrupt_initialize()`` method from bsp_start() in the bspstart.c file 309 which sets up this table to store the ISR addresses, whose size is based on the 310 definition of macros, ``BSP_INTERRUPT_VECTOR_MIN`` and 311 ``BSP_INTERRUPT_VECTOR_MAX`` in include/bsp.h 295 312 296 313 For the generic handler table to properly function, some bsp specific code is 297 required, that should be present in irq/irq.c . The bsp-specific functions required298 to be writen by the BSP developer are :299 300 -.. index:: bsp_interrupt_facility_initialize()301 302 314 required, that should be present in ``irq/irq.c``. The bsp-specific functions 315 required to be writen by the BSP developer are : 316 317 .. index:: bsp_interrupt_facility_initialize() 318 319 - ``bsp_interrupt_facility_initialize()`` contains bsp specific interrupt 303 320 initialization code(Clear Pending interrupts by modifying registers, etc.). 304 This method is called from bsp_interrupt_initialize() internally while setting up305 the table.306 307 -.. index:: bsp_interrupt_handler_default()308 309 ``bsp_interrupt_handler_default()`` acts as a fallback handler when 310 no ISRaddress has been provided corresponding to a vector in the table.311 312 -.. index:: bsp_interrupt_dispatch()313 314 ``bsp_interrupt_dispatch()`` service the ISR by handling 315 any bsp specific code & calling the generic method bsp_interrupt_handler_dispatch()316 which in turn services the interrupt by running the ISR after looking it up in317 t he table. It acts as an entry to the interrupt switchboard, since the bsp321 This method is called from ``bsp_interrupt_initialize()`` internally while 322 setting up the table. 323 324 .. index:: bsp_interrupt_handler_default() 325 326 - ``bsp_interrupt_handler_default()`` acts as a fallback handler when no ISR 327 address has been provided corresponding to a vector in the table. 328 329 .. index:: bsp_interrupt_dispatch() 330 331 - ``bsp_interrupt_dispatch()`` service the ISR by handling any bsp specific 332 code & calling the generic method ``bsp_interrupt_handler_dispatch()`` which 333 in turn services the interrupt by running the ISR after looking it up in the 334 table. It acts as an entry to the interrupt switchboard, since the bsp 318 335 branches to this function at the time of occurrence of an interrupt. 319 336 320 -.. index:: bsp_interrupt_vector_enable()321 322 337 .. index:: bsp_interrupt_vector_enable() 338 339 - ``bsp_interrupt_vector_enable()`` enables interrupts and is called in 323 340 irq-generic.c while setting up the table. 324 341 325 -.. index:: bsp_interrupt_vector_disable()326 327 342 .. index:: bsp_interrupt_vector_disable() 343 344 - ``bsp_interrupt_vector_disable()`` disables interrupts and is called in 328 345 irq-generic.c while setting up the table & during other important parts. 329 346 … … 332 349 .. code:: c 333 350 334 rtems_status_code rtems_interrupt_handler_install( /* returns status code \*/ 335 rtems_vector_number vector, /* interrupt vector \*/ 336 const char \*info, /* custom identification text \*/ 337 rtems_option options, /* Type of Interrupt \*/ 338 rtems_interrupt_handler handler, /* interrupt handler \*/ 339 void \*arg /* parameter to be passed to handler at the time of invocation \*/ 351 rtems_status_code rtems_interrupt_handler_install( /* returns status code */ 352 rtems_vector_number vector, /* interrupt vector */ 353 const char *info, /* custom identification text */ 354 rtems_option options, /* Type of Interrupt */ 355 rtems_interrupt_handler handler, /* interrupt handler */ 356 void *arg /* parameter to be passed 357 to handler at the time of 358 invocation */ 340 359 ) 341 rtems_status_code rtems_interrupt_handler_remove( /* returns status code \*/342 rtems_vector_number vector, /* interrupt vector \*/343 rtems_interrupt_handler handler, /* interrupt handler \*/344 void \*arg /* parameter to be passed to handler \*/360 rtems_status_code rtems_interrupt_handler_remove( /* returns status code */ 361 rtems_vector_number vector, /* interrupt vector */ 362 rtems_interrupt_handler handler, /* interrupt handler */ 363 void *arg /* parameter to be passed to handler */ 345 364 ) 346 347 .. COMMENT: COPYRIGHT (c) 1988-2002.348 349 .. COMMENT: On-Line Applications Research Corporation (OAR).350 351 .. COMMENT: All rights reserved.352 -
bsp_howto/networking.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: COPYRIGHT (c) 1988-2002. 4 .. COMMENT: On-Line Applications Research Corporation (OAR). 5 .. COMMENT: All rights reserved. 2 6 3 7 Networking Driver … … 7 11 ============ 8 12 9 This chapter is intended to provide an introduction to the 10 procedure for writing RTEMS network device drivers. 11 The example code is taken from the 'Generic 68360' network device 12 driver. The source code for this driver is located in the``c/src/lib/libbsp/m68k/gen68360/network`` directory in the RTEMS 13 source code distribution. Having a copy of this driver at 14 hand when reading the following notes will help significantly. 13 This chapter is intended to provide an introduction to the procedure for 14 writing RTEMS network device drivers. The example code is taken from the 15 'Generic 68360' network device driver. The source code for this driver is 16 located in the ``c/src/lib/libbsp/m68k/gen68360/network`` directory in the 17 RTEMS source code distribution. Having a copy of this driver at hand when 18 reading the following notes will help significantly. 19 20 .. sidebar:: *Legacy Networking Stack* 21 22 This docuemntation is for the legacy FreeBSD networking stack in the RTEMS 23 source tree. 15 24 16 25 Learn about the network device 17 26 ============================== 18 27 19 Before starting to write the network driver become completely 20 familiar with the programmer's view of the device. 21 The following points list some of the details of the 22 device that must be understood before a driver can be written. 23 24 - Does the device use DMA to transfer packets to and from 25 memory or does the processor have to 26 copy packets to and from memory on the device? 27 28 - If the device uses DMA, is it capable of forming a single 29 outgoing packet from multiple fragments scattered in separate 30 memory buffers? 31 32 - If the device uses DMA, is it capable of chaining multiple 33 outgoing packets, or does each outgoing packet require 34 intervention by the driver? 35 36 - Does the device automatically pad short frames to the minimum 37 64 bytes or does the driver have to supply the padding? 38 39 - Does the device automatically retry a transmission on detection 40 of a collision? 41 42 - If the device uses DMA, is it capable of buffering multiple 43 packets to memory, or does the receiver have to be restarted 44 after the arrival of each packet? 45 46 - How are packets that are too short, too long, or received with 47 CRC errors handled? Does the device automatically continue 48 reception or does the driver have to intervene? 49 50 - How is the device Ethernet address set? How is the device 51 programmed to accept or reject broadcast and multicast packets? 52 53 - What interrupts does the device generate? Does it generate an 54 interrupt for each incoming packet, or only for packets received 55 without error? Does it generate an interrupt for each packet 56 transmitted, or only when the transmit queue is empty? What 57 happens when a transmit error is detected? 58 59 In addition, some controllers have specific questions regarding 60 board specific configuration. For example, the SONIC Ethernet 61 controller has a very configurable data bus interface. It can 62 even be configured for sixteen and thirty-two bit data buses. This 63 type of information should be obtained from the board vendor. 28 Before starting to write the network driver become completely familiar with the 29 programmer's view of the device. The following points list some of the details 30 of the device that must be understood before a driver can be written. 31 32 - Does the device use DMA to transfer packets to and from memory or does the 33 processor have to copy packets to and from memory on the device? 34 35 - If the device uses DMA, is it capable of forming a single outgoing packet 36 from multiple fragments scattered in separate memory buffers? 37 38 - If the device uses DMA, is it capable of chaining multiple outgoing packets, 39 or does each outgoing packet require intervention by the driver? 40 41 - Does the device automatically pad short frames to the minimum 64 bytes or 42 does the driver have to supply the padding? 43 44 - Does the device automatically retry a transmission on detection of a 45 collision? 46 47 - If the device uses DMA, is it capable of buffering multiple packets to 48 memory, or does the receiver have to be restarted after the arrival of each 49 packet? 50 51 - How are packets that are too short, too long, or received with CRC errors 52 handled? Does the device automatically continue reception or does the driver 53 have to intervene? 54 55 - How is the device Ethernet address set? How is the device programmed to 56 accept or reject broadcast and multicast packets? 57 58 - What interrupts does the device generate? Does it generate an interrupt for 59 each incoming packet, or only for packets received without error? Does it 60 generate an interrupt for each packet transmitted, or only when the transmit 61 queue is empty? What happens when a transmit error is detected? 62 63 In addition, some controllers have specific questions regarding board specific 64 configuration. For example, the SONIC Ethernet controller has a very 65 configurable data bus interface. It can even be configured for sixteen and 66 thirty-two bit data buses. This type of information should be obtained from 67 the board vendor. 64 68 65 69 Understand the network scheduling conventions 66 70 ============================================= 67 71 68 When writing code for the driver transmit and receive tasks, 69 take care to follow the network scheduling conventions. All tasks 70 which are associated with networking share various 71 data structures and resources. To ensure the consistency 72 of these structures the tasks 73 execute only when they hold the network semaphore (``rtems_bsdnet_semaphore``). 74 The transmit and receive tasks must abide by this protocol. Be very 75 careful to avoid 'deadly embraces' with the other network tasks. 76 A number of routines are provided to make it easier for the network 77 driver code to conform to the network task scheduling conventions. 72 When writing code for the driver transmit and receive tasks, take care to 73 follow the network scheduling conventions. All tasks which are associated with 74 networking share various data structures and resources. To ensure the 75 consistency of these structures the tasks execute only when they hold the 76 network semaphore (``rtems_bsdnet_semaphore``). The transmit and receive tasks 77 must abide by this protocol. Be very careful to avoid 'deadly embraces' with 78 the other network tasks. A number of routines are provided to make it easier 79 for the network driver code to conform to the network task scheduling 80 conventions. 78 81 79 82 - ``void rtems_bsdnet_semaphore_release(void)`` 80 This function releases the network semaphore. 81 The network driver tasks must call this function immediately before 82 making any blocking RTEMS request. 83 This function releases the network semaphore. The network driver tasks must 84 call this function immediately before making any blocking RTEMS request. 83 85 84 86 - ``void rtems_bsdnet_semaphore_obtain(void)`` 85 This function obtains the network semaphore. 86 If a network driver task has released the network semaphore to allow other87 network-related tasks to run while the task blocks, then this function must88 be called to reobtain the semaphore immediately after the return from the89 blocking RTEMS request. 90 91 - ``rtems_bsdnet_event_receive(rtems_event_set, rtems_option, rtems_interval, rtems_event_set \*)``92 The network driver task should call this function when it wishes to wait 93 for an event. This function releases the network semaphore,94 calls ``rtems_event_receive`` to wait for the specified event95 or events and reobtains the semaphore.96 The value returned is the value returned by the``rtems_event_receive``.87 This function obtains the network semaphore. If a network driver task has 88 released the network semaphore to allow other network-related tasks to run 89 while the task blocks, then this function must be called to reobtain the 90 semaphore immediately after the return from the blocking RTEMS request. 91 92 - ``rtems_bsdnet_event_receive(rtems_event_set, rtems_option, rtems_interval, 93 rtems_event_set *)`` 94 The network driver task should call this function when it wishes to wait for 95 an event. This function releases the network semaphore, calls 96 ``rtems_event_receive`` to wait for the specified event or events and 97 reobtains the semaphore. The value returned is the value returned by the 98 ``rtems_event_receive``. 97 99 98 100 Network Driver Makefile 99 101 ======================= 100 102 101 Network drivers are considered part of the BSD network package and as such 102 are to be compiled with the appropriate flags. This can be accomplished by 103 adding ``-D__INSIDE_RTEMS_BSD_TCPIP_STACK__`` to the ``command line``. 104 If the driver is inside the RTEMS source tree or is built using the 105 RTEMS application Makefiles, then adding the following line accomplishes 106 this: 107 108 .. code:: c 103 Network drivers are considered part of the BSD network package and as such are 104 to be compiled with the appropriate flags. This can be accomplished by adding 105 ``-D__INSIDE_RTEMS_BSD_TCPIP_STACK__`` to the ``command line``. If the driver 106 is inside the RTEMS source tree or is built using the RTEMS application 107 Makefiles, then adding the following line accomplishes this: 108 109 .. code-block:: makefile 109 110 110 111 DEFINES += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ 111 112 112 This is equivalent to the following list of definitions. Early versions 113 of the RTEMS BSD network stack required that all of these be defined. 114 115 .. code:: c 116 117 -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \\ 118 -DDIAGNOSTIC -DBOOTP_COMPAT 119 120 Defining these macros tells the network header files that the driver 121 is to be compiled with extended visibility into the network stack. This 122 is in sharp contrast to applications that simply use the network stack. 123 Applications do not require this level of visibility and should stick 124 to the portable application level API. 125 126 As a direct result of being logically internal to the network stack, 127 network drivers use the BSD memory allocation routines This means, 128 for example, that malloc takes three arguments. See the SONIC 129 device driver (``c/src/lib/libchip/network/sonic.c``) for an example 130 of this. Because of this, network drivers should not include``<stdlib.h>``. Doing so will result in conflicting definitions 131 of ``malloc()``. 132 133 *Application level* code including network servers such as the FTP 134 daemon are *not* part of the BSD kernel network code and should not be 135 compiled with the BSD network flags. They should include``<stdlib.h>`` and not define the network stack visibility 136 macros. 113 This is equivalent to the following list of definitions. Early versions of the 114 RTEMS BSD network stack required that all of these be defined. 115 116 .. code-block:: makefile 117 118 -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS -DDIAGNOSTIC -DBOOTP_COMPAT 119 120 Defining these macros tells the network header files that the driver is to be 121 compiled with extended visibility into the network stack. This is in sharp 122 contrast to applications that simply use the network stack. Applications do 123 not require this level of visibility and should stick to the portable 124 application level API. 125 126 As a direct result of being logically internal to the network stack, network 127 drivers use the BSD memory allocation routines This means, for example, that 128 malloc takes three arguments. See the SONIC device driver 129 (``c/src/lib/libchip/network/sonic.c``) for an example of this. Because of 130 this, network drivers should not include ``<stdlib.h>``. Doing so will result 131 in conflicting definitions of ``malloc()``. 132 133 *Application level* code including network servers such as the FTP daemon are 134 *not* part of the BSD kernel network code and should not be compiled with the 135 BSD network flags. They should include ``<stdlib.h>`` and not define the 136 network stack visibility macros. 137 137 138 138 Write the Driver Attach Function 139 139 ================================ 140 140 141 The driver attach function is responsible for configuring the driver 142 and making the connection between the network stack 143 and the driver. 144 145 Driver attach functions take a pointer to an``rtems_bsdnet_ifconfig`` structure as their only argument. 146 and set the driver parameters based on the 147 values in this structure. If an entry in the configuration 148 structure is zero the attach function chooses an 149 appropriate default value for that parameter. 150 151 The driver should then set up several fields in the ifnet structure 152 in the device-dependent data structure supplied and maintained by the driver: 141 The driver attach function is responsible for configuring the driver and making 142 the connection between the network stack and the driver. 143 144 Driver attach functions take a pointer to an ``rtems_bsdnet_ifconfig`` 145 structure as their only argument. and set the driver parameters based on the 146 values in this structure. If an entry in the configuration structure is zero 147 the attach function chooses an appropriate default value for that parameter. 148 149 The driver should then set up several fields in the ifnet structure in the 150 device-dependent data structure supplied and maintained by the driver: 153 151 154 152 ``ifp->if_softc`` 155 Pointer to the device-dependent data. The first entry 156 in the device-dependent data structure must be an ``arpcom`` 153 Pointer to the device-dependent data. The first entry in the 154 device-dependent data structure must be an ``arpcom`` structure. 155 156 ``ifp->if_name`` 157 The name of the device. The network stack uses this string and the device 158 number for device name lookups. The device name should be obtained from 159 the ``name`` entry in the configuration structure. 160 161 ``ifp->if_unit`` 162 The device number. The network stack uses this number and the device name 163 for device name lookups. For example, if ``ifp->if_name`` is ``scc`` and 164 ``ifp->if_unit`` is ``1``, the full device name would be ``scc1``. The 165 unit number should be obtained from the ``name`` entry in the configuration 157 166 structure. 158 167 159 ``ifp->if_name``160 The name of the device. The network stack uses this string161 and the device number for device name lookups. The device name should162 be obtained from the ``name`` entry in the configuration structure.163 164 ``ifp->if_unit``165 The device number. The network stack uses this number and the166 device name for device name lookups. For example, if``ifp->if_name`` is '``scc``' and ``ifp->if_unit`` is '``1``',167 the full device name would be '``scc1``'. The unit number should be168 obtained from the 'name' entry in the configuration structure.169 170 168 ``ifp->if_mtu`` 171 The maximum transmission unit for the device. For Ethernet 172 devices thisvalue should almost always be 1500.169 The maximum transmission unit for the device. For Ethernet devices this 170 value should almost always be 1500. 173 171 174 172 ``ifp->if_flags`` 175 The device flags. Ethernet devices should set the flags 176 to ``IFF_BROADCAST|IFF_SIMPLEX``, indicating that the177 device can broadcast packets to multiple destinations178 and does not receive and transmit at thesame time.173 The device flags. Ethernet devices should set the flags to 174 ``IFF_BROADCAST|IFF_SIMPLEX``, indicating that the device can broadcast 175 packets to multiple destinations and does not receive and transmit at the 176 same time. 179 177 180 178 ``ifp->if_snd.ifq_maxlen`` 181 The maximum length of the queue of packets waiting to be 182 sent to thedriver. This is normally set to ``ifqmaxlen``.179 The maximum length of the queue of packets waiting to be sent to the 180 driver. This is normally set to ``ifqmaxlen``. 183 181 184 182 ``ifp->if_init`` … … 192 190 193 191 ``ifp->if_output`` 194 The address of the output function. Ethernet devices 195 should set this to ``ether_output``. 196 197 RTEMS provides a function to parse the driver name in the 198 configuration structure into a device name and unit number. 199 .. code:: c 192 The address of the output function. Ethernet devices should set this to 193 ``ether_output``. 194 195 RTEMS provides a function to parse the driver name in the configuration 196 structure into a device name and unit number. 197 198 .. code-block:: c 200 199 201 200 int rtems_bsdnet_parse_driver_name ( 202 const struct rtems_bsdnet_ifconfig \*config,203 char \**namep201 const struct rtems_bsdnet_ifconfig *config, 202 char **namep 204 203 ); 205 204 206 The function takes two arguments; a pointer to the configuration 207 structure and a pointer to a pointer to a character. The function 208 parses the configuration name entry, allocates memory for the driver 209 name, places the driver name in this memory, sets the second argument 210 to point to the name and returns the unit number. 211 On error, a message is printed and -1 is returned. 212 213 Once the attach function has set up the above entries it must link the 214 driver data structure onto the list of devices by 215 calling ``if_attach``. Ethernet devices should then 216 call ``ether_ifattach``. Both functions take a pointer to the 217 device's ``ifnet`` structure as their only argument. 218 219 The attach function should return a non-zero value to indicate that 220 the driver has been successfully configured and attached. 205 The function takes two arguments; a pointer to the configuration structure and 206 a pointer to a pointer to a character. The function parses the configuration 207 name entry, allocates memory for the driver name, places the driver name in 208 this memory, sets the second argument to point to the name and returns the unit 209 number. On error, a message is printed and ``-1`` is returned. 210 211 Once the attach function has set up the above entries it must link the driver 212 data structure onto the list of devices by calling ``if_attach``. Ethernet 213 devices should then call ``ether_ifattach``. Both functions take a pointer to 214 the device's ``ifnet`` structure as their only argument. 215 216 The attach function should return a non-zero value to indicate that the driver 217 has been successfully configured and attached. 221 218 222 219 Write the Driver Start Function. … … 224 221 225 222 This function is called each time the network stack wants to start the 226 transmitter. This occures whenever the network stack adds a packet 227 to a device's send queue and the ``IFF_OACTIVE`` bit in the 228 device's ``if_flags`` is not set. 229 230 For many devices this function need only set the ``IFF_OACTIVE`` bit in the``if_flags`` and send an event to the transmit task 231 indicating that a packet is in the driver transmit queue. 223 transmitter. This occures whenever the network stack adds a packet to a 224 device's send queue and the ``IFF_OACTIVE`` bit in the device's ``if_flags`` is 225 not set. 226 227 For many devices this function need only set the ``IFF_OACTIVE`` bit in the 228 ``if_flags`` and send an event to the transmit task indicating that a packet is 229 in the driver transmit queue. 232 230 233 231 Write the Driver Initialization Function. 234 232 ========================================= 235 233 236 This function should initialize the device, attach to interrupt handler, 237 and start the driver transmit and receive tasks. The function 238 .. code:: c 239 240 rtems_id 241 rtems_bsdnet_newproc (char \*name, 242 int stacksize, 243 void(\*entry)(void \*), 244 void \*arg); 234 This function should initialize the device, attach to interrupt handler, and 235 start the driver transmit and receive tasks. The function: 236 237 .. code-block:: c 238 239 rtems_id rtems_bsdnet_newproc( 240 char *name, 241 int stacksize, 242 void (*entry)(void *), 243 void *arg 244 ); 245 245 246 246 should be used to start the driver tasks. 247 247 248 248 Note that the network stack may call the driver initialization function more 249 than once. 250 Make sure multiple versions of the receive and transmit tasks are not accidentally 251 started. 249 than once. Make sure multiple versions of the receive and transmit tasks are 250 not accidentally started. 252 251 253 252 Write the Driver Transmit Task 254 253 ============================== 255 254 256 This task is reponsible for removing packets from the driver send queue and sending them to the device. The task should block waiting for an event from the 257 driver start function indicating that packets are waiting to be transmitted. 258 When the transmit task has drained the driver send queue the task should clear 259 the ``IFF_OACTIVE`` bit in ``if_flags`` and block until another outgoing 260 packet is queued. 255 This task is reponsible for removing packets from the driver send queue and 256 sending them to the device. The task should block waiting for an event from 257 the driver start function indicating that packets are waiting to be 258 transmitted. When the transmit task has drained the driver send queue the task 259 should clear the ``IFF_OACTIVE`` bit in ``if_flags`` and block until another 260 outgoing packet is queued. 261 261 262 262 Write the Driver Receive Task 263 263 ============================= 264 264 265 This task should block until a packet arrives from the device. If the 266 device is an Ethernet interface the function ``ether_input`` should be called 267 to forward the packet to the network stack. The arguments to ``ether_input`` 268 a re a pointer to the interface data structure, a pointer to the ethernet269 header anda pointer to an mbuf containing the packet itself.265 This task should block until a packet arrives from the device. If the device 266 is an Ethernet interface the function ``ether_input`` should be called to 267 forward the packet to the network stack. The arguments to ``ether_input`` are 268 a pointer to the interface data structure, a pointer to the ethernet header and 269 a pointer to an mbuf containing the packet itself. 270 270 271 271 Write the Driver Interrupt Handler 272 272 ================================== 273 273 274 A typical interrupt handler will do nothing more than the hardware 275 manipulation required to acknowledge the interrupt and send an RTEMS event 276 to wake up the driver receive or transmit task waiting for the event. 277 Network interface interrupt handlers must not make any calls to other 278 network routines. 274 A typical interrupt handler will do nothing more than the hardware manipulation 275 required to acknowledge the interrupt and send an RTEMS event to wake up the 276 driver receive or transmit task waiting for the event. Network interface 277 interrupt handlers must not make any calls to other network routines. 279 278 280 279 Write the Driver IOCTL Function … … 284 283 commands which must be handled are: 285 284 286 ``SIOCGIFADDR`` 287 288 ``SIOCSIFADDR`` 289 290 If the device is an Ethernet interface these 291 commands should be passed on to ``ether_ioctl``. 285 ``SIOCGIFADDR``, ``SIOCSIFADDR`` 286 If the device is an Ethernet interface these commands should be passed on 287 to ``ether_ioctl``. 292 288 293 289 ``SIOCSIFFLAGS`` 294 295 This command should be used to start or stop the device, 296 depending on the state of the interface ``IFF_UP`` and``IFF_RUNNING`` bits in ``if_flags``: 290 This command should be used to start or stop the device, depending on the 291 state of the interface ``IFF_UP`` and``IFF_RUNNING`` bits in ``if_flags``: 297 292 298 293 ``IFF_RUNNING`` 299 300 294 Stop the device. 301 295 302 296 ``IFF_UP`` 303 304 297 Start the device. 305 298 306 299 ``IFF_UP|IFF_RUNNING`` 307 308 300 Stop then start the device. 309 301 310 302 ``0`` 311 312 303 Do nothing. 313 304 … … 315 306 ============================================ 316 307 317 This function should print the values of any statistic/diagnostic 318 counters the network driver may use. The driver ioctl function should call 319 the statistic-printing function when the ioctl command is``SIO_RTEMS_SHOW_STATS``. 320 321 .. COMMENT: COPYRIGHT (c) 1988-2002. 322 323 .. COMMENT: On-Line Applications Research Corporation (OAR). 324 325 .. COMMENT: All rights reserved. 326 308 This function should print the values of any statistic/diagnostic counters the 309 network driver may use. The driver ioctl function should call the 310 statistic-printing function when the ioctl command is ``SIO_RTEMS_SHOW_STATS``. -
bsp_howto/non_volatile_memory.rst
r54514fe r6d7a4d2 1 1 .. comment SPDX-License-Identifier: CC-BY-SA-4.0 2 3 .. COMMENT: Written by Eric Norum 4 .. COMMENT: COPYRIGHT (c) 1988-2002. 5 .. COMMENT: On-Line Applications Research Corporation (OAR). 6 .. COMMENT: All rights reserved. 2 7 3 8 Non-Volatile Memory Driver 4 9 ########################## 5 10 6 The Non-Volatile driver is responsible for providing an 7 interface to various types of non-volatile memory. These 8 types of memory include, but are not limited to, Flash, EEPROM, 9 and battery backed RAM. The capabilities provided 11 The Non-Volatile driver is responsible for providing an interface to various 12 types of non-volatile memory. These types of memory include, but are not 13 limited to, Flash, EEPROM, and battery backed RAM. The capabilities provided 10 14 by this class of device driver are: 11 15 … … 24 28 - Erase the Non-Volatile Memory Area 25 29 26 There is currently only one non-volatile device driver included in the 27 RTEMS source tree. The information provided in this chapter 28 is based on drivers developed for applications using RTEMS. 29 It is hoped that this driver model information can form the 30 basis for a standard non-volatile memory driver model that 31 can be supported in future RTEMS distribution. 30 There is currently only one non-volatile device driver included in the RTEMS 31 source tree. The information provided in this chapter is based on drivers 32 developed for applications using RTEMS. It is hoped that this driver model 33 information can form the basis for a standard non-volatile memory driver model 34 that can be supported in future RTEMS distribution. 32 35 33 36 Major and Minor Numbers 34 37 ======================= 35 38 36 The *major* number of a device driver is its index in the 37 RTEMS Device Address Table. 38 39 A *minor* number is associated with each device instance 40 managed by a particular device driver. An RTEMS minor number 41 is an ``unsigned32`` entity. Convention calls 42 dividing the bits in the minor number down into categories 43 that specify an area of non-volatile memory and a partition 44 with that area. This results in categories 45 like the following: 46 47 - *area* - indicates a block of non-volatile memory 48 49 - *partition* - indicates a particular address range with an area 50 51 From the above, it should be clear that a single device driver 52 can support multiple types of non-volatile memory in a single system. 53 The minor number is used to distinguish the types of memory and 54 blocks of memory used for different purposes. 39 The ``major`` number of a device driver is its index in the RTEMS Device 40 Address Table. 41 42 A ``minor`` number is associated with each device instance managed by a 43 particular device driver. An RTEMS minor number is an ``unsigned32`` entity. 44 Convention calls dividing the bits in the minor number down into categories 45 that specify an area of non-volatile memory and a partition with that area. 46 This results in categories like the following: 47 48 - ``area`` - indicates a block of non-volatile memory 49 50 - ``partition`` - indicates a particular address range with an area 51 52 From the above, it should be clear that a single device driver can support 53 multiple types of non-volatile memory in a single system. The minor number is 54 used to distinguish the types of memory and blocks of memory used for different 55 purposes. 55 56 56 57 Non-Volatile Memory Driver Configuration 57 58 ======================================== 58 59 59 There is not a standard non-volatile driver configuration table but some 60 fields are common across different drivers. The non-volatile memory driver 61 configuration table is typically an array of structures with each 62 structure containing the information for a particular area of 63 non-volatile memory. 64 The following is a list of the type of information normally required 65 to configure each area of non-volatile memory. 66 67 *memory_type* 60 There is not a standard non-volatile driver configuration table but some fields 61 are common across different drivers. The non-volatile memory driver 62 configuration table is typically an array of structures with each structure 63 containing the information for a particular area of non-volatile memory. The 64 following is a list of the type of information normally required to configure 65 each area of non-volatile memory. 66 67 ``memory_type`` 68 68 is the type of memory device in this area. Choices are battery backed RAM, 69 EEPROM, Flash, or an optional user-supplied type. If the user-supplied type70 is configured, then the user is responsible for providing a set of69 EEPROM, Flash, or an optional user-supplied type. If the user-supplied 70 type is configured, then the user is responsible for providing a set of 71 71 routines to program the memory. 72 72 73 *memory* 73 ``memory`` 74 74 is the base address of this memory area. 75 75 76 *attributes* 77 is a pointer to a memory type specific attribute block. Some of 78 the fields commonly contained in this memory type specific attribute 79 structure area: 80 81 *use_protection_algorithm* 82 76 ``attributes`` 77 is a pointer to a memory type specific attribute block. Some of the fields 78 commonly contained in this memory type specific attribute structure area: 79 80 ``use_protection_algorithm`` 83 81 is set to TRUE to indicate that the protection (i.e. locking) algorithm 84 should be used for this area of non-volatile memory. A particular 85 type of non-volatile memory may not have a protection algorithm. 86 87 *access* 88 82 should be used for this area of non-volatile memory. A particular type 83 of non-volatile memory may not have a protection algorithm. 84 85 ``access`` 89 86 is an enumerated type to indicate the organization of the memory 90 devices in this memory area. The following is a list of the 91 accesstypes supported by the current driver implementation:92 - simple unsigned8 93 - simple unsigned1694 - simple unsigned3295 - simple unsigned6496 - single unsigned8 at offset 0 in an unsigned1697 - single unsigned8 at offset 1in an unsigned1698 - single unsigned8 at offset 0 in an unsigned3299 - single unsigned8 at offset 1in an unsigned32100 - single unsigned8 at offset 2in an unsigned32101 - single unsigned8 at offset 3in an unsigned32102 103 *depth* 104 87 devices in this memory area. The following is a list of the access 88 types supported by the current driver implementation: 89 90 - simple unsigned8 91 - simple unsigned16 92 - simple unsigned32 93 - simple unsigned64 94 - single unsigned8 at offset 0 in an unsigned16 95 - single unsigned8 at offset 1 in an unsigned16 96 - single unsigned8 at offset 0 in an unsigned32 97 - single unsigned8 at offset 1 in an unsigned32 98 - single unsigned8 at offset 2 in an unsigned32 99 - single unsigned8 at offset 3 in an unsigned32 100 101 ``depth`` 105 102 is the depth of the progamming FIFO on this particular chip. Some 106 103 chips, particularly EEPROMs, have t