From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7443 invoked by alias); 10 Aug 2007 14:18:56 -0000 Received: (qmail 7397 invoked by uid 22791); 10 Aug 2007 14:18:54 -0000 X-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,DK_POLICY_SIGNSOME,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from londo.lunn.ch (HELO londo.lunn.ch) (80.238.139.98) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 10 Aug 2007 14:18:50 +0000 Received: from lunn by londo.lunn.ch with local (Exim 3.36 #1 (Debian)) id 1IJVKA-0008JC-00; Fri, 10 Aug 2007 16:18:46 +0200 Date: Fri, 10 Aug 2007 14:18:00 -0000 From: Andrew Lunn To: Alexey Shusharin Cc: ecos-patches@sourceware.org Subject: Re: CAN waking calls Message-ID: <20070810141846.GI13510@lunn.ch> References: <1186372023.14247.14.camel@killix> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="61jdw2sOBCFtR2d/" Content-Disposition: inline In-Reply-To: <1186372023.14247.14.camel@killix> User-Agent: Mutt/1.5.16 (2007-06-11) X-Virus-Checked: Checked by ClamAV on sourceware.org X-IsSubscribed: yes Mailing-List: contact ecos-patches-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: ecos-patches-owner@ecos.sourceware.org X-SW-Source: 2007-08/txt/msg00012.txt.bz2 --61jdw2sOBCFtR2d/ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 718 On Mon, Aug 06, 2007 at 10:47:03AM +0700, Alexey Shusharin wrote: > Hello all, > > This patch adds waking calls functionality to CAN I/O driver. Now CAN > application can wake up threads, when CAN event is arrived, without > accessory thread. > Hi Alexey I reworked your patch a little. I renamed wake to callback, which is more generic. You can do real work in DSRs, you just have to be careful. So you don't always need to wake up a thread. Since there is no test case for this new feature, it is possible i have broken it. So please can you test it. If it all works i will then commit it. Do you think you could add a testcase to the can loop back driver which uses this feature? Thanks Andrew --61jdw2sOBCFtR2d/ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="can_callback.diff" Content-length: 7409 Index: io/can/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/io/can/current/ChangeLog,v retrieving revision 1.10 diff -u -r1.10 ChangeLog --- io/can/current/ChangeLog 31 Jul 2007 09:04:16 -0000 1.10 +++ io/can/current/ChangeLog 10 Aug 2007 14:15:06 -0000 @@ -1,3 +1,17 @@ +2007-08-06 Alexey Shusharin + Andrew Lunn + + * cdl/io_can.cdl: Added option CYGOPT_IO_CAN_SUPPORT_CALLBACK + + * include/canio.h: Added struct cyg_can_callback_cfg for setting + callback configurations. + + * include/can.h: Added declaration and initialization of callback + configuration in struct can_channel. + + * src/can.c: Added callback configuration changing and + application function call. + 2007-07-02 Uwe Kindler * cdl/io_can.cdl: Added interface CYGINT_IO_CAN_CHANNELS for Index: io/can/current/cdl/io_can.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/io/can/current/cdl/io_can.cdl,v retrieving revision 1.4 diff -u -r1.4 io_can.cdl --- io/can/current/cdl/io_can.cdl 3 Jul 2007 14:42:18 -0000 1.4 +++ io/can/current/cdl/io_can.cdl 10 Aug 2007 14:15:06 -0000 @@ -217,7 +217,18 @@ which allows clients to switch read() and write() call semantics from blocking to non-blocking." } - + + cdl_option CYGOPT_IO_CAN_SUPPORT_CALLBACK { + display "Support callback on events" + default_value 0 + description " + This option enables extra code in the generic CAN driver + which allows application to register a callback for + events. The callback function is called from DSR + context so you should be careful to only call API + functions that are safe in DSR context." + } + cdl_component CYGOPT_IO_CAN_SUPPORT_TIMEOUTS { display "Support read/write timeouts" flavor bool Index: io/can/current/include/can.h =================================================================== RCS file: /cvs/ecos/ecos/packages/io/can/current/include/can.h,v retrieving revision 1.3 diff -u -r1.3 can.h --- io/can/current/include/can.h 26 Mar 2007 10:43:36 -0000 1.3 +++ io/can/current/include/can.h 10 Aug 2007 14:15:06 -0000 @@ -168,15 +168,23 @@ // struct can_channel { - can_lowlevel_funs *funs; - can_callbacks_t *callbacks; - void *dev_priv; // Whatever is needed by actual device routines - cyg_can_info_t config; // Current configuration - bool init; // true if driver is already initialized - can_cbuf_t out_cbuf; // buffer for transmit can messages - can_cbuf_t in_cbuf; // buffer with received can events + can_lowlevel_funs *funs; + can_callbacks_t *callbacks; + void *dev_priv; // Whatever is needed by actual device routines + cyg_can_info_t config; // Current configuration + bool init; // true if driver is already initialized + can_cbuf_t out_cbuf; // buffer for transmit can messages + can_cbuf_t in_cbuf; // buffer with received can events +#ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK + cyg_can_callback_cfg callback_cfg; // Callback configuration +#endif }; +#ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK +#define CYG_CAN_CALLBACK_INIT , {(cyg_can_event_cb_t) 0, 0} +#else +#define CYG_CAN_CALLBACK_INIT +#endif #define CAN_CHANNEL_USING_INTERRUPTS(_l, \ @@ -193,6 +201,7 @@ false, \ CBUF_INIT(_out_buf, _out_buflen, _TX_TIMEOUT), \ CBUF_INIT(_in_buf, _in_buflen, _RX_TIMEOUT) \ + CYG_CAN_CALLBACK_INIT \ }; Index: io/can/current/include/canio.h =================================================================== RCS file: /cvs/ecos/ecos/packages/io/can/current/include/canio.h,v retrieving revision 1.6 diff -u -r1.6 canio.h --- io/can/current/include/canio.h 31 Jul 2007 09:04:16 -0000 1.6 +++ io/can/current/include/canio.h 10 Aug 2007 14:15:06 -0000 @@ -327,6 +327,23 @@ #define CYGNUM_CAN_HDI_TIMESTAMP 0x10 // driver supports timestamps +// +// Callback configuration structure. +// + +typedef void (*cyg_can_event_cb_t)(cyg_uint16); +// +// flag_mask should be set with a combination of CYGNUM_CAN_EVENT_* flags. +// If one of these events happens, the callback function will be called, +// with the actually event flags passed as a parameter. +// +typedef struct cyg_can_callback_cfg_st +{ + cyg_can_event_cb_t callback_func; // callback function + cyg_uint16 flag_mask; // flags mask +} cyg_can_callback_cfg; + + //=========================================================================== // CAN MESSAGE ACCESS MACROS // Index: io/can/current/src/can.c =================================================================== RCS file: /cvs/ecos/ecos/packages/io/can/current/src/can.c,v retrieving revision 1.4 diff -u -r1.4 can.c --- io/can/current/src/can.c 26 Mar 2007 10:43:36 -0000 1.4 +++ io/can/current/src/can.c 10 Aug 2007 14:15:07 -0000 @@ -665,6 +665,27 @@ } break; + +#ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK + // + // Set waking calls configuration + // To disable waking calls set waking_mask = 0 + // + case CYG_IO_SET_CONFIG_CAN_CALLBACK: + { + if (*len != sizeof(cyg_can_callback_cfg)) + { + return -EINVAL; + } + + // Copy data under DSR locking + cyg_drv_dsr_lock(); + chan->callback_cfg = *((cyg_can_callback_cfg*) xbuf); + cyg_drv_dsr_unlock(); + } + break; +#endif //CYGOPT_IO_CAN_SUPPORT_CALLBACK + default: // // pass down to lower layers @@ -695,6 +716,9 @@ { can_cbuf_t *cbuf = &chan->in_cbuf; CYG_CAN_EVENT_T *prxbuf = (CYG_CAN_EVENT_T *)cbuf->pdata; +#ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK + cyg_uint16 flags; +#endif // // cbuf is a ring buffer - if the buffer is full, then we overwrite the @@ -722,7 +746,11 @@ prxbuf[cbuf->put].flags |= CYGNUM_CAN_EVENT_OVERRUN_RX; cbuf->get = (cbuf->get + 1) % cbuf->len; } - + +#ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK + flags = prxbuf[cbuf->put].flags; +#endif + cbuf->put = (cbuf->put + 1) % cbuf->len; if (cbuf->waiting) @@ -730,6 +758,15 @@ cbuf->waiting = false; cyg_drv_cond_broadcast(&cbuf->wait); } +#ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK + // Call application callback function, if any of the flag events + // are unmasked. + if((flags & chan->callback_cfg.flag_mask) && + (chan->callback_cfg.callback_func)) + { + chan->callback_cfg.callback_func(flags); + } +#endif } cyg_drv_dsr_unlock(); --61jdw2sOBCFtR2d/--