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.