U23 2007/MateCrew
< U23 2007
Revision as of 02:09, 7 June 2007 by 213.196.231.109 (talk)
avr-portremote-server
Unser Hauptprojekt ist eine Komplette Implementierung eines Dienstes auf dem Etherrape und einem zugehörigen Client mit eigens entwickeltem Protokoll zur Steuerung der IO Pins über die Netzwerkschnittstelle. Hierzu fassen wir ein Passwort,ein Kommando,den IO Port und einen Wert,der gesetzt/weggenommen werden soll in unsere Protokollimplementierung.
Im folgenden die Implementierung des Clients:
#include <iostream> #include <string> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <math.h> #define MAX_COMMANDS 4 #define MAX_PORTS 3 //#define DEBUG // setzen fuer debug ausgaben #define MAX_ARGS 7 #define GET_MODE 2 using namespace std; char * command_types[MAX_COMMANDS]={"additive","substractive","get","set"}; char * port_types[MAX_PORTS]={"DDRA","DDRC","DDRD"}; struct remote_command{ /*{{{*/ string password; unsigned int command_type; unsigned int ioport; unsigned int value; /*}}}*/ } user_command; void list_commands(){ /*{{{*/ for(int i=0;i<MAX_COMMANDS;i++) cout<<"["<<i<<"]"<<"\t "<<command_types[i]<<endl; /*}}}*/ } void list_ports(){ /*{{{*/ for(int i=0;i<MAX_PORTS;i++) cout<<"["<<i<<"]"<<"\t "<<port_types[i]<<endl; /*}}}*/ } void interactive(){ /**/ } void make_request(string& request,char* pw=0,char* com=0,char* ioport=0,int dec_val=0){ /*{{{*/ request= ( (pw!=NULL) ? pw : user_command.password ) ; request+=" "; request+=( (pw!=NULL) ? ( (unsigned char)atoi(com) ) : ( (char)(user_command.command_type) ) ); request+=( (pw!=NULL) ? ( (unsigned char)(atoi(ioport)) ):(char)(user_command.ioport)); request+=( (pw!=NULL) ? ( (unsigned char)(unsigned int)dec_val) : (char)(int)(user_command.value)); #ifndef DEBUG cout<<"hier gecastet auf void: "<<(int)&(user_command.value)<<endl; #endif /*}}}*/ } void write_output(char* buf){ /*{{{*/ cout<<"Command: "<<command_types[(int)(unsigned char)(buf[0])] <<endl<<"Port: "<<(int)(unsigned char)(buf[1]) <<endl<<"Wert: "<<(int)(unsigned char)(buf[2]); /*}}}*/ } int main(int argc,char* argv[]){ sockaddr_in target; int mysocket=socket(AF_INET,SOCK_STREAM,0); string request; char buf[64]; if(argc < 3){ cout<<"usage: "<<argv[0]<<" {target-ip} {target-port} [password command ioport value]"<<endl; exit(1); } if(argc < 4 ){ interactive(); make_request(request); } else{ int dec_val=0; if(argc < MAX_ARGS){ cout<<"Too few arguments for a command!!!"<<endl; exit(1); } else{ #ifdef DEBUG cout<<"VALUE IST: "<<argv[6]; #endif sscanf(argv[6],"%x",&dec_val); make_request(request,argv[3],argv[4],argv[5],dec_val); } } #ifdef DEBUG /*{{{*/ cout<<"request is: "<<request<<endl; cout<<"length of request: "<<request.length()<<endl; cout<<"values: "<<endl; for(unsigned int i=0;i<=request.length();i++){ cout<<"position: "<<i<<" int wert: "<<(int)request[i]<<" zeichen: "<<request[i]<<endl; } /*}}}*/ #endif target.sin_family=AF_INET; target.sin_port=htons(atoi(argv[2])); target.sin_addr.s_addr=inet_addr(argv[1]); // establish connection if(connect(mysocket,(sockaddr*)&target,sizeof(target))<0) err<<"failed to establish connection"<<endl; cout<<"connection established"<<endl; //send command to etherrape if(write(mysocket,(void*)request.c_str(),request.length() + 1) < 0) cerr<<"failed to write data"<<endl; // etherrape will send us the port status if(user_command.command_type== GET_MODE ){ if(read(mysocket,(void*)buf,strlen(buf)-1)>=1){ write_output(buf); } else{ cerr<<"failed to read data"<<endl; } } close(mysocket); return 0; }
portremoted:
#include <string.h> #include "../uip/uip.h" #include "../debug.h" #include "fnord.h" struct fnord_command{ /* * stores all needed protocol data */ uint8_t ctype; //command type (set,unset,additive,substractive) uint8_t ioport; //ioport (PORTA/C/D) uint8_t data; //data (1 byte) } incoming_command; void init_fnord(void){ // we listen on port 2324 (defined in fnord.h) uip_listen(HTONS(FNORD_PORT)); } void net_add_port(){ /* * add incoming value to PORTX */ cfg.options.io_ddr[(incoming_command.ioport)] |= incoming_command.data; cfg.options.io[(incoming_command.ioport)] |= incoming_command.data; } void net_sub_port(){ /* * substract incoming value from PORTX */ cfg.options.io[(incoming_command.ioport)] &= ~(incoming_command.data); } void net_get_port(){ /* * substract incoming value from PORTX */ ((uint8_t *)uip_appdata)[0]=NET_GET_PORT; ((uint8_t *)uip_appdata)[1]=incoming_command.ioport; ((uint8_t *)uip_appdata)[2]=cfg.options.io[(incoming_command.ioport)]; ((uint8_t *)uip_appdata)[3]='\0'; uip_send(uip_appdata,4); } void net_set_port(){ cfg.options.io[(incoming_command.ioport)] = incoming_command.data; } void handle_fnord(void) { uint8_t logged_in=0; if(uip_connected()) debug_print("New client connected\n"); if(uip_newdata()) { ((uint8_t *)uip_appdata)[uip_datalen()] = 0; uint8_t offset=0; char password[uip_len]; for(offset;((uint8_t *)uip_appdata)[offset]!=' ' && offset<uip_len;offset++){ password[offset]=((uint8_t *)uip_appdata)[offset]; } password[offset]='\0'; debug_printf("Password is: '%s', user entered: '%s' \n",FNORD_PASS,password); if(!(strcmp(password,FNORD_PASS))) logged_in=1; else logged_in=0; if(logged_in){ debug_print("Password correct, logged in!\n\n"); incoming_command.ctype=((uint8_t *)uip_appdata)[++offset]; incoming_command.ioport=((uint8_t *)uip_appdata)[++offset]; incoming_command.data=((uint8_t *)uip_appdata)[++offset]; debug_print("New data recieved:\n"); debug_printf("ctype: %i\n",incoming_command.ctype); debug_printf("ioport: %i\n",incoming_command.ioport); debug_printf("data: %i\n\n\n",incoming_command.data); switch(incoming_command.ctype){ case NET_ADD_PORT: net_add_port(); break; case NET_SUB_PORT: net_sub_port(); break; case NET_GET_PORT: net_get_port(); break; case NET_SET_PORT: net_set_port(); break; } } else debug_print("Incorrect password!\n\n\n"); } }
LED-Dimmer
Für unseren Dimmer für LEDs benutzen wir insgesamt 3 Funktionen:
- Die Main mit einer Endlosschleife für ewiges hell und dunkel Dimmen durch Aufruf von den andern Beiden Funktionen
- Die Funktion my_wait(uint32_t time), welche einfach wartet
- Die Funktion dim(uint8_t ratio), welche für den schnellen Ein-/Ausschaltvorgang der LEDs zuständig ist
Die Main:
#include <avr/io.h> #include <util/delay.h>
#define F_CPU 2000000000L void my_wait(uint32_t); void dim(uint8_t); int main(){ DDRA=0xff; // LED ausschalten PORTA=0; uint16_t i=0; PORTA|=0x02; //Die Endlosschleife for(;;){ for(i=0;i<0xfff;i++){ // ein bisschen warten my_wait(1); // ein- und ausschalten // je größer i wird desto größer wird auch der Quotient der an bla übergeben wird // dadurch verändert sich auch der zeitliche Abstand zwischen dem Ein- und Ausschalten // wodurch die LED wiederum heller oder dunkler erscheint dim(i/0xf); } } PORTA|=0x03; return 0; }
Die Wait:
void my_wait(uint32_t time) { uint32_t i=0; for(i;i<(time);i++) //vordefinierte Funktion welche einen Leerlauf in Dauer von n Milisekunden auslöst _delay_ms(1); }
Die Dim:
void dim(uint8_t ratio){ uint32_t i=0; // LED anschalten PORTA|=0x01; for(i;i<ratio;i++){} // LED ausschalten PORTA&=~0x01; for(i=ratio;i<255;i++){} }
Project
Team
- Scout
- F3lix
- Toby