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 | 
