Is this a gcc or a kernel bug?
Hi, i had an assignment from my university to program a
joystick manufactured by ms ( don't know if that has anything to do about it)
anyway, the model is:
Microsoft Corp. SideWinder Force Feedback 2 Joystick
and it uses the iforce driver module.
i have written the attached code
which compiles with the following gcc
aris@debian:~$ gcc --version
gcc (Debian 4.3.2-1.1) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
when i run the a.out, the system freezes totally, i mean i cannot even move the mouse
that happens with
linux-image-2.6.26-2-amd64
but not with
linux-image-2.6.30-rc7-amd64
it also works on a 2.6.29 kernel that i use on my netbook?
what is the fault here? Gcc or the kernel?
Thanks
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#define BITS_PER_LONG (sizeof(long) * 8)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#define N_EFFECTS 6
int fd;
struct ff_effect effects[N_EFFECTS];
struct input_event play, stop;
void openfeedback(char*);
void constantforce(char*,double,double,int);
void periodicforce(char*,int,double,double,double,int);
void springforce(char*,double,int);
void damperforce(char*,double,int);
void strongrumble(char*,int);
void weakrumble(char*,double,int);
int waveformtypes[]={FF_SQUARE,FF_TRIANGLE,FF_SINE,FF_SAW_UP,FF_SAW_DOWN};
int main(int argc, char** argv){
int wave;
double width;
double angle;
double period;
double coeff;
int i;
/**
for(i=3; i>=1; i--){
printf("Beginning constant force Apply in %d seconds\n",i);
sleep(1);
}
printf("\n");
for(width=25000; width<=100000; width+=75000){
for(angle=0; angle<=360; angle+=90){
printf("Width=%f \t Angle=%f\n",width,angle);
constantforce(argv[1],width,angle,5);
}
}
**/
for(i=3; i>=1; i--){
printf("Beginning Spring force Apply in %d seconds\n",i);
sleep(1);
}
printf("\n");
for(coeff=10000; coeff<=30000; coeff+=10000){
printf("Spring Coefficient %f\n",coeff);
springforce(argv[1],coeff,5);
}
for(i=3; i>=1; i--){
printf("Beginning Periodic force Apply in %d seconds\n",i);
sleep(1);
}
printf("\n");
for(wave=0; wave<=4; wave++){
for(width=0.6; width<=1.4; width+=0.8){
for(period=0.4; period<=1.0; period+=0.3){
for(angle=0; angle<=90; angle+=90){
printf("Playing wave=%d || width=%f period=%f angle=%f\n",waveformtypes[wave],width,period, angle);
periodicforce(argv[1],waveformtypes[wave],width,angle,period,3);
}
}
}
}
/**
for(coeff=1.0; coeff>=0.2; coeff-=0.2)
weakrumble(argv[1],coeff,3);
**/
}
void openfeedback(char* a){
fd = open(a, O_RDWR);
if (fd == -1) {
perror("Open device file");
exit(1);
}
}
void periodicforce(char* event,int waveform,double width,double angle,double period,int secstoplay){
openfeedback(event);
/** TYPES OF WAVEFORMS
FF_SQUARE
FF_TRIANGLE
FF_SINE
FF_SAW_UP
FF_SAW_DOWN
FF_CUSTOM
**/
double hexangle;
hexangle= (angle/360.0)*0x10000;
effects[0].type = FF_PERIODIC;
effects[0].id = -1;
effects[0].u.periodic.waveform = waveform;
effects[0].u.periodic.period = period*0x100; /* Period in seconds*/
effects[0].u.periodic.magnitude = width*0x4000; /* 0.5 * Maximum magnitude */
effects[0].u.periodic.offset = 0;
effects[0].u.periodic.phase = 0;
effects[0].direction = hexangle; //0x4000; /* Along X axis */
effects[0].u.periodic.envelope.attack_length = 0x100;
effects[0].u.periodic.envelope.attack_level = 0;
effects[0].u.periodic.envelope.fade_length = 0x100;
effects[0].u.periodic.envelope.fade_level = 0;
effects[0].trigger.button = 0;
effects[0].trigger.interval = 0;
effects[0].replay.length = 20000; /* 20 seconds */
effects[0].replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effects[0]) == -1) {
perror("Upload effects[0]");
}
play.type = EV_FF;
play.code = effects[0].id;
play.value = 1;
write(fd, (const void*) &play, sizeof(play));
sleep(secstoplay);
close(fd);
}
void constantforce(char* event,double width,double angle,int secstoplay){
openfeedback(event);
/**Convert Angles from deg to hex **/
double hexangle;
hexangle= (angle/360.0)*0x10000;
/* download a constant effect */
effects[1].type = FF_CONSTANT;
effects[1].id = -1;
effects[1].u.constant.level = width; //0x2000;
effects[1].direction = hexangle; //0x0000;
effects[1].u.constant.envelope.attack_length = 0x100;
effects[1].u.constant.envelope.attack_level = 0;
effects[1].u.constant.envelope.fade_length = 0x100;
effects[1].u.constant.envelope.fade_level = 0;
effects[1].trigger.button = 0;
effects[1].trigger.interval = 0;
/** THIS IS NOT NEEDED ==> effects[1].replay.length = 20000; // 20 seconds **/
effects[1].replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effects[1]) == -1) {
perror("Upload effects[1]");
}
play.type = EV_FF;
play.code = effects[1].id;
play.value = 1;
write(fd, (const void*) &play, sizeof(play));
sleep(secstoplay);
close(fd);
}
void springforce(char* event,double coefficient,int secstoplay){
openfeedback(event);
/* download an condition spring effect */
effects[2].type = FF_SPRING;
effects[2].id = -1;
effects[2].u.condition[0].right_saturation = 0x7fff;
effects[2].u.condition[0].left_saturation = 0x7fff;
effects[2].u.condition[0].right_coeff = coefficient; //0x2000;
effects[2].u.condition[0].left_coeff = coefficient; //0x2000;
effects[2].u.condition[0].deadband = 0x0;
effects[2].u.condition[0].center = 0x0;
effects[2].u.condition[1] = effects[2].u.condition[0];
effects[2].trigger.button = 0;
effects[2].trigger.interval = 0;
effects[2].replay.length = 20000; /* 20 seconds */
effects[2].replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effects[2]) == -1) {
perror("Upload effects[2]");
}
play.type = EV_FF;
play.code = effects[2].id;
play.value = 1;
write(fd, (const void*) &play, sizeof(play));
sleep(secstoplay);
close(fd);
}
void damperforce(char* event,double coefficient,int secstoplay){
openfeedback(event);
/* download an condition damper effect */
effects[3].type = FF_DAMPER;
effects[3].id = -1;
effects[3].u.condition[0].right_saturation = 0x7fff;
effects[3].u.condition[0].left_saturation = 0x7fff;
effects[3].u.condition[0].right_coeff = coefficient;//0x2000;
effects[3].u.condition[0].left_coeff = coefficient;//0x2000;
effects[3].u.condition[0].deadband = 0x0;
effects[3].u.condition[0].center = 0x0;
effects[3].u.condition[1] = effects[3].u.condition[0];
effects[3].trigger.button = 0;
effects[3].trigger.interval = 0;
effects[3].replay.length = 20000; /* 20 seconds */
effects[3].replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effects[3]) == -1) {
perror("Upload effects[3]");
}
play.type = EV_FF;
play.code = effects[3].id;
play.value = 1;
write(fd, (const void*) &play, sizeof(play));
sleep(secstoplay);
close(fd);
}
void strongrumble(char* event,int secstoplay){
openfeedback(event);
/* a strong rumbling effect */
effects[4].type = FF_RUMBLE;
effects[4].id = -1;
effects[4].u.rumble.strong_magnitude = 0x8000; //0x8000 0xD6D8
effects[4].u.rumble.weak_magnitude = 0;
effects[4].replay.length = 5000;
effects[4].replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effects[4]) == -1) {
perror("Upload effects[4]");
}
play.type = EV_FF;
play.code = effects[4].id;
play.value = 1;
write(fd, (const void*) &play, sizeof(play));
sleep(secstoplay);
close(fd);
}
void weakrumble(char* event,double width,int secstoplay){
openfeedback(event);
/* a weak rumbling effect */
effects[5].type = FF_RUMBLE;
effects[5].id = -1;
effects[5].u.rumble.strong_magnitude = 0;
effects[5].u.rumble.weak_magnitude = width*0xc000;
effects[5].replay.length = 5000;
effects[5].replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effects[5]) == -1) {
perror("Upload effects[4]");
}
play.type = EV_FF;
play.code = effects[5].id;
play.value = 1;
write(fd, (const void*) &play, sizeof(play));
sleep(secstoplay);
close(fd);
}
Reply to: