I am new in CANoe, and also CAPL language. But I want to ask you:
How can I send a message with CAPL on the network of ECU's. For example: I want to send an Hex number( it is a question for an ECU) and after that I want to see the response of this question.
I don't know if I was very clear but, if you have any answers I would be grateful.
Sending message in CAPL
You can send a message (or multiple messages) on any event,
for example, a keypress, the reception of another message, the reception of an error frame, or a timer expiring.
Sending an event message involves creating an event procedure, declaring a message to send, and sending the message in the event procedure.
The message can be declared as a global variable so that it can be accessed in any event procedure.
As shown in the message object section, you can declare a message’s structure in your program or you can use an associated database.
In this example, we will declare one of each in the Global Variables window
variables
{
message EngineData msg1; // Defined in database
message 0x101 msg2; // Standard message 101 (hex)
message 0x105x msg3; // Extended message 105 (hex)
}
Now, to send a message, we only need to put one of these lines into an event procedure:
output(msg1);
output(msg2);
Of course, we can also add data to the message before we send it.
The EngineData message has signals defined in the database, but the other message does not. Therefore, we have to use two different methods to add data to the messages.
msg1.EngSpeed.phys = 1000;
msg1.EngTemp.phys = 150;
msg1.IdleRunning = 1;
output(msg1);
msg2.DLC = 4; // Allocate 4 data bytes in msg2
msg2.byte(0) = 0x16; // First word is 16 hex
msg2.byte(1) = 7; // Second word is 7 decimal
output(msg2);
Responding Message
on message 0x101 // This is the identifier of your response
{
if(this.byte(0) == 0x16)
{
write("Response is the expected!");
}
}
or
on message msg2 // This is the identifier of your response
{
if(this.byte(0) == 0x16)
{
write("Response is the expected!");
}
}
You can use as given below,
variables
{
message BCMmsg01 msg_BCMmsg01; // declaration of message into a variable
}
on key 'z'
{
msg_BCMmsg01.C_AutoLockCmd = 3; // assign the value to the message
output(msg_BCMmsg01); //send the message to the CAN bus
}
Hopefully I clarified your question. Let me know if you need more clarification.
Joe showed the way the message (in this case the hex value) is sent. If you want to see the response, you need to know the response ID (for example 0x62C)
on message 0x62C /* This is the identifier of your response */
{
if(this.byte(X) == 0xYY) { /* X is the byte of the response you are interested and Y the value of that byte*/
write("Response is the expected!");
}
I hope this answers your question.
Related
I am using CANoe 11.0 to send a signal value from a button.
I have a message from a CAN db with 6 signals, 8 bits for each signal. The message is cyclic but with a cycle time of 0ms, so, in order to send it, I figured out I need a button. But everything I tried so far doesn't work.
eg:
on message X
{
if (getValue(ev_button) == 1)
{
X.signalname = (getValue(ev_signalvariable));
}
}
or I tried working on the signal itself:
on signal Y
{
if (getValue(ev_button) == 1)
{
putValue(ev_signalY,this);
}
}
The issue you are having is due to the callback. Both on message and on signal callbacks happen when that message or signal is updated on the bus.
In your code, you expect to update a signal, if you pressed a button, but only if you detect that signal was updated in the first place. Do you see the loophole?
To fix this, you may create a system variable, associate that with the button (so that it is 0 = not pressed and 1 = pressed), then use the on sysvar callback:
on sysvar buttonPressed
{
// prepare message
// send message
}
I assume you already have something like message yourMessage somewhere, and that you know the name of the signal from the DBC and that the DBC is linked to your configuration. So you'll need to:
// prepare message
yourMessage.yourValue1 = <some value>
yourMessage.yourValue2 = <some other value>
// ...
// repeat for all relevant signals
and then
// send message
send(yourMessage)
Google docs propose the following model (https://cloud.google.com/apis/design/errors#error_model) for sending rich errors in gRPC but it seems that the error string is sent to the user every time. What I want to do is to send a code and then map it to a string when it reaches the client.
What I want to know is whatever the proto3 language supports writing data so that I would use it client-side, without defining a custom structure for the purposes of mapping error codes to error messages.
In your proto definition, define a simple enum with any extra error codes:
enum extraStatusCode {
UNKNOWN = 0; // not set/used
TOO_MANY_FOOS = 1;
NOT_ENOUGH_BARS = 2;
}
And include it as a top-level field in any returned message:
message User {
string uid = 1;
string email = 2;
// ...
extraStatusCode = 15;
}
if a message is sent with a non-zero extraStatusCode - then an edge case was encountered.
I'm wondering if it is possible to create a CAPL code in which, by using "on key" feature, the user may:
- activate a replay mode (.asc file)
- activate a filter on it
- activate additionally a specific signal (not present in asc files)
- deactivate the replay mode
- deactivate the specific signal
- activate or deactivate alternatively specific messages and/or trace
In detail, for the moment I am using this one:
/*#!Encoding:1252*/
variables // declaration of the specific messages I need
{
message MESSAGE01 msg_MESSAGE01 ;
message MESSAGE02 msg_MESSAGE02 ;
}
on key 't' // here I'd need the activation of a replay block in .asc format with a filter on a specific message
{
// Really don't know how to insert here
}
on key 'd' // here I'd need the deactivation of a replay block in .asc format
{
// Really don't know how to insert here
}
on key 'p' // specific signals deactivation
{
msg_MESSAGE01.SIGNAL01= 0; // assign the value to the message
msg_MESSAGE02.SIGNAL02 = 1; // assign the value to the message
output(msg_MESSAGE01); //send the message to the CAN bus
output(msg_MESSAGE02); //send the message to the CAN bus
// output(output of the asc file); // if activated, I'd like to see in output all the messages of the .asc; if not, I'd like to see just those specific signals.
}
on key 'u' // specific signals deactivation
{
// msg_MESSAGE01.SIGNAL01 = none; // here, I'd like to "unset" the value
msg_MESSAGE02.SIGNAL02= 0;
output(msg_MESSAGE01);
output (msg_MESSAGE02);
// output(output of the asc file); // if activated, I'd like to see in output all the messages of the .asc; if not, I'd like to see just those specific signals.
}
If not clear, I'm available to explain better my request :)
Thank you in advance ^^
Cheers
Welcome to StackOverflow!
You can actually activate a replay block (at least on CANoe, please have a look for compatibility on CANalyzer).
I'd need the activation/deactivation of a replay block in .asc format
variables
{
char replayName[32] = "ibus_data";
}
on key 'b'
{
replayStart( replayName);
}
on key 'e'
{
replayStop( replayName);
}
on key 's'
{
replaySuspend( replayName);
}
on key 'r'
{
replayResume( replayName);
}
on key 'w'
{
writeReplayState( replayName);
}
void writeReplayState( char name[])
{
switch ( replayState( name))
{
case 0:
write( "Replay Block %s is stopped", replayName);
break;
case 1:
write( "Replay Block %s is running", replayName);
break;
case 2:
write( "Replay Block %s is suspended", replayName);
break;
default:
write( "Error: Replay Block %s has an unknown state!", replayName);
break;
};
}
You'll have to configure the replay file beforehands, and the filter part requires a different solution. For more information, check the reference and this example: ReplayStart, ReplayStop, ReplaySuspend, ReplayResume, ReplayState
From: CAPL Function Overview » General » Example: ReplayStart, ReplayStop, ReplaySuspend, ReplayResume, ReplayState
specific signals activation/deactivation
One "hacky" solution that pops into my mind, it to have a flag system in place. Of course, ugly solution, probably there is something better at hand. Try something like:
on message myMessage
{
if (flag)
output(myMessage)
}
on key 'u'
{
flag ? 0 : 1 // short for: toggle the status of the flag
}
Please let me know if this helped.
Regarding this piece of code:
on key 'p' // specific signals deactivation
{
msg_MESSAGE01.SIGNAL01= 0; // assign the value to the message
msg_MESSAGE02.SIGNAL02 = 1; // assign the value to the message
output(msg_MESSAGE01); //send the message to the CAN bus
output(msg_MESSAGE02); //send the message to the CAN bus
}
Please note that it won't do what you expect. You are asking to send the message on user keyboard action. If the message was already set for cyclic output, it will continue to go with the clock and an extra publish will be made on keyboard. Otherwise, message will only be published once.
The proposed solution works with a flag in the on message *, that, in turn, works as a filter, blocking the message and repeating it only if the flag is set.
You can just add Replay Block to the bus, and in configuration type specified start/stop key. Specified signals activation/deactivation can stay as you wrote it.
I have Protocol Buffer for logging data.
message Message {
required double val1 = 1;
optional int val2 = 2;
}
message BigObject {
repeated Message message = 1;
}
I receive messages one per second. They stored in memory with my BigObject and they used for some tasks. But at the same time i want to store that messages in file for backup in case application crash. Simple writing BigObject every time will be waste of time. And I trying to find way to write only added messages since last write to file. Is there a way for that?
Protobuf is an appendable format, and your layout is ideal for this. Just open your file positioned at the end, and start with a new (empty) BigObject. Add/serialize just the new Message instance, and write to the file (from the end onwards).
Now, if you parse your file from the beginning you will get a single BigObject with all the Message instances (old and new).
You could actually do this by logging each individual Message as it arrives, as long as you wrap it in a BigObject each time, i.e. in pseudo-code
loop {
msg = await NextMessage();
wrapper = new BigObject();
wrapper.Messages.Add(msg);
file = OpenFileAtEnd();
wrapper.WriteTo(file);
file.Close();
}
As with most "legacy" MSDN pages, the page for ReportEvent has too little information for me to make much sense of it. I've tried searching, but can't find a good, clean, simple example of the function's usage. Could anyone suggest one?
I ended up using this:
HANDLE eventLog;
WORD type;
const char* msg;
// ... snip ...
ReportEvent(eventLog, type, 0, 1, NULL, 1, 0, &LPCTSTR(msg), NULL);
Seems to work well enough.
Well this seems to be a very old thread, landed here looking for a good example of Report Event... but figured out you have not received any replies...and would have probably already found the solution.
The reason you see "Event Id not found" is because the EventViewer is not able to load/lookup the text resource to be displayed for the event Id. Sorry if last line sounded geeky.. but this is what i understand of EventLog:
-EventLogging has two aspects
Registering with EventLog (or in other terms creating EventSource)
Logging or Writing into Event Log
Viewing or Reading from log
When you register in event log, you simply specify a eventSource (any name that identifies that log) + EventMessageFile, Category File and SupportedEventTypes. Here EventMessageFile points to a DLL/EXE that contains your message descriptions/resources.
When you log an event, you simply log it with some data like EventID, Category ID and EventData. But when you view it using any EventViewer (or Windows eventVwr.exe) the viewer reads your events, looks for a DLL/EXE associated with your eventSource(pointed by EventMessageFile), and renders the decription from the resource section of that DLL/EXE.
This DLL is nothing but a simple resource file that was compiled using MessageCompiler, and contains a "MessageTable". This is done to provide culture specific event logging
This is the reason, When you export the log into XML/TXT etc from your EventViewer, It asks you if you want to Save it "with Display informaion" or "without display information", so that you can view it on computers that do not have EventMessageFile.
JFYI the reg entry is located at:
HKLM\CurrentControlSet\System\Services\EventLog\Application
one catch: If you're wondering how .Net does it..., it simply does it by providing a default EventMessageFile called EventLogMessage.dll (found under %SYSTEMROOT%\Microsoft.Net\Framework\vXXXX\)
As I recall it is a pain to set up correctly - you need to add messages to you application using the Message Compiler - if you skip this you won't see useful messages only error codes. Take a look at Creating a Windows NT Service by Using ATL for an example
The sample Windows Service C++, is a windows service reporting to event log, you can get the code from https://code.msdn.microsoft.com/windowsapps/CppWindowsService-cacf4948
in particular, the following function (quoted from ServiceBase.cpp) does it
//
// FUNCTION: CServiceBase::WriteEventLogEntry(PWSTR, WORD)
//
// PURPOSE: Log a message to the Application event log.
//
// PARAMETERS:
// * pszMessage - string message to be logged.
// * wType - the type of event to be logged. The parameter can be one of
// the following values.
//
// EVENTLOG_SUCCESS
// EVENTLOG_AUDIT_FAILURE
// EVENTLOG_AUDIT_SUCCESS
// EVENTLOG_ERROR_TYPE
// EVENTLOG_INFORMATION_TYPE
// EVENTLOG_WARNING_TYPE
//
void CServiceBase::WriteEventLogEntry(PWSTR pszMessage, WORD wType)
{
HANDLE hEventSource = NULL;
LPCWSTR lpszStrings[2] = { NULL, NULL };
hEventSource = RegisterEventSource(NULL, m_name);
if (hEventSource)
{
lpszStrings[0] = m_name;
lpszStrings[1] = pszMessage;
ReportEvent(hEventSource, // Event log handle
wType, // Event type
0, // Event category
0, // Event identifier
NULL, // No security identifier
2, // Size of lpszStrings array
0, // No binary data
lpszStrings, // Array of strings
NULL // No binary data
);
DeregisterEventSource(hEventSource);
}
}