Toon posts:

[C, Kylix] Code converteer probleem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig om vanuit Kylix bepaalde hardware aan te sturen. Nu hebben we daarvoor een driver. Deze driver werkt met IOCTL code's. Het probleem is dat mijn programma met onbekende IOCTL's werkt volgens het log bestand.

Hieronder is de informatie te zien van hoe het in C ontworpen is:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define MAJOR_NUM 240

typedef union
{
  struct
  {
    unsigned int card;
    unsigned long mask;
    unsigned long data;
  } enable, write;
  struct
  {
    unsigned int card;
    unsigned long data;
  } read;
} gpio_ops;

#define IOCTL_GPIO_ENABLE _IOW (MAJOR_NUM, 1, gpio_ops *)
#define IOCTL_GPIO_READ   _IOWR(MAJOR_NUM, 2, gpio_ops *)
#define IOCTL_GPIO_WRITE  _IOW (MAJOR_NUM, 3, gpio_ops *)


Nu weet ik niet precies wat dat gpio_ops * betekent, maar het gaat om de grootte van die union. De union is 12 bytes groot.


In mijn Kylix programma doe ik het als volgt:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  TEnable = packed record
    Card: LongInt;  // C ==> int
    Mask: ulong;    // C ==> unsigned long
    Data: ulong;    // C ==> unsigned long
  end;

  TWrite = packed record
    Card: LongInt;  // C ==> int
    Mask: ulong;    // C ==> unsigned long
    Data: ulong;    // C ==> unsigned long
  end;

  TRead = packed record
    Card: LongInt; // C ==> int
    Data: ulong;   // C ==> unsigned long
  end;

  IOCTL_GPIO_ENABLE := __IOW(MAJOR_NUM, 1, Sizeof(TEnable));
  IOCTL_GPIO_READ := __IOWR(MAJOR_NUM, 2, Sizeof(TRead));
  IOCTL_GPIO_WRITE := __IOW(MAJOR_NUM, 3, Sizeof(TWrite));

Maar deze IOCTL_GPIO's zijn dus volgens het systeem niet juist.

Nu wilde ik eerst de IOCTL_GPIO nummers weergegeven met een test programma in c. Alleen door mijn zeer beperkte kennis van C lukte me dat niet.

Maar ziet iemand misschien wat er fout zou kunnen gaan. (In het log bestand staat niet meer informatie. Alleen het nummer van het onbekende IOCTL_GPIO nummer).

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 22:29

Creepy

Tactical Espionage Splatterer

Je geeft nu als laatste argument de grootte van de gpio_ops mee, terwijl in de C code een pointer naar het gpio_ops record wordt meegegeven.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Bedankt, het had er inderdaad wat mee te maken.

Inmiddels werkt de aansturing perfect.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Unions zijn altijd exact net zo groot als hun grootste member, in dit geval klopt dus iig de sizeof(TRead) niet daar die 8 bytes zal geven ipv de 12 gewenste.

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
curry684 schreef op 07 July 2003 @ 12:14:
Unions zijn altijd exact net zo groot als hun grootste member, in dit geval klopt dus iig de sizeof(TRead) niet daar die 8 bytes zal geven ipv de 12 gewenste.
Dat hoeft niet : een union van een short(2 bytes) en char[3] mag 4 bytes zijn. Stel namelijk dat je een array van die unions hebt en dat de tweede union een short bevat. Op veel HW moet de short aligned zijn, dus die kan niet op array+3 gealloceerd zijn.

offtopic:
sizeof(short) hoeft natuurlijk geen twee te zijn, lees dan char[sizeof(short)+1]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Dat betreft algemene struct padding en is niet unionspecifiek.

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 07 juli 2003 @ 12:14:
Unions zijn altijd exact net zo groot als hun grootste member, in dit geval klopt dus iig de sizeof(TRead) niet daar die 8 bytes zal geven ipv de 12 gewenste.
Dus ik moet er het volgende van maken:
Delphi:
1
IOCTL_GPIO_READ := __IOWR(MAJOR_NUM, 2, Sizeof(TWrite));

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 22:29

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 07 July 2003 @ 13:53:
[...]
Dus ik moet er het volgende van maken:
Delphi:
1
IOCTL_GPIO_READ := __IOWR(MAJOR_NUM, 2, Sizeof(TWrite));
Eehh... zie mijn opmerking hierboven over de pointer i.p.v. de size meegeven ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1