I am running a beaglebone and want to write a program to sample the ADC. I am trying to use the blacklib (http://blacklib.yigityuce.com/index.html) from here. I cloned the git:
https://github.com/yigityuce/BlackLib
and tried to compile the example with
g++ exampleAndTiming.cpp -std=c++11
This however gives me a ton of errors like these:
In file included from exampleAndTiming.cpp:33:0:
exampleAndTiming/exampleAndTiming_GPIO.h: In function 'void exampleAndTiming_GPIO()':
exampleAndTiming/exampleAndTiming_GPIO.h:97:12: error: 'sleep' was not declared in this scope
sleep(1);
^
In file included from exampleAndTiming.cpp:34:0:
exampleAndTiming/exampleAndTiming_ADC.h: In function 'void exampleAndTiming_ADC()':
exampleAndTiming/exampleAndTiming_ADC.h:67:16: error: 'usleep' was not declared in this scope
usleep(1000);
^
so I include unistd.h (in exampleAndTiming.cpp), but then I get errors like these:
/tmp/ccbgiXE9.o: In function `exampleAndTiming_GPIO()':
exampleAndTiming.cpp:(.text+0x50): undefined reference to `Timing::startMeasure(std::string)'
exampleAndTiming.cpp:(.text+0x80): undefined reference to `BlackLib::BlackGPIO::BlackGPIO(BlackLib::gpioName, BlackLib::direction, BlackLib::workingMode)'
exampleAndTiming.cpp:(.text+0xbc): undefined reference to `Timing::endMeasure(std::string)'
exampleAndTiming.cpp:(.text+0xec): undefined reference to `BlackLib::BlackGPIO::BlackGPIO(BlackLib::gpioName, BlackLib::direction, BlackLib::workingMode)'
exampleAndTiming.cpp:(.text+0x104): undefined reference to `BlackLib::BlackGPIO::BlackGPIO(BlackLib::gpioName, BlackLib::direction, BlackLib::workingMode)'
exampleAndTiming.cpp:(.text+0x11c): undefined reference to `BlackLib::BlackGPIO::BlackGPIO(BlackLib::gpioName, BlackLib::direction, BlackLib::workingMode)'
exampleAndTiming.cpp:(.text+0x158): undefined reference to `Timing::startMeasure(std::string)'
I've been looking at some library examples and compiling it, but I cannot make sense of it all. I've compiled plenty of c++ and c programs before, but I can't get this one to work. So any help will be appreciated.
COMPLETE GUIDE how to compile BLACKLIB directly on BEAGLEBONE BLACK (rev C) running ANGSTROM:
Programs:
Putty - to communicate with BBB from Windows (using SSH with USB cable)
WinSCP - to manage (upload, create, delete) files directly on BBB
Code::Blocks - to write C++ programs
optionally
Termite 2.9 - to send and receive UART transmission from UART<->USB converter (actually Putty could be used to do that as well)
1) get the BlackLib from official site
2) unzip the library and copy following files into separate folder :
BlackADC.cpp, BlackADC.h, BlackCore.cpp, BlackCore.h, BlackDef.h, BlackErr.h, BlackGPIO.cpp, BlackGPIO.h, BlackI2C.cpp, BlackI2C.h, BlackLib.h, BlackPWM.cpp, BlackPWM.h, BlackSPI.cpp, BlackSPI.h, BlackUART.cpp, BlackUART.h
3) open following files in Code::Blocks BlackUART.cpp, BlackSPI.cpp, BlackI2C.cpp and add
#include <unistd.h>
right after #include "BlackUART.h", the "unistd.h" includes all the functions like sleep(), open(), close(), ... that otherwise seems missing
4) create your own program main.cpp, you may use the following code for testing UART1 and UART2:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sstream>
#include <string>
#include <iostream>
#include "BlackLib.h"
int main(){
std::string writeToUart1;
std::string writeToUart2;
std::string readFromUart1;
std::string readFromUart2;
int counter;
std::ostringstream os1;
std::ostringstream os2;
BlackLib::BlackUART Uart1(BlackLib::UART1,
BlackLib::Baud9600,
BlackLib::ParityEven,
BlackLib::StopOne,
BlackLib::Char8 );
// Pins on BeagleBone Black REV C
// UART1_RX -> GPIO_15 (P9.24)
// UART1_RX -> GPIO_14 (P9.26)
BlackLib::BlackUART Uart2(BlackLib::UART2,
BlackLib::Baud9600,
BlackLib::ParityEven,
BlackLib::StopOne,
BlackLib::Char8 );
// Pins on BeagleBone Black REV C
// UART2_RX -> GPIO_2 (P9.22)
// UART2_RX -> GPIO_3 (P9.21)
std::cout << "Program UART start" << std::endl << std::flush;
Uart1.open( BlackLib::ReadWrite | BlackLib::NonBlock );
Uart2.open( BlackLib::ReadWrite | BlackLib::NonBlock );
counter = 0;
while (true){
os1.str("");
os1.clear();
os1 << "Uart1 to TX: " << counter << "\n";
writeToUart1 = os1.str();
Uart1 << writeToUart1;
readFromUart1 = "";
Uart1 >> readFromUart1;
if (readFromUart1.compare("") != 0){
std::cout << "Uart1 from RX: " << readFromUart1 << "\n" << std::flush;
}
Uart1.flush( BlackLib::bothDirection );
counter++;
sleep(2);
os2.str("");
os2.clear();
os2 << "Uart2 to TX: " << counter << "\n";
writeToUart2 = os2.str();
Uart2 << writeToUart2;
readFromUart2 = "";
Uart2 >> readFromUart2;
if (readFromUart2.compare("") != 0){
std::cout << "Uart2 from RX: " << readFromUart2 << "\n" << std::flush;
}
Uart2.flush( BlackLib::bothDirection );
counter++;
sleep(2);
}
return 1;
}
5) save the main.cpp to the same folder as the BlackLib files
6) using WinSCP, create directory on the BBB (e.g. /home/uart) and copy all the BlackLib files and main.cpp into this folder
7) open Putty and navigate to the folder by :
cd /home/uart
8) compile the files by using :
gcc *.cpp -o main -std=c++11
9) run the program :
./main
10) connect the wires to UART<->USB converter and BBB. The ouput from BBB should look like :
Uart2 to TX: 1 OR Uart1 to TX: 0
Uart2 to TX: 3 OR Uart1 to TX: 2
depending on connection of wires
It seems I managed to fix it myself, some nooblike behaviour not including all the cpp files, but even more, I also needed to add #include to BlackCore.h to avoid tons of undefined function errors.
final command:
g++ exampleAndTiming.cpp exampleAndTiming/Timing.cpp BlackADC.cpp BlackCore.cpp BlackGPIO.cpp BlackI2C.cpp BlackPWM.cpp BlackSPI.cpp BlackUART.cpp -std=c++11
I'd probably need to make a makefile to compile the library seperately, time to do some more digging and learning.
I am the creator of BlackLib, Yiğit YÜCE. You found your answer by yourself. The makefile which you mentioned on your comment will be published shortly.
Related
I am working on Windows and I am trying to write an array into a Ubuntu device using C++ in Visual Studio 2019. Here's a sample of my code:
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs, int *iAnsSize, char *sAns)
...
...
...
char pcFolderName[256];
char pcFileName[256];
sprintf(pcFolderName, "%s\\%s",pcSavePath, pcUUTSerialNumber);
sprintf(pcFileName, "%s\\calib_rfclock.conf",pcFolderName);
// WRITE TABLE ON PC
FILE *pFileW;
pFileW = fopen(pcFileName,"wb");
fwrite(&CalibTable, sizeof(char), CalibTable.hdr.v1.u32Len, pFileW);
fclose(pFileW);
}
return 0;
However, I keep having this pop-up from Microsoft Visual C++ Debug Library that says:
Debug Assertion Failed:
Program:...
File: f:\dd\vctools\crt_bld\sefl_x86\crt\src\fwrite.c
Line: 77
Expression: (stream != NULL)
...
I found this thread and I tried logging in as root on my Ubuntu device. I also tried:
mount -o remount,rw /path/to/parent/directory
chmod 777 /path/to/parent/directory
And I can also create/edit manualy any file in the directory I'm trying to write into with my code, but I get the same error when running it.
Anyone knows what could cause this? I think it could be on the Windows side, but I don't know what I am doing wrong. Thanks a lot in advance.
You never check that opening the file succeeds - and it most likely fails, which is why you get the debug pop-up. Your use of \ as directory delimiters may be the only reason why it fails, but you should check to be sure.
I suggest that you use std::filesystem::path (C++17) to build your paths. That makes it easy to create paths in a portable way. You could also make use of a C++ standard std::ofstream to create the file. That way you don't need to close it afterwards. It closes automatically when it goes out of scope.
Example:
#include <cerrno>
#include <cstring>
#include <filesystem>
#include <fstream>
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs,
int *iAnsSize, char *sAns)
{
...
// Build std::filesystem::paths:
auto pcFolderName = std::filesystem::path(pcSavePath) / pcUUTSerialNumber;
auto pcFileName = pcFolderName / "calib_rfclock.conf";
// only try to write to the file if opening the file succeeds:
if(std::ofstream pFileW(pcFileName, std::ios::binary); pFileW) {
// Successfully opened the file, now write to it:
pFileW.write(reinterpret_cast<const char*>(&CalibTable),
CalibTable.hdr.v1.u32Len);
} else {
// Opening the file failed, print the reason:
std::cerr << pcFileName << ": " << std::strerror(errno) << std::endl;
}
...
}
Making my way from Python to C++ (I've been programming in Python 2 years now), I stumbled in the examples of the GDAL API for raster processing. The very first example gave me some problems.
I wrote this code to open a raster on my computer, and write a message if there is any problem by opening the raster.
Here my code:
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h" /* for CPLMalloc() */
#include <iostream>
using namespace std;
int main() {
GDALDatasetH hDataset;
GDALAllRegister();
hDataset = GDALOpen("Isle_wight.tif", GA_ReadOnly);
if ( hDataset == NULL)
{cout << "Invalid Raster Dataset"<< endl;}
else { cout << "Dataset open correctly!" << endl;}
return 0;
}
I know that can be very trivial, but I can't understand this error message at compiling time:
g++ -o gdal_open_dataset gdal_open_dataset.cpp
/tmp/cc2ehnnc.o: In function `main':
gdal_open_dataset.cpp:(.text+0x1e): undefined reference to 'GDALAllRegister'
gdal_open_dataset.cpp:(.text+0x2f): undefined reference to `gdalOpen' collect2:error: ld returned 1 exit status
Could anyone help me with this please?
I am trying to run this simple example in GDCM. I have installed the library c++ version and the installation works perfectly fine but I am not able to figure out how to compile and run a example.
#include "gdcmReader.h"
#include "gdcmWriter.h"
#include "gdcmAttribute.h"
#include <iostream>
int main(int argc, char *argv[])
{
if( argc < 3 )
{
std::cerr << argv[0] << " input.dcm output.dcm" << std::endl;
return 1;
}
const char *filename = argv[1];
const char *outfilename = argv[2];
// Instanciate the reader:
gdcm::Reader reader;
reader.SetFileName( filename );
if( !reader.Read() )
{
std::cerr << "Could not read: " << filename << std::endl;
return 1;
}
// If we reach here, we know for sure only 1 thing:
// It is a valid DICOM file (potentially an old ACR-NEMA 1.0/2.0 file)
// (Maybe, it's NOT a Dicom image -could be a DICOMDIR, a RTSTRUCT, etc-)
// The output of gdcm::Reader is a gdcm::File
gdcm::File &file = reader.GetFile();
// the dataset is the the set of element we are interested in:
gdcm::DataSet &ds = file.GetDataSet();
// Contruct a static(*) type for Image Comments :
gdcm::Attribute<0x0020,0x4000> imagecomments;
imagecomments.SetValue( "Hello, World !" );
// Now replace the Image Comments from the dataset with our:
ds.Replace( imagecomments.GetAsDataElement() );
// Write the modified DataSet back to disk
gdcm::Writer writer;
writer.CheckFileMetaInformationOff(); // Do not attempt to reconstruct the file meta to preserve the file
// as close to the original as possible.
writer.SetFileName( outfilename );
writer.SetFile( file );
if( !writer.Write() )
{
std::cerr << "Could not write: " << outfilename << std::endl;
return 1;
}
return 0;
}
/*
* (*) static type, means that extra DICOM information VR & VM are computed at compilation time.
* The compiler is deducing those values from the template arguments of the class.
*/
It has a few header files that it is looking for namely gdcmreader, gdcmwriter and I want to figure out the compiler flags to use to be able to run this file.
I am doing g++ a.cpp -lgdcmCommon -lgdcmDICT but that gives me the error
a.cpp:18:24: fatal error: gdcmReader.h: No such file or directory
compilation terminated.
Can you please help me out? I have searched everywhere but I can't seem to figure out how to run this file.
When using files that are in different locations of your "normal" files you must instruct the compiler and the linker how to find them.
Your code has a #include <someFile.h> command.
The <> usage means "in other path". The compiler already knows common "other paths" as for "stdio" for common libraries.
In case of "not normal", you can tell g++ where to find the headers by adding -Imydir to the command line (replace 'mydir' with the proper path)
For the libraries, static (.a) or dynamic (.so) the same history stands.
The -Lmydir tells g++ where to look for libraries.
Your command line may look like
g++ a.cpp -I/usr/include -L/usr/local/lib -lgdcmCommon -lgdcmDICT
You did not tell how did you install gdcm library, I assume that using apt system. There are two types of libraries, "normal" and "developer" ones. To be able to compile your own software, you need the latter. So, for example in Ubuntu 16.04, type apt-get install libgdcm2-dev. Then all necessary headers will be installed in /usr/include/gdcm-2.6.
I would like to read some variable's value in Matlab from c++. I searched in Internet and found out below example in Matlab Documentation Page.
for using this example I Did below steps:
I add this include path to project :
c:\program files\Matlab\r2017b\extern\include
then I Add this path Library Directory :
c:\program Files\Matlab\r2017b\extern\lib\win64\microsoft
then I Add this library to project :
"libMatlabEngine.lib"
"libMatlabDataArray.lib"
then I placed needed DLLs beside application EXE file.
then I ran the application after that application faced with access violataion error when startMATLAB() Method has been ran.
Note: I had other problem that I resolved it. but I think that problem was very strange and may be knowing that problem help you to find main reason of my problems.
problem was : when I set dll's files path in environment variables my app didn't find dlls and get "no entry point to *.dll" run time error. but when I copy dlls beside of exe, my app saw them.(I restarted VS2013 after change environment variables.)
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <iostream>
void callgetVars() {
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
// Evaluate MATLAB statement
matlabPtr->eval(convertUTF8StringToUTF16String("[az,el,r] = cart2sph(5,7,3);"));
// Get the result from MATLAB
matlab::data::TypedArray<double> result1 = matlabPtr->
getVariable(convertUTF8StringToUTF16String("az"));
matlab::data::TypedArray<double> result2 = matlabPtr->
getVariable(convertUTF8StringToUTF16String("el"));
matlab::data::TypedArray<double> result3 = matlabPtr->
getVariable(convertUTF8StringToUTF16String("r"));
// Display results
std::cout << "az: " << result1[0] << std::endl;
std::cout << "el: " << result2[0] << std::endl;
std::cout << "r: " << result3[0] << std::endl;
}
I use vs2013 and Matlab 2017b in windows 7.
Thanks for your help.
When I execute the following program on the my embedded Linux nothing happens:
#include <boost/thread/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
#include <boost/atomic.hpp>
void Test(void)
{
std::cout << "Hello World" << std::endl;
}
int main(int argc, char* argv[])
{
std::cout << "init";
boost::thread producer_thread(Test);
producer_thread.join();
std::cout << "end";
}
# ./prog -> nothing happens here
The last few lines from strace output are:
open("/lib/libboost_thread.so.1.55.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\240\272\0\0004\0\0\0"..., 512) = 512
lseek(3, 95536, SEEK_SET) = 95536
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1200) = 1200
lseek(3, 95226, SEEK_SET) = 95226
read(3, "A'\0\0\0aeabi\0\1\35\0\0\0\0055T\0\6\3\10\1\t\1\22\4\24\1\25\1"..., 40) = 40
exit_group(1) = ?
+++ exited with 1 +++
#
The cross compiled libbost_thread is right installed at /lib.
The program exit before main() being called. The program runs normal under my Ubuntu.
Target: ARM with buildroot (sama5d3)
Toolchain: arm-linux-gnueabihf-
Regards
Maybe as a hint:
Have you linked against libpthread with compile and link option -pthread for your target?
If not it can have the same effect as seen in your environment: The prog starts, try to start a new thread, have no threading enabled and call the abort() function. Because abort() simply leave the prog with error in exit code nothing else happens.
Can you also add your compile & link commands for debugging purpose please!
In addition:
Your outputs without endl will not be printed because cout is buffered. The buffer will be printed only if you call flush or send a endl. Maybe you change this in your example.
Hope that helps...
strace is a tool that traces system calls. In your example, this consists of calls to open(), lseek(), and read(). Specifically, the snippet that you pasted shows the OS's dynamic library loader opening the libboost_thread.so.1.55.0 file and reading its contents; nothing more. It doesn't really demonstrate anything about your program except that it is linked against that library.
I found the problem.
The boost library was compiled with arm-linux-gnueabi- (elibc) and the buildroot is compiled with uClibc.