Mercurial > hg > beaglert
comparison core/RTAudio.cpp @ 174:1e629f126322
AuxiliaryTask can now be scheduled from setup(). Closes #1373
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 28 Dec 2015 13:53:11 +0100 |
parents | 5f4408705eed |
children | 9bfe04d184fb fb2cf9c00024 |
comparison
equal
deleted
inserted
replaced
173:2877bc2cd449 | 174:1e629f126322 |
---|---|
42 typedef struct { | 42 typedef struct { |
43 RT_TASK task; | 43 RT_TASK task; |
44 void (*function)(void); | 44 void (*function)(void); |
45 char *name; | 45 char *name; |
46 int priority; | 46 int priority; |
47 bool started; | |
47 } InternalAuxiliaryTask; | 48 } InternalAuxiliaryTask; |
48 | 49 |
49 const char gRTAudioThreadName[] = "beaglert-audio"; | 50 const char gRTAudioThreadName[] = "beaglert-audio"; |
50 const char gRTAudioInterruptName[] = "beaglert-pru-irq"; | 51 const char gRTAudioInterruptName[] = "beaglert-pru-irq"; |
51 | 52 |
212 } | 213 } |
213 | 214 |
214 // Set default volume levels | 215 // Set default volume levels |
215 BeagleRT_setDACLevel(settings->dacLevel); | 216 BeagleRT_setDACLevel(settings->dacLevel); |
216 BeagleRT_setADCLevel(settings->adcLevel); | 217 BeagleRT_setADCLevel(settings->adcLevel); |
218 // TODO: add more argument checks | |
217 for(int n = 0; n < 2; n++){ | 219 for(int n = 0; n < 2; n++){ |
218 if(settings->pgaGain[n] > 59.5){ | 220 if(settings->pgaGain[n] > 59.5){ |
219 std::cerr << "PGA gain out of range [0,59.5]\n"; | 221 std::cerr << "PGA gain out of range [0,59.5]\n"; |
220 exit(1); | 222 exit(1); |
221 } | 223 } |
299 | 301 |
300 // Populate the rest of the data structure and store it in the vector | 302 // Populate the rest of the data structure and store it in the vector |
301 newTask->function = functionToCall; | 303 newTask->function = functionToCall; |
302 newTask->name = strdup(name); | 304 newTask->name = strdup(name); |
303 newTask->priority = priority; | 305 newTask->priority = priority; |
306 newTask->started = false; | |
304 | 307 |
305 gAuxTasks.push_back(newTask); | 308 gAuxTasks.push_back(newTask); |
306 | 309 |
307 return (AuxiliaryTask)newTask; | 310 return (AuxiliaryTask)newTask; |
308 } | 311 } |
309 | 312 |
310 // Schedule a previously created auxiliary task. It will run when the priority rules next | 313 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next |
311 // allow it to be scheduled. | 314 // allow it to be scheduled. |
312 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task) | 315 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task) |
313 { | 316 { |
314 InternalAuxiliaryTask *taskToSchedule = (InternalAuxiliaryTask *)task; | 317 InternalAuxiliaryTask *taskToSchedule = (InternalAuxiliaryTask *)task; |
315 | 318 if(taskToSchedule->started == false){ // Note: this is not the safest method to check if a task |
319 BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest. | |
320 // A safer approach would use rt_task_inquire() | |
321 } | |
316 rt_task_resume(&taskToSchedule->task); | 322 rt_task_resume(&taskToSchedule->task); |
317 } | 323 } |
318 | 324 |
319 // Calculation loop that can be used for other tasks running at a lower | 325 // Calculation loop that can be used for other tasks running at a lower |
320 // priority than the audio thread. Simple wrapper for Xenomai calls. | 326 // priority than the audio thread. Simple wrapper for Xenomai calls. |
336 rt_task_suspend(NULL); | 342 rt_task_suspend(NULL); |
337 } | 343 } |
338 | 344 |
339 if(gRTAudioVerbose == 1) | 345 if(gRTAudioVerbose == 1) |
340 rt_printf("auxiliary task %s ended\n", name); | 346 rt_printf("auxiliary task %s ended\n", name); |
347 } | |
348 | |
349 | |
350 int BeagleRT_startAuxiliaryTask(AuxiliaryTask task){ | |
351 InternalAuxiliaryTask *taskStruct; | |
352 taskStruct = (InternalAuxiliaryTask *)task; | |
353 if(taskStruct->started == true) | |
354 return 0; | |
355 if(rt_task_start(&(taskStruct->task), &auxiliaryTaskLoop, taskStruct)) { | |
356 cerr << "Error: unable to start Xenomai task " << taskStruct->name << endl; | |
357 return -1; | |
358 } | |
359 taskStruct->started = true; | |
360 return 0; | |
341 } | 361 } |
342 | 362 |
343 // startAudio() should be called only after initAudio() successfully completes. | 363 // startAudio() should be called only after initAudio() successfully completes. |
344 // It launches the real-time Xenomai task which runs the audio loop. Returns 0 | 364 // It launches the real-time Xenomai task which runs the audio loop. Returns 0 |
345 // on success. | 365 // on success. |
368 } | 388 } |
369 | 389 |
370 // The user may have created other tasks. Start those also. | 390 // The user may have created other tasks. Start those also. |
371 vector<InternalAuxiliaryTask*>::iterator it; | 391 vector<InternalAuxiliaryTask*>::iterator it; |
372 for(it = gAuxTasks.begin(); it != gAuxTasks.end(); it++) { | 392 for(it = gAuxTasks.begin(); it != gAuxTasks.end(); it++) { |
373 InternalAuxiliaryTask *taskStruct = *it; | 393 return BeagleRT_startAuxiliaryTask(*it); |
374 | |
375 if(rt_task_start(&(taskStruct->task), &auxiliaryTaskLoop, taskStruct)) { | |
376 cerr << "Error: unable to start Xenomai task " << taskStruct->name << endl; | |
377 return -1; | |
378 } | |
379 } | 394 } |
380 | 395 |
381 return 0; | 396 return 0; |
382 } | 397 } |
383 | 398 |