Memory layout of a data structure: Difference between revisions
m (<lang>) |
|||
Line 37: | Line 37: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
<lang ada> |
|||
type Bit is mod 2; |
|||
type Bit is mod 2; |
|||
⚫ | |||
⚫ | |||
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; |
|||
⚫ | |||
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; |
|||
⚫ | |||
end record; |
|||
</lang> |
|||
=={{header|C}}/{{header|C++}}== |
=={{header|C}}/{{header|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. |
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; |
|||
⚫ | |||
}; |
|||
</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. |
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. |
||
Line 116: | Line 120: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
<ocaml> |
<lang ocaml> |
||
open ExtLib |
|||
class rs232_data = object |
class rs232_data = object |
||
val d = BitSet.create 9 |
val d = BitSet.create 9 |
||
Line 140: | Line 145: | ||
method set_ring_indicator b = (if b then BitSet.set else BitSet.unset) d 8 |
method set_ring_indicator b = (if b then BitSet.set else BitSet.unset) d 8 |
||
end |
end |
||
;; |
|||
;;</ocaml> |
|||
</lang> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
<lang perl> |
|||
⚫ | |||
use Bit::Vector::Minimal qw(); |
|||
⚫ | |||
my %rs232 = reverse ( |
|||
1 => 'PG Protective ground', |
|||
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); |
|||
⚫ | |||
</perl> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 178: | Line 186: | ||
code below merely defines a dictionary with the pin names corresponding to entries in the dictionary. |
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 = { |
rs232 = { |
||
Line 207: | Line 216: | ||
rs232["RD Received data"] = 1 |
rs232["RD Received data"] = 1 |
||
print rs232["TC Transmit clock"] |
print rs232["TC Transmit clock"] |
||
</lang> |
Revision as of 12:50, 31 January 2009
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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'}); </perl>
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>