2011-09-30 17 views
7

Sto usando la programmazione seriale per collegarsi cavo seriale al mio iPhonecollegare l'accessorio al dispositivo iPhone jailbreak

il mio codice è come sotto

#include <stdio.h> /* Standard input/output definitions */ 
#include <string.h> /* String function definitions */ 
#include <unistd.h> /* UNIX standard function definitions */ 
#include <fcntl.h> /* File control definitions */ 
#include <errno.h> /* Error number definitions */ 
#include <termios.h> /* POSIX terminal control definitions */ 

static struct termios gOriginalTTYAttrs; 

static int OpenSerialPort() 
{ 
    int  fileDescriptor = -1; 
    int  handshake; 
    struct termios options; 

    // Open the serial port read/write, with no controlling terminal, and don't wait for a connection. 
    // The O_NONBLOCK flag also causes subsequent I/O on the device to be non-blocking. 
    // See open(2) ("man 2 open") for details. 

    fileDescriptor = open("/dev/tty.iap", O_RDWR | O_NOCTTY | O_NONBLOCK); 
    if (fileDescriptor == -1) 
    { 
     printf("Error opening serial port %s - %s(%d).\n", 
       "/dev/tty.iap", strerror(errno), errno); 
     goto error; 
    } 

    // Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed 
    // unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned 
    // processes. 
    // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details. 

    if (ioctl(fileDescriptor, TIOCEXCL) == -1) 
    { 
     printf("Error setting TIOCEXCL on %s - %s(%d).\n", 
      "/dev/tty.iap", strerror(errno), errno); 
     goto error; 
    } 

    // Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block. 
    // See fcntl(2) ("man 2 fcntl") for details. 

    if (fcntl(fileDescriptor, F_SETFL, 0) == -1) 
    { 
     printf("Error clearing O_NONBLOCK %s - %s(%d).\n", 
      "/dev/tty.iap", strerror(errno), errno); 
     goto error; 
    } 

    // Get the current options and save them so we can restore the default settings later. 
    if (tcgetattr(fileDescriptor, &gOriginalTTYAttrs) == -1) 
    { 
     printf("Error getting tty attributes %s - %s(%d).\n", 
      "/dev/tty.iap", strerror(errno), errno); 
     goto error; 
    } 

    // The serial port attributes such as timeouts and baud rate are set by modifying the termios 
    // structure and then calling tcsetattr() to cause the changes to take effect. Note that the 
    // changes will not become effective without the tcsetattr() call. 
    // See tcsetattr(4) ("man 4 tcsetattr") for details. 

    options = gOriginalTTYAttrs; 

    // Print the current input and output baud rates. 
    // See tcsetattr(4) ("man 4 tcsetattr") for details. 

    printf("Current input baud rate is %d\n", (int) cfgetispeed(&options)); 
    printf("Current output baud rate is %d\n", (int) cfgetospeed(&options)); 

    // Set raw input (non-canonical) mode, with reads blocking until either a single character 
    // has been received or a one second timeout expires. 
    // See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details. 

    cfmakeraw(&options); 
    options.c_cc[VMIN] = 1; 
    options.c_cc[VTIME] = 10; 

    // The baud rate, word length, and handshake options can be set as follows: 

    cfsetspeed(&options, B19200); // Set 19200 baud  
    options.c_cflag |= (CS8); // RTS flow control of input 


    printf("Input baud rate changed to %d\n", (int) cfgetispeed(&options)); 
    printf("Output baud rate changed to %d\n", (int) cfgetospeed(&options)); 

    // Cause the new options to take effect immediately. 
    if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1) 
    { 
     printf("Error setting tty attributes %s - %s(%d).\n", 
      "/dev/tty.iap", strerror(errno), errno); 
     goto error; 
    }  
    // Success 
    return fileDescriptor; 

    // Failure "/dev/tty.iap" 
error: 
    if (fileDescriptor != -1) 
    { 
     close(fileDescriptor); 
    } 

    return -1; 
} 

int main(int args, char *argv[]) 
{ 
    int fd; 
    char somechar[8]; 
    fd=OpenSerialPort(); // Open tty.iap with no hardware control, 8 bit, BLOCKING and at 19200 baud 
    if(fd>-1) 
    { 
     write(fd,"*",1); // Write handshaking message over serial 
     /////////////////////////////////////////////////////////////////////////////////////////////////// 
     // After this, our device or our PC program should be strobing serial ground to gain access to the Iphone Serial Line 
     ////////////////////////////////////////////////////////////////////////////////////////////////// 
     read(fd,&somechar[0],1); // Read 1 byte over serial. This will block (wait) untill the byte has been received 
     if(somechar[0]=='*') // Check if this byte is a "handshaking" message 
     { 
      printf("Serial connection established!\n"); // If it is, we have established a connection to the device and can freely read/write over serial! 
      while(1) // Do this forever or untill someone presses CTRL+C 
      { 
       read(fd,&somechar[0],1); // Read a character over serial! 
       putchar(somechar[0]); // Write the character to the Terminal!! 
      } 
     } 
    } 
    return 0; 
} 

ma quando vado a controllare il cavo è connesso o non ho ottenuto un errore come questo

Errore nell'apertura della porta seriale /dev/tty.iap - Operazione non consentita (1).

c'è qualcuno conosce la soluzione e per favore mi dia suggerimento se sto andando in modo sbagliato in realtà io sono una nuova in fase di sviluppo iOS in modo più confuso.

Grazie

+0

Non ho alcuna familiarità con quel livello di codifica su un iPhone jb. Tuttavia alcuni controlli di tipo unix possono illuminare gli altri. Quali permessi sono su /dev/tty.iap e l'utente su cui stai eseguendo il codice ha le autorizzazioni per il dispositivo (anche se suppongo che tu stia eseguendo il codice ssh'd come root?). – Diziet

+0

@Raj come hai visto l'output delle tue dichiarazioni printf? Ovviamente la finestra della console Xcode non funzionerà perché il tuo iDevice è collegato al tuo dispositivo seriale usando un connettore dock personalizzato presumo? – Chris

risposta

2

Forse i seguenti articoli iPhone comunicazione seriale può aiutare?

iPhone/iPod Touch Serial Port Tutorial da Collin Meyer

e

iPhone Serial Communication

+0

Sono riuscito a comunicare jb iPhone all'accessorio tramite comunicazione seriale ma ho un problema con iPhone 4g. Ho ricevuto un errore "Connessione seriale fallita" ogni volta che provo a connettere l'accessorio a iPhoen4g. funziona bene con 3g o 3gs – Raj

+0

@Raj Okay, beh, dovresti aggiornare la tua domanda originale per riflettere questo allora. – fuzz

+0

@Fulvio, secondo link aveva la risposta, almeno nel mio caso. +1 per quello (era qualche tempo fa). – newenglander

0

ho ottenuto lo stesso errore quando si cerca di aprire la porta seriale su un iPod Touch jailbroken con iOS 5.0 utilizzando un binario creato con Xcode. Tuttavia quando ho usato gcc (per l'iPhone con set di flag appropriati) sulla riga di comando sul mio Mac invece di Xcode e ho creato un'app della riga di comando per iOS, il file binario che è stato generato è stato in grado di aprire la porta seriale e leggere i comandi dal mio accessorio esterno. Dovrebbe essere possibile creare una libreria e collegarla a Xcode e avere lo stesso risultato (sebbene non l'abbia ancora provato).

Aggiornamento: Sfortunatamente la creazione di una libreria in gcc e il suo collegamento in un progetto Xcode ha prodotto lo stesso errore di prima. Possibili soluzioni:

  • chiamata la riga di comando applicazione da iOS Xcode GUI
  • compilare l'applicazione stessa con gcc invece di Xcode

In realtà, è ancora più semplice di questo, ho trovato passando attraverso il secondo link nella risposta di Fulvio: Devi solo spostare l'app in una directory diversa da quella in cui Xcode normalmente li inserisce. Come suggerito nel post di blog, ho inserito la mia app in una directory per le app Cydia (/private/var/stash/Applications) e ho potuto aprire la porta seriale: non è stata necessaria la compilazione di gcc.

Quindi il mio gcc -compiled della riga di comando applicazione è stata in grado di leggere dalla porta seriale perché ero eseguirlo nella home directory di root, che pure non ha le restrizioni della directory normale apps (/private/var/mobile/Applications) - -qualunque tali restrizioni potrebbero essere.

Problemi correlati