Mercurial > hg > beaglert
changeset 155:13d25cbcde03
merge
author | Andrew McPherson <andrewm@eecs.qmul.ac.uk> |
---|---|
date | Wed, 07 Oct 2015 22:56:14 +0100 |
parents | f25940933503 (current diff) 3b7270949a97 (diff) |
children | 89f28a867a09 |
files | |
diffstat | 5 files changed, 502 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Wed Oct 07 22:50:47 2015 +0100 +++ b/.cproject Wed Oct 07 22:56:14 2015 +0100 @@ -14,11 +14,11 @@ </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.528876549" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug" postannouncebuildStep="Kills the process running on the BeagleBone (if any) and copies the new binary to the BeagleBone in beaglert/" postbuildStep="ssh root@192.168.7.2 "kill -s 2 \`pidof ${BuildArtifactFileName}\` 2>/dev/null; sleep 0.5; scp host:${PWD}/${BuildArtifactFileName} ~/beaglert/ && echo 'done copying\n' | wall || echo 'error'|wall""> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.528876549" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug" postannouncebuildStep="Kills the process running on the BeagleBone (if any) and copies the new binary to the BeagleBone in beaglert/" postbuildStep="ssh root@192.168.7.2 "kill -s 2 \`pidof ${BuildArtifactFileName}\` 2>/dev/null"; scp ${BuildArtifactFilePrefix}${BuildArtifactFileName} root@192.168.7.2:~/beaglert/ && echo 'done copying\n' | wall || echo 'error'|wall"> <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.528876549." name="/" resourcePath=""> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.681872250" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.295375065" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> - <builder buildPath="${workspace_loc:/BBB_audio+input/Debug}" id="cdt.managedbuild.target.gnu.builder.exe.debug.26322421" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"> + <builder arguments="-j6" buildPath="${workspace_loc:/BBB_audio+input/Debug}" command="make" id="cdt.managedbuild.target.gnu.builder.exe.debug.26322421" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"> <outputEntries> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="Debug"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="Release"/> @@ -57,13 +57,13 @@ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.308014221" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> </tool> <tool command="arm-linux-gnueabihf-g++ " id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.214461086" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> - <tool command="arm-linux-gnueabihf-g++ " commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1669966018" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> + <tool command="arm-linux-gnueabihf-g++" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1669966018" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> <option id="gnu.cpp.link.option.paths.462980690" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> - <listOptionValue builtIn="false" value="/usr/xenomai/lib"/> + <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib"/> + <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib/xenomai"/> <listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/xenomai/lib"/> - <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib"/> <listOptionValue builtIn="false" value="/usr/lib/arm-linux-gnueabihf"/> - <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib/xenomai"/> + <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/lib"/> </option> <option id="gnu.cpp.link.option.libs.139390951" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> <listOptionValue builtIn="false" value="rt"/> @@ -82,9 +82,7 @@ </tool> <tool command="arm-linux-gnueabihf-as" id="cdt.managedbuild.tool.gnu.assembler.exe.debug.37270610" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> <option id="gnu.both.asm.option.include.paths.1403814918" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"> - <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include/xenomai/include"/> <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/> - <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include"/> <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/> <listOptionValue builtIn="false" value=""${workspace_loc:/BeagleRT/include}""/> </option> @@ -95,6 +93,7 @@ <sourceEntries> <entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/basic_writeFile"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration> @@ -103,7 +102,9 @@ </cconfiguration> <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1521194538"> <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1521194538" moduleId="org.eclipse.cdt.core.settings" name="Release"> - <externalSettings/> + <externalSettings> + <externalSetting/> + </externalSettings> <extensions> <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> @@ -183,7 +184,7 @@ <sourceEntries> <entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/basic"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/scope"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/WriteFile.cpp Wed Oct 07 22:56:14 2015 +0100 @@ -0,0 +1,245 @@ +/* + * WriteFile.cpp + * + * Created on: 5 Oct 2015 + * Author: giulio + */ + +#include "WriteFile.h" +//initialise static members +bool WriteFile::staticConstructed=false; +AuxiliaryTask WriteFile::writeAllFilesTask=NULL; +std::vector<WriteFile *> WriteFile::objAddrs(0); +bool WriteFile::threadRunning; +bool WriteFile::threadIsExiting; +int WriteFile::sleepTimeMs; + +void WriteFile::staticConstructor(){ + if(staticConstructed==true) + return; + staticConstructed=true; + threadIsExiting=false; + threadRunning=false; + writeAllFilesTask = BeagleRT_createAuxiliaryTask(WriteFile::run, 60, "writeAllFilesTask"); +} + +WriteFile::WriteFile(){ + buffer = NULL; + format = NULL; + header = NULL; + footer = NULL; + stringBuffer = NULL; +}; + +void WriteFile::init(const char* filename){ //if you do not call this before using the object, results are undefined + file = fopen(filename, "w"); + variableOpen = false; + lineLength = 0; + echo = false; + bufferLength = 0; + readPointer = 0; + writePointer = 0; + sleepTimeMs = 1; + stringBufferLength = 1000; + stringBuffer = (char*)malloc(sizeof(char) * (stringBufferLength)); + setHeader("variable=[\n"); + setFooter("];\n"); + staticConstructor(); //TODO: this line should be in the constructor, but cannot because of a bug in BeagleRT + objAddrs.push_back(this); +} + +void WriteFile::setEcho(bool newEcho){ + echo=newEcho; +} + +void WriteFile::print(const char* string){ + if(echo == true){ + printf("%s", string); + } + if(file != NULL){ + fprintf(file, "%s", string); + } +} + +void WriteFile::writeLine(){ + int stringBufferPointer = 0; + for(unsigned int n = 0; n < formatTokens.size(); n++){ + int numOfCharsWritten = snprintf( &stringBuffer[stringBufferPointer], stringBufferLength - stringBufferPointer, + formatTokens[n], buffer[readPointer]); + stringBufferPointer += numOfCharsWritten; + readPointer++; + if (readPointer >= bufferLength){ + readPointer -= bufferLength; + } + } + print(stringBuffer); +} + +void WriteFile::setLineLength(int newLineLength){ + lineLength=newLineLength; + free(buffer); + bufferLength = lineLength * 10000; // circular buffer of length 10000 lineLenghts + buffer = (float*)malloc(sizeof(float) * bufferLength); +} + +void WriteFile::log(float value){ + if(format == NULL || buffer == NULL) + return; + buffer[writePointer] = value; + writePointer++; + if(writePointer == bufferLength){ + writePointer = 0; + } + if(writePointer == readPointer){ + fprintf(stderr, "WriteFile: pointers crossed, you should probably write less data to disk\n"); + } + if(threadRunning == false){ + startThread(); + } +} + +void WriteFile::log(float* array, int length){ + for(int n = 0; n < length; n++){ + log(array[n]); + } +} + +WriteFile::~WriteFile() { + free(format); + free(buffer); + free(header); + free(footer); + free(stringBuffer); +} + +void WriteFile::setFormat(const char* newFormat){ + allocateAndCopyString(newFormat, &format); + for(unsigned int n = 0; n < formatTokens.size(); n++){ + free(formatTokens[n]); + } + formatTokens.clear(); + int tokenStart = 0; + bool firstToken = true; + for(unsigned int n = 0; n < strlen(format)+1; n++){ + if(format[n] == '%' && format[n + 1] == '%'){ + n++; + } else if (format[n] == '%' || format[n] == 0){ + if(firstToken == true){ + firstToken = false; + continue; + } + char* string; + unsigned int tokenLength = n - tokenStart; + if(tokenLength == 0) + continue; + string = (char*)malloc((1+tokenLength)*sizeof(char)); + for(unsigned int i = 0; i < tokenLength; i++){ + string[i] = format[tokenStart + i]; + } + string[tokenLength] = 0; + formatTokens.push_back(string); + tokenStart = n; + } + } + setLineLength(formatTokens.size()); +} + +int WriteFile::getNumInstances(){ + return objAddrs.size(); +} + +void WriteFile::startThread(){ + BeagleRT_scheduleAuxiliaryTask(writeAllFilesTask); +} + +void WriteFile::stopThread(){ + threadIsExiting=true; +} + +bool WriteFile::threadShouldExit(){ + return(gShouldStop || threadIsExiting); +} + +bool WriteFile::isThreadRunning(){ + return threadRunning; +} + +float WriteFile::getBufferStatus(){ + return 1-getOffset()/(float)bufferLength; +} + +int WriteFile::getOffset(){ + int offset = writePointer - readPointer; + if( offset < 0) + offset += bufferLength; + return offset; +} + +void WriteFile::writeOutput(){ + while( getOffset() >= lineLength ){ //if there is less than one line worth of data to write, skip over. + // So we make sure we always write full lines + writeLine(); + } +} + +void WriteFile::writeAllOutputs(){ + for(unsigned int n = 0; n < objAddrs.size(); n++){ + objAddrs[n] -> writeOutput(); + } +} + +void WriteFile::writeAllHeaders(){ + for(unsigned int n = 0; n < objAddrs.size(); n++){ + objAddrs[n] -> writeHeader(); + } +} + +void WriteFile::writeAllFooters(){ + for(unsigned int n = 0; n < objAddrs.size(); n++){ + objAddrs[n] -> writeFooter(); + } +} + +void WriteFile::writeHeader(){ + print(header); +} + +void WriteFile::writeFooter(){ + print(footer); + fflush(file); + fclose(file); +} + +void WriteFile::setHeader(const char* newHeader){ + allocateAndCopyString(newHeader, &header); + sanitizeString(header); +} + +void WriteFile::setFooter(const char* newFooter){ + allocateAndCopyString(newFooter, &footer); +} + +void WriteFile::sanitizeString(char* string){ + for(int unsigned n = 0; n < strlen(string); n++){ //purge %'s from the string + if(string[n] == '%'){ + string[n] = ' '; + } + } +} + +void WriteFile::run(){ + threadRunning = true; + writeAllHeaders(); + while(threadShouldExit()==false){ + writeAllOutputs(); + usleep(sleepTimeMs*1000); + } + writeAllFooters(); // when ctrl-c is pressed, the last line is closed and the file is closed + threadRunning = false; +} + +void WriteFile::allocateAndCopyString(const char* source, char** destination){ + free(*destination); + *destination = (char*)malloc(sizeof(char) * (strlen(source) + 1)); + strcpy(*destination, source); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/WriteFile.h Wed Oct 07 22:56:14 2015 +0100 @@ -0,0 +1,85 @@ +/* + * WriteMFile.h + * + * Created on: 5 Oct 2015 + * Author: giulio + */ + +#ifndef WRITEMFILE_H_ +#define WRITEMFILE_H_ +#include <BeagleRT.h> +#include <vector> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +class WriteFile { +private: + static AuxiliaryTask writeAllFilesTask; + bool echo; + char *header; + char *footer; + char *stringBuffer; + int stringBufferLength; + int bufferLength; + float* buffer; + int readPointer; + int writePointer; + bool variableOpen; + char* format; + int lineLength; + static int sleepTimeMs; + FILE *file; + void writeLine(); + void writeHeader(); + void writeFooter(); + void allocateAndCopyString(const char* source, char** destination); + void print(const char* string); + void setLineLength(int newLineLength); + std::vector<char *> formatTokens; + static void sanitizeString(char* string); + static void sanitizeString(char* string, int numberOfArguments); + static bool isThreadRunning(); + static bool auxiliaryTaskRunning; + static bool threadShouldExit(); + static bool threadIsExiting; + static bool threadRunning; + static bool staticConstructed; + static void staticConstructor(); + static std::vector<WriteFile *> objAddrs; +public: + WriteFile(); + void setEcho(bool newEcho); + void setFormat(const char* newFormat); + void setHeader(const char* newHeader); + void setFooter(const char* newFooter); + void log(float* array, int length); + void log(float value); + void init(const char* filename); + + /** + * Gets the distance between the write and read pointers of + * the buffer that holds data to be written to disk. + */ + int getOffset(); + + /** + * Inquiries the status of the buffer that holds data to be written to disk. + * + * @return a value between 0 and 1, with 0 being buffer full (writing to disk not fast enough) + * and 1 being buffer empty (writing to disk is fast enough). + */ + float getBufferStatus(); + void writeOutput(); + ~WriteFile(); + static int getNumInstances(); + static void writeAllHeaders(); + static void writeAllFooters(); + static void writeAllOutputs(); + static void startThread(); + static void stopThread(); + static void run(); +}; + +#endif /* WRITEMFILE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/basic_writeFile/main.cpp Wed Oct 07 22:56:14 2015 +0100 @@ -0,0 +1,97 @@ +/* + * main.cpp + * + * Created on: Oct 24, 2014 + * Author: parallels + */ +#include <unistd.h> +#include <iostream> +#include <cstdlib> +#include <libgen.h> +#include <signal.h> +#include <getopt.h> +#include <BeagleRT.h> + +using namespace std; + +// Handle Ctrl-C by requesting that the audio rendering stop +void interrupt_handler(int var) +{ + gShouldStop = true; +} + +// Print usage information +void usage(const char * processName) +{ + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --frequency [-f] frequency: Set the frequency of the oscillator\n"; + cerr << " --help [-h]: Print this menu\n"; +} + +int main(int argc, char *argv[]) +{ + BeagleRTInitSettings settings; // Standard audio settings + float frequency = 440.0; // Frequency of oscillator + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + + // Parse command-line arguments + while (1) { + int c; + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) + break; + switch (c) { + case 'h': + usage(basename(argv[0])); + exit(0); + case 'f': + frequency = atof(optarg); + break; + case '?': + default: + usage(basename(argv[0])); + exit(1); + } + } + + // Initialise the PRU audio device + if(BeagleRT_initAudio(&settings, &frequency) != 0) { + cout << "Error: unable to initialise audio" << endl; + return -1; + } + + // Start the audio device running + if(BeagleRT_startAudio()) { + cout << "Error: unable to start real-time audio" << endl; + return -1; + } + + // Set up interrupt handler to catch Control-C and SIGTERM + signal(SIGINT, interrupt_handler); + signal(SIGTERM, interrupt_handler); + + // Run until told to stop + while(!gShouldStop) { + usleep(100000); + } + + // Stop the audio device + BeagleRT_stopAudio(); + + // Clean up any resources allocated for audio + BeagleRT_cleanupAudio(); + + // All done! + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/basic_writeFile/render.cpp Wed Oct 07 22:56:14 2015 +0100 @@ -0,0 +1,64 @@ +#include <BeagleRT.h> +#include <Scope.h> +#include <cmath> +#include <WriteFile.h> + +float gPhase1, gPhase2; +float gFrequency1, gFrequency2; +float gInverseSampleRate; + +WriteFile file1; +WriteFile file2; + +bool setup(BeagleRTContext *context, void *userData) +{ + gInverseSampleRate = 1.0/context->audioSampleRate; + file1.init("out1.m"); //set the file name to write to + file1.setHeader("myvar=[\n"); //set a line to be printed at the beginning of the file + file1.setFooter("];\n"); //set a line to be printed at the end of the file + file1.setEcho(true); // enable echo to the console (as well as to the file) + file1.setFormat("%.5f %.10f %f\n"); // set the format that you want to use for your output. Please use %f only (with modifiers) + file2.init("out2.m"); + file2.setHeader("input=[\n"); + file2.setFooter("];\n"); + file2.setEcho(false); + file2.setFormat("%f\n"); + gPhase1 = 0.0; + gPhase2 = 0.0; + + gFrequency1 = 200.0; + gFrequency2 = 201.0; + return true; +} + +void render(BeagleRTContext *context, void *userData) +{ + static int count = 0; + if((count&16383) == 0){ + file2.log(context->audioIn, context->audioFrames); //write the input buffer every so often + } + for(unsigned int n = 0; n < context->audioFrames; n++) { + float chn1 = sinf(gPhase1); + float chn2 = sinf(gPhase2); + gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate; + gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate; + if(gPhase1 > 2.0 * M_PI) + gPhase1 -= 2.0 * M_PI; + if(gPhase2 > 2.0 * M_PI) + gPhase2 -= 2.0 * M_PI; + if( (count&511) == 0){ + file1.log(chn1); + file1.log(chn2); + file1.log(count); + } + count++; + } +} + +// cleanup_render() is called once at the end, after the audio has stopped. +// Release any resources that were allocated in initialise_render(). + +void cleanup(BeagleRTContext *context, void *userData) +{ + +}