2012-09-08 3 views
1

Redopark SDK와 함께 MonoTouch를 사용하고 Objective-C로 작성된 Redpark 직렬 케이블 예제 프로그램 (여기서는 Xcode에서 완벽하게 실행할 수 있음)을 C#으로 복제하려고합니다 :MonoTouch의 Redpark SDK 사용

https://github.com/mono/monotouch-bindings/tree/master/Redpark

을 내 프로젝트에 사용할 수있는 .DLL을 만들어 :

https://github.com/bjepson/iPhone-Arduino-Simple-Switch

는 나는 여기의 바인딩 기존 사용. 필자의 프로젝트에서는 모든 것이 원활하게 진행되었다. (필자는 cableConnected와 cableDisconnected 델리게이트 콜백을 잘 처리 할 수 ​​있었다.) 쓸 때까지.

Stacktrace: 

at MonoTouch.RedPark.RscMgr.Write (int16,uint) <IL 0x00010, 0x00113> 
    at tester2.tester2ViewController.toggleLED (MonoTouch.Foundation.NSObject) [0x00069] in /Users/salgarcia/Projects/tester2/tester2/tester2ViewController.cs:57 
    at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff> 
    at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
    at tester2.Application.Main (string[]) [0x00000] in /Users/salgarcia/Projects/tester2/tester2/Main.cs:17 
    at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff> 

Native stacktrace: 

0 tester2        0x001c2a25 mono_handle_native_sigsegv + 244 
1 tester2        0x001af065 mono_sigsegv_signal_handler + 172 
2 libsystem_c.dylib     0x329f17ed _sigtramp + 48 
3 tester2        0x00003a63 __inline_memcpy_chk + 30 
4 tester2        0x00003a63 __inline_memcpy_chk + 30 
5 tester2        0x00004011 -[RscMgr writeRscMessage:Length:MsgData:] + 220 
6 tester2        0x00004131 -[RscMgr write:Length:] + 100 
7 tester2        0x000438d8 wrapper_managed_to_native_ApiDefinition_Messaging_int_objc_msgSend_short_UInt32_intptr_intptr_int16_uint + 256 
8 tester2        0x001aa024 tester2_tester2ViewController_toggleLED_MonoTouch_Foundation_NSObject + 680 
9 tester2        0x000f76c0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200 
10 tester2        0x001b0843 mono_jit_runtime_invoke + 1054 
11 tester2        0x0022c40f mono_runtime_invoke + 90 
12 tester2        0x001ad14d native_to_managed_trampoline_tester2_tester2ViewController_toggleLED + 220 
13 CoreFoundation      0x3553f3fd -[NSObject performSelector:withObject:withObject:] + 52 
14 UIKit        0x33034e07 -[UIApplication sendAction:to:from:forEvent:] + 62 
15 UIKit        0x33034dc3 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 30 
16 UIKit        0x33034da1 -[UIControl sendAction:to:forEvent:] + 44 
17 UIKit        0x33034b11 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 492 
18 Foundation       0x350ff933 __NSFireDelayedPerform + 414 
19 CoreFoundation      0x355b9a33 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14 
20 CoreFoundation      0x355b9699 __CFRunLoopDoTimer + 364 
21 CoreFoundation      0x355b826f __CFRunLoopRun + 1206 
22 CoreFoundation      0x3553b4a5 CFRunLoopRunSpecific + 300 
23 CoreFoundation      0x3553b36d CFRunLoopRunInMode + 104 
24 GraphicsServices     0x371d7439 GSEventRunModal + 136 
25 UIKit        0x33047cd5 UIApplicationMain + 1080 
26 tester2        0x0001fcc4 wrapper_managed_to_native_MonoTouch_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 240 
27 tester2        0x001a9744 tester2_Application_Main_string__ + 152 
28 tester2        0x000f76c0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200 
29 tester2        0x001b0843 mono_jit_runtime_invoke + 1054 
30 tester2        0x0022c40f mono_runtime_invoke + 90 
31 tester2        0x0022f123 mono_runtime_exec_main + 306 
32 tester2        0x00232a4f mono_runtime_run_main + 482 
33 tester2        0x001b529f mono_jit_exec + 94 
34 tester2        0x00271c70 main + 2216 
35 tester2        0x00004860 start + 40 

================================================================= 
Got a SIGSEGV while executing native code. This usually indicates 
a fatal error in the mono runtime or one of the native libraries 
used by your application. 
================================================================= 

나는 시리얼 포트가 실제로 열리지 않았다 즉, 내가 할 수있는 (문제가 무엇인지에 대한 입력을 찾고 있어요 : 나는 쓰기 기능을 사용하려고 할 때, 프로그램은 SIGSEGV와 충돌 "txbuffer"에 대해 잘못된 데이터 유형을 사용하고 있습니다. 바인딩이 제대로 구현되지 않았고 대리인을 올바르게 설정하지 않았습니다.) 이에 대한 피드백은 크게 감사하겠습니다!

참고로

가 여기 내 C# 나란히 목표 - C 구현을입니다/MonoTouch 구현 :

목표 - C 레드 파크 라이브러리 ".H"파일

#import <Foundation/Foundation.h> 
#import <ExternalAccessory/ExternalAccessoryDefines.h> 
#import <ExternalAccessory/EAAccessoryManager.h> 
#import <ExternalAccessory/EAAccessory.h> 
#import <ExternalAccessory/EASession.h> 

#include "redparkSerial.h" 



enum 
{ 
    kMsrCts = 0x01, 
    kMsrRi = 0x02, 
    kMsrDsr = 0x04, 
    kMsrDcd = 0x08, 

}; 

enum { 
    kRSC_StreamBufferSize = 4096, 
    kRSC_MaxMessageDataLength = 230, 
    kRSC_SerialReadBufferSize = 4096, 
    kRsc_TxFifoSize = 256, 
    kRSC_NoPasscode = 0 
}; 


typedef enum DataSizeType 
{ 
    kDataSize7 = SERIAL_DATABITS_7, 
    kDataSize8 = SERIAL_DATABITS_8 
} DataSizeType; 

typedef enum ParityType 
{ 
    kParityNone = SERIAL_PARITY_NONE, 
    kParityOdd = SERIAL_PARITY_ODD, 
    kParityEven = SERIAL_PARITY_EVEN 
} ParityType; 

typedef enum StopBitsType 
{ 
    kStopBits1 = STOPBITS_1, 
    kStopBits2 = STOPBITS_2 
} StopBitsType; 


@protocol RscMgrDelegate; 

@interface RscMgr : NSObject <NSStreamDelegate> { 

    id <RscMgrDelegate> theDelegate; 

    // EA api variables 
    EASession *theSession; 
    EAAccessory *theAccessory; 
    NSArray *supportedProtocols; 
    NSString *connectedProtocol; 

    // rsc port control/info structures 
    serialPortConfig portConfig; 
    serialPortStatus portStatus; 
    serialPortControl portControl; 

    // EASession stream handling 
    // for collecting RSC Messages 
    unsigned char *rxStreamBuffer; 
    int rxCount; 
    int rxCountTotal; 
    int txCountTotal; 
    int rxRemain; 
    int readLen; 

    unsigned char *txStreamBuffer; 
    int txIn; 
    int txOut; 
    int txStreamEmpty; 

    // internal dtr and rts state bits 
    int dtrState; 
    int rtsState; 

    // serial data buffer 
    // for collecting serial bytes received from the serial port 
    UInt8 *serialReadBuffer; 
    int serialReadIn; 
    int serialReadOut; 
    int serialReadBytesAvailable; 

    BOOL encodingEnabled; 
    UInt32 thePasscode; 

} 

- (void) setDelegate:(id <RscMgrDelegate>) delegate; 


// Initializes the RscMgr and reigsters for accessory connect/disconnect notifications. 
- (id) init; 

// establish communication with the Redpark Serial Cable. This call will also 
// configure the serial port based on defaults or prior calls to set the port config 
// (see setBaud, setDataSize, ...) 
- (void) open; 

// simple serial port config interface 
// can be called anytime (even after open: call) 
- (void) setBaud:(int)baud; 
- (void) setDataSize:(DataSizeType)dataSize; 
- (void) setParity:(ParityType)parity; 
- (void) setStopBits:(StopBitsType)stopBits; 

// read write serial bytes 
- (int) write:(UInt8 *)data Length:(UInt32)length; 
- (int) read:(UInt8 *)data Length:(UInt32)length; 
- (int) getReadBytesAvailable; 

/* 
returns a bit field (see redparkSerial.h) 
0-3 current modem status bits for CTS, RI, DSR, DCD, 4-7 previous modem status bits 

MODEM_STAT_CTS 0x01 
MODEM_STAT_RI 0x02 
MODEM_STAT_DSR 0x04 
MODEM_STAT_DCD 0x08 
*/ 
- (int) getModemStatus; 

// returns true if DTR is asserted 
- (BOOL) getDtr; 

// returns true if RTS is asserted 
- (BOOL) getRts; 

// set DTR state 
- (void) setDtr:(BOOL)enable; 

// set RTS state 
- (void) setRts:(BOOL)enable; 

// advanced (full) serial port config interface (see redparkSerial.h) 
- (void) setPortConfig:(serialPortConfig *)config RequestStatus:(BOOL)reqStatus; 
- (void) setPortControl:(serialPortControl *)control RequestStatus:(BOOL)reqStatus; 
- (void) getPortConfig:(serialPortConfig *) portConfig; 
- (void) getPortStatus:(serialPortStatus *) portStatus; 

// advanced advanced 
// write a raw message 
- (int) writeRscMessage:(int)cmd Length:(int)len MsgData:(UInt8 *)msgData; 

// GPS cable only - requires loopback connector 
- (void) testGpsCable; 

@end 

@protocol RscMgrDelegate <NSObject> 

// Redpark Serial Cable has been connected and/or application moved to foreground. 
// protocol is the string which matched from the protocol list passed to initWithProtocol: 
- (void) cableConnected:(NSString *)protocol; 

// Redpark Serial Cable was disconnected and/or application moved to background 
- (void) cableDisconnected; 

// serial port status has changed 
// user can call getModemStatus or getPortStatus to get current state 
- (void) portStatusChanged; 

// bytes are available to be read (user calls read:) 
- (void) readBytesAvailable:(UInt32)length; 

@optional 
// called when a response is received to a getPortConfig call 
- (void) didReceivePortConfig; 

// GPS Cable only - called with result when loop test completes. 
- (void) didGpsLoopTest:(BOOL)pass; 

@end 

목표 - C " .H "

#import <UIKit/UIKit.h> 
#import "RscMgr.h" 

#define BUFFER_LEN 1024 

@interface HelloArduinoViewController : UIViewController <RscMgrDelegate> { 

RscMgr *rscMgr; 
UInt8 rxBuffer[BUFFER_LEN]; 
UInt8 txBuffer[BUFFER_LEN]; 

UISwitch *toggleSwitch; 
} 

@property (nonatomic, retain) IBOutlet UISwitch *toggleSwitch; 
- (IBAction)toggleLED:(id)sender; 

@end 

목표 - C 파일 "하는 .m"파일

#import "HelloArduinoViewController.h" 

@implementation HelloArduinoViewController 
@synthesize toggleSwitch; 

- (void)dealloc 
{ 
    [toggleSwitch release]; 
    [super dealloc]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

#pragma mark - View lifecycle 


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    rscMgr = [[RscMgr alloc] init]; 
    [rscMgr setDelegate:self]; 

} 


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

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

- (IBAction)toggleLED:(id)sender { 
    if (toggleSwitch.on) { // check the state of the button 
     txBuffer[0] = (int) '1'; 
    } else { 
     txBuffer[0] = (int) '0'; 
    } 

    // Send 0 or 1 to the Arduino 
    [rscMgr write:txBuffer Length:1];   
} 

#pragma mark - RscMgrDelegate methods 

- (void) cableConnected:(NSString *)protocol { 
    [rscMgr setBaud:9600]; 
    [rscMgr open]; 
} 

- (void) cableDisconnected { 

} 

- (void) portStatusChanged { 

} 

- (void) readBytesAvailable:(UInt32)numBytes { 
} 

- (BOOL) rscMessageReceived:(UInt8 *)msg TotalLength:(int)len { 
    return FALSE;  
} 

- (void) didReceivePortConfig { 
} 

@end 

내 C#/MonoTouch 구현

문제는 내가 데이터가 기록되는 통과하기 위해 필요한 것을 발견 내 MonoTouch 구현 코드에 해결되었다
using System; 
using MonoTouch.Foundation; 
using MonoTouch.UIKit; 
using MonoTouch.RedPark; 

namespace tester2 
{ 
    public partial class tester2ViewController : UIViewController 
    { 
     static RscMgr rscMgr; 
     MyRedparkDelegate delegate1; 

     short[] rxbuffer = new short[1024]; 
     short[] txbuffer = new short[1024]; 

     public tester2ViewController() : base ("tester2ViewController", null) 
     { 
     } 

     public override void DidReceiveMemoryWarning() 
     { 
      base.DidReceiveMemoryWarning(); 
     } 

     public override void ViewDidLoad() 
     { 
      base.ViewDidLoad(); 
      rscMgr = new RscMgr(); 
      delegate1 = new MyRedparkDelegate(); 
      rscMgr.SetDelegate(delegate1); 
     } 

     public override void ViewDidUnload() 
     { 
      base.ViewDidUnload(); 
      ReleaseDesignerOutlets(); 
     } 

     public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation) 
     { 
      return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown); 
     } 

     partial void toggleLED (NSObject sender) 
     { 
      if(toggleSwitch.On) { 
       txbuffer[0] = (int) '1'; 
      } else { 
       txbuffer[0] = (int) '0'; 
      } 
      rscMgr.Write (txbuffer[0], 1); 
     } 

     public class MyRedparkDelegate : RscMgrDelegate 
     { 
      public MyRedparkDelegate() 
      { 
      } 
      public override void CableConnected (string protocol) 
      { 
       rscMgr.SetBaud (9600); 
       rscMgr.Open(); 
      } 
      public override void CableDisconnected() 
      { 
      } 
      public override void PortStatusChanged() 
      { 
      } 
      public override void ReadBytesAvailable (uint length) 
      { 
      } 
     } 
    } 
} 
+0

당신을 돕기 위해'RscMgr'을위한 Obj-C 헤더 파일을 게시해야합니다. – jonathanpeppers

+0

테스트하려면 특수한 하드웨어가 필요합니다. –

+0

@ miguel.de.icaza 물론이 특정 문제에 대한 redpark 직렬 케이블이지만, 결국에는 직렬 통신 장치가 장착되어 있습니다 (이 샘플 프로젝트에는 기본 arduino 만 사용하고 있습니다) – salgarcia

답변

1

그래서 위의 코드에서 Write를

 rscMgr.Write(ref txbuffer[0],1); 

으로 변경했으며 예상대로 작동했습니다. SDK 다운로드와 함께 제공된 Redpark Serial cable SDK 사용 설명서를 철저하게 읽는 데 도움이되었습니다.