2012-03-02 89 views
2

我有一個運行iOS 5.0.1的越獄Iphone 4,我試圖通過Dock連接器將串行數據發送到我的Arduino。我使用Minicom成功發送了數據到Arduino,但我似乎無法在應用程序中使用它。這是我的代碼,錯誤在底部。Iphone串行端口錯誤

#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 */ 

#import "ViewController.h" 

static struct termios gOriginalTTYAttrs; 

static int OpenSerialPort(void); 

@implementation ViewController 
@synthesize dataLabel, startData; 
@synthesize timer; 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Release any cached data, images, etc that aren't in use. 
} 

#pragma mark - View lifecycle 

- (void)viewDidLoad 
{ 

    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 


    [super viewDidAppear:animated]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 


-(IBAction)startSerial:(id)sender{ 
    timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(targetMethod:) userInfo:nil repeats:YES]; 
      } 



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_NDELAY); 

     NSLog(@"%d",fileDescriptor); 


     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; 
    } 

-(void) targetMethod: (NSTimer *) theTimer { 

    //dataLabel.text = @"timer running"; 

      int fd; 
      char somechar[8]; 
      fd=OpenSerialPort(); // Open tty.iap with no hardware control, 8 bit, BLOCKING and at 19200 baud 
    NSLog(@"%d",fd); 

    dataLabel.text = [NSString stringWithFormat:@"%d",fd]; 

      if(fd>-1) 
      {     
       // dataLabel.text = @"got port"; 

       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 
       { 
        dataLabel.text = @"handshake accepted"; 

        printf("Serial connection established!\n"); // If it is, we have established a connection to the device and can freely read/write over serial! 
        while(true) // Do this forever or untill someone presses CTRL+C 
        { 
         dataLabel.text = @"in the loop"; 

         read(fd,&somechar[0],1); // Read a character over serial! 

         dataLabel.text = [NSString stringWithFormat:@"%@",somechar[0]]; // Write the character to the Terminal!! 
        } 
       } 
      } 

} 
    @end 

,但我得到的錯誤是:

2012-03-01 19:58:03.507 Iphone-Serial[2470:707] -1 
    Error opening serial port /dev/tty.iap - Resource busy(16). 

我應該重新啓動我的電話?或者以某種方式關閉串口?

感謝, 安德魯

回答

1

您的應用程序必須具有root權限訪問tty.iap。只需ssh到您的設備(以root身份),並且可以解決此問題。從簡單的代碼開始,獲得響應並擴展更多。