Mercurial > hg > beaglert
changeset 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 | 2877bc2cd449 |
children | 9bfe04d184fb fb2cf9c00024 |
files | .cproject core/RTAudio.cpp include/BeagleRT.h projects/basic_passthru/render.cpp |
diffstat | 4 files changed, 88 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Mon Dec 28 04:11:59 2015 +0100 +++ b/.cproject Mon Dec 28 13:53:11 2015 +0100 @@ -90,10 +90,20 @@ </tool> </toolChain> </folderInfo> + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.528876549.2008927038" name="/" resourcePath="projects/basic_passthru"> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1736850748" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug" unusedChildren=""> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1097917114" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base.1542380883"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1032137455" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.2030825480"/> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2021994070" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.917207395"/> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1495645726" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug.214461086"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.139128145" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1669966018"/> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.757962791" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug.37270610"/> + </toolChain> + </folderInfo> <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry excluding="main.cpp" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_passthru"/> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/logAllAnalogs"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/> </sourceEntries> </configuration> @@ -181,10 +191,20 @@ </tool> </toolChain> </folderInfo> + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.1521194538.842563663" name="/" resourcePath="projects/basic_passthru"> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.586079455" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release" unusedChildren=""> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.909396192" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base.810674388"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.426622727" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.163790048"/> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.967588030" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1302828968"/> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.240084743" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release.281634187"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1381992272" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.929570421"/> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.2090246626" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release.2052985276"/> + </toolChain> + </folderInfo> <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry excluding="main.cpp" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_passthru"/> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/logAllAnalogs"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/> </sourceEntries> </configuration>
--- a/core/RTAudio.cpp Mon Dec 28 04:11:59 2015 +0100 +++ b/core/RTAudio.cpp Mon Dec 28 13:53:11 2015 +0100 @@ -44,6 +44,7 @@ void (*function)(void); char *name; int priority; + bool started; } InternalAuxiliaryTask; const char gRTAudioThreadName[] = "beaglert-audio"; @@ -214,6 +215,7 @@ // Set default volume levels BeagleRT_setDACLevel(settings->dacLevel); BeagleRT_setADCLevel(settings->adcLevel); + // TODO: add more argument checks for(int n = 0; n < 2; n++){ if(settings->pgaGain[n] > 59.5){ std::cerr << "PGA gain out of range [0,59.5]\n"; @@ -301,18 +303,22 @@ newTask->function = functionToCall; newTask->name = strdup(name); newTask->priority = priority; + newTask->started = false; gAuxTasks.push_back(newTask); return (AuxiliaryTask)newTask; } -// Schedule a previously created auxiliary task. It will run when the priority rules next +// Schedule a previously created (and started) auxiliary task. It will run when the priority rules next // allow it to be scheduled. void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task) { InternalAuxiliaryTask *taskToSchedule = (InternalAuxiliaryTask *)task; - + if(taskToSchedule->started == false){ // Note: this is not the safest method to check if a task + BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest. + // A safer approach would use rt_task_inquire() + } rt_task_resume(&taskToSchedule->task); } @@ -340,6 +346,20 @@ rt_printf("auxiliary task %s ended\n", name); } + +int BeagleRT_startAuxiliaryTask(AuxiliaryTask task){ + InternalAuxiliaryTask *taskStruct; + taskStruct = (InternalAuxiliaryTask *)task; + if(taskStruct->started == true) + return 0; + if(rt_task_start(&(taskStruct->task), &auxiliaryTaskLoop, taskStruct)) { + cerr << "Error: unable to start Xenomai task " << taskStruct->name << endl; + return -1; + } + taskStruct->started = true; + return 0; +} + // startAudio() should be called only after initAudio() successfully completes. // It launches the real-time Xenomai task which runs the audio loop. Returns 0 // on success. @@ -370,12 +390,7 @@ // The user may have created other tasks. Start those also. vector<InternalAuxiliaryTask*>::iterator it; for(it = gAuxTasks.begin(); it != gAuxTasks.end(); it++) { - InternalAuxiliaryTask *taskStruct = *it; - - if(rt_task_start(&(taskStruct->task), &auxiliaryTaskLoop, taskStruct)) { - cerr << "Error: unable to start Xenomai task " << taskStruct->name << endl; - return -1; - } + return BeagleRT_startAuxiliaryTask(*it); } return 0;
--- a/include/BeagleRT.h Mon Dec 28 04:11:59 2015 +0100 +++ b/include/BeagleRT.h Mon Dec 28 13:53:11 2015 +0100 @@ -437,6 +437,7 @@ * This function will stop the BeagleRT audio/sensor system. After this function returns, no further * calls to render() will be issued. */ +int BeagleRT_startAuxiliaryTask(AuxiliaryTask it); void BeagleRT_stopAudio(); /** @@ -580,6 +581,21 @@ AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name); /** + * \brief Start an auxiliary task so that it can be run. + * + * This function will start an auxiliary task but will NOT schedule it. + * It will also set a flag in the associate InternalAuxiliaryTask to flag the + * task as "started", so that successive calls to the same function for a given AuxiliaryTask + * have no effect. + * The user should never be required to call this function directly, as it is called + * by BeagleRT_scheduleAuxiliaryTask if needed (e.g.: if a task is scheduled in setup() ) + * or immediately after starting the audio thread. + * +* \param task Task to start. + */ + +int BeagleRT_startAuxiliaryTask(AuxiliaryTask task); +/** * \brief Run an auxiliary task which has previously been created. * * This function will schedule an auxiliary task to run. When the task runs, the function in the first
--- a/projects/basic_passthru/render.cpp Mon Dec 28 04:11:59 2015 +0100 +++ b/projects/basic_passthru/render.cpp Mon Dec 28 13:53:11 2015 +0100 @@ -19,10 +19,20 @@ // // Return true on success; returning false halts the program. +AuxiliaryTask taskOne; +AuxiliaryTask taskTwo; +void funOne(){ + rt_printf("setup\n"); +} +void funTwo(){ + rt_printf("render\n"); +} bool setup(BeagleRTContext *context, void *userData) { // Nothing to do here... - +// taskOne = BeagleRT_createAuxiliaryTask(funOne, 1, "funOne"); +// taskTwo = BeagleRT_createAuxiliaryTask(funTwo, 99, "funTwo"); +// BeagleRT_scheduleAuxiliaryTask(taskOne); return true; } @@ -33,25 +43,28 @@ void render(BeagleRTContext *context, void *userData) { +// if(context->audioSampleCount % 16384 == 0) +// BeagleRT_scheduleAuxiliaryTask(taskTwo); // Simplest possible case: pass inputs through to outputs for(unsigned int n = 0; n < context->audioFrames; n++) { for(unsigned int ch = 0; ch < context->audioChannels; ch++) - context->audioOut[n * context->audioChannels + ch] = context->audioIn[n * context->audioChannels + ch]; + context->audioOut[n * context->audioChannels + ch] = + context->audioIn[n * context->audioChannels + ch]; } // Same with matrix, only if matrix is enabled - if(context->analogFrames != 0) { - for(unsigned int n = 0; n < context->analogFrames; n++) { - for(unsigned int ch = 0; ch < context->analogChannels; ch++) { - // Two equivalent ways to write this code - // The long way, using the buffers directly: - // context->analogOut[n * context->analogChannels + ch] = context->analogIn[n * context->analogChannels + ch]; - - // Or using the macros: - analogWriteFrame(context, n, ch, analogReadFrame(context, n, ch)); - } - } - } +// if(context->analogFrames != 0) { +// for(unsigned int n = 0; n < context->analogFrames; n++) { +// for(unsigned int ch = 0; ch < context->analogChannels; ch++) { +// // Two equivalent ways to write this code +// // The long way, using the buffers directly: +// // context->analogOut[n * context->analogChannels + ch] = context->analogIn[n * context->analogChannels + ch]; +// +// // Or using the macros: +// analogWriteFrame(context, n, ch, analogReadFrame(context, n, ch)); +// } +// } +// } } // cleanup() is called once at the end, after the audio has stopped.