/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
struct til char array og tilbage igen.
Fra : Jens Lund Jensen


Dato : 01-05-04 17:22

hej gruppe.

jeg sidder lige og programmere lidt på en netværksgrænseflade.

jeg har en struct af type PAKKE som jeg gerne vil have splittet op i et
char array ,så jeg kan sende dem over en UART. jeg er lidt i tvivl om det
kan lade sig gøre?. For at gøre det hele lidt mere besværligt så skal det
virke på både en alm PC, en PIC16F877 og en MSP430F149 .

Jeg regner med at modtagelsen af structen kan foregå ved at samle de
enkelte char i et array og så caste arrayet til en PAKKE struct.

MVH Jens Jensen.

lidt kode:

struct pakke_def{
unsigned char ID;
unsigned char Modtager_adr;
unsigned char Afsender_adr;
char Data[MAX_DATA_STOERRELSE];
};
typedef struct pakke_def PAKKE;

// globalt Char array med plads til structen.
unsigned char pakke_send_array[(char) sizeof(PAKKE)+1];

//send funktion
char MAC_send(void)
{

PAKKE pakke_send = KOE_laes(3); // KOE_laes returnere en PAKKE struct
MAC_send_pakke_count = (char) sizeof(PAKKE); //Antal char
pakke_send_array = (char *) &pakke_send; //struct til chararray

// her sendes den første char, resten ordnes via interrupt routine.
U0TXBUF = *pakke_send_array;
return 0;
}//Slut på funktion



--
"Just once, I'd like to time-travel and not see Nazis."

 
 
Igor V. Rafienko (01-05-2004)
Kommentar
Fra : Igor V. Rafienko


Dato : 01-05-04 18:32

[ Jens Lund Jensen ]

[ ... ]

> jeg har en struct af type PAKKE som jeg gerne vil have splittet op i
> et char array ,så jeg kan sende dem over en UART. jeg er lidt i
> tvivl om det kan lade sig gøre?


Siden struct'en din består av utelukkende chars, blir det en relativt
enkel sak.


> Jeg regner med at modtagelsen af structen kan foregå ved at samle de
> enkelte char i et array og så caste arrayet til en PAKKE struct.


Det greieste er å lage to rutiner som gjør det motsatt av hverandre.

[ ... ]


> struct pakke_def{
> unsigned char ID;
> unsigned char Modtager_adr;
> unsigned char Afsender_adr;
> char Data[MAX_DATA_STOERRELSE];
> };
> typedef struct pakke_def PAKKE;
>
> // globalt Char array med plads til structen.
> unsigned char pakke_send_array[(char) sizeof(PAKKE)+1];


1) typecast til char er unødvendig
2) hvorfor +1?


> //send funktion
> char MAC_send(void)
> {
>
> PAKKE pakke_send = KOE_laes(3); // KOE_laes returnere en PAKKE struct
> MAC_send_pakke_count = (char) sizeof(PAKKE); //Antal char
> pakke_send_array = (char *) &pakke_send; //struct til chararray


Man kan ikke tilordne til en array (det er en non-modifiable lvalue,
hvis jeg ikke husker feil).


> // her sendes den første char, resten ordnes via interrupt routine.
> U0TXBUF = *pakke_send_array;
> return 0;
> }//Slut på funktion


Jeg misliker typecasts i de tilfellene der dette kan unngåes. Du aner
ikke hvordan kompilatoren velger å plassere data i pakke_def i minne,
og akkurat på det nivået er det viktig å ha kontroll over det. Så selv
om det går an å konvertere en pakke_def peker til en char peker, er
det neppe dette man egentlig vil.

Jeg foreslår to funksjoner: den ene som "flater ut" pakke_def, den
andre som ta den "utflatede" representasjonen og bygger opp en struct:

typedef struct packet_t {
unsigned char id;
unsigned char receiver_address;
unsigned char sender_address;
char data[MAX_DATA_SIZE];
} packet_t;


void
packet_to_array(packet_t p, unsigned char *array)
{
array[0] = p.id;
array[1] = p.receiver_address;
array[2] = p.sender_address;
memmove(array+3, p.data, max_data_size);
}

void
array_to_packet(packet_t p, unsigned char *array)
{
memset(&p, 0, sizeof p);
/* The rest is left as an exercise for the reader */
}

Mappingen vil da foregå omtrent slik (bruk fastbredde skrifttype):

packet_t
+------------------------------------------------------+
|++++ +----------------+ +--------------+ +---- ... --+|
||id| |receiver_address| |sender_address| |data ||
|+--+ +----------------+ +--------------+ +---- ... --+|
+------------------------------------------------------+

|
[array_to_packet]
|
v
array of bytes
0 1 2 3 N <- array index / byte number
+--+--+--+-- ... --+
| | | | <data> |
+--+--+--+-- ... --+
^ ^ ^
| | +--+
| | |
| +--+ sender_address
id |
receiver_address

Legg merke til at det ikke spiller noen rolle hvordan struct'en legges
ut i minne opprinnelig. Det kan godt være "hull" mellom datafelt, men
disse vil altså ikke påvirke hva som sendes ut på nettverket.

Siden det er en uting å gi folk hele løsningen gratis, foreslår jeg at
du skriver array_to_packet selv.

NB! Det er likevel en forutsetning for at dette skal virket at både
avsender og mottager representerer verdier med chars på samme måte
(fx. dersom id er et tegn, er det viktig at både avsender og mottager
tolker den numeriske verdien likt (fx. ved valg av det samme
tegnetsettet)). Dersom denne forutsetningen ikke er tilstedet, vil man
være nødt til å velge en felles representasjon for verdidomener for
hvert enkelt felt å lage konverteringsfunksjoner for det. Et eksempel
på dette er hton* og ntoh*-funksjonene i *nixfamilien (de opererer dog
med tall, heller enn chars).





ivr
--
<html><form><input type crash></form></html>

Søg
Reklame
Statistik
Spørgsmål : 177580
Tips : 31968
Nyheder : 719565
Indlæg : 6409076
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste