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