Memory layout of a data structure: Difference between revisions
m <lang> |
No edit summary |
||
Line 180: | Line 180: | ||
$vec->set($rs232{'RD Received data'}, 1); |
$vec->set($rs232{'RD Received data'}, 1); |
||
$vec->get($rs232{'TC Transmit clock'}); |
$vec->get($rs232{'TC Transmit clock'}); |
||
</ |
</lang> |
||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 15:29, 3 February 2009
You are encouraged to solve this task according to the task description, using any language you may know.
It is often useful to control the memory layout of fields in a data structure to match an interface control definition, or to interface with hardware. Define a data structure matching the RS-232 Plug Definition. Use the 9-pin definition for brevity.
Pin Settings for Plug (Reverse order for socket.) __________________________________________ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 _________________ 1 2 3 4 5 6 7 8 9 25 pin 9 pin 1 - PG Protective ground 2 - TD Transmitted data 3 3 - RD Received data 2 4 - RTS Request to send 7 5 - CTS Clear to send 8 6 - DSR Data set ready 6 7 - SG Signal ground 5 8 - CD Carrier detect 1 9 - + voltage (testing) 10 - - voltage (testing) 11 - 12 - SCD Secondary CD 13 - SCS Secondary CTS 14 - STD Secondary TD 15 - TC Transmit clock 16 - SRD Secondary RD 17 - RC Receiver clock 18 - 19 - SRS Secondary RTS 20 - DTR Data terminal ready 4 21 - SQD Signal quality detector 22 - RI Ring indicator 9 23 - DRS Data rate select 24 - XTC External clock 25 -
Ada
<lang ada> type Bit is mod 2; type Rs_232_Layout is record
Carrier_Detect : Bit; Received_Data : Bit; Transmitted_Data : Bit; Data_Terminal_ready : Bit; Signal_Ground : Bit; Data_Set_Ready : Bit; Request_To_Send : Bit; Clear_To_Send : Bit; Ring_Indicator : Bit;
end record;
for Rs_232_Layout use record
Carrier_Detect at 0 range 0..0; Received_Data at 0 range 1..1; Transmitted_Data at 0 range 2..2; Data_Terminal_Ready at 0 range 3..3; Signal_Ground at 0 range 4..4; Data_Set_Ready at 0 range 5..5; Request_To_Send at 0 range 6..6; Clear_To_Send at 0 range 7..7; Ring_Indicator at 0 range 8..8;
end record; </lang>
C /C++
Note: The order of the fields is implementation-defined (i.e. the first bit might be the least-significant one or the most-significant one). On GCC and MSVC++, the first bit is the least-significant one. <lang c> struct RS232_data {
unsigned carrier_detect : 1; unsigned received_data : 1; unsigned transmitted_data : 1; unsigned data_terminal_ready : 1; unsigned signal_ground : 1; unsigned data_set_ready : 1; unsigned request_to_send : 1; unsigned clear_to_send : 1; unsigned ring_indicator : 1;
}; </lang> The ":1" gives the number of allocated bits. For unused bits (e.g. pin 11 in the 25-pin version above) the field name can be omitted.
Forth
Low level hardware control is a typical use of Forth. None of this is standard, however, since hardware I/O mechanisms differ on different systems. Forth does not have a structure mechanism, much less bitfields. These would be represented instead via bitmask constants if doing real serial port control.
: masks ( n -- ) 0 do 1 i lshift constant loop ; 9 masks DCD RxD TxD DTR SG DSR RTS CTS RI
Example usage, assuming I/O primitives in and out:
hex 3fd constant com1-ctrl decimal : wait-ready begin com1-ctrl in CTS and until ; : wait-rx begin com1-ctrl in CTS and 0= until ; : send-byte ( b -- ) \ send assuming N81 (no parity, 8 bits data, 1 bit frame) 255 and 9 0 do RTS com1-ctrl out wait-ready dup 1 and if TxD else 0 then com1-ctrl out wait-rx 2/ loop drop ;
Of course, this is a very simplified view of the full RS-232 protocol. Also, although this represents the order of the pins in a D-9 connector, this would not necessarily be the same as the order of the bits in a control register.
OCaml
<lang ocaml> open ExtLib class rs232_data = object
val d = BitSet.create 9
method carrier_detect = BitSet.is_set d 0 method received_data = BitSet.is_set d 1 method transmitted_data = BitSet.is_set d 2 method data_terminal_ready = BitSet.is_set d 3 method signal_ground = BitSet.is_set d 4 method data_set_ready = BitSet.is_set d 5 method request_to_send = BitSet.is_set d 6 method clear_to_send = BitSet.is_set d 7 method ring_indicator = BitSet.is_set d 8
method set_carrier_detect b = (if b then BitSet.set else BitSet.unset) d 0 method set_received_data b = (if b then BitSet.set else BitSet.unset) d 1 method set_transmitted_data b = (if b then BitSet.set else BitSet.unset) d 2 method set_data_terminal_ready b = (if b then BitSet.set else BitSet.unset) d 3 method set_signal_ground b = (if b then BitSet.set else BitSet.unset) d 4 method set_data_set_ready b = (if b then BitSet.set else BitSet.unset) d 5 method set_request_to_send b = (if b then BitSet.set else BitSet.unset) d 6 method set_clear_to_send b = (if b then BitSet.set else BitSet.unset) d 7 method set_ring_indicator b = (if b then BitSet.set else BitSet.unset) d 8
end
</lang>
Perl
<lang perl> use Bit::Vector::Minimal qw(); my $vec = Bit::Vector::Minimal->new(size => 24);
my %rs232 = reverse (
1 => 'PG Protective ground', 2 => 'TD Transmitted data', 3 => 'RD Received data', 4 => 'RTS Request to send', 5 => 'CTS Clear to send', 6 => 'DSR Data set ready', 7 => 'SG Signal ground', 8 => 'CD Carrier detect', 9 => '+ voltage (testing)', 10 => '- voltage (testing)', 12 => 'SCD Secondary CD', 13 => 'SCS Secondary CTS', 14 => 'STD Secondary TD', 15 => 'TC Transmit clock', 16 => 'SRD Secondary RD', 17 => 'RC Receiver clock', 19 => 'SRS Secondary RTS', 20 => 'DTR Data terminal ready', 21 => 'SQD Signal quality detector', 22 => 'RI Ring indicator', 23 => 'DRS Data rate select', 24 => 'XTC External clock',
);
$vec->set($rs232{'RD Received data'}, 1); $vec->get($rs232{'TC Transmit clock'}); </lang>
Python
This task cannot really be done efficiently in Python, as there is no type analogous to bit fields. The code below merely defines a dictionary with the pin names corresponding to entries in the dictionary.
<lang python>
- Controlling Fields in a Structure in Python
rs232 = { "PG Protective ground":1, "TD Transmitted data":2, "RD Received data":3, "RTS Request to send":4, "CTS Clear to send":5, "DSR Data set ready":6, "SG Signal ground":7, "CD Carrier detect":8, "+ voltage (testing)":9, "- voltage (testing)":10, "SCD Secondary CD":12, "SCS Secondary CTS":13, "STD Secondary TD":14, "TC Transmit clock":15, "SRD Secondary RD":16, "RC Receiver clock":17, "SRS Secondary RTS":19, "DTR Data terminal ready":20, "SQD Signal quality detector":21, "RI Ring indicator":22, "DRS Data rate select":23, "XTC External clock":24 }
rs232["RD Received data"] = 1
print rs232["TC Transmit clock"]
</lang>