[USB]Obj-c HID

kollyv

Membre confirmé
17 Avril 2007
31
0
Hello,

je vais démarrer un projet dont le but est de mettre à jour le firmware d'une télécommande reliée par USB et utilisant le driver HID.

Je ne connais malheureusment pas du totu objective-c. J'ai déjà réalisé une applic similiaire en C#.

Après pas mal de recherche je me suis rendu compte qu'il n'existait pas grand chose pour le faire en obj-c.

Il me semble que le HID manager a été fait en C.

J'ai quand meme trouvé une lib qui fait du binding avec l'api en C depuis obj-c

http://violasong.com/blog/2007/02/

Est ce que qqu connait un moyen de le faire. Sachant que je n'ai pas bcp de temps j'aimerais pouvoir éviter de tout refaire. Surtout qu'il va falloir comprendre objective-c.

Est ce que le faire avec Carbon (C++) serait plus adatpé.

J'utilise Xcode.

Merci d'avance :)
 
Tu auras plus de chance dans "Développement sur Mac"…
 
Le C peut être appelé sans restriction dans un programme en Obj-C. Donc pour l'interface tu peux choisir la techno que tu veux : Carbon ou Cocoa. :zen:
 
Ok merci, je vais essayé d'y aller comme ca en utilisant IOHIDLib et je verrai bien au fur et a mesure. Je repasserai sans doute :)
 
Mais comment je dois faire vu qu'elles ne sont pas dans la même syntaxe. J'ai un peu du mal à m'y faire avec cet objec-c. Qqu n'aurait pas un exemple d'écriture/lecture sur un device hid?
 
Bon on reprend : l'Obj-C est une surcouche du C, qui apporte une notion de programmation objet. Les syntaxes du C et de l'Obj-C sont les MEMES pour ce qui concerne la programmation procédurale, seule les aspects "objet" sont spécifiques à l'obj-C.
Dans un programme en Obj-C rien n'interdit de mettre un printf ou un strlen, ou je ne sais quoi d'autre tiré d'une librairie C quelconque.

Et pire encore tu peux mélanger de l'Obj-C et du C++ : ça s'appelle Obj-C++ :D
 
Bon alors super merci, je pense que cette information est un bon point de départ ;-)

Je ne voyais pas la chose comme ca. Je ne connais pas bien le C non plus... Bon bah je v essayer de m'en sortire avec tout ca

Encore merci pour ton aide :)
 
Bonjour,

je fais remonter ce topic car je cherche à communiquer avec un périphérique USB HID quelconque (je suis encore jeune développeur en électronique, accompagné par un jeune programmeur sous Delphi).
Bref, actuellement, j'ai une DLL sous XP et un bout de code pour Delphi (donc en Pascal) qui me permet d'envoyer et de recevoir des données à un périphérique USB HID uniquement en donnant son PID et VID.
Malheureusement pour moi, je bosse sous OSX et les logiciels sous XP ne sont pour moi qu'une "vision" (je ne touche pas à Delphi, je le connais mas je n'y touche pas).
Je voulais donc me mettre à développer avec Xcode (oui, moi qui ne touchais parfois qu'à l'assembleur et souvent au C, mais côté microcontrôleur). Un ami prof m'a conseillé de me mettre à Cocoa, ce que j'ai fait.
J'ai un peu tâtonné, trébuché, raté, planté... pendant 2-3 jours puis j'ai enfin saisi d'un seul coup le fonctionnement de l'Objective C (mais je dois encore me perfectionner).
Finalement, je voudrais faire un petit programme utile et surtout maîtriser la communication avec toutes mes créations en élec qui sont des périphériques USB HID.
Donc je voudrais connaître l'issue de la demande originale de ce topic et/ou avoir un peu d'aide pour parvenir à mon objectif.



Merci !
 
Je suis aussi preneur d'une bonne adresse (hormis le site de dev apple) où je peux trouver de l'aide (forums inclus).
Même en anglais, ç ne me gène que rarement.
 
La documentation est assez complete, dans /Developer/Examples/IOKit/usb et /Developer/Examples/Kernel/IOKit/usb tu trouveras des bases

il y a deux cas possibles :

1 - tu utilises les outils USB generiques car ton matériel n'a rien de très spécifique et utilise
des choses très génériques auquel cas tu peux faire un client cocoa lié au iokit qui te permettra
de communiquer avec ton device /et matériel

2 - ton matériel est vendor specifique et a besoin d 'implementer la class (abstract) HID, avec des vérifications et traductions spécifiques, alors tu auras besoin de développer un petit driver, tu utiliseras alors les USBNotification a l'interieur de ton driver afin de pouvoir communiquer avec ton client dans le userspace (simple exemple mount/unmount)

si c'est le cas, voila un peu près les choses dont tu pourrais avoir besoin (un simple skeleton qui ressemblerait à ceci) :
Bloc de code:
#ifndef IOUSBHIDDRIVER_H
#define IOUSBHIDDRIVER_H

//Provides a simple memory descriptor that allocates its own buffer memory.
#include <IOKit/IOBufferMemoryDescriptor.h>

//Time based event source mechanism.
#include <IOKit/IOTimerEventSource.h>

//IOHIDDevice defines a Human Interface Device (HID) object, which will interact with the HID 
// Manager by publishing static properties in the I/O Registry, and also by reporting HID events 
//through shared memory.
#include <IOKit/hid/IOHIDDevice.h>

/* take a look here
#include <IOKit/usb/IOUSBBus.h>
#include <IOKit/usb/IOUSBInterface.h>
#include <IOKit/usb/USB.h>
#include <IOKit/usb/IOUSBController.h>
*/
//This header contains the definition of the IOUSBControllerV2 class, which is a subclass of 
//IOUSBController. The IOUSBControllerV2 class supports high-speed (480 Mb/s) devices. 
#include <IOKit/usb/IOUSBControllerV2.h>

class USBSample : public IOHIDDevice
{
OSDeclareDefaultStructors(USBSample)
protected:
	IOUSBInterface 				*thisInterface;
	IOUSBDevice 				*thisDevice;
	IOUSBPipe 				*thisPipe;
	IOUSBCompletion     		       thisCompletion;
	IOBufferMemoryDescriptor 	       *thisBuffer;
 public:
    virtual bool start(IOService *provider);
    virtual void stop(IOService *provider);
    virtual bool terminate(IOOptionBits options = 0);
    virtual bool finalize(IOOptionBits options);
}

#endif  // IOUSBHIDDRIVER_H

mais je te conseilerais d'&#233;tendre un controller et de faire un pointer static sur MyHID
&#224; l'interieur de ta class maitresse


http://www.usb.org/developers/hidpage
 
  • J’aime
Réactions: obi wan
Merci pour cette r&#233;ponse assez compl&#232;te (et le temps pass&#233; dessus)


J'ai donc quelques questions qui suivent :
Suite aux propositions 1 et 2, je me demande comment diff&#233;rencier un p&#233;riph&#233;rique qui n'a rien de particulier.
Clairement : j'utilise dans mes projets des microcontr&#244;leurs PIC18 (et DsPIC33). G&#233;n&#233;ralement les PIC18 que j'utilise ont un port USB. J'utilise donc un un firmware HID donn&#233; en exemple par Microchip que je modifie selon mes besoins. Bien souvent, mon p&#233;riph&#233;rique n'a absolument rien de sp&#233;cifique, c'est une interface utilisateur standard qui n'est reconnu comme rien (ni souris, ni joystick, ni clavier... rien du tout). Sous Windows, j'ai trouv&#233; une DLL mcHID.dll et un code "mod&#232;le" sous Delphi qui permet de communiquer avec mes interfaces uniquement &#224; l'aide du PID et VID qu'on pr&#233;cise dans le code (et c'est tr&#232;s pratique car je n'ose imaginer la difficult&#233; de devoir tout refaire &#224; chaque fois). En gros, on remplit un tableau char et hop, on envoie.
Je cherche donc &#224; refaire la m&#234;me chose avec XCode : remplir un tableau et envoyer mes octets par USB au p&#233;riph&#233;rique sp&#233;cifi&#233; par son VID et PID.

J'esp&#232;re que cette pr&#233;cision pour vous permettre de me lancer sur la bonne voie...




Vous avez aussi &#233;crit :
La documentation est assez complete, dans /Developer/Examples/IOKit/usb et /Developer/Examples/Kernel/IOKit/usb tu trouveras des bases
Excusez moi pour mon ignorance, mes lorsque je vais dans ces r&#233;pertoires, je ne trouve pas de documentation.


EDIT : mes p&#233;riph&#233;riques sont en USB 2.0 Full Speed (12 Mbits/s)
 
Dans l'attente d'une réponse, j'ai tenté avec les exemples fournis.
Bref, USBSimpleExample trouve bien mon périphérique mais retourne cette erreur :
Bloc de code:
dealWithInterface: unable to open interface. ret = e00002c5

D'après ce que j'ai vu (IOReturn.h), cela indique que le périphérique est déjà utilisé.
Dès lors, je ne sais absolument pas quoi faire :rolleyes:
 
je pense que c'est un probleme de droit d'acces depuis le userspace

http://forum.microchip.com/printable.aspx?m=125158&mpage=2

as tu essay&#233; avec sudo ?

ou alors quelque chose de vendor specifique qui n'est pas support&#233; ?

http://lists.apple.com/archives/Usb/2006/Dec/msg00038.html

" The KVM switch is reporting a pollingRate of 0 on the interrupt endpoint,
which is not allowed by the USB 1.1 spec. By reading the whole
thread, it's obvious that since 2002, Apple has changed the behavior
so the interface can be created, but still won't allow the endpoint
to be created, since it doesn't follow the USB specification.

Has anything else changed since 2002, or is there a workaround, or am
I just not going to be able to communicate with the interrupt
endpoint on interface #1? Shame on the company that made this KVM
switch for not adhering to the USB and HID specs! "

tu n'as pas install&#233; xcode complet , re-telecharge sur l'ADC et r&#233;installe la totalit&#233;
 
Pour Xcode, je l'ai installé avec le CD que j'ai reçu via l'ADC student, donc je pense que tout y est.

J'ai lancé mon programme avec un sudo et j'obtiens la même erreur...


Mais dans le doute, je vais réinstaller Xcode complet.
Je vous tiens au courant.
 
J'ai bien réinstallé Xcode (téléchargement du fichier dmg + installations de tous les pkg).
Visiblement, ça na rien changé.
 
Je reviens &#224; la charge car &#231;a fait plus d'une semaine que je pi&#233;tine...

Je suis toujours preneur d'une aide, mais qui reste &#224; ma port&#233;e.

Alors j'ai tent&#233; plusieurs choses quand m&#234;me :
Utilisation de libusb : j'ai plusieurs probl&#232;mes de fonctions non d&#233;clar&#233;es (usb-init, etc... avec une erreur zerolink) >> J'ai cherch&#233; dans tous le sens et j'ai finallement abandonn&#233;.
Essai de cr&#233;ation d'un driver vide pour que le syst&#232;me lib&#232;re mon p&#233;riph&#233;rique et donc pour revenir &#224; "USBSimple example" : le fichier kext se chargerai, impossible &#224; d&#233;charger et rien de lib&#233;r&#233;... >> J'ai cherch&#233; des exemples sur le net et dans les docs Apple : rien ne m'a aid&#233; donc abandon aussi.
 
Je vais poster ma solution:

J'ai utilisé le wrappeur DDHIdLib -> http://www.dribin.org/dave/blog/archives/2007/03/19/ddhidlib_10/

L'inisialisation:
Bloc de code:
@try{mDevices = [[DDHidDevice allDevices] retain] ;}@catch(NSException * e){}
        int i;    
        for (i = 0; i < [mDevices count]; i++ ){
            DDHidDevice * device =    (DDHidDevice*)[mDevices objectAtIndex: i];
            if ([device vendorId] == 7057 && [device productId] == 10 ){
                ewooDevice = device;
            }
        }
La callback pour la lecture: (ReaderReportCallback)
Bloc de code:
static void ReaderReportCallback(void *target, IOReturn result,
    void *refcon, void *sender, UInt32 size) {


}
L'initialisation de la callback:
Bloc de code:
    ewooDeviceInterface = [ewooDevice deviceInterface];
    NSXThrowError((*ewooDeviceInterface)->open(ewooDeviceInterface,options));
    ioReturnValue = (*ewooDeviceInterface)->createAsyncPort(ewooDeviceInterface,&monPort);
    ioReturnValue = (*ewooDeviceInterface)->createAsyncEventSource(ewooDeviceInterface,&maLoop );
    rl = CFRunLoopGetCurrent ();
    ioReturnValue =  (*ewooDeviceInterface)->setInterruptReportHandlerCallback(ewooDeviceInterface, buffer,338, ReaderReportCallback,buffer,NULL);
    (*ewooDeviceInterface)->startAllQueues(ewooDeviceInterface);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), maLoop, kCFRunLoopDefaultMode);

et pour écrire un report:

Bloc de code:
ioReturnValue = (*ewooDeviceInterface)->setReport(ewooDeviceInterface, reportType,12,start,64,2000,NULL,NULL,NULL);

Ce code fonctionne. Le problème que je rencontre est le suivant:

Sur MAC intel: j'ai une corrupte stack si je ne lance pas l'application avec ROSETTA.

SI j'enlève l'initilisation de la callback ca fonctionne.

Est ce que qqu peut m'aider?