comparison core/RTAudio.cpp @ 284:7bfb25a2e158 Doxy prerelease

Merge
author Robert Jack <robert.h.jack@gmail.com>
date Tue, 17 May 2016 15:53:24 +0100
parents 88cf310417cd
children c55c6f6c233c
comparison
equal deleted inserted replaced
269:ac8eb07afcf5 284:7bfb25a2e158
39 39
40 // Data structure to keep track of auxiliary tasks we 40 // Data structure to keep track of auxiliary tasks we
41 // can schedule 41 // can schedule
42 typedef struct { 42 typedef struct {
43 RT_TASK task; 43 RT_TASK task;
44 void (*argfunction)(void*);
44 void (*function)(void); 45 void (*function)(void);
45 char *name; 46 char *name;
46 int priority; 47 int priority;
47 bool started; 48 bool started;
49 bool hasArgs;
50 void* args;
51 bool autoSchedule;
48 } InternalAuxiliaryTask; 52 } InternalAuxiliaryTask;
49 53
50 const char gRTAudioThreadName[] = "beaglert-audio"; 54 const char gRTAudioThreadName[] = "beaglert-audio";
51 const char gRTAudioInterruptName[] = "beaglert-pru-irq"; 55 const char gRTAudioInterruptName[] = "beaglert-pru-irq";
52 56
289 293
290 // Create a calculation loop which can run independently of the audio, at a different 294 // Create a calculation loop which can run independently of the audio, at a different
291 // (equal or lower) priority. Audio priority is defined in BEAGLERT_AUDIO_PRIORITY; 295 // (equal or lower) priority. Audio priority is defined in BEAGLERT_AUDIO_PRIORITY;
292 // priority should be generally be less than this. 296 // priority should be generally be less than this.
293 // Returns an (opaque) pointer to the created task on success; 0 on failure 297 // Returns an (opaque) pointer to the created task on success; 0 on failure
294 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name) 298 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void* args), int priority, const char *name, void* args, bool autoSchedule)
295 { 299 {
296 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask)); 300 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask));
297 301
298 // Attempt to create the task 302 // Attempt to create the task
299 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) { 303 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) {
301 free(newTask); 305 free(newTask);
302 return 0; 306 return 0;
303 } 307 }
304 308
305 // Populate the rest of the data structure and store it in the vector 309 // Populate the rest of the data structure and store it in the vector
306 newTask->function = functionToCall; 310 newTask->argfunction = functionToCall;
307 newTask->name = strdup(name); 311 newTask->name = strdup(name);
308 newTask->priority = priority; 312 newTask->priority = priority;
309 newTask->started = false; 313 newTask->started = false;
310 314 newTask->args = args;
315 newTask->hasArgs = true;
316 newTask->autoSchedule = autoSchedule;
317
311 getAuxTasks().push_back(newTask); 318 getAuxTasks().push_back(newTask);
312 319
313 return (AuxiliaryTask)newTask; 320 return (AuxiliaryTask)newTask;
321 }
322 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name, bool autoSchedule)
323 {
324 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask));
325
326 // Attempt to create the task
327 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) {
328 cout << "Error: unable to create auxiliary task " << name << endl;
329 free(newTask);
330 return 0;
331 }
332
333 // Populate the rest of the data structure and store it in the vector
334 newTask->function = functionToCall;
335 newTask->name = strdup(name);
336 newTask->priority = priority;
337 newTask->started = false;
338 newTask->hasArgs = false;
339 newTask->autoSchedule = autoSchedule;
340
341 getAuxTasks().push_back(newTask);
342
343 return (AuxiliaryTask)newTask;
314 } 344 }
315 345
316 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next 346 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next
317 // allow it to be scheduled. 347 // allow it to be scheduled.
318 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task) 348 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task)
322 BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest. 352 BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest.
323 // A safer approach would use rt_task_inquire() 353 // A safer approach would use rt_task_inquire()
324 } 354 }
325 rt_task_resume(&taskToSchedule->task); 355 rt_task_resume(&taskToSchedule->task);
326 } 356 }
357 void BeagleRT_autoScheduleAuxiliaryTasks(){
358 vector<InternalAuxiliaryTask*>::iterator it;
359 for(it = getAuxTasks().begin(); it != getAuxTasks().end(); it++) {
360 if ((InternalAuxiliaryTask *)(*it)->autoSchedule){
361 BeagleRT_scheduleAuxiliaryTask(*it);
362 }
363 }
364 }
327 365
328 // Calculation loop that can be used for other tasks running at a lower 366 // Calculation loop that can be used for other tasks running at a lower
329 // priority than the audio thread. Simple wrapper for Xenomai calls. 367 // priority than the audio thread. Simple wrapper for Xenomai calls.
330 // Treat the argument as containing the task structure 368 // Treat the argument as containing the task structure
331 void auxiliaryTaskLoop(void *taskStruct) 369 void auxiliaryTaskLoop(void *taskStruct)
332 { 370 {
371 InternalAuxiliaryTask *task = ((InternalAuxiliaryTask *)taskStruct);
372
333 // Get function to call from the argument 373 // Get function to call from the argument
334 void (*auxiliary_function)(void) = ((InternalAuxiliaryTask *)taskStruct)->function; 374 void (*auxiliary_argfunction)(void* args) = task->argfunction;
335 const char *name = ((InternalAuxiliaryTask *)taskStruct)->name; 375 void (*auxiliary_function)(void) = task->function;
376
377 // get the task's name
378 const char *name = task->name;
336 379
337 // Wait for a notification 380 // Wait for a notification
338 rt_task_suspend(NULL); 381 rt_task_suspend(NULL);
339 382
340 while(!gShouldStop) { 383 while(!gShouldStop) {
341 // Then run the calculations 384 // Then run the calculations
342 auxiliary_function(); 385 if (task->hasArgs)
386 auxiliary_argfunction(task->args);
387 else
388 auxiliary_function();
343 389
344 // Wait for a notification 390 // Wait for a notification
345 rt_task_suspend(NULL); 391 rt_task_suspend(NULL);
346 } 392 }
347 393