Vector CANalyzer in offline mode. Playing back CAN recording, and processing with CAPL script to identify areas of interest quickly. Have many CAN recordings to analyse. If an area of interest is found, print the current logging filename, and time location within file, to write window:
on message Frame_of_Interest
{
if( this.rpm > 0 )
{
if( this.torque == 0 )
{
write("HIT in file %s at location %s", logging filename, time location);
}
}
}
Any help much appreciated.
Related
Ive incorporated multiple features i want in a microcontroller program (ESP32 Wroom32) and needed some advice on the best way to keep the program running and receive messages while it is running.
Current code:
//includes and declarations
setup()
{
//setup up wifi, server
}
main(){
WiFiClient client = server.available();
byte new_command[40];
if (client) // If client object is created, a connection is setup
{
Serial.println("New wifi Client.");
String currentLine = ""; //Used to print messages
while (client.connected())
{
recv_byte = client.read();
new_command = read_incoming(&recv_byte, client); //Returns received command and check for format. If invalid, returns a 0 array
if (new_command[0] != 0) //Checks if message is not zero, None of valid messages start with zero
{
execute_command(new_command);
//new_command is set to zero
}
}//end of while loop
}//end of if loop
}
The downside of this is that the ESP32 waits till the command is finished executing before it is ready to receive a new message. It is desired that the ESP32 receive commands and store them, and execute it at its own pace. I am planning to change the current code to receive a messages while the code is running as follows:
main()
{
WiFiClient client = server.available();
byte new_command[40];
int command_count = 0;
byte command_array[50][40];
if (command_count != 0)
{
execute_command(command_array[0]);
//Decrement command_count
//Shift all commands in command_array by 1 row above
//Set last executed command to zero
}
}//end of main loop
def message_interrupt(int recv_byte, WiFiClient& running_client)
{
If (running_client.connected())
{
recv_byte = running_client.read();
new_command = read_incoming(&recv_byte, running_client); //Returns received command and check for format. If invalid, returns a 0 array
//add new command to command_array after last command
//increment command_count
}
}
Which interrupt do I use to receive the message and update the command_array ? https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html Doesnt mention any receive/transmit events. I couldnt find any receive/transmit interrupt either or maybe I searched for the wrong term.
I'm writing a tool that needs to walk all the threads of the current process regularly under Windows. So far, so good.
So I'm using CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0), then walking the thread list. Unfortunately, my profiler shows that this is very expensive (~30% CPU when I repeat this about once per second).
Is there a better/faster way to do this?
Before Windows 8.1, you can use NtGetNextThread as #ErykSun mentioned in the question comments, but it's not documented.
Since Windows 8.1, you can use PssCaptureSnapshot. Example usage can be found here.
Both solutions query only the desired process and not the whole system, so they're much faster.
The relevant parts, just in case:
#include <processsnapshot.h>
// ...
HPSS hSnapshot;
error = ::PssCaptureSnapshot(hProcess, PSS_CAPTURE_THREADS, 0, &hSnapshot);
// ...
PSS_THREAD_INFORMATION info;
if(ERROR_SUCCESS != ::PssQuerySnapshot(hSnapshot, PSS_QUERY_THREAD_INFORMATION, &info, sizeof(info))) {
printf("No thread information\n");
return;
}
printf("Threads captured: %u\n", info.ThreadsCaptured);
HPSSWALK hWalk;
if(ERROR_SUCCESS == ::PssWalkMarkerCreate(nullptr, &hWalk)) {
PSS_THREAD_ENTRY thread;
while(ERROR_SUCCESS == ::PssWalkSnapshot(hSnapshot, PSS_WALK_THREADS, hWalk, &thread, sizeof(thread))) {
printf("TID: %6u Created: %s Priority: %2d User: %s Kernel: %s\n",
thread.ThreadId,
TimeToString(thread.CreateTime).c_str(),
thread.Priority,
TimeSpanToString(thread.UserTime).c_str(), TimeSpanToString(thread.KernelTime).c_str());
}
::PssWalkMarkerFree(hWalk);
}
// ...
::PssFreeSnapshot(::GetCurrentProcess(), hSnapshot);
I am trying atm to create a shared memory file for my process. The filename constists of several parts to identify the process the SHM belongs to and whats its content. An example would be:
shm_pl_dev_system_25077
I create all the files in a directory I created in /tmp where I have full write and read permissions.
So the complete Path would be:
/tmp/pl_dev/shm_pl_dev_system_25077
I create several files there, some fifo pipes and other stuff and also the shm. The only Problem I get is that shm_open will always return the errno 63 (ENAMETOOLONG).
Can you tell me what the issue here is?
Here is the code:
handle_ = ::shm_open(shm_name.get(), O_RDWR, 0755);
if (handle_ == -1 && errno == ENOENT)
{
// SHM does not yet exists, so create it!
handle_ = ::shm_open(shm_name.get(), O_CREAT | O_RDWR, 0755);
if (handle_ != -1) {
created_ = true;
}
else
{
if (!silent_)
{
log.error("Couldn't create the SHM (%d).", errno);
}
return false;
}
}
Okay. As it seems OSX is very limited in the filename of SHMs... The maximum length for a filename currently is 31 chars per section (see PSHMNAMELENGTH in /usr/include/sys/posix_shm.h)
I'm using D as a scripting language for Windows 7 console stuff to automate boring tasks. One of my scripts (open.exe) is supposed to allow me to open stuff from the command line without me having to specify which program I use (I have a configuration file with this stuff). Now, I use executeShell to do this, and call something like start [name of program I want to use] [name of input file]. If I do this directly from the shell, it returns immediately, but if I do it using my D script, it doesn't return until the program that it opens is closed. What should I do to allow it to return immediately?
For reference purposes, this is the business logic of my script (the main method just does some argument parsing for piping purposes):
immutable path = "some//path//going//to//config//file.conf";
void process(string input) {
string extension = split(input,".")[1]; //get file extension from input
auto config = File(path,"r"); auto found = false;
while (!config.eof()){
auto line = chomp(config.readln());
if (line[0]!='#') { //skip comment lines
auto divided = split(line, ":");
if (divided[0] == extension) {
found = true;
auto command = "start " ~ divided[1] ~ " " ~ input;
auto result = executeShell(command);
//test for error code and output if necessary
writeln(result.output);
}
}
}
if (!found)
writeln("ERROR: Don't know how to open " ~ input);
}
From the top of the std.process documentation:
Execute and wait for completion, collect output - executeShell
The Windows start program spawns a process and exits immediately. D's executeShell does something else. If you'd like to spawn another program, use the appropriate functions: spawnProcess or spawnShell.
I want to read and write from serial using events/interrupts.
Currently, I have it in a while loop and it continuously reads and writes through the serial. I want it to only read when something comes from the serial port. How do I implement this in C++?
This is my current code:
while(true)
{
//read
if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL)){
//error occurred. Report to user.
}
//write
if(!WriteFile(hSerial, szBuff, n, &dwBytesRead, NULL)){
//error occurred. Report to user.
}
//print what you are reading
printf("%s\n", szBuff);
}
Use a select statement, which will check the read and write buffers without blocking and return their status, so you only need to read when you know the port has data, or write when you know there's room in the output buffer.
The third example at http://www.developerweb.net/forum/showthread.php?t=2933 and the associated comments may be helpful.
Edit: The man page for select has a simpler and more complete example near the end. You can find it at http://linux.die.net/man/2/select if man 2 select doesn't work on your system.
Note: Mastering select() will allow you to work with both serial ports and sockets; it's at the heart of many network clients and servers.
For a Windows environment the more native approach would be to use asynchronous I/O. In this mode you still use calls to ReadFile and WriteFile, but instead of blocking you pass in a callback function that will be invoked when the operation completes.
It is fairly tricky to get all the details right though.
Here is a copy of an article that was published in the c/C++ users journal a few years ago. It goes into detail on the Win32 API.
here a code that read serial incomming data using interruption on windows
you can see the time elapsed during the waiting interruption time
int pollComport(int comport_number, LPBYTE buffer, int size)
{
BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;
int n;
double TimeA,TimeB;
// Specify a set of events to be monitored for the port.
SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR );
while (m_comPortHandle[comport_number] != INVALID_HANDLE_VALUE)
{
// Wait for an event to occur for the port.
TimeA = clock();
WaitCommEvent (m_comPortHandle[comport_number], &dwCommModemStatus, 0);
TimeB = clock();
if(TimeB-TimeA>0)
cout <<" ok "<<TimeB-TimeA<<endl;
// Re-specify the set of events to be monitored for the port.
SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR);
if (dwCommModemStatus & EV_RXCHAR)
{
// Loop for waiting for the data.
do
{
ReadFile(m_comPortHandle[comport_number], buffer, size, (LPDWORD)((void *)&n), NULL);
// Display the data read.
if (n>0)
cout << buffer <<endl;
} while (n > 0);
}
return(0);
}
}