Re: How to send a CAN message while in a kernel module?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 22/03/2020 19.03, Robert Barrows wrote:
Thank you for all the direction Oliver,  I think I am on the correct path,
but now have can_send returning with a "-1" (ERESTART). I used raw_sendmsg
as a template for this and cut out (hopefully) unneeded code, but I am
concerned I cut out something I needed.  Would you mind taking another look?

I would recommend to test your code with a virtual CAN (vcan0) first.

You should bring the system into the state that you can run

cangen vcan0

in one terminal and

candump vcan0

in another terminal and see some data there.

And then let your kernel module send on vcan0.

Running on a real CAN interface can have (wiring/termination) issue you would not like to debug when developing a kernel module ;-)

There's a problem with your code too:



Thanks.

int SendCanTime(struct timespec *tsCurrentTime) {

   struct sk_buff *skb;
   struct can_frame *frame = kmalloc(sizeof (struct can_frame), GFP_KERNEL);

This creates a memory leak ...

Just use a static buffer:

struct can_frame frame;
struct can_frame *cf = &frame;


   struct net_device *dev;
   int err = 0;
   int thetime = tsCurrentTime->tv_sec;

   // Set up can frame
   frame->can_id = 0x00050F93 | CAN_EFF_FLAG;

cf->can_id = 0x00050F93 | CAN_EFF_FLAG;

   frame->can_dlc = 6;

dito ...

   frame->data[0] = 0x00;
   frame->data[1] = 0x02;
   memcpy(frame->data+2, &thetime, sizeof(int));

   // Find the netdevice named can0
   read_lock(&dev_base_lock);
   dev = first_net_device(&init_net);
   while (!strcmp(dev->name, "can0")) {
     printk(KERN_INFO "found [%s]\n", dev->name);
     dev = next_net_device(dev);
   }
   read_unlock(&dev_base_lock);

   if (!dev)
     return -ENXIO;

   // Create skb
   skb = alloc_can_skb(dev, &frame);

skb = alloc_can_skb(dev, &cf);

I hope I made the pointer stuff correctly :-)

   if (!skb)
     goto put_dev;

   skb->dev = dev;

   err = can_send(skb, 0);

   dev_put(dev);

   if (err)
     goto send_failed;

   return 0;

//kfree_skb(skb);
put_dev:
   dev_put(dev);
send_failed:
   return err;

}
                                                                                ^




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux