|
int main() {
#ifdef STEP
cout << "Project VNAR-19270 VNA-1023 (6 base) Vector network analyzer" << endl;
cout << "DEBUG ****RUNNING WORKING COPY of VNA_2 " << endl;
#endif
int iCPU = 0;
iCPU = system ("omp_get_num_procs");
cout << "# of CPU's " << dec << +iCPU << endl;
exit(1);
Now returns omp_get_num_procs not found.
I think the problem is also in crosscompiler settings.
Also the "remote AKA RPi" OS has no OpenMP installed.
I need to check that.
I was just looking for an advise if my syntax is OK.
|
|
|
|
|
The syntax looks OK now. The error message implies the the omp_get_num_procs program cannot be found in any of the standard locations, so you may need to provide the full path. As I said before, you will not get the correct answer from the call to system ; see the man page for details. In order to get the correct number you need to connect the external command's stdout stream to your application, which you can then read and process as required.
[edit]
You need to re-read k5054's message above.
[/edit]
modified 8-Feb-19 11:54am.
|
|
|
|
|
Richard MacCutchan wrote: The error message implies the the omp_get_num_procs program cannot be found in any of the standard locations
That's not surprising omp_get_num_procs() is a function call in the OpenMP library. I'm not sure why the OP thinks that it needs to be wrapped in a call to system(). If they could answer that question, maybe we can tell him why he's mistaken, and how to fix his mistake.
|
|
|
|
|
Thanks, I see from your previous message that you have explained that.
|
|
|
|
|
int iCPU = 0;
iCPU = omp_get_num_procs();
cout << "# of CPU's " << dec << +iCPU << endl;
exit(1);
Using system( ) because without it I get
./src/VNA_1022_BASE.o: In function `main':
/media/jim/DEV/Eclipse_2019_03_M1/workspace/eclipse-workspace/VNAR_19280/Debug/../src/VNA_1022_BASE.cpp:253: undefined reference to `omp_get_num_procs'
makefile:80: recipe for target 'VNAR_19280' failed
collect2: error: ld returned 1 exit status
make: *** [VNAR_19280] Error 1
"make all" terminated with exit code 2. Build might be incomplete.
I believe it is NOT only syntax issue, but something is missing in setting OpenMP.
I'll take a look at the verbose output of both complier and linker to see anything obvious.
|
|
|
|
|
The linker message undefined reference to `omp_get_num_procs' is the clue, here. You need to tell your IDE to link in libgomp when compiling this project.
What made you think that using system() was the right thing here?
|
|
|
|
|
Habit, used to equerry other system info.
Yes, the linker has given me a hit to check another instruction how to implement OpenMP.
The first one did not included the "link to gomp".
Not everything posted on internet is true and I should have known better anyway.
Now if I can figure out how to tell my IDE to use OpenMP I'll be a happy camper.
|
|
|
|
|
Yes, by using system you are not calling the omp_get_num_procs function at all. You need to understand the difference between using system to run an external application, and calling a library function directly. In the above case you are missing the library that contains the omp_get_num_procs function. So you just need to add it to the LIB section of your makefile, or in the linker section of your project in the IDE (not sure which one you are using here).
modified 9-Feb-19 4:39am.
|
|
|
|
|
"ls" command sends output to "cout".
How do I get it to C++ code buffer?
This code outputs desired /dev/spi x string to a console, I need it to save it in a buffer for further
processing. How?
system("ls -l -x /dev/spi*");
Cheers
Vaclav
|
|
|
|
|
use popen(). e.g.
#include <cstdio>
FILE *cmd = popen("ls -l -x /dev/spi*", "r");
while(!feof(cmd) && !ferr(cmd)) {
fscanf(cmd, ...);
}
fclose(cmd);
If you've got boost, then maybe boost.process will be a better fit.
If you just need filenames, maybe glob() is all you need
#include <glob>
glob_t spi_files;
glob("/dev/spi*", 0, 0, &spi_files);
for(size_t i = 0; i < spi_files.gl_pathc; ++i) {
char *filename = gl.pathv[i];
...
}
globfree(&spi_files);
If you need further information about the files, then you can call stat() on the file, see man stat(2). Also see man glob(3) for the usage of arguments 2 and 3 (0s in above code).
There's also boost.filesystem, which may help you. If you've got a C++17 compilant compiler (gcc v8), then you also have <filesystem> in the stdlib
|
|
|
|
|
Thanks
I just downloaded boost , like to try it, but it does not included format.
I need to figure out how to "insert" format without having to delete ( I have not (intentionally) deleted anything from my OS, scary !) boost and re-install it from a different source.
|
|
|
|
|
Vaclav_ wrote: I just downloaded boost , like to try it, but it does not included format.
I'm not sure what you mean. Are you trying to figure out how to install boost for your OS?
If you have a reasonably recent linux version, you should be able to get boost via the package management system - e.g. apt, yum, etc. But take a look at what version of boost the system is providing, if you're wanting to use boost.process. That was added in v 1.64 which seems to be from April 2017, so that's a recent addition.
|
|
|
|
|
To moderator
I have received e-mail of message flagged as spam.
There is no spam in it, just normal reply.
Funny - how can I receive e-mail of message "pending approval"?
|
|
|
|
|
That just means that the automatic spam filter saw something in the message that may be suspicious. It then holds the message in the pending queue until a member with the relevant authority can review it, and release or reject.
|
|
|
|
|
So this "automation" passes the suspicious message to me ?
It is not OK to view on forum , but OK to "spam" me ?
Yet another half-baked software.
PS
I really want to know WHY you replied to my post?
Do you spend your time surfing every forum here?
Cheers
|
|
|
|
|
It seems that everything you don't understand is somehow taken as a personal assault. The spam filter is designed to prevent the site being flooded with rubbish (which often happens). As it is a piece of automated code, it errs on the side of caution, and sometimes flags innocent messages. Why is that half-baked?
|
|
|
|
|
It seems that everything you don't understand is somehow taken as a personal assault.
Nice example.
Have a nice day.
|
|
|
|
|
There are plenty of resources about ioctl.
All of them refer to "files" which is OK.
What is missing - as far as I am concerned - is actual code where commands and data passed via ioctl function are processed.
It is very common to read " use plain write " to do the hardware manipulation.
Since "what are you trying to do" is often first reply - here is a sample.
Purpose of the code is to output data to I2C hardware:
iResult = write(FileDescriptor,Data,iSize);
Works as expected.
When I get more familiar with ioctl I'll try use I2C ioctl "write macro" instead of "plain" write.
My primary question is - how to find the actual Linux code which "transfers" the write function to sending I2C clock and data. (Mrs Google - via Github - keeps giving me the "files" and not reference to actual Linux source code - perhaps I am asking wrong way - again. )
My secondary is - how to verify that my code actually reads I2C ACK when I send the I2C address.
All I am getting is "number of characters processed", which is fine, but does it "include " verifying the ACK?
Cheers
|
|
|
|
|
|
Yes, that is one of the doc I am using.
I do not see the device / driver dependency.
I thought the "ioctl" sort of bypasses the need for driver giving me access to kernel directly.
I am trying to send generic "write" i2c data.
I am under the impression that once the file descriptor is opened for "device " - in this case "dev/i2c-1" that is all I need to implement the ioctl.
I am not sure how to find the Linux source code for this.
|
|
|
|
|
Yes that is correct, sort of. The ioctl call allows you to send special messages to the device driver in order to control the device beyond normal read and write. For example the disk driver has ioctl messages that will return details of the physical settings of the disk. But these messages still go to the device driver, they do not bypass it. The actual details will vary from device to device, so you need the specific information related to the device you are accessing.
|
|
|
|
|
Yes, I know in case of I2C I need to know the actual data format to accomplish the task.
For now I like to verify that when I initialize the file descriptor with device and then call ioctl to tell the file descriptor to open commutation with I2C slave - by passing the actual I2C hardware address , - then I do not need to write the actual data "prefixed " with the address.
That is the part I am having trouble understanding - but I'll try to "write" with and without sending the I2C address.
I may post the code when I am done testing this.
Cheers
Vaclav
|
|
|
|
|
Found this one and it looks OK , but it seems that "open source" concept can be a challenge when it comes to Linux documentation.
Linux Man Pages[^]
No, I do not have specific question about an application.
PS
Is this forum recent addition to CodeProject?
Cheers
Vaclav
|
|
|
|
|
If you have a Linux system then you should use the man pages installed there. I have used Linux man pages[^] in the past, which seem quite comprehensive.
Yes, this is a recent addition to the forums.
|
|
|
|
|
I would like somebody to walk me thru this code to help me understand some details I am having an issue with.
The purpose of the code is to send 8 bits data to hardware – LCD - using SPI communication protocol and Linux ioctl, in C++.
It in an essence works, but I “do not get” totally how.
Since I am not interested in psychoanalysis of my code or “doing it differently” I would prefer to hold off my questions until somebody with interest and knowledge of all of the above – passing data to function , operation of ioctl “command” - SPI_IOC_MESSAGE and SPI (bidirectional ) communication replies.
Basic implementation of the code is a copy of C code and I like to clean it up so it looks as real C++.
function call
vna.spi.SPI_Transfer_3_Line(1);// send command - software reset
function SPI transfer
Reformatted
int C_IOCTL_SPI::SPI_Transfer_3_Line(char data) {
#ifdef DEBUG
cout << "*** TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
cout << " data " << +data << endl;
cout << " @ line \033[0m " << dec << __LINE__ << endl;
cout << "\033[0m " << endl;
#endif
struct spi_ioc_transfer xfer[2];
unsigned char buf[32], *bp;
unsigned char tx_buf[32], *tx_bp;
unsigned char rx_buf[32], *rx_bp;
int len, status;
if (FileDescriptor) {
#ifdef DEBUG
cout << "FileDescriptor OK " << dec << +FileDescriptor << endl;
#endif
}
memset(xfer, 0, sizeof xfer);
memset(buf, 0, sizeof buf);
memset(tx_buf, 0, sizeof tx_buf);
memset(rx_buf, 0, sizeof rx_buf);
len = sizeof buf;
buf[0] = data;
xfer[0].tx_buf = (unsigned long) buf;
xfer[0].rx_buf = (unsigned long) buf;
xfer[0].len = 1; for (int index = 0; index != xfer[0].len; index++)
cout << "TX buffer index " << dec << index << " 0x" << hex << +buf[index]<< endl;
for (int index = 0; index < 0x10; index++) {
if (buf[index])
cout
<< " ******************** commnad tx buffer value "
<< +buf[index] << endl;
}
xfer[1].rx_buf = (unsigned long) buf;
xfer[1].len = 16; status = ioctl(FileDescriptor, SPI_IOC_MESSAGE(2), xfer);
if (status < 0) {
cout << "status " << status << endl;
perror("Transfer error SPI_IOC_MESSAGE");
return -1;
}
printf("Expected reply of %d characters \n", len);
printf("Processed %d characters \n", status);
#ifdef DEBUG
cout << " TX DATA 0x" << hex << +data << endl;
cout << " TX DATA dec " << dec << +data << endl;
#endif
printf("response(%d): ", status);
for (int index = 0; index != xfer[1].len; index++) {
if (buf[index])
cout
<< " !!!!!!!!!!!!!!!!!!!!!! DATA response rx buffer value "
modified 27-Dec-18 12:43pm.
|
|
|
|