photron Geschrieben December 7, 2012 at 09:21 Geschrieben December 7, 2012 at 09:21 Ich vermute das die letzte Mail so zu verstehen ist, das die Bindings noch kein 2.0 unterstützen ?! C/C++ Bindings im git sind jetzt für Protokoll v2 umgebaut. Zitieren
skippi Geschrieben December 7, 2012 at 14:01 Geschrieben December 7, 2012 at 14:01 OOps tffbcontrol.c: In function 'MasterBrickReset': tffbcontrol.c:151:10: error: too many arguments to function 'ipcon_create' ip_connection.h:293:6: note: declared here tffbcontrol.c:151:10: error: void value not ignored as it ought to be tffbcontrol.c:157:11: error: too many arguments to function 'ipcon_enumerate' ip_connection.h:342:5: note: declared here tffbcontrol.c:192:8: error: too many arguments to function 'ipcon_create' ip_connection.h:293:6: note: declared here tffbcontrol.c:192:8: error: void value not ignored as it ought to be tffbcontrol.c:199:9: error: too many arguments to function 'ipcon_enumerate' ip_connection.h:342:5: note: declared here tffbcontrol.c:214:9: error: too many arguments to function 'ipcon_enumerate' ip_connection.h:342:5: note: declared here tffbcontrol.c: In function 'trimwhitespace': tffbcontrol.c:262:3: warning: implicit declaration of function 'isspace' [-Wimplicit-function-declaration] tffbcontrol.c: In function 'setupLCDDevice': tffbcontrol.c:840:5: error: too few arguments to function 'lcd_20x4_create' bricklet_lcd_20x4.h:92:6: note: declared here tffbcontrol.c:842:5: warning: implicit declaration of function 'ipcon_add_device' [-Wimplicit-function-declaration] tffbcontrol.c:854:35: error: too few arguments to function 'lcd_20x4_register_callback' bricklet_lcd_20x4.h:107:6: note: declared here tffbcontrol.c:857:34: error: too few arguments to function 'lcd_20x4_register_callback' bricklet_lcd_20x4.h:107:6: note: declared here tffbcontrol.c: In function 'setupVTempBricklet': tffbcontrol.c:865:5: error: too few arguments to function 'temperature_create' bricklet_temperature.h:95:6: note: declared here tffbcontrol.c:876:35: error: too few arguments to function 'temperature_register_callback' bricklet_temperature.h:110:6: note: declared here tffbcontrol.c: In function 'setupRTempBricklet': tffbcontrol.c:886:5: error: too few arguments to function 'temperature_create' bricklet_temperature.h:95:6: note: declared here tffbcontrol.c:899:35: error: too few arguments to function 'temperature_register_callback' bricklet_temperature.h:110:6: note: declared here tffbcontrol.c: In function 'setupSTempBricklet': tffbcontrol.c:909:5: error: too few arguments to function 'temperature_create' bricklet_temperature.h:95:6: note: declared here tffbcontrol.c:920:35: error: too few arguments to function 'temperature_register_callback' bricklet_temperature.h:110:6: note: declared here tffbcontrol.c: In function 'setupIO16Bricklet': tffbcontrol.c:949:2: error: too few arguments to function 'io16_create' bricklet_io16.h:115:6: note: declared here tffbcontrol.c:966:3: error: too few arguments to function 'io4_register_callback' bricklet_io4.h:130:6: note: declared here tffbcontrol.c: In function 'setupIO4Bricklet': tffbcontrol.c:984:5: error: too few arguments to function 'io4_create' bricklet_io4.h:115:6: note: declared here tffbcontrol.c:1001:3: error: too few arguments to function 'io4_register_callback' bricklet_io4.h:130:6: note: declared here tffbcontrol.c: In function 'setupServoBrick': tffbcontrol.c:1115:26: error: too few arguments to function 'servo_register_callback' brick_servo.h:223:6: note: declared here tffbcontrol.c: In function 'cb_enumerate': tffbcontrol.c:1136:7: error: too few arguments to function 'master_create' brick_master.h:246:6: note: declared here tffbcontrol.c:1142:5: warning: implicit declaration of function 'master_get_version' [-Wimplicit-function-declaration] tffbcontrol.c:1161:4: warning: implicit declaration of function 'lcd_20x4_get_version' [-Wimplicit-function-declaration] tffbcontrol.c:1171:4: warning: implicit declaration of function 'temperature_get_version' [-Wimplicit-function-declaration] tffbcontrol.c:1204:4: warning: implicit declaration of function 'io4_get_version' [-Wimplicit-function-declaration] tffbcontrol.c:1215:4: warning: implicit declaration of function 'io16_get_version' [-Wimplicit-function-declaration] tffbcontrol.c:1225:7: error: too few arguments to function 'imu_create' brick_imu.h:253:6: note: declared here tffbcontrol.c:1231:5: warning: implicit declaration of function 'imu_get_version' [-Wimplicit-function-declaration] tffbcontrol.c:1246:7: error: too few arguments to function 'servo_create' brick_servo.h:208:6: note: declared here tffbcontrol.c:1247:4: warning: implicit declaration of function 'servo_get_version' [-Wimplicit-function-declaration] tffbcontrol.c: In function 'main': tffbcontrol.c:1324:5: error: too many arguments to function 'ipcon_create' ip_connection.h:293:6: note: declared here tffbcontrol.c:1324:5: error: void value not ignored as it ought to be tffbcontrol.c:1330:6: error: too many arguments to function 'ipcon_enumerate' ip_connection.h:342:5: note: declared here tffbcontrol.c:1342:6: warning: implicit declaration of function 'ipcon_join_thread' [-Wimplicit-function-declaration] make: *** [tffbcontrol.o] Error 1 Da ist ja doch die Wochendarbeit gesichert. Warum kein ipcon_join_thread mehr ? .... Na ich schau mir ersteinmal alle notwendigen Änderungen an... Zitieren
photron Geschrieben December 7, 2012 at 14:30 Autor Geschrieben December 7, 2012 at 14:30 Die generellen API Änderungen sind hier beschrieben: http://www.tinkerforge.com/doc/Protocol_20.html Es wird auch noch eine Portierungsanleitung geben, hier mal die wichtigsten Punkte: Die host und port Parameter sind von sind von ipcon_create nach ipcon_connect gewandert. ipcon_create stellt nicht mehr die TCP/IP Verbindung her, dass tut jetzt ipcon_connect. ipcon_connect startet auch erst die internen Threads. ipcon_enumerate nimmt kein Callback Parameter mehr, dafür ist jetzt ipcon_register_callback da. Es gibt neue Callbacks neben Enumerate, die darüber informieren wenn die TCP/IP hergestellt und getrennt wurde. <device>_create nimmt jetzt neben der UID noch die IPConnection als Parameter und es gibt kein ipcon_add_device mehr. <device>_register_callback nimmt jetzt ein user_data Parameter und alle Callback Signaturen sind um ein user_data Parameter erweitert. Der user_data Wert der bei <device>_register_callback übergeben wird wir dann an den registrierten Callback weitergereicht. Die meiste Information aus <device>_get_version ist jetzt im neuen Enumerate Callback untergebracht. Es gibt statt <device>_get_version jetzt nur noch <device>_get_api_version. Mit <device>_set_response_expected kann man für Setter aktivieren, dass der Brick eine Antwort schickt um sicher gehen zu können, dass der Setter auch angekommen ist. ipcon_discconnect wartet standardmässig auf das Beenden der internen Threads. Da die internen Threads jetzt nicht mehr durchlaufen sondern in ipcon_connect erzeugt und in ipcon_disconnect beendet werden funktioniert ipcon_join_thread nicht mehr wie vorher und wurde entfernt. Falls du einen solchen Syncronisierungsmeachnismus benötigst musst du ihn die jetzt selber bauen. Interne verwendet die IPConnection solche Dinge weiterhin. Müssen wir mal gucken was wir da machen können um Programme die ipcon_join_thread verwendet haben weiter zu unterstützen. Schau dir auch die aktualisierten Beispiele an. Zitieren
skippi Geschrieben December 7, 2012 at 15:03 Geschrieben December 7, 2012 at 15:03 Erstmal danke für die Erläuterungen. ipcon_join_thread habe ich benutzt um mein Program zu beenden wenn der brickd gestorben ist. Wie merke ich das jetzt ? Zitieren
photron Geschrieben December 7, 2012 at 15:30 Autor Geschrieben December 7, 2012 at 15:30 ipcon_join_thread habe ich benutzt um mein Program zu beenden wenn der brickd gestorben ist. Wie merke ich das jetzt ? Ah, trickreich! Wenn brickd stirbt, dann reist die TCP/IP Verbindung ab. Dafür gab es vorher keinen richtigen Mechanismus das mitzubekommen. Dafür gibt es jetzt den Disconnected Callback: void disconnected(int disconnect_reason, void *user_data) { printf("disconnected: %d\n", diconnect_reason); } ipcon_register_callback(ipcon, IPCON_CALLBACK_DISCONNECTED, disconnected, NULL); disconnect_reason kann REQUEST, ERROR oder SHUTDOWN sein. Bei REQUEST hast du explizit vorher ipcon_disconnect aufgerufen. Bei SHUTDOWN hat die Gegenseite die Verbindung geschlossen. Bei ERROR ist ein Fehler aufgetreten. Standardmäßig ist Auto-Reconnect an, so dass die IPConnection in diesem Fall automatisch versucht die Verbindung wieder aufzubauen, nachdem sie dir den Callback über den Disconnect zugestellt hat. Das kann über ipcon_set_auto_reconnect kontrolliert werden. ipcon_set_auto_reconnect(ipcon, false) und ipcon_disconnect brechen ein laufendes Auto-Reconnect ab. Und ipcon_get_connection_state verät dir den aktuellen Zustand der TCP/IP Verbindung. Als gegenstück zum Disconnected Callback gibt es den Connected Callback, der mitteilt dass die TCP/IP Verbindung aufgebaut wurde. Zitieren
skippi Geschrieben December 7, 2012 at 16:18 Geschrieben December 7, 2012 at 16:18 Ok, also ein Callback mehr und join_thread() gegen pause() austauschen. Der "disconnected()" kann dann ggf. das Prog. beenden oder auf einen Neuaufbau warten. Zitieren
photron Geschrieben December 7, 2012 at 16:32 Autor Geschrieben December 7, 2012 at 16:32 Mir ist nicht klar wie du pause() verwenden willst hier. Du solltest aber definitiv nicht pause() in einem Callback aufrufen, vor allem nicht im Disconnected Callback, weil du damit den Callback Thread anhältst und der sich so dann nicht um das Auto-Reconnect kümmern kann. Du kannst generell nicht in einem Callback auf einen anderen warten, da es nur einen Callback Thread gibt. Zitieren
skippi Geschrieben December 7, 2012 at 16:59 Geschrieben December 7, 2012 at 16:59 Also mein Prog war auch schon mit Protokoll 1 so aufgebaut, wie Ihr es für Version 2.0 empfehlt: Das main() hat nur die ip_connection aufgebaut, enumerate() getriggert und danach im Wesentlichen im join_thread gewartet. Der weitere interne Ablauf inclusive der Device Initialisierungen läuft zunächst in den enumerate() callbacks ab. Die eigentliche Programmfunktion resultiert dann aus zyklischen Callbacks, die (mangels entsprechender Fähigkeiten der Masterbrick) mittels der Monoflop Funktionalität des IO-Bricklets realisiert ist. Mittels alarm() ist dann noch ein Watchdog realisiert, der bellt wenn der Monoflop-Callback ausbleibt. Damit kann man das 'Echtzeitsystem' der Brick für den ganzen Ablauf nutzen. Die Alternative wäre es auf dem Host zu realisieren, dann machen aber die Callbacks aus meiner Sicht keinen Sinn mehr. Zitieren
photron Geschrieben December 7, 2012 at 17:46 Autor Geschrieben December 7, 2012 at 17:46 Ah. Du hältst mit pause() den Haupt-Thread an und arbeitest dann aus den Callback heraus. Ja das ist okay so Du hast also ipcon_join_thread so verwendet wie es gedacht war. Im Moment haben wir in Protokoll 2.0 keinen gleichwertigen Ersatz dafür. Deswegen meinte ich eben auch schon: Müssen wir mal gucken was wir da machen können um Programme die ipcon_join_thread verwendet haben weiter zu unterstützen. Zitieren
photron Geschrieben December 14, 2012 at 14:35 Autor Geschrieben December 14, 2012 at 14:35 Es wird als Ersatz für die Funktionalität von ipcon_join_thread dann ipcon_wait und ipcon_unwait geben. ipcon_wait blockiert so lange bis ipcon_unwait aufgerufen wird. Intern wird dazu eine Semaphore benutzt, ipcon_wait zählt runter und ipcon_unwait zählt rauf. Zitieren
skippi Geschrieben December 17, 2012 at 16:23 Geschrieben December 17, 2012 at 16:23 Hm, hat schon mal jemand in C einen erfolgreichen 2.0 enumerate Callback gesehen ? Bei mir sagt der brickd2.0: 2012-12-17 16:41:01.790983 <D> <client.c:127> Creating client from socket (handle: 14) 2012-12-17 16:41:01.791052 <I> <network.c:89> Added new client (socket: 14) 2012-12-17 16:41:01.792155 <D> <client.c:85> Got request (U: 0, L: 8, F: 254, S: 1, R: 0) from socket (handle: 14) 2012-12-17 16:41:01.792201 <D> <usb.c:308> Broadcasting request (U: 0, L: 8, F: 254, S: 1, R: 0) to 1 Brick(s) 2012-12-17 16:41:01.792314 <D> <transfer.c:218> Submitted write transfer 0x9767728 for 8 bytes to Master Brick [6dJgzT] 2012-12-17 16:41:01.792354 <D> <brick.c:477> Forced to sent request to Master Brick [6dJgzT] 2012-12-17 16:41:01.800577 <D> <transfer.c:62> Read transfer 0x9766f70 returned successfully from Master Brick [6dJgzT] 2012-12-17 16:41:01.800633 <D> <brick.c:60> Got callback (U: 3425828921, L: 34, F: 253) from Master Brick [6dJgzT] 2012-12-17 16:41:01.800662 <D> <network.c:224> Broadcasting callback (U: 3425828921, L: 34, F: 253) to 1 client(s) 2012-12-17 16:41:01.800767 <D> <client.c:186> Forced to sent response to client (socket: 14) 2012-12-17 16:41:01.800840 <D> <transfer.c:218> Submitted read transfer 0x9766f70 for 80 bytes to Master Brick [6dJgzT] 2012-12-17 16:41:01.800899 <D> <transfer.c:62> Write transfer 0x9767728 returned successfully from Master Brick [6dJgzT] 2012-12-17 16:41:28.479791 <I> <client.c:57> Socket (handle: 14) disconnected by client Die Programmstruktur ist etwa: /* Callback for stack control */ void cb_enumerate(char *uid, char *conn_uid, char position, uint8_t hwv[3], uint8_t fwv[3], uint16_t device_ident, uint8_t enumtype, void *udata) { fprintf(stderr," UID: %3.9s connected at UID: %3.9s @ position\n", uid,conn_uid,position); fprintf(stderr," Identifier: %2x\n", device_ident); ...} in main() { ........ ipcon_create(&Regmem->ipcon); if(ipcon_connect(&Regmem->ipcon, HOST, PORT) < 0) { fprintf(stderr, "Could not create brickd connection\n"); exit(1); } else { ipcon_register_callback(&Regmem->ipcon,IPCON_CALLBACK_ENUMERATE,cb_enumerate,NULL); usleep(100); // Enumerate Bricks and Bricklets ipcon_enumerate(&Regmem->ipcon); } ..... } Das ganze noch auf x86-linux. Die brickd Connection klappt offensichtlich, aber der enumerate_cb bleibt aus. Zitieren
borg Geschrieben December 18, 2012 at 07:48 Geschrieben December 18, 2012 at 07:48 Folgendes funktioniert bei mir: #include <stdio.h> #include "ip_connection.h" #define HOST "localhost" #define PORT 4223 // Print incoming enumeration information void cb_enumerate(const char *uid, const char *connected_uid, char position, uint8_t hardware_version[3], uint8_t firmware_version[3], uint16_t device_identifier, uint8_t enumeration_type, void *user_data) { printf("UID: %s\n", uid); printf("Enumeration Type: %d\n", enumeration_type); if(enumeration_type == IPCON_ENUMERATION_TYPE_DISCONNECTED) { return; } printf("Connected UID: %s\n", connected_uid); printf("Position: %c\n", position); printf("Hardware Version: %d.%d.%d\n", hardware_version[0], hardware_version[1], hardware_version[2]); printf("Firmware Version: %d.%d.%d\n", firmware_version[0], firmware_version[1], firmware_version[2]); printf("Device Identifier: %d\n", device_identifier); printf("\n"); } int main() { // Create IP connection IPConnection ipcon; ipcon_create(&ipcon); if(ipcon_connect(&ipcon, HOST, PORT) < 0) { fprintf(stderr, "Could not connect to brickd\n"); exit(1); } // Register enumeration callback to "cb_enumerate" ipcon_register_callback(&ipcon, IPCON_CALLBACK_ENUMERATE, cb_enumerate, NULL); ipcon_enumerate(&ipcon); printf("Press key to exit\n"); getchar(); } Zitieren
skippi Geschrieben December 18, 2012 at 09:36 Geschrieben December 18, 2012 at 09:36 Bei mir leider nicht: (Originalcode von oben) realtimevm@otcontrol-virtual:~/projects/tinkerforge/fbheatcontrol/tffbcontrol$ make clean rm *.o tffbcontrol tffbdbg vitolog realtimevm@otcontrol-virtual:~/projects/tinkerforge/fbheatcontrol/tffbcontrol$ make b2test cc -pthread -g -c b2test.c cc -pthread -g -c ip_connection.c cc -pthread -g -c brick_master.c cc -g -pthread -o b2test b2test.o ip_connection.o brick_master.o realtimevm@otcontrol-virtual:~/projects/tinkerforge/fbheatcontrol/tffbcontrol$ ./b2test Press key to exit Braucht es eine spezielle gcc Version ? Der brickd meldet ein enumerate event 2012-12-18 10:27:36.724534 <I> <network.c:89> Added new client (socket: 14) 2012-12-18 10:27:36.724714 <D> <client.c:85> Got request (U: 0, L: 8, F: 254, S: 1, R: 0) from socket (handle: 14) 2012-12-18 10:27:36.724752 <D> <usb.c:308> Broadcasting request (U: 0, L: 8, F: 254, S: 1, R: 0) to 1 Brick(s) 2012-12-18 10:27:36.724831 <D> <transfer.c:218> Submitted write transfer 0x8cac728 for 8 bytes to Master Brick [6dJgzT] 2012-12-18 10:27:36.724864 <D> <brick.c:477> Forced to sent request to Master Brick [6dJgzT] 2012-12-18 10:27:36.743694 <D> <transfer.c:62> Read transfer 0x8cabe38 returned successfully from Master Brick [6dJgzT] 2012-12-18 10:27:36.743814 <D> <brick.c:60> Got callback (U: 3425828921, L: 34, F: 253) from Master Brick [6dJgzT] 2012-12-18 10:27:36.743895 <D> <network.c:224> Broadcasting callback (U: 3425828921, L: 34, F: 253) to 1 client(s) 2012-12-18 10:27:36.744136 <D> <client.c:186> Forced to sent response to client (socket: 14) 2012-12-18 10:27:36.744216 <D> <transfer.c:218> Submitted read transfer 0x8cabe38 for 80 bytes to Master Brick [6dJgzT] 2012-12-18 10:27:36.744276 <D> <transfer.c:62> Write transfer 0x8cac728 returned successfully from Master Brick [6dJgzT] 2012-12-18 10:27:38.208589 <I> <client.c:57> Socket (handle: 14) disconnected by client Gibt es neuere bindings ? Zitieren
skippi Geschrieben December 18, 2012 at 10:02 Geschrieben December 18, 2012 at 10:02 Ok, es läuft. Es waren nicht neuere bindings notwendig, sondern ein neuerer brickd-2.0. Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.