3 * @purpose Implementation of sensor thread
4 * TODO: Finalise implementation
14 * Read a data value from a sensor; block until value is read
15 * @param sensor_id - The ID of the sensor
16 * @returns The current value of the sensor
18 DataPoint GetData(int sensor_id)
20 // switch based on the sensor_id at the moment for testing;
21 // might be able to just directly access ADC from sensor_id?
22 //TODO: Implement for real sensors
25 //TODO: Deal with time stamps properly
34 d.value = (float)(rand() % 100) / 100;
37 Fatal("Unknown sensor id: %d", sensor_id);
40 usleep(100000); // simulate delay in sensor polling
47 * @param s - Sensor to destroy
49 void Destroy(Sensor * s)
51 // Maybe move the binary file into long term file storage?
59 * @param s - Sensor to initialise
61 void Sensor_Init(Sensor * s, int id)
67 #define FILENAMESIZE BUFSIZ
68 char filename[FILENAMESIZE];
69 //if (s->id >= pow(10, FILENAMESIZE))
72 Fatal("Too many sensors! FILENAMESIZE is %d; increase it and recompile.", FILENAMESIZE);
75 pthread_mutex_init(&(s->mutex), NULL);
77 sprintf(filename, "%d", s->id);
78 unlink(filename); //TODO: Move old files somewhere
80 s->file = fopen(filename, "a+b"); // open binary file
81 Log(LOGDEBUG, "Initialised sensor %d; binary file is \"%s\"", id, filename);
86 * Run the main sensor polling loop
87 * @param arg - Cast to Sensor* - Sensor that the thread will handle
88 * @returns NULL (void* required to use the function with pthreads)
90 void * Sensor_Main(void * arg)
92 Sensor * s = (Sensor*)(arg);
94 while (true) //TODO: Exit condition
96 // The sensor will write data to a buffer until it is full
97 // Then it will open a file and dump the buffer to the end of it.
100 // The reason I've added the buffer is because locks are expensive
101 // But maybe it's better to just write data straight to the file
102 // I'd like to do some tests by changing SENSOR_DATABUFSIZ
104 while (s->write_index < SENSOR_DATABUFSIZ)
106 s->buffer[s->write_index] = GetData(s->id);
110 //Log(LOGDEBUG, "Filled buffer");
112 // CRITICAL SECTION (no threads should be able to read/write the file at the same time)
113 pthread_mutex_lock(&(s->mutex));
114 fseek(s->file, 0, SEEK_END);
115 int amount_written = fwrite(s->buffer, sizeof(DataPoint), SENSOR_DATABUFSIZ, s->file);
116 if (amount_written != SENSOR_DATABUFSIZ)
118 Fatal("Wrote %d data points and expected to write %d to \"%s\" - %s", amount_written, SENSOR_DATABUFSIZ, strerror(errno));
120 //Log(LOGDEBUG, "Wrote %d data points for sensor %d", amount_written, s->id);
121 pthread_mutex_unlock(&(s->mutex));
122 // End of critical section
124 s->write_index = 0; // reset position in buffer
131 * Fill buffer with most recent sensor data
132 * @param s - Sensor to use
133 * @param buffer - Buffer to fill
134 * @param bufsiz - Size of buffer to fill
135 * @returns The number of DataPoints actually read
137 int Sensor_Query(Sensor * s, DataPoint * buffer, int bufsiz)
140 //CRITICAL SECTION (Don't access file while sensor thread is writing to it!)
141 pthread_mutex_lock(&(s->mutex));
143 fseek(s->file, -bufsiz*sizeof(DataPoint), SEEK_END);
144 amount_read = fread(buffer, sizeof(DataPoint), bufsiz, s->file);
145 //Log(LOGDEBUG, "Read %d data points", amount_read);
146 pthread_mutex_unlock(&(s->mutex));