Re 0x0011

Return and security access

I finally returned from some blog laziness, since it took me over one month for a new entry. I did not plan to follow this expectable behavior, but what can I say, I didn’t used CAPL that much recently and also had not so much progress.

In the meantime, I tried to establish some security access functions to my simulation, but the conclusion is, that I‘ missing the right DLL file to include into CANoe, all other solutions would’ve been veeery time  consuming.

Who ever cares about security access (it is, as the name says a function with which e.g. diagnosis functions can be secured, e.g. erase memory functions), can read the following .pdf and is hopefully perfect prepared afterwards:

SN-IND-1-003_SecurityAccess_CANoe

But to just get some additional benefit for you, I prepared a schematic illustration, how security access should work in my opinion:

security_access_schematic

 

Write From file function

To start with another topic, as I described before, I implemented kind of a write-function, that reads a string and writes this to a .txt file (check out ‚ 0x0009 ‚).

Now I want to do the way round and read values from a (.txt) file, that I can use later on. We have the following problem description: we want to send some data to an ECU, some of the data is static, some we want to took from our input-string (lets say this would be value #67 out of our string).

First I tried it with this code:

case  1:    /* write memory */
            if(something);

      glbHandleWrite = openFileRead („test.txt“,0);

      if (glbHandleWrite != 0 && fileGetString(StringLongWrite, elcount(StringLongWrite), glbHandleWrite) != 0)
      {
      SendReq[0] = 0x11;
      SendReq[1] = 0x12;
      SendReq[2] = 0x13;
      SendReq[3] = StringLongWrite[66];  // because first string-value is equal to ‚0‘
      SendRequest(ServicePhys, 4);
      setTimer( TimeOutTimer, TimeOutLong);
      write („data %s“, StringLongWrite);
      break;
      }

      else write(„Data file cannot be opened „);

with the data in dataformat 0x01 0x02 0x03 … in a „test.txt“ file.

Of course this doesn’t worked out, since we need to convert the string "0x01"  (for example) to a number, eg. using the strtol() function.

The working function would be:

if (glbHandleWrite != 0 && fileGetString(StringLongWrite, elcount(StringLongWrite), glbHandleWrite) != 0)

     {

     pos = strtol(StringLongWrite, pos, data[66]);

SendReq[0] = 0x11;

SendReq[1] = 0x12;

SendReq[2] = 0x13;

SendReq[3] = = data[66];

SendRequest(ServicePhys, 4);

or, to put it in a more general way:

on start

message 0x123 msg; 

char StringLongWrite[32] = „0x01 0x02 0x03“; 

long data[2]; 

dword pos = 0;  

pos = strtol(StringLongWrite, pos, data[0]); 

pos = strtol(StringLongWrite, pos, data[1]); 

pos = strtol(StringLongWrite, pos, data[2]);  

write(„0x%02x,0x%02x,0x%02x“, data[0], data[1], data[2]);  

msg.dlc = 8;  msg.byte(0) = 0x42; 

msg.byte(1) = data[0]; 

msg.byte(2) = data[1]; 

msg.byte(3) = data[2];  

output(msg);

}

Thanks sergej from stackoverflow for this hint!

 

 

Re 0x0011

short update 0x0010

hey there, just a short update from my site to keep this blog running. lately I learned much new stuff, but also struggled a bit (I asked a second, I guess more specific question on StackOverflow which was not answered after 5 minutes and wasn’t even yet – so I deleted it after a while; so I would now rate this site from superduperextracool down to very very helpful).

there are just some things that have come to my mind and I want to share with you.

first thing is, I talked about this OSEK tp function to send and receive data recently in some former entrys.

I found this good example from another user from StackOverflow:

„Take a look at the OSEK_TP CANoe demo. It shows how to transmit and receive date over ISO-TP (Transport Protocol, ISO 15765-2). See the nodeA.can file and the OSEL_TP API reference for implementation details.

Here is minimal example:

Create and configure a connection:

long handle;
handle = CanTpCreateConnection(0);    // 0 = Normal mode
CanTpSetTxIdentifier(handle, 0x700);  // Tx CAN-ID
CanTpSetRxIdentifier(handle, 0x708);  // Rx CAN-ID

Send data:

BYTE data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
CanTpSendData(handle, data, elcount(data));

To receive data, you have to implement the following callback function:

void CanTp_ReceptionInd(long connHandle, byte data[])
{
    write("Received %d byte on connection %d: [%02x] ...",
            elcount(data), connHandle, data[0]);
}

You can also check out the „CCI_Implementation.cin“ that should hide somewhere in your CAN (Demo)folders. I think this should do it for the moment.

Another topic is, that for my latest release of simulation to colleagues I thought it was a good idea to create a changelog, to track changes in future. via Google I found this helpful (well, at least a bit funny) site:

keepachangelog .

So if you ever consider writing a changelog, this might be a good start.

Please note also, that I added a link, describing how to go with a CANAlyzer Demo-Version from Vector to test (without license or HW at least), some of the CANoe features (untested).
I hope it works.

 

 

short update 0x0010

meeting the community 0x0009

Dear everybody, yesterday and today were quite successful days for me. Since this is a blog, I will tell you how I first get in touch with programming community in my life (well, that is half the truth, once I registered for an National Instruments Labview forum, but never participated actively). It was quite easy: I registered myself at Stack Overflow, which is some kind of programming community/a platform for Q&A regarding programming questions.

The reason was, I don’t had a clue, how to proceed with the problem I wrote about some entries ago (read a buffer, while buffersize in total exceeds memorysize I can get with one request). I believe there are a lot of elegant solutions, including state machines, while/if/-statements etc, but since I’m a beginner, I prefer to stick with the „solid“ but complicated coding right now. Maybe at some point I have more knowledge to do it in a more efficient way.

So my idea was, registering at Stack Overflow and ask my question(s). Registration was quite easy, and the steps to finally ask my question self describing.

CAPLQ

A very short time after my question, I got really good help from 2 guys (thanks at users @Shark @Lundin):

CAPLA

 

with which help I was able to build my working code (I segregated my memory-read function in [n] functions, where n = triggered from function n-1 via on timer trigger):

 

variables

{
  msTimer ReadReqTimer;
  …
  msTimer ReadReqTimerN;
  int ReadTimeDef = 1000;  // 1 second timer (when used as msTimer as stated above)
 
  byte rqBuffer[256];     // request buffer (Tx data) – 256 bytes
  byte rsBuffer[256];     // receive buffer (Rx data)
  byte rsBuffer1[256];   // help buffer for reiceiving 1
  …
  byte rsBufferN[1024];         // help buffer for receiving N
  char Outputstring[2048];  // array/buffer for output function
  int diagnosticaction = 0;    // value for different diagnosis cases/actions
  dword glbHandle = 0;         // handling of output function
 
}

void Diagnosisrequest ( byte diagnosticaction) /* I have built different cases for different diagnosis actions here */
{
  case  1:   /* case1: read memory */
… /*some code for validation in between*/
        {
 rqBuffer[0] = 0x01;  /* I defined the data transferred with a send request via CAN msg (transport via OSEK fct) */
 rqBuffer[1] = 0x02;  /* this would be data 01 02 03 04 (lets assume this would be a function to read my memory) */
 rqBuffer[2] = 0x03; 
 rqBuffer[3] = 0x04;

         … /*some code for sending this request via OSEK fct*/
 
        setTimer (ReadReqTimer, ReadTimeDef);         
      }

break;
}
on timer ReadReqTimer
{
   if (condition) /* a condition for validation of Response */
     {
          
        /* start last request:   analog you would define your requests 2, 3, 4..n, like how much steps do you need. */
 diagnosticaction = XYZ;  /* see definition below*/
         rqBuf[0] = 0x01;
         rqBuf[1] = 0x02;  
        rqBuf[2] = 0x03;
        rqBuf[3] = 0x05; /* this would be data 01 02 03 05 (lets assume this would be a function to read another part of memory) */      

         … /*some code for sending this request via OSEK fct
       setTimer ( ReadReqTimer1, ReadTimeDef);  // set next timer … ReadReqTimer1, 2, … n
       
     }
}
void handleResponse
{
 switch(diagnosticaction)
     {
    case  0: /*some other case, e.g. no action*/
    break;
  case  1:  /* read memory */
   if (rsBufer[0] == 0xXYZ)  // XYZ would be a hex-number (e.g. 01), for checking a valid incoming response message
           {
           memcpy(rsBuffer1, rsBuffer, 1024);
            }
   else if (condition)
doSomethingorDoNothing;
   break;   // brake statement, this is important to terminate case
 
     
     
      case XYZ:  /* our latest case for memory-read – copy together the buffer from former response Buffers and print it to a file (see also former blogentry) */
       if (rsBufer[0] == 0xXYZ)   /* XYZ would be a hex-number (e.g. 01), for checking a valid incoming response message */
           {
            memcpy(rsBufferN, rsBuffer, 1024);
            glbHandle = openFileWrite („filename.txt“,0);   /* Format and print buffer data */
            snprintf(Outputstring, elcount(Outputstring), „memory read:  %02X %02X %02X % 02X %02X %02X\n“, rsBuffer1[1], rsBuffer1[…], rsBuffer1[n], rsBufferN[1], rsBufferN[…], rsBufferN[n]);
    filePutString (Outputstring, elcount(Outputstring),glbHandle);
    fileClose(glbHandle);
   }
   else if (condition)
   doSomethingorDoNothing;
   break;   /* brake statement, this is always important to terminate case */

       }
}

 

 

 

 

meeting the community 0x0009

receive one Msg, send another Msg 0x0008

Hello everybody,

in the last days I was working more on other things, but now I just returned for some more small CAPL action.

For first time I had the problem to send a CAN Msg, when I receive another CAN-Msg (because for the moment, most of my diagnosis node based on: sending a request/Msg — data will be send (Request/Tx) and received (Response/Rx) via OSEK function–> analyze the Rx data)

I knew which data this should be (I looked for it in the trace), because I wanted to actively send it from a node as a substitute CAN frame for another node I deactivated, and where this signal originally comes from.

You can also find some help for this in the ‚ ProgrammingWithCAPL ‚ by chapter 11.3.

so lets say in trace I have seen, that I want to transmit data with ID 789, Data DLC is 4 and data is 0x01 0x02 0x03 0x04. Than one solution would be the following:

variables  /* declare Msg in the variables section */

{

message 0x789 myNewMsg = {dlc = 4};

}

on message TriggerMsg /*as you know, CAPL is not time- but event based. For trigger, in this case I choose another CAN Msg, that should be there if my new signal is also there; „on message“ is a CAPL function, „TriggerMsg“ is a example-name */

{

 myNewMsg.byte(0)= 0x01;

 myNewMsg.byte(1)= 0x02;

 myNewMsg.byte(2)= 0x03;

 myNewMsg.byte(3)= 0x04;

output(myNewMsg);

}

 

 

 

 

receive one Msg, send another Msg 0x0008

graphic panel 0x0 007 (hey there James!)

I’m just having some more time on a travel, so lets use it for some more content.
I’d like to introduce my gfx panel, with which I plan to handle my functions.
Since you can imagine, its much more easier to control your messages and functions with a graphical interface, than tiping code in a console er something.
so this is a working screen from my panel:

panel1
You will know, that you can create or modify panels with the ‚Panel Designer‘ (which is for instance be included with CANoe full version -> Tools Panel Designer)
The view from Panel Designer is pretty much the same, as its later on on the screen.
So how do we create a button, that is connected to a message in a CAPL node, we’d like to send via CAN?

It’s not that hard. Lets for example take the „ECU reset“, since this is a simple function.
– First of all, its important to create variables in CANoe, you will later link in the panel. Its really strong recommended from Vector, that you create well defined variables in tables (e.g. as system variables), because you might share your code with colleagues or even work on it together. If you just define variables somewhere in the code, it might get really confusing in the end.
ya da da, ya da da, you can read this whole stuff in the documents I linked in my „First Aid Section“, so no need I tell you)
To do so, go to CANoe -> Configuration -> system variables.
You can now add User-Defined variables.

systemvar1
Fill in a Namespace, e.g. „myCAPLmsgs“ and than name the variable in some kind you will know what they mean, for our example maybe „EcuReset“.
You can also edit your variable that it fits your needs. For a button, we just need an Integer (for an on/off button, no further values have to be set).
– go to a the Panel Designer and grab a button and drag it somewhere
– the most important thing now is, that you assign your button to the variable you defined.This can be done under the properties/symbol -> choose ‚System Variable‘ (the one you created before)
– now you can  connect your button to CAPL code: in CAPL browser:

on sysvar sysvar::Namespace::Name /* (Namespace + Name are the attributes of the system variable you defined before in CANoe) */
{
 SomeCodeToDoSomething;
}

You can load the panels after you created them via ‚Configuration -> Panels‘, and, if they’re already implemented in your configuration file via ‚View->Panels‘.

graphic panel 0x0 007 (hey there James!)

finally some working code 0x0006

today I solved one of my problems.

of course I will also provide you my solution. It was the simple question, how to write some data into a textfile for later analysis.

variables
{
byte buffer[1024];   // receive buffer for CAN-data via OSEK_tp.dll (1024 byte)
char StringLong[howeverlongyouneedit];  // for output string
dword glbHandle = 0;
}
OSEKTL_DataInd (long rxCount) /function to receive data via OSEK_tp.dll
{

[some code…]

OSEKTL_GetRxData( buffer, rxCount );
EmpfangAuswerten(rxCount);

[some code…]

}

/*with the OSEK function, we’re able to send and receive data directly to an addressed ECU. That said, if we do a diagnosis request to our ECU and read the memory by Address, the cells  of the memory are looking like this: Address: 0x0000, 0x0001, …. ; data: 0x00 … 0xFF. So this would be memory size of 1. We can handle this via a PDU command which looks like (naaah, I wouldn’t tell you, I guess its very specific, lets just say its looking like) 11 22 00 00 01 00 01, where some of the fields gives us the address (e.g. 01 00 = #256) and the „01“ at the end a memory size of 1.*/

/*[send a Request to ECU – read memory – e.g. 4 cells Memory]
[receive Response – e.g. 00 01 02 01] ; response is written in „buffer“*/
glbHandle = openFileWrite („testreport.txt“,0);

/* Format and store the data */
snprintf(StringLong, elcount(StringLong), „bufferdata: %02X … %02X\n“,buffer[1], buffer[2], …, buffer[i]); //in this case i = 4

/*I did it the way that the number of „%02X“ equals number of „i“ — which is veeery complicated when you want to read >> 100 byte) */
filePutString (StringLong, elcount(StringLong),glbHandle);
fileClose(glbHandle);

finally some working code 0x0006

a solution? 0x0005

alternative title: the internet is a treasury

yesterday I found a document in the internet with a bunch of code, that looks pretty much like the things I’m planning.
The title from the file is „Codigo del Proyecto“ which is spanish I assume and just means „project information“. It contains just code for a CAPL-Node
„X10_Tester.can“. So nobody I can praise, ask for permission or whatever. I’m okay with that 😉 Since it was found in Google, I think it is okay, to upload it here (whoever did the coding: thanks anyway!)

Codigo del Proyecto

As we see from the Node-title, it would likely provide us some information about tester functionalities. Which is pretty damn cool, since I’m also planning to do a tester/diagnosis node for my simulation.

Go with the file, I leave it uncommented so far (I’m far from understanding everything).
Its too big, to copy the code to our blog.
Maybe some lines are helpful.

I’m personally trying some of the filePutString-things so far for me, because for my string they’re not working at the moment:

void filewrite_C()  
/* this function is used somewhere else to process a string is written into a file */
 {
 glbHandle = OpenFileWrite ("report123.txt",0);
 if ( glbHandle!=0 )
 {
filePutString (buffer, elcount(buffer),glbHandle);
 fileClose (glbHandle);
 }
 }
ERROR: types of parameters do not match.
buffer: initalisation see below:
variables
 {
 byte buffer[1024]
 }

and than used in an OSEK transport function (more soon).

a solution? 0x0005

a problem 0x0004

ok, lets see what we got.

First of all, lets have a look on my Simulation Setup:

configuration

you see its very simple,

  • a (our) component (=ECU), which is disabled at the moment (this was one of the first and the best shortcuts I ever learned in CANoe, selecting a node pressing ‚SPACE‘ bar to activate/deactivate) due to the reason that I use a real component with same behavior on my desk,
  • a node for all of the rest of car functions and
  • a diag-node (the one we want to design and implement in CAPL code) which will provide us some diagnosis functions and I/O control with a graphic panel

So just straight to my biggest problem at the moment, before I will briefly describe some other code:

A .cdd file (CANdela file) describes diagnosis services you can do with a component. In my case one service is that you read the internal memory by address. (ReadByAddress). This service would be quite useful in reading the whole memory, which is a function I want to realize.

Now the difficulty: this service is just defined with a memory size of max 256 bytes. memory contains about 20 times this seize. How to read memory with this function? I thought about doing some loops or a request after a request, but after all, it seems not be that easy..

For this I asked Vector support, and the answer was either doing some state machine, or defining a test module (which I heard and read something about, but can not do it right now). The propose was to use some code like its in the example „Diagnostics\UDSSim\Tester\Download.cin“… well.. fine.

 

 

 

a problem 0x0004

mind the gap

I’m still very existed about my new blog but I’m afraid today isnt enough time to provide some more input.

So i will just upload 4 files I currently used in my actual project (at least more or less) and we will talk about it later this week (by any chance on Wendnesday I guess :] ).

AN-IND-1-001_CANoe_CANalyzer_as_Diagnostic_Tools

AN-IND-1-002_Testing_with_CANoe

AN-IND-1-012_CAPL_Callback_Interface

SN-IND-1-015_CANoe_CANalyzer_Padding_DiagnosticFrames

(all provided and copyright by Vector)

See you R

mind the gap

keep the pace

So yesterday was a quite successful day (not only in personal, recover from a cold) but specially for my BLOG. I got the first follower (cheers @seppolog) which was made me thinking „woohoo“ when I logged in on wordpress today.

So no need in slowing down now 😉 I hope if I’m looking at this screen in one year, there will be hundreds of blogentrys (ok lets be realistic, I think 2-3 per week would be fine).

So first of all I’d like to talk about the work I’m doing right now. as you can see in my ‚About‘ I’m in the automotive industry, I’m closely connected to one electronic control unit (ECU) as one component of the whole car-architecture. Some device from the field of telematics.

As my company supplies this component to an OEM, my job is to keep it running at customers side. Therefor, future tasks (in timeline, we have still way to go to series prodcution) are much about analysing the behavior, specially when there are errors detectet.

Which programm could be more useful in the car architecture environment as Vectors CANoe? (I guess none?). Anyway, I will have to deal with it (and its quite interesting).

So this are the facts for my first (and guess more ore less all-time) project:

  • running CANoe full license 8.2. which connects me to CAN architecture via VN1610 CAN device
  • different residual bus simulations, created by colleagues, the customer or others – describing the behavior of the whole car, or important parts that interact with our device
  • one simulation I created on my own (basically I will work on that one, but the others were quite useful to understand how some things are done)  – created with Vectors Model Generation Wizard (for me it was just organizing some files, reading a document and pressing some buttons, so nothing I could ever write about). In fact I think that the MWG is a really cool add-on from Vector (if you know what you’re doing ;))
  • a CANdela .cdd file, with could be included, and with which diagnosis of the component is possible
  • a device on my table

Soon I’m gone provide you finally some code (I will try to remember how I started, to have a realistic impression on my CAPL journey – since than I improved a bit, but not that much I guess ;p)

keep the pace