Here is some details
Note:- All command are working fine with OSCALL function in compiler VC12
with complier VC14
exe name is RemDicomNodes.exe
CMD command prompt:-
RemDicomNodes 5 6 1 2 3 10 8 9
RemDicomNodes.exe 1 A
RemDicomNodes 2 B B 0 localhost 1 "BE" 104 3 1 7 7 60 0 "" 2 0 0 0 0 "" 3 0 0 0 0 "" 0 6 1 2 3 10 8 9 0 0 0 0 NoConversion 0 0 0 0 1 0 0 1 BE 0 0 0 IPv4 0 0 10 0 1 0
Above all commands are working fine and showing proper output on CMD command prompt
With OSCAll function:-
RemDicomNodes 5 6 1 2 3 10 8 9
#(Working fine i am getting output in variable "outputbuffer" which i am using inside readfile API)
RemDicomNodes.exe 1 A
#(Working fine i am getting output in variable "outputbuffer" which i am using inside readfile API)
RemDicomNodes.exe 2 B B 0 localhost 1 """BE"""" " 104 3 1 7 7 60 0 " """""" " 2 0 0 0 0 " """""" " 3 0 0 0 0 " """"""" 0 6 1 2 3 10 8 9 0 0 0 0 NoConversion 0 0 0 0 1 0 0 0 AE 0 0 0 IPv4 0 0 10 0 1 0"
#Problem(that any arguments we are send but it is not working, i am not getting output in variable "outputbuffer" which i am using inside readfile API it is not printing anything )
This is the function which i am using to run my exe
BOOL MagicWatchComProc::OSCall(CString i_cmd, CString& a_output, DWORD& a_exitCode, long i_timeOut)
{
STARTUPINFO aStartupInfo;
PROCESS_INFORMATION aProcessInfo;
HANDLE hReadHandle = NULL;
HANDLE hWriteHandle = NULL;
HANDLE hErrorHandle = NULL;
DWORD dwBytesRead = 0;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
//time_t l_timeOut = 300000; //5 min.
//reset output string
a_output = "";
DEBUG_TRACE(_T("OSCall: launching ") + i_cmd);
if (!i_cmd)
{
DEBUG_TRACE(_T("OSCall: Error: empty command\n"));
return false;
}
//reset errors
SetLastError(0);
// Initialize process startup structure
FillMemory(&aStartupInfo, sizeof(aStartupInfo), 0);
//GetStartupInfo(&aStartupInfo);
aStartupInfo.cb = sizeof(aStartupInfo);
aStartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
aStartupInfo.wShowWindow = SW_HIDE;
// Create pipe that will transfer the process output to our buffer
if(!CreatePipe(&hReadHandle, &hWriteHandle, &sa, 0))
{
DEBUG_TRACE(_T("OSCall: Error: Pipe creation\n"));
return false;
}
// Set process' stdout to our pipe
aStartupInfo.hStdOutput = hWriteHandle;
// We are going to duplicate our pipe's write handle
// and pass it as stderr to create process. The idea
// is that some processes have been known to close
// stderr which would also close stdout if we passed
// the same handle. Therefore we make a copy of stdout's
// pipe handle.
if (!DuplicateHandle( GetCurrentProcess(), hWriteHandle, GetCurrentProcess(), &hErrorHandle, 0, TRUE, DUPLICATE_SAME_ACCESS ))
{
CloseHandle(hReadHandle);
CloseHandle(hWriteHandle);
DEBUG_TRACE(_T("OSCall: Error: duplicate handle\n"));
return false;
}
aStartupInfo.hStdError = hErrorHandle;
// Check input parameter
TCHAR l_inputCommand[2048];
_tcscpy(l_inputCommand, i_cmd);
// Create process of service program
if(!CreateProcess( NULL, l_inputCommand, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &aStartupInfo, &aProcessInfo ))
{
CloseHandle(hReadHandle);
CloseHandle(hWriteHandle);
CloseHandle(hErrorHandle);
DEBUG_TRACE(_T("OSCall: Error: could not create process\n"));
return false;
}
// The process is alive now and has inherited the environment, now
// we can release the critical section
// Close the write end of our pipe (both copies)
// so it will die when the child process terminates
CloseHandle(hWriteHandle);
CloseHandle(hErrorHandle);
// We close the handle of the process in order to prevent memory leaks when
// the process terminates.
//CloseHandle(aProcessInfo.hThread);
// Allocate memory for output buffer
DWORD dwAvailableOutput = 16;
CHAR outputbuffer[18];
//CString strPipeName;
//DWORD dwSize = 0;
//GetNamedPipeHandleState( hReadHandle, NULL, NULL, NULL, NULL, strPipeName.GetBuffer(1), dwSize );
//WaitNamedPipe( strPipeName, 100 );
// -> Read output from CGI program
time_t l_time;
time_t l_startTime;
time(&l_startTime);
do
{
time(&l_time);
if( (l_time - l_startTime) > i_timeOut)
{
SetLastError(WAIT_TIMEOUT);
break;
}
if( ReadFile( hReadHandle, outputbuffer, dwAvailableOutput, &dwBytesRead, NULL ) )
{
outputbuffer[dwBytesRead] = 0; // null terminate
a_output += outputbuffer;
}
}
//We are done
while ( GetLastError() != ERROR_BROKEN_PIPE );
//reset ERROR_BROKEN_PIPE error
if(GetLastError() == ERROR_BROKEN_PIPE)
SetLastError(0);
//DEBUG_TRACE(_T("OSCall: command output: ") + a_output);
//CloseHandle(hErrorHandle);
CloseHandle(hReadHandle);
if( !GetLastError() )
{
return true;
}
else
{
DEBUG_TRACE(_T("OSCall: Error: cmd command failed. Error code: ")+ i2cs(GetLastError()) +_T("; ExitCode: ")+ i2cs(a_exitCode) +_T("."));
return false;
}
}
int main()
{
DWORD dwExitCode = 0;
long l_timeOut = 60000; //ms = 10 min
BOOL bRet = FALSE;
CString strInstallLmutil(_T("cmd.exe /C "));
CString strLmutilInstallFile(_T("remdicomnodes.exe"));
CString strPathLmutilInstall;
strPathLmutilInstall.Format(_T("%s\\bin\\%s"),strtemp,strLmutilInstallFile);
strInstallOption = _T("");
strInstallOption = _T(" 2 B B 0 localhost 1 \"""BE""\"" " 104 3 1 7 7 60 0 " "\"""\"" " 2 0 0 0 0 " "\"""\"" " 3 0 0 0 0 " "\"""\""" 0 6 1 2 3 10 8 9 0 0 0 0 NoConversion 0 0 0 0 1 0 0 0 AE 0 0 0 IPv4 0 0 10 0 1 0");
bRet = OSCall ( cmd, l_commandOutput, dwExitCode, l_timeOut);
SAM_TRACE1("OSCall: bRet value: :%d ",bRet);
if( bRet == FALSE )
{
SAM_TRACE0("remdicomnodes.exe execution failed \n");
}
return 0;
}
i called shmdt() successfully, but shared memory segment can't be removed..
this is my code:
#include <sys/types.h>
#include <sys/shm.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
key_t key = ftok(".", 'T');
if (key == -1) {
fprintf(stderr, "get key failed, error: %s\n", strerror(errno));
exit(1);
}
int shmid = shmget(key, sizeof(int) * 10, IPC_CREAT);
if (shmid == -1) {
fprintf(stderr, "get shmid failed, error: %s\n", strerror(errno));
exit(1);
}
void* shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (void*)-1) {
fprintf(stderr, "get shmaddr failed, error: %s\n", strerror(errno));
exit(1);
}
if (shmdt(shmaddr) == -1) {
fprintf(stderr, "detach failed, error: %s\n", strerror(errno));
exit(1);
}
return 0;
}
after that, i execute ipcs -m
# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 1179648 root 0 4 0
0x00000000 1212417 root 0 4 0
0x00000000 1245186 root 0 4 0
0x00000000 1277955 root 0 4 0
0x00000000 1310724 root 0 4 0
0x00000000 1343493 root 0 4 0
0x00000000 1376262 root 0 4 0
0x00000000 1409031 root 0 4 0
0x00000000 1441800 root 0 4 0
0x00000000 1474569 root 0 4 0
0x54010004 1671178 root 0 40 0
0x00000000 1540107 root 0 4 0
shmdt() detaches the shared memory segment located at the address
specified by shmaddr from the address space of the calling process.
The to-be-detached segment must be currently attached with shmaddr
equal to the value returned by the attaching shmat() call.
shmdt only detaches the calling process from attached memory. It will not remove the shared memory created by the process.
For more information please read the man page of the respective system calls.
I have an embedded Atmel ARM926 board that I created a usb serial ko to get data from an FTDI as USBtty0. This board also has a serial port DBGU which is used as the console terminal that normally runs at 230kb. When I config the USBtty0 port to the required 115kb, DBGU apparently changes to 115kb as well.
if( m_fdELMdev = open(m_ELMdevice, O_RDWR | O_NOCTTY )< 0)
{//error
}
else
{
// Configure the port
tcgetattr(m_fdELMdev, &dev_settings);
dev_settings.c_cflag |= B115200;
cfmakeraw(&dev_settings);
}
Can someone please tell me what I might be doing wrong?
This is snippet of my devices.tab
/dev/tty c 640 0 0 4 0 0 1 4
/dev/tty c 640 0 0 5 0 - - -
/dev/ttyGS c 640 0 0 252 0 - - -
/dev/ttyS c 640 0 0 4 64 0 1 3
/dev/watchdog c 640 0 0 10 130 - - -
/dev/zero c 640 0 0 1 5 - - -
/dev/ttyACM0 c 640 0 0 166 0 - - -
/dev/ttyUSB0 c 640 0 0 188 0 - - -
Also, I occasionally see some 'Interrupted System Calls' from select. How do I need to handle these? Do I retry the select until I get some data? Then what if I never get any data?
enter code here
do
{
iret = select(m_fdELMdev + 1, &fdrefid, NULL, NULL, &porttime);
switch(iret)
{
case READ_TIMEOUT:
ierr = -1;
break;
case READ_ERROR:
g_dbg->debug("CACS_Elm327::Select error:%s (%d)\n",strerror(errno), errno);
ierr = -1;
break;
default:
iret = read(m_fdELMdev, data, ilen);
g_dbg->debug("CACS_Elm327::Readport_ELM:read %s %d\n", data, iret );
break;
}
}while((ierr == 0) && (iret<ilen) );
I am forking a process and running a wc command using execl. Now under correct arguments, it runs fine, but when I give a wrong file name, it fails, but in both the cases the return value of
WEXITSTATUS(status)
is always 0.
I believe there is something wrong with what I am doing, but I'm not sure what is. Reading man pages and Google suggests that I should get a correct value as per the status code.
Here is my code:
#include <iostream>
#include <unistd.h>
int main(int argc, const char * argv[])
{
pid_t pid = fork();
if(pid <0){
printf("error condition");
} else if(pid == 0) {
printf("child process");
execl("/usr/bin/wc", "wc", "-l", "/Users/gabbi/learning/test/xyz.st",NULL);
printf("this happened");
} else {
int status;
wait(&status);
if( WIFEXITED( status ) ) {
std::cout << "Child terminated normally" << std::endl;
printf("exit status is %d",WEXITSTATUS(status));
return 0;
} else {
}
}
}
If you supply a name of non existing file to execl() as 1st argument it fails. If this happens the program leaves without returning any specifiy value. So the default of 0 is returned.
You could fix the for example like this:
#include <errno.h>
...
int main(int argc, const char * argv[])
{
pid_t pid = fork();
if(pid <0){
printf("error condition");
} else if(pid == 0) {
printf("child process");
execl(...); /* In case exec succeeds it never returns. */
perror("execl() failed");
return errno; /* In case exec fails return something different then 0. */
}
...
You are not passing the file name from argv to the child process
Instead of
execl("/usr/bin/wc", "wc", "-l", "/Users/gabbi/learning/test/xyz.st",NULL);
Try this,
execl("/usr/bin/wc", "wc", "-l", argv[1],NULL);
The output I got on my machine
xxx#MyUbuntu:~/cpp$ ./a.out test.txt
6 test.txt
Child terminated normally
exit status is 0
xxx#MyUbuntu:~/cpp$ ./a.out /test.txt
wc: /test.txt: No such file or directory
Child terminated normally
exit status is 1
This was an xcode issue, running from console works fine. I am a Java guy, doing some assignments in CPP. Nevertheless, it might come handy to someone getting stuck at similar issue.
Im trying to write a programm in c++ to let my computer communicate with a trinamic steprockerboard.
They already provided an example file, to get you on the way. This works perfect, but is really simplistic.
Now I want to read the results from the usb device, and they made a function for that:
//Read the result that is returned by the module
//Parameters: Handle: handle of the serial port, as returned by OpenRS232
//Address: pointer to variable to hold the reply address returned by the module
// Status: pointer to variable to hold the status returned by the module (100 means okay)
//Value: pointer to variable to hold the value returned by the module
prototype:
UCHAR GetResult(HANDLE Handle, UCHAR *Address, UCHAR *Status, int *Value)
Now I wrote the following:
UCHAR* adr;
UCHAR* stat;
int* val;
SendCmd(RS232Handle, 1, TMCL_MVP, 0, 0, -3200); // move to next position
SendCmd(RS232Handle,1, TMCL_GAP, 8, 0, 0); // tell motor to look if position is reached
GetResult(RS232Handle,adr,stat,val); //ask for the result, value must give a 1 if so
printf("results from USB device: adr=%d, stat=%d, val=%d\n", adr, stat, val);
But when I run the program, and try this option, the program chrashes.
Has anybody got an idea what might cause the problem? (the code I supplied is only a part of my program, the whole code can be find below.
It is not my intention that you read the whole code, the problem should be above, but only for who is interested I also put the rest down here)
// TMCLTest.cpp : Show how to communicate with a TMCM module in TMCL
//
#include "stdafx.h"
#include <iostream>
//Opcodes of all TMCL commands that can be used in direct mode
#define TMCL_ROR 1
#define TMCL_ROL 2
#define TMCL_MST 3
#define TMCL_MVP 4
#define TMCL_SAP 5
#define TMCL_GAP 6
#define TMCL_STAP 7
enter code here#define TMCL_RSAP 8
enter code here#define TMCL_SGP 9
#define TMCL_GGP 10
#define TMCL_STGP 11
#define TMCL_RSGP 12
#define TMCL_RFS 13
#define TMCL_SIO 14
#define TMCL_GIO 15
#define TMCL_SCO 30
#define TMCL_GCO 31
#define TMCL_CCO 32
//Opcodes of TMCL control functions (to be used to run or abort a TMCL program in the module)
#define TMCL_APPL_STOP 128
#define TMCL_APPL_RUN 129
#define TMCL_APPL_RESET 131
//Options for MVP commandds
#define MVP_ABS 0
#define MVP_REL 1
#define MVP_COORD 2
//Options for RFS command
#define RFS_START 0
#define RFS_STOP 1
#define RFS_STATUS 2
#define FALSE 0
#define TRUE 1
//Result codes for GetResult
#define TMCL_RESULT_OK 0
#define TMCL_RESULT_NOT_READY 1
#define TMCL_RESULT_CHECKSUM_ERROR 2
//Open serial interface
//Usage: ComHandle=OpenRS232("COM1", CBR_9600)
HANDLE OpenRS232(const char* ComName, DWORD BaudRate)
{
HANDLE ComHandle;
DCB CommDCB;
COMMTIMEOUTS CommTimeouts;
ComHandle=CreateFile(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(GetLastError()!=ERROR_SUCCESS) return INVALID_HANDLE_VALUE;
else
{
GetCommState(ComHandle, &CommDCB);
CommDCB.BaudRate=BaudRate;
CommDCB.Parity=NOPARITY;
CommDCB.StopBits=ONESTOPBIT;
CommDCB.ByteSize=8;
CommDCB.fBinary=1; //Binary Mode only
CommDCB.fParity=0;
CommDCB.fOutxCtsFlow=0;
CommDCB.fOutxDsrFlow=0;
CommDCB.fDtrControl=0;
CommDCB.fDsrSensitivity=0;
CommDCB.fTXContinueOnXoff=0;
CommDCB.fOutX=0;
CommDCB.fInX=0;
CommDCB.fErrorChar=0;
CommDCB.fNull=0;
CommDCB.fRtsControl=RTS_CONTROL_TOGGLE;
CommDCB.fAbortOnError=0;
SetCommState(ComHandle, &CommDCB);
//Set buffer size
SetupComm(ComHandle, 100, 100);
//Set up timeout values (very important, as otherwise the program will be very slow)
GetCommTimeouts(ComHandle, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout=MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier=0;
CommTimeouts.ReadTotalTimeoutConstant=0;
SetCommTimeouts(ComHandle, &CommTimeouts);
return ComHandle;
}
}
//Close the serial port
//Usage: CloseRS232(ComHandle);
void CloseRS232(HANDLE Handle)
{
CloseHandle(Handle);
}
//Send a binary TMCL command
//e.g. SendCmd(ComHandle, 1, TMCL_MVP, MVP_ABS, 1, 50000); will be MVP ABS, 1, 50000 for module with address 1
//Parameters: Handle: Handle of the serial port (returned by OpenRS232).
// Address: address of the module (factory default is 1).
// Command: the TMCL command (see the constants at the begiining of this file)
// Type: the "Type" parameter of the TMCL command (set to 0 if unused)
// Motor: the motor number (set to 0 if unused)
// Value: the "Value" parameter (depending on the command, set to 0 if unused)
void SendCmd(HANDLE Handle, UCHAR Address, UCHAR Command, UCHAR Type, UCHAR Motor, INT Value)
{
UCHAR TxBuffer[9];
DWORD BytesWritten;
int i;
TxBuffer[0]=Address;
TxBuffer[1]=Command;
TxBuffer[2]=Type;
TxBuffer[3]=Motor;
TxBuffer[4]=Value >> 24;
TxBuffer[5]=Value >> 16;
TxBuffer[6]=Value >> 8;
TxBuffer[7]=Value & 0xff;
TxBuffer[8]=0;
for(i=0; i<8; i++)
TxBuffer[8]+=TxBuffer[i];
//Send the datagram
WriteFile(Handle, TxBuffer, 9, &BytesWritten, NULL);
}
//Read the result that is returned by the module
//Parameters: Handle: handle of the serial port, as returned by OpenRS232
// Address: pointer to variable to hold the reply address returned by the module
// Status: pointer to variable to hold the status returned by the module (100 means okay)
// Value: pointer to variable to hold the value returned by the module
//Return value: TMCL_RESULT_OK: result has been read without errors
// TMCL_RESULT_NOT_READY: not enough bytes read so far (try again)
// TMCL_RESULT_CHECKSUM_ERROR: checksum of reply packet wrong
UCHAR GetResult(HANDLE Handle, UCHAR *Address, UCHAR *Status, int *Value)
{
UCHAR RxBuffer[9], Checksum;
DWORD Errors, BytesRead;
COMSTAT ComStat;
int i;
//Check if enough bytes can be read
ClearCommError(Handle, &Errors, &ComStat);
if(ComStat.cbInQue>8)
{
//Receive
ReadFile(Handle, RxBuffer, 9, &BytesRead, NULL);
Checksum=0;
for(i=0; i<8; i++)
Checksum+=RxBuffer[i];
if(Checksum!=RxBuffer[8]) return TMCL_RESULT_CHECKSUM_ERROR;
*Address=RxBuffer[0];
*Status=RxBuffer[2];
*Value=(RxBuffer[4] << 24) | (RxBuffer[5] << 16) | (RxBuffer[6] << 8) | RxBuffer[7];
} else return TMCL_RESULT_NOT_READY;
return TMCL_RESULT_OK;
}
int main(int argc, char* argv[])
{
int i;
int Type, Motor, Velocity, Position,ref1;
UCHAR Address, Status;
int Value, Timeout;
HANDLE RS232Handle;
RS232Handle=OpenRS232("COM3", 9600);
// set parameters
SendCmd(RS232Handle, 1, TMCL_SAP, 140, 0, 5); //SAP 140, 0, 5 // set microsteps to 32 (32 additional steps per step of 1.8 degr.)
//SAP 4, 0, 500 //set max vel.
//SAP 5, 0, 100 //set max acc.
//SAP 6, 0, 255 //set abs. max current to 2.8 ampere
//SAP 7, 0, 50 //set standby current ((50/250)*2.8A)
printf("VPI Test Setup\n \n" );
do
{
printf("1 - Rotate clockwise (10 rotations)\n");
printf("2 - Rotate counter-clockwise (10 rotations)\n");
printf("3 - Stop motor\n");
printf("4 - Start test (First 100 rotations clockwise, \n then 100 rotations counter clockwise)\n");
printf("\n99 - End\n");
scanf("%d", &i);
switch(i)
{
case 1:
SendCmd(RS232Handle, 1, TMCL_MVP, 0, 0, 32000); //ABS(4th parameter) = 0
break;
case 2:
SendCmd(RS232Handle, 1, TMCL_MVP, 0, 0, -32000); //ABS(4th parameter) = 0
break;
case 3:
SendCmd(RS232Handle, 1, TMCL_MST, 0, 0, 0);
break;
case 4:
//SendCmd(RS232Handle, 1, TMCL_RFS,0,0,0);
printf("Test started \n" );
//UCHAR done;
UCHAR* adr;
UCHAR* stat;
int* val;
//SendCmd(RS232Handle, 1, TMCL_SAP, 193, 1, 2); //SAP 193,1,2
SendCmd(RS232Handle, 1, TMCL_MVP, 0, 0, -3200); //ABS(4th parameter) = 0
SendCmd(RS232Handle,1, TMCL_GAP, 8, 0, 0);
GetResult(RS232Handle,adr,stat,val);
printf("results from USB device: adr=%d, stat=%d, val=%d\n", adr, stat, val);
//CHAR GetResult(HANDLE Handle, UCHAR *Address, UCHAR *Status, int *Value)
// if(done != 2)
// {
// printf("rotation backwards started \n");
// SendCmd(RS232Handle, 1, TMCL_MVP, 0, 0, 3200);
// }
// }
break;
}
SendCmd(RS232Handle, 1, TMCL_ROL, 0, Motor, Velocity);
SendCmd(RS232Handle, 1, TMCL_ROL, 0, Motor, Velocity);
if(i==1 || i==2 || i==3 || i==4)
{
Address=0;
Status=0;
Value=0;
Timeout=GetTickCount();
while(GetResult(RS232Handle, &Address, &Status, &Value) ==TMCL_RESULT_NOT_READY && abs(GetTickCount()-Timeout)<1000);
printf("Result: Address=%d, Status=%d, Value=%d\n", Address, Status, Value);
}
}
while(i!=99);
CloseRS232(RS232Handle);
return 0;
}
Address, Status and Value should point to valid variables. So, your code should look something like:
UCHAR adr;
UCHAR stat;
int val;
GetResult(RS232Handle,&adr,&stat,&val);
What is happening now is that your variables (adr, stat and val) are not initialized, so, they point to random locations in memory. When you pass these variables to GetResult, it tries to write to those random locations.