Data Representation - Controlling Fields in a Structure
From Rosetta Code
Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they 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 -
Contents |
[edit] 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;
[edit] 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.
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;
};
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.
[edit] 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.
[edit] 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'});
[edit] Python
# Controlling Fields in a Structure in Python
# This task is easily accomplished with the use of a Python dictionary.
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
}
#assignation and retrieval of data is trivial
rs232["RD Received data"] = 1
print rs232["TC Transmit clock"]
Categories: Programming Tasks | Solutions by Programming Task | Ada | C | C++ | Forth | Perl | Python

