canopennode / canopennode Goto Github PK
View Code? Open in Web Editor NEWCANopen protocol stack
Home Page: https://canopennode.github.io/CANopenNode/index.html
License: Apache License 2.0
CANopen protocol stack
Home Page: https://canopennode.github.io/CANopenNode/index.html
License: Apache License 2.0
My company is writing ARM code for the Kinetis K20. This is the platform also used by PJRC's Teensyduino.
I've written a driver for the K20 and so far it seems to be working great. I've commited the driver to a local branch, if you want to give me push access I'll add it and create a pull request so you can look it over.
Disclaimer: I've commented the code so it's reasonably legible, but I haven't cleaned it up to ensure it meets all the coding style guidelines. I've tested SDO, HB, and HB consumer but not PDO.
I may be not understanding the way this is suppose to work but if i have a domain variable and i want to transfer a bigger buffer than CO_SDO_BUFFER_SIZE then it fails with an SDO abort of CO_SDO_AB_DEVICE_INCOMPAT
I have defined a OD access function via CO_OD_configure() and then i am doing the following in my function :-
if(ODF_arg->reading)
{
ODF_arg->dataLengthTotal = com1_buffer.count;
ODF_arg->dataLength = com1_buffer.count;
ODF_arg->data = com1_buffer.buffer;
}
So i have updated the data pointer to point at my buffer and set the sizes
if i set the ODF_arg->dataLength > CO_SDO_BUFFER_SIZE then the SDO transfer fails. If i remove the check on line 641 of CO_SDO.c which says :-
/* dataLength (upadted by pODFunc) must be inside limits */
if((SDO->ODF_arg.dataLength == 0U) || (SDO->ODF_arg.dataLength > SDOBufferSize)){
return CO_SDO_AB_DEVICE_INCOMPAT; /* general internal incompatibility in the device */
}
then it works perfectly and i get all bytes transferred by SDO (in my case a segmented sdo transfer)
Reading the comments on CO_SDO.h around line 323 it states
* Size must be at least equal to size of largest variable in @ref CO_SDO_objectDictionary.
* If data type is domain, data length is not limited to SDO buffer size.
So that comment would suggest that the above check should not be present for DOMAIN type variables?
Have i made a mistake with my implementation or is this a bug?
Thanks!
Using the ODE based on XUL files didn't work for me after many hours of research.
So I started to develop a new ODE written in python3.
Hopefully this will make scripting really easy.
You can see my working copy at ExMachina repository
I'll make a PR once it's usable. Right now only the data structure and the configuration file is working.
Comments and remarks are welcome.
Best regards,
Ben
I apologize if I posted this question at wrong place. I tried to find your email address but not succeeded. So posted a question here.
I want to use your code in binary form in my commercial product. Can I use it? I have read the terms of GPL2 but it is confusing so I decided to ask you directly.
Are Microchip PIC 18's supported?
It would be useful to just have a section in the Readme.md file which states that the library can be used in commercial projects. I read the License description but was still unsure if it really allows to use it in a commercial project. But fortunately I found the discussion in the forum (https://sourceforge.net/p/canopennode/discussion/387151/thread/b7910450/) which discusses the issue.
So to make this more obvious to anybody a extra section would be helpful.
hi
i wana use canopennode stack for stm32f4 to control other devices(servers or slaves) via sdo Protocol
but I've afew problem about it.
1- what is the process for config sdo?
2- what is the process for sending a sdo massage and check the respond packet for being sure about that writing to object dictionary of slave done correctly ?
3- I cant find any practical help or pdf for using this stack
thanks for helping me
So, today I tried to compile the sample code for the STM32. There are a lot of build errors so I will try to fix them and add a pull as soon as possible. But first I had a question concerning CO_init(...)
So in the latest Version of the stack this function uses some fixed prototype of
CO_ReturnError_t CO_init(
int32_t CANbaseAddress,
uint8_t nodeId,
uint16_t bitRate)
{
So the problem here is that an STM32 has some different type here. It would be better to use CAN_TypeDef *CANbaseAddress, for STM32. But thats not possible because CO_init isn´t a driver part function. So what was your idea here? I the driver template there is some hit... could be different for other microcontroller. But then you use a fix int32_t.
The only solution here is to use a mapping in the driver...
CAN0 => CANbaseAdress 0x1 => mapps to CAN_TypeDef CAN1 in the function.
CAN0 => CANbaseAdress 0x2 => mapps to CAN_TypeDef CAN1 in the function.
or use some preprocessor magic.
cheers
mathias
Hey,
I'm testing with the Conformance Test Tool and observe a strange behavior at Test PDO 26, the test tries to map too long objects. However, the error bits are set in object 1001, for the other error tests e. g.: PDO 25 (too many objects) this does not happen. The reason for this is that the function CO_RPDOconfigMap
is executed in line 630 of CO_PDO. c, which is not executed in the other tests.
Is that a bug? The error bits are not reset anywhere except during reset.
I'm trying to implement a few variable-length strings in the Object Dictionary (read-only, so SDO upload).
What's the recommended way of going about it?
@martinwag: what I'm trying to do is read (among other things) the software version just like you posted here, would you care to share how you did that? Did you implement some custom OD function or do you just patch CO_OD.c before compiling?
Thank you!
As mentioned here (https://sourceforge.net/p/canopennode/discussion/387151/thread/397f3912/) I'm in the process of implementing LSS.
I've pushed a first version to my local repo in lss branch (https://github.com/martinwag/CANopenNode/tree/add-lss). Feel free to have a look, but be aware that this is still experimental. If you find errors or have other hints, please let me know :-)
Current features
Current limitations:
My application requires that I independently control two motors via two independent CAN buses (latency concerns on single bus). I'm using Linux and socketCAN.
I'm looking at the CANopenNode library and it appears that it provides a nice implementation, however it also appears that I can only use a single CAN interface per application. Is this correct? I am guessing I would need to modify the library to support multiple interfaces? Or is there a cleaner way to approach this?
FYI - I searched the discussion forums on SourceForge and found a thread from 2014 (https://sourceforge.net/p/canopennode/discussion/387151/thread/04054e35/?limit=25#37dc). Is this still true? Best approach would be to modify and implement multiple COO globals? If so, is this something that may be desirable for the masses, thus would require me submitting a pull request?
Thanks!
I’m using CANopenNode for an actuator project. Asynchronous RPDOs work fine. However, I noticed that some synchronous RPDO commands were getting lost. It looks like CO_RPDO_process() clears the CANrxNew flags every time it is called, rather than just when the sync flag is set and the RPDO processed. The main loop calls CO_process_SYNC_RPDO() once every one millisecond tick. If the sync message arrives once every 10ms and the RPDO arrives at some random time between syncs, there would be a 90% chance of the function resetting the new flag without processing the RPDO. I’m wondering if this is a bug or I’ve misunderstood something. Thanks.
I am very much interested in implementing CANopen with the CANopenNode project.
I am currently analyzing canopend to analyze CANopenNode, but there is one question.
This is related to operatingState when reconnecting CANopen cable.
My environment is as follows.
CANopen PLC : LS's XBL-CMEA(NodeId:127)
canopend : mcp2515 + mcp2551(NodeID:77)
I have registered canopend's CANopenSocket.eds file in XBL-CMEA.
Below is a diagram of the network situation in XG-CANopen, a related program of XBL-CEMA. (XG-CANopen is a control program of XBML-CMEA)
I have a CAN to USB (CANtact) product for debugging CANopen.
I use this USB to check the can-bus data.
Now connect the cable and run canopend to send the heartbeat signals as shown below.
Here, when I unplug the canopend cable, the following repetitive data appears.(Output data of XBL-CEMA)
If the cable is reconnected, canopend will not enter the operation state while repeating the same communication as the image below.(pre-operation state)
https://youtu.be/IgOp8XYmlrI
And PDO communication is not possible either.
I thought that reconnecting the cable to the canopend device would restore the operation and communicate smoothly.
In case of canopencomm 'reset communication' signal, communication is restored.
I wanted the communication to be automatically restored upon cable connection without going through canopencomm.
So I modified the source as shown below.
KwonTae-young/CANopenSocket@e01be10
When I tested it, the communication was restored automatically when the cable was connected.
https://youtu.be/bepekqQ_NdQ
I implemented it as if I did reset comunication in canopencomm in that part for testing.
Is reset communication the only way to recover communications in this situation?
Is this the best way?
I am a beginner in canopen.
I'm sorry if it was a basic question.
I'm sorry I do not have enough English. :)
Thanks!
It is my understanding that this should be possible, and doing it should reset the error counter.
I also found this piece of code that suggests this has been thought of at some point.
If I try to do this write, the function above never gets executed, instead CO_SDO_AB_READONLY error is thrown here
This happens even though OD entry for this register in initialised like this with attribute of 0x8E and never changes. (Note that CO_ODA_READABLE == 0x04)
What happens is that when the object for this registered is fetched from the OD the attribute member is populated with this function that makes sure that subindex zero is never written to.
Hi folks,
CO_PDO.c lock/unlock as below are needed, no ?
int16_t CO_TPDOsend(CO_TPDO_t *TPDO){
:
/* Copy data from Object dictionary. */
CO_LOCK_OD();
/* Prevent mid-use multibyte object dictionary item alter by interrupting item write */
for(; i>0; i--) {
*(pPDOdataByte++) = **(ppODdataByte++);
}
CO_UNLOCK_OD(); /* Allow object dictionary item alter */
:
}
This to prevent for example, interrupt when only one byte of a uint16 object has been copied,
then an interrupting user-code function updates the uint16 in the OD, then the above code
resumes and copies the second byte. Resulting in, the sent uint16 comprising an old and new byte,
which do not necessarily form a coherent whole, for the usage in question. At least, if you have an
interrupting routine that writes to the OD, as I have.
Of course, the same applies to any interrupted multibyte object copy. Such as a float, or a string
(max 8 bytes): If part old bytes, and part new bytes, are copied, the resultant sent whole might not
necessarily be coherent. Or even legitimate, for a float.
In CO_driver.h, lock/unlock macros defined for example thus:
#define CO_LOCK_OD() __disable_irq( ); /**< Lock critical section when accessing Object Dictionary */
#define CO_UNLOCK_OD() __enable_irq( ); /**< Unlock critical section when accessing Object Dictionary */
Presently the stack uses just in SDO.c as below, same reason I'd guess:
uint32_t CO_SDO_readOD(CO_SDO_t *SDO, uint16_t SDOBufferSize){
:
/* copy data from OD to SDO buffer if not domain */
if(ODdata != NULL){
CO_LOCK_OD();
while(length--) *(SDObuffer++) = *(ODdata++);
CO_UNLOCK_OD();
:
Best regards,
David
When doing a SDO block upload and immediately after that starting another SDO request, this request is dropped.
This happens e.g. in the CANopen conformance test tool when checking SDO test 19 followed by 21. This is equivalent to the following linux commands
#do SDO upload block
cansend can0 67f#a0.00.10.00.14.00.00.00
sleep 0.1
cansend can0 67f#a3.00.00.00.00.00.00.00
sleep 0.1
cansend can0 67f#a2.01.14.00.00.00.00.00
sleep 0.1
#SDO block upload end
cansend can0 67f#a1.00.00.00.00.00.00.00
#immediately start next SDO communication
cansend can0 67f#C2.17.10.00.02.00.00.00
I've narrowed this down to the CO_SDO_receive() function. This receives the new request before the "SDO block upload end" message is processed, and therefore just drops it.
When looking at the spec, I can't find anything that would speak against having this sequence. I also think this is a realistic scenario for the client to just start the next request after one has finished.
From looking at the code, I have no idea how to fix this easily, at least for upstream...
I've also had a look at the other SDO transfer methods. They are not affected as the end message is always from server to client.
reference: CiA301, 7.2.4.3.12 Protocol SDO block upload
Hi,
I can't find this in the docs - is there a reason that I shouldn't declare the ROM OD entries struct as const? This basically gives the compiler the option to not place this stuff inside RAM.
In the current implementation, I can't find a difference between ROM and RAM, both are loaded to ram, both are lost at reset.
what is the use of IO.html in canopennode
Ups sorry, was not on current branch.
Was already fixed!
when the master stop to send heartbeat to canopennode 'node'
the node go to pre-op-> this is ok
but the node was locked, impossible to return to operational state.
canopen node dosn't accept the nmt message
Hi,
I want to trigger some events via canopen sdo messages, like writting to index 0x2000 should start some measurement. As I can see, there is no callback functionality per OD entry, so I wonder what is the recomended way to figure out which OD entry has changed and call right handler?
I would like to know if it is possible with this stack to to multiple simultaneous SDO transactions.
Like reading from two different nodes at once. As I understand I have to call CO_SDOclient_setup every time my target changes before using CO_SDOclientDownloadInitiate or CO_SDOclientUploadInitiate. Is it somehow possible (like creating two instances of CO_SDOclient_t) to do to simultaneous transactions?
Hi Folks!
I am just about to getting started using this lib. I had a good look at the lib and have a few questions before I start.
If I understand correctly, this lib provides the CANopen machinery and provides hooks where I can add in my own drivers. How to do this I can find in the drvTemplate
. Correct?
I want to use the lib on an STM32F072. There is two drivers for STM32's. Can I simply use the generic one or am I better off writing my own?
To autogenerate the Object Database, a "Web Application" is needed. I figured that I can only use it in IE (ohwow.). But even in IE I get some errors and are unable to generate a project. How do I create a new project?
The project is completely unmaintained. But there are a lot of pull requests and apparently interested people. Why not just create a fork of the project and have it maintained by some active people and not just one person? I would really love to use this lib and also contribute but with it largely unmaintained it's kind of bad ...
Thanks a lot for any answers & best regards,
Yatekii
While using a PLC from Frenzel+Berg, I noticed that the stack always assumes a data length of 4 bytes when a SDO download initiate message is received which has the size indication bit not set.
(excerpt from CO_SDO.c:806)
/* Expedited transfer */
if((SDO->CANrxData[0] & 0x02U) != 0U){
/* is size indicated? Get message length */
if((SDO->CANrxData[0] & 0x01U) != 0U){
len = 4U - ((SDO->CANrxData[0] >> 2U) & 0x03U);
}
else{
len = 4U;
}
This results in an abort message, if the triggered data type is not exactly 32 bytes long!
Is this really the desired behaviour?
Changing the else-case to
/* get message length from OD */
else{
len = SDO->ODF_arg.dataLength;
}
makes it work for me. This assumes the sender really knows what he is doing, the CO_SDO_writeOD() function will take as many bytes as needed*. Unfortunately the CIA-301 document does not say anything about this case, other that it exists.
Regards,
Kai
[* out of the 4 possible data bytes]
Now CO_init looks like this:
CO_ReturnError_t CO_init(
int32_t CANbaseAddress,
uint8_t nodeId,
uint16_t bitRate);
However, CANbaseAddress usually is an address of some kind of structure, for example, in stm32 it's a pointer to CAN_TypeDef
.
So casting it to and from int32_t
is:
int32_t
Since CANbaseAddress is used only for forwarding to CO_driver and not for it's numerical value, correct way of passing it will be as void *
.
Hi,
i've added a manual PDO mode to CANopenNode. This can be used for special use cases like serial data streaming via PDO where every PDO message must be delivered (like this gateway: https://www.ixxat.com/products/products-industrial/gateways-and-bridges/can-gw100-rs232).
This required me to do changes to PDO and CAN driver. This now contains a additional send function that checks for remaining queue space before sending.
This function is used when a PDO is sent. This applies to all TPDOs, not only the ones under user control!
I'm not sure if we want this changes in the mainline stack. Have a look at it, if we want it I can create a pull-request.
https://github.com/martinwag/CANopenNode/tree/add-manual-pdo
regards & have a nice christmas
Martin
I am interested in using this library with a STM32F4XX microcontroller. The project I am planning on using it with is a commercial project, and I would not be able to apply the GPL license to the commercial portion of the code.
I am trying to ascertain the correct approach to cleanly separating the commercial client code from the CANopenNode library code. Is the exemption applied in a similar manner to that of the LGPL? In other words, if I design my client code so that it only uses this library via linking, will that be allowed? If so, are both static and dynamic linking allowed?
Of course the terms of the GPL will be maintained otherwise, and this library's source, along with any modification made in order to get it working on the microcontroller (driver development, etc.) will be made available to anyone using the product being developed. It is also my intention to provide any updates to this code base back upstream via a pull request, presuming you are interested in such modifications.
Is this the correct approach?
I am new to CAN open protocol. Is it possible to create CAN Open slave using this library in PIC controller
Hi,
I need for a single node to autonomously transmit several process data (i.e. more than 4 PDOs * 8 bytes/PDO).
In my understanding there's a limit for each node to only send 4 different PDOs, and CANOpen already defines multiplexed PDOs to address such a case (at the cost of extra bandwidth of course).
Is there any plan or idea to implement such a feature in CANopenNode?
Would there be any alternative (e.g. by using custom COB-IDs?) I wouldn't need to deploy a huge number of nodes so I might as well restrict the usage of NodeIDs to e.g. 8,16,24 etc... so that the node with ID 16 can use up all the COB-IDs that would normally be used by 8 different nodes (with ID between 16 and 23).
Any suggestion welcome...
Thank you!
Hello,
During the development of my application, I have found a problem with the emission of the heartbeat when I choose to reset node.
In function CO_NMT_process, a negative value can appear and the heartbeat will be emit 3 or 4 times every ms and create an error with TX_OVERFLOW
So, I made a correction that I share here :
/* Heartbeat producer message & Bootup message */
if((HBtime && NMT->HBproducerTimer >= HBtime) || NMT->operatingState == CO_NMT_INITIALIZING){
NMT->HBproducerTimer = NMT->HBproducerTimer - HBtime;
NMT->HB_TXbuff->data[0] = NMT->operatingState;
CO_CANsend(NMT->HB_CANdev, NMT->HB_TXbuff);
if(NMT->operatingState == CO_NMT_INITIALIZING){
if(HBtime > NMT->firstHBTime)
NMT->HBproducerTimer = HBtime - NMT->firstHBTime;
// ! CORRECTION ! //
else
NMT->HBproducerTimer = 0;
// ! CORRECTION ! //
if((NMTstartup & 0x04) == 0) NMT->operatingState = CO_NMT_OPERATIONAL;
else NMT->operatingState = CO_NMT_PRE_OPERATIONAL;
}
}
Best regards,
Valentin
Hi folks,
I'm trying to understand the usage intent, of the code below, within drvTemplate > CO_driver.c.
In very general terms, the design intent would seem to be, send the message if the CAN CPU hardware is free (with the 1 in 1 && to be replaced by a check that it is, as the supplied CPU drivers have done).
But if not free, set the buffer->bufferFull flag, indicating that the buffer in question has a pending message to be sent, in due course, by interrupt. For example, TPDO->CANtxBuff>bufferFull.
And that it how I find the stack to be operating - I have it all up and running, on an Infineon XMC4 CPU, with a CO_driver.c I have created, from the template.
Just one problem, though: When the function below is again called, if the buffer->bufferFull flag is set,
a CO_EMC_CAN_OVERRUN EMCY is generated. And indeed, I see this EMCY, with a CANbus analyser. But it seems to me, this EMCY doesn't need to be generated. Because there hasn't really been an overrun and loss of message. Just, a message is waiting to be sent by interrupt.
But perhaps, I've got something wrong with my understanding, Can anyone shed some light ?
Infact, I think this CO_EMC_CAN_OVERRUN is constantly occurring. But of course, just the one EMCY occurs, because I think I read that CANOpen by design doesn't repeat the same EMCY, until cleared.
Anyway, a consequence of the EMCY, is that 1003h Pre-defined error, changes from 0 to 0x10, signifying a comms error. As a result, NMT blocks transition of my device to Operational mode, from Pre-Op or Stopped.
It goes OK to Operational at boot or on NMT comms reset, though.
Thanks,
David King
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer){
CO_ReturnError_t err = CO_ERROR_NO;
/* Verify overflow */
if(buffer->bufferFull){
if(!CANmodule->firstCANtxMessage){
/* don't set error, if bootup message is still on buffers */
CO_errorReport((CO_EM_t*)CANmodule->em, CO_EM_CAN_TX_OVERFLOW, CO_EMC_CAN_OVERRUN, buffer->ident);
}
err = CO_ERROR_TX_OVERFLOW;
}
CO_LOCK_CAN_SEND();
/* if CAN TX buffer is free, copy message to it */
if(1 && CANmodule->CANtxCount == 0){
CANmodule->bufferInhibitFlag = buffer->syncFlag;
/* copy message and txRequest */
}
/* if no buffer is free, message will be sent by interrupt */
else{
buffer->bufferFull = true;
CANmodule->CANtxCount++;
}
CO_UNLOCK_CAN_SEND();
return err;
}
Available CAN filters for PIC32 is hardcoded to 32 (see line 137 of CO_driver.c), while PIC32MX 1/2/5 only have 16. Trying to configure filters past the 16th fails and the associated COB-ID message is ignored. For example PIC32MX530F128L is affected. The datasheet points to the CAN section of PIC32 family reference manual which says there are 32 filters, but the datasheet specifies 16 and reality agrees. See datasheet (DS60001290D-page 243 figure 23-1)
Hi there!
Sorry for my English)
I've reconstructed this code to work under OS control, using queues, semaphores and other instruments. Want to push it here and make a public property. How can I do it?
Please contact me: [email protected]
Hi Janez,
currently, CANopenNode is marked in the Readme.md as using GPL with linking exception. This is true for all sources, except the socketCAN driver. Those are GPLv2.
I would like to use this driver (and fix some bugs/add features to it). However GPL means that I can't integrate it into my application, forcing me to build a completely new one.
Can we change that to the license that is used for the driver template?
Thanks!
Not quite sure this an issue, but the ODL_errorStatusBits_stringLength must be at least 10, that makes the custom object 0x2100 mandatory. And this is not according DS301.
/* Verify features from CO_OD *************************************************/
/* generate error, if features are not correctly configured for this project */
#if CO_NO_NMT_MASTER > 1 \
|| CO_NO_SYNC != 1 \
|| CO_NO_EMERGENCY != 1 \
|| CO_NO_SDO_SERVER == 0 \
|| (CO_NO_SDO_CLIENT != 0 && CO_NO_SDO_CLIENT != 1) \
|| (CO_NO_RPDO < 1 || CO_NO_RPDO > 0x200) \
|| (CO_NO_TPDO < 1 || CO_NO_TPDO > 0x200) \
|| ODL_consumerHeartbeatTime_arrayLength == 0 \
**|| ODL_errorStatusBits_stringLength < 10**
#error Features from CO_OD.h file are not corectly configured for this project!
#endif
How to use the example io.eds and io.html present in the canopennode example program to the canopen i/o module
In CO_CANmodule_init() function, rxArray[] is only partly initialized. When not all elements are initialized by the following CANopenNode init functions, undefined behaviour occurs upon message reception.
This causes a problem for me on implementing LSS. In normal operation all elements are initialized correctly. But with LSS, there is a case where only LSS is initialized and the rest of the stack is not (Startup without valid node ID).
I've solved this by defaulting all values of the array as followed:
for(i=0U; i<rxSize; i++){
rxArray[i].ident = 0U;
rxArray[i].mask = 0xFFFFFFFF;
rxArray[i].object = NULL;
rxArray[i].pFunct = NULL;
}
Mask must be set to not mask out any bits as otherwise software filter in
if(((rcvMsgIdent ^ buffer->ident) & buffer->mask) == 0U){
will always match when buffer is not set up by stack.
For me this works as expected, but I don't know if we can just apply that to all the other avaliable drivers. There shouldn't be a problem as those values currently contain "random" values, but who knows...
txArray[] is also only partially initialzied. However, I think this is not a problem because those entries are only used after initialization.
My working environment is Linux.
I tested CANopen using CANopenSocket's canopend. It worked well.
I created shared memory in canopend and tried to exchange PDO data with other programs.
I know that CANopenNode is a GPL linking exception.
However, CANopenSocket is a generic GPL v2.
I tested with canopend and tried to use shared memory, but gave up because it was GPL v2.
So I tried to use the GPL linking exception CANopenNode/CANopenNode/example/main.c.
After analyzing the source, I found that the CANopenNode/CANopenSocket/canopend/src/main.c and CANopenNode stacks were very similar.
Both CANopenNode/CANopenNode/example/main.c and CANopenNode/CANopenSocket/canopend/src/main.c both use the stack of CANopenNode.
Both are thought of as a kind of daemon using CANopenNode.
This part confuses me.
I am a newbie in connection with the GPL license.
I tried to find the mailing list but could not find it.
Is it a question to ask here?
I'm sorry I do not have enough English.
Hi all,
There is a conflict between a typedef in CO_OD.h and a macro defined in math.h
typedef domain_t DOMAIN;
(l.53)
Of course, it is not dramatic at all, but hey, worth the shot to say it.
I have to manage CANOpen with LPCXpresso4337 board , which has two independent CAN controllers.
But LPCOpen's implementation of CCAN is a bit different from CAN of LPC17xx. So CANOpenNode doesn't work in LPC43xx.
My interpretation of this code is that should the if statement evaluate to false the corresponding return won't be called, and the program will erroneously move onto the next case statement. Each case statement should end with a break;.
Lines 843 to 850 in 5338015
Hello,
I am getting my sample for the STM32F103 Olimex P103 demo more and more to work. So simple read and write seems to work. Now I do not really know how to add the interaction with the input and output´s. Is it right that the demo should support 8 digital in, 8 digital out, and 8 analog in, and 8 analog out?
I also study the STM32 example which i found in the old SVN repo i don't see any read and write of the outputs or inputs whether analog or digital.
I do not have any PIC but I tried to study the CANopenNodePIC demo also. Does this demo also use the main from the CANopenNode Stack example ... so is it also an IO demo using the IO.eds file from the stack reop? It isn´t really not easy for someone which is quite new to canopen.
So can someone help me: Which file is the right one for the IO example? How does the interaction with the IO´s work? And where should I read and write the output?
many thanks.
cheers
mathias
Hello,
I am using your CANOpennode software on a SAMA5D2 processor for a project of ours.
I got everything to make and was using the provided example main to just test that things were working before moving to implementing the driver interface when I encounted a problem.
At the beginning of main.c there are these lines:
/* disable CAN and CAN interrupts */ printf("Disable CAN and interrupts\n\r"); CO->CANmodule[0]->CANnormal = false;
seems straight forward, but on my eval board the program hangs and won't continue after this statement. I get the output from the printf, and then nothing after that.
From what I can tell CO has been created, but it is set to NULL.
It only gets initialised after this call:
/* initialize CANopen */ printf("Calling CO_init\n\r"); err = CO_init(0/* CAN module address */, 10/* NodeID */, 250 /* bit rate */);
I have looked at the PIC example and it is the same, yet I would assume it runs.
I feel like using the pointer before it's initialized is incorrect, and it doesn't work on my board, but I don't see anyone else complaining.
What am I missing here.
Thank you.
I need to act as SDO master for multiple slave nodes. For example, I am node ID 0x3. I need to read (client upload) from node 0x8 and also from node 0x9.
Initially I call CO_SDOclient_setup() for each node ID that I will be reading from. Then I call CO_CANsetNormalMode().
From what I can tell, every time change which node I am reading from, I need to call CO_SDOclient_setup() again. However CO_SDOclient_setup calls CO_CANrxBufferInit() which is only supposed to be called in the communications reset section. Hence switching from reading node 0x08 to 0x09 (for example) calls CO_CANrxBufferInit() after I have already exited the communications reset section, and the whole thing crashes.
Am I using this properly? What is the correct way to select which node ID I wish to talk to?
If I only talk to one node, everything works fine.
Hello.
I am using the Object Dictionary Editor to create Object data for use with CANopenNode.
However, I could not find the Object Dictionary Editor in a subproject at https://github.com/CANopenNode.
I was able to find the Object Dictionary Editor at https://sourceforge.net/projects/canopennode/files/canopennode/CANopenNode-3.10/.
My idea is that the repository has been moved from sourceforge to github.
Perhaps this Object Dictionary Editor is an old version.
When I check, CO_OD.c and CO_OD.h created by Object Dictionary Editor downloaded from sourceforge are declared as LGPL.
However, CANopenNode is a GPL linking exception.
Lines 1 to 50 in 5338015
Lines 1 to 50 in 5338015
This confuses me.
Where can I download the Object Dictionary Editor?
I'm sorry I do not have enough English. :)
Thanks!
Using the excellent libedsharp EDSeditor V0.5.2 or 6 beta I have one problem: I can not get either version to set CO_NO_NMT_MASTER to 1. I am using it with the .eds file that comes with CANopenSocket. Any suggestions?
Dear All,
I'm working on CANopennode on dsPIC33 (PIC24_dsPIC33) custom hardware platform and I'm trying to set up SDO block mode upload.
I'm able to perform SDO segmented transfer, but I'm having some mistakes on SDO block mode upload on server side.
I'm sending the request from a client node to a server node and I want to read a 32 byte buffer.
I've done many tests and I'm gone deep inside the library also in debug mode in order to better understand how the block mode transfer works.
In the detail I need to read a 32Byte variable ( called "bufferSpare")@ Index Ox7000 on Server Side.
At the end I'm able to perform the data transfer (SDO block mode upload) only if the variable on the Object Dictionary on Server side is defined as "VISIBLE STRING".
This is the object dictionary definition
"{0x7000, 0x00, 0x3E, 32, (void*)&CO_OD_RAM.bufferSpare[0]},"
If I define the variable as an array of 32 elements , type unsigned 8 the SDO block mode fails (the server answer to the client as if it needs to perform a segmented mode). This seems to be connected to the lenght of data.
If I define the variable as array the SDO manager recognizes it as leght is 1 byte (ist this the lenght of the sigle array element?) ; If I define the variable as a "VISIBLE STRING" of 32 characters the SDO manager rcognizes the legnht as 32 and the SDO block transfer is done.
Is this something I need to configure on the Object Dictionary on Server Side to make werk the SDO Block Mode transfer also for Array variables? Or is there any implementation limit that frorce me to use "VISIBLE STRING" type variables for block mode transfer?
I'll very appreciate any helps.
Best Regards
Emanuele
While looking at error #39, I came across receive message signaling. This is currently done by copying the message and then setting a flag in one thread/interrupt and evaluation in another thread/main loop. This might work on some embedded compilers (like the free microchip ones), but can break when enabling compiler optimization. As soon as you do that, your compiler is allowed to shuffle around memory copy operations as it likes to do. So you have no guarantee that xxx->CANrxNew = true;
is actually executed last.
I'm thinking about the 'best way' to fix this. I can see some options that might be viable:
__sync_synchronize()
. I have no idea how (and if) to add the memory barrier with other compilers.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.