Mercurial > hg > beaglert
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 |