You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "HedongGao (via GitHub)" <gi...@apache.org> on 2024/10/13 14:09:20 UTC

[PR] nuttx/can: support to Send message priority sorting function. [nuttx]

HedongGao opened a new pull request, #14207:
URL: https://github.com/apache/nuttx/pull/14207

   Linked list-based priority sorting function for sending messages.
   
   ## Summary
   
   This PR introduces a new priority-based sending mechanism for the CAN protocol stack, addressing the need for deterministic message delivery in time-critical applications. The change modifies the CAN driver files to implement a linked list-based priority queue for outgoing CAN frames.
   
   The priority of a CAN frame is determined by CAN ID. This allows applications to prioritize critical messages, ensuring they are transmitted ahead of less important ones, even under high bus load.
   
   ## Impact
   
   New Feature: Adds priority-based sending for CAN frames.
   User Impact: YES. Users can now enable and configure priority sending using Kconfig options.
   Build Impact: YES. To enable priority sending, users must select the CAN_TXPRIORITY during build configuration.
   Compatibility Impact: Assess backward compatibility.
   
   ## Testing
   
   The application layer sends unordered CAN messages, constructs a scenario where the sending queue is full, and manually adds log information to record the frame order in the priority sending queue. Print the frame.can_id information for each frame as follows:
   
   tx_list has full, and frame order is : 0x193 , 0x198, 0x19B, 0x1b5, 0x1b9, 0x259, 0x268, 0x2a1, 0x311, 0x319
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799389049


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);

Review Comment:
   Thank you pkarashchenko!
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#issuecomment-2411432885

   @pkarashchenko Hello pkarashchenko, I checked the reason for the CI failure and it says: failed to connect github 443.
   Can you please help me retrigger it?  Thank you!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1800277757


##########
include/nuttx/can/can_sender.h:
##########
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * include/nuttx/can/can_sender.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_CAN_SENDER_H
+#define __INCLUDE_NUTTX_CAN_SENDER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <nuttx/list.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mutex.h>
+#include <nuttx/can/can.h>
+
+#ifdef CONFIG_CAN
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_CAN_TXPRIORITY 
+
+/* There are three linked lists to manage TX buffer:
+ * tx_send  - cache message send from application but not send to H/W.
+ *            Sorted in ascending order based on can_id.
+ * tx_untcf - cache message send to H/W but not confirmation.  Sorted in
+ *            ascending order based on can_id.
+ * tx_free  - can_write function get a tx_free node, write message, then move
+ *            this node to tx_send list.
+ */
+
+  #define FREE_FULL(sender) \

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#issuecomment-2412601217

   > > @pkarashchenko Hello pkarashchenko, I checked the reason for the CI failure and it says: failed to connect github 443. Can you please help me retrigger it? Thank you!
   > 
   > triggered, but you can push the new patch by self to restart ci.
   
   Ok, I learned it !


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799362825


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_untcf)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_untcf, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+
+#else
+  msg = &cd_sender->tx_buffer[cd_sender->tx_queue];
+
+  /* Increment the FIFO queue index before sending (because dev_send()
+   * might call can_txdone()).
+   */
+
+  cd_sender->tx_queue++;
+
+  if (cd_sender->tx_queue == CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_queue = 0;
+    }
+#endif
+
+  return msg;
+}
+
+/****************************************************************************
+ * Name: can_revert_msg
+ *
+ * Description:
+ *   Rever msg in sender, because sending failed.
+ *
+ ****************************************************************************/
+
+void can_revert_msg(FAR struct can_txcache_s *cd_sender ,
+                    FAR struct can_msg_s *msg)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;

Review Comment:
   Done!



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_untcf)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_untcf, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+
+#else
+  msg = &cd_sender->tx_buffer[cd_sender->tx_queue];
+
+  /* Increment the FIFO queue index before sending (because dev_send()
+   * might call can_txdone()).
+   */
+
+  cd_sender->tx_queue++;
+
+  if (cd_sender->tx_queue == CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_queue = 0;
+    }
+#endif
+
+  return msg;
+}
+
+/****************************************************************************
+ * Name: can_revert_msg
+ *
+ * Description:
+ *   Rever msg in sender, because sending failed.
+ *
+ ****************************************************************************/
+
+void can_revert_msg(FAR struct can_txcache_s *cd_sender ,
+                    FAR struct can_msg_s *msg)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+
+  msg_node = container_of(msg, struct can_msg_node_s, msg);
+
+  list_delete(&msg_node->list);
+
+  list_add_head(&cd_sender->tx_send, &msg_node->list);
+#else
+  (void)(msg);
+  if (cd_sender->tx_queue == 0)
+    {
+      cd_sender->tx_queue = CONFIG_CAN_TXFIFOSIZE - 1;
+    }
+  else
+    {
+      cd_sender->tx_queue--;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_send_done
+ *
+ * Description:
+ *   Release the sender resources, after the tragic message is successfully
+ *   sent to the bus.
+ *
+ ****************************************************************************/
+
+void can_send_done(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct list_node *node;

Review Comment:
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799363430


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;

Review Comment:
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "GUIDINGLI (via GitHub)" <gi...@apache.org>.
GUIDINGLI merged PR #14207:
URL: https://github.com/apache/nuttx/pull/14207


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "nuttxpr (via GitHub)" <gi...@apache.org>.
nuttxpr commented on PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#issuecomment-2408995677

   [**\[Experimental Bot, please feedback here\]**](https://github.com/search?q=repo%3Aapache%2Fnuttx+13552&type=issues)
   
   
   
   ## PR Requirements Assessment:
   
   This PR appears to **partially meet** the NuttX requirements. Here's a breakdown:
   
   **Strengths:**
   
   * **Summary:**
       * Clearly states the "why" (need for deterministic message delivery).
       * Identifies the "what" (linked list-based priority queue in CAN driver).
       * Explains the "how" (CAN ID determines priority). 
   * **Impact:**
       *  Addresses most impact areas (User, Build, Compatibility).
       *  Highlights user-facing changes (Kconfig options).
   * **Testing:**
       * Provides a testing scenario and methodology.
       * Includes log snippets showcasing priority queue behavior.
   
   **Areas for Improvement:**
   
   * **Summary:**
       *  **Missing:** Links to related NuttX issues or PRs (if applicable).
   * **Impact:**
       * **Hardware Impact:**  Unclear if specific architectures, boards, or drivers are affected. Needs clarification (NO/YES + details).
       * **Documentation Impact:** Needs confirmation if documentation updates are required/provided (NO/YES + details).
       * **Security Impact:**  Not addressed. Consider potential security implications of priority-based messaging (e.g., denial-of-service). 
       * **Compatibility Impact:** "Assess backward compatibility" is too vague.  Provide a concrete assessment (YES/NO + specific details about potential compatibility breaks). 
   * **Testing:**
       * **Incomplete Logs:** Show logs from *before* the change to demonstrate the difference in behavior.
       * **Build/Target Details:** Specify the build host(s) and target(s) used for testing (OS, CPU, compiler, architecture, board, configuration).
   
   **Recommendations:**
   
   1. **Complete Missing Information:** Fill in the gaps identified in the "Areas for Improvement" section.
   2. **Expand Testing Details:**  Provide comprehensive logs and testing environment information.
   3. **Review NuttX Contribution Guidelines:** Familiarize yourself with the official NuttX contribution guidelines for any specific formatting or content requirements. 
   
   By addressing these points, you'll significantly improve the clarity and completeness of your PR, making it easier for reviewers to understand and approve your changes. 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799362287


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;

Review Comment:
   Done!



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;

Review Comment:
   Done!
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#issuecomment-2411572127

   > @pkarashchenko Hello pkarashchenko, I checked the reason for the CI failure and it says: failed to connect github 443. Can you please help me retrigger it? Thank you!
   
   triggered, but you can push the new patch by self to restart ci.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "pkarashchenko (via GitHub)" <gi...@apache.org>.
pkarashchenko commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1798609188


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;

Review Comment:
   ```suggestion
     FAR struct can_msg_s *msg = NULL;
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)

Review Comment:
   ```suggestion
     list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
                          struct can_msg_node_s, list)
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)

Review Comment:
   ```suggestion
   FAR struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
   ```



##########
include/nuttx/can/can_sender.h:
##########
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * include/nuttx/can/can_sender.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_CAN_SENDER_H
+#define __INCLUDE_NUTTX_CAN_SENDER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <nuttx/list.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mutex.h>
+#include <nuttx/can/can.h>
+
+#ifdef CONFIG_CAN
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_CAN_TXPRIORITY 
+
+/* There are three linked lists to manage TX buffer:
+ * tx_send  - cache message send from application but not send to H/W.
+ *            Sorted in ascending order based on can_id.
+ * tx_untcf - cache message send to H/W but not confirmation.  Sorted in
+ *            ascending order based on can_id.
+ * tx_free  - can_write function get a tx_free node, write message, then move
+ *            this node to tx_send list.
+ */
+
+  #define FREE_FULL(sender) \

Review Comment:
   This is GCC extension and is C89 incompatible



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));

Review Comment:
   Better to check this after all variable as declared to get C89 compatibility



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_untcf)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_untcf, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+
+#else
+  msg = &cd_sender->tx_buffer[cd_sender->tx_queue];
+
+  /* Increment the FIFO queue index before sending (because dev_send()
+   * might call can_txdone()).
+   */
+
+  cd_sender->tx_queue++;
+
+  if (cd_sender->tx_queue == CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_queue = 0;
+    }
+#endif
+
+  return msg;
+}
+
+/****************************************************************************
+ * Name: can_revert_msg
+ *
+ * Description:
+ *   Rever msg in sender, because sending failed.
+ *
+ ****************************************************************************/
+
+void can_revert_msg(FAR struct can_txcache_s *cd_sender ,
+                    FAR struct can_msg_s *msg)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;

Review Comment:
   ```suggestion
     FAR struct can_msg_node_s *msg_node;
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;

Review Comment:
   ```suggestion
     FAR struct can_msg_node_s *msg_node;
     FAR struct can_msg_node_s *tmp_node;
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);

Review Comment:
   ```suggestion
     msg_node = list_first_entry(&cd_sender->tx_send,
                                 struct can_msg_node_s, list);
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)

Review Comment:
   ```suggestion
     list_for_every_entry(&cd_sender->tx_send, tmp_node,
                          struct can_msg_node_s, list)
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);

Review Comment:
   I think this should be upper
   ```
   #if defined(CONFIG_CAN_TXPRIORITY) && CONFIG_CAN_TXFIFOSIZE <= 0
   #  error "CONFIG_CAN_TXFIFOSIZE should be positive non-zero value"
   #endif
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_untcf)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_untcf, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+
+#else
+  msg = &cd_sender->tx_buffer[cd_sender->tx_queue];
+
+  /* Increment the FIFO queue index before sending (because dev_send()
+   * might call can_txdone()).
+   */
+
+  cd_sender->tx_queue++;
+
+  if (cd_sender->tx_queue == CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_queue = 0;
+    }
+#endif
+
+  return msg;
+}
+
+/****************************************************************************
+ * Name: can_revert_msg
+ *
+ * Description:
+ *   Rever msg in sender, because sending failed.
+ *
+ ****************************************************************************/
+
+void can_revert_msg(FAR struct can_txcache_s *cd_sender ,

Review Comment:
   ```suggestion
   void can_revert_msg(FAR struct can_txcache_s *cd_sender,
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);

Review Comment:
   Check after variable are declared



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_untcf)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_untcf, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+
+#else
+  msg = &cd_sender->tx_buffer[cd_sender->tx_queue];
+
+  /* Increment the FIFO queue index before sending (because dev_send()
+   * might call can_txdone()).
+   */
+
+  cd_sender->tx_queue++;
+
+  if (cd_sender->tx_queue == CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_queue = 0;
+    }
+#endif
+
+  return msg;
+}
+
+/****************************************************************************
+ * Name: can_revert_msg
+ *
+ * Description:
+ *   Rever msg in sender, because sending failed.
+ *
+ ****************************************************************************/
+
+void can_revert_msg(FAR struct can_txcache_s *cd_sender ,
+                    FAR struct can_msg_s *msg)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+
+  msg_node = container_of(msg, struct can_msg_node_s, msg);
+
+  list_delete(&msg_node->list);
+
+  list_add_head(&cd_sender->tx_send, &msg_node->list);
+#else
+  (void)(msg);
+  if (cd_sender->tx_queue == 0)
+    {
+      cd_sender->tx_queue = CONFIG_CAN_TXFIFOSIZE - 1;
+    }
+  else
+    {
+      cd_sender->tx_queue--;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_send_done
+ *
+ * Description:
+ *   Release the sender resources, after the tragic message is successfully
+ *   sent to the bus.
+ *
+ ****************************************************************************/
+
+void can_send_done(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct list_node *node;

Review Comment:
   ```suggestion
     FAR struct list_node *node;
   ```



##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;

Review Comment:
   ```suggestion
     FAR struct list_node *node;
     FAR struct can_msg_node_s *msg_node;
     FAR struct can_msg_node_s *tmp_node;
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799362002


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)

Review Comment:
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1800297145


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));
+#ifdef CONFIG_CAN_TXPRIORITY
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  if (list_is_empty(&cd_sender->tx_send))
+    {
+      return NULL;
+    }
+
+  msg_node = list_first_entry(&cd_sender->tx_send,
+                            struct can_msg_node_s, list);
+  msg = &msg_node->msg;
+
+  /* Move the node from tx_send to tx_untcf before
+   * sending(because dev_send() might call can_txdone()).
+   */
+
+  list_delete(&msg_node->list);
+
+  /* Sort unconfirmed messages in ascending order */
+
+  list_for_every_entry(&cd_sender->tx_untcf, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_untcf)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_untcf, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+
+#else
+  msg = &cd_sender->tx_buffer[cd_sender->tx_queue];
+
+  /* Increment the FIFO queue index before sending (because dev_send()
+   * might call can_txdone()).
+   */
+
+  cd_sender->tx_queue++;
+
+  if (cd_sender->tx_queue == CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_queue = 0;
+    }
+#endif
+
+  return msg;
+}
+
+/****************************************************************************
+ * Name: can_revert_msg
+ *
+ * Description:
+ *   Rever msg in sender, because sending failed.
+ *
+ ****************************************************************************/
+
+void can_revert_msg(FAR struct can_txcache_s *cd_sender ,

Review Comment:
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1800279633


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)
+    {
+      if (tmp_node->msg.cm_hdr.ch_id > msg->cm_hdr.ch_id)
+        {
+          /* Prioritize tx frame based on canid */
+
+          break;
+        }
+    }
+
+  if (&tmp_node->list == &cd_sender->tx_send)
+    {
+      /* Inserted at the end of the linked list */
+
+      list_add_tail(&cd_sender->tx_send, &msg_node->list);
+    }
+  else
+    {
+      list_add_before(&tmp_node->list, &msg_node->list);
+    }
+#else
+  memcpy(&cd_sender->tx_buffer[cd_sender->tx_tail], msg, msglen);
+
+  /* Increment the tail of the circular buffer */
+
+  cd_sender->tx_tail++;
+  if (cd_sender->tx_tail >= CONFIG_CAN_TXFIFOSIZE)
+    {
+      cd_sender->tx_tail = 0;
+    }
+#endif
+
+  return;
+}
+
+/****************************************************************************
+ * Name: can_get_msg
+ *
+ * Description:
+ *   Get send message from sender.
+ *
+ ****************************************************************************/
+
+struct can_msg_s *can_get_msg(FAR struct can_txcache_s *cd_sender)
+{
+  struct can_msg_s *msg = NULL;
+
+  /* No.. The sender should not be empty in this case */
+
+  DEBUGASSERT(!FREE_FULL(cd_sender));

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799363201


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);
+
+  struct list_node *node;
+  struct can_msg_node_s *msg_node;
+  struct can_msg_node_s *tmp_node;
+
+  node = list_remove_head(&cd_sender->tx_free);
+  msg_node = container_of(node, struct can_msg_node_s, list);
+  memcpy(&msg_node->msg, msg, msglen);
+
+  list_for_every_entry(&cd_sender->tx_send, tmp_node,
+                        struct can_msg_node_s, list)

Review Comment:
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] nuttx/can: support to Send message priority sorting function. [nuttx]

Posted by "HedongGao (via GitHub)" <gi...@apache.org>.
HedongGao commented on code in PR #14207:
URL: https://github.com/apache/nuttx/pull/14207#discussion_r1799383030


##########
drivers/can/can_sender.c:
##########
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * drivers/can/can_sender.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can/can_sender.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_xmit_init
+ *
+ * Description:
+ *   Initial dev sender.
+ *
+ ****************************************************************************/
+
+void can_sender_init(FAR struct can_txcache_s *cd_sender)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(CONFIG_CAN_TXFIFOSIZE > 0);
+  int i;
+
+  list_initialize(&cd_sender->tx_send);
+  list_initialize(&cd_sender->tx_free);
+  list_initialize(&cd_sender->tx_untcf);
+
+  for (i = 0; i < CONFIG_CAN_TXFIFOSIZE; i++)
+    {
+      list_add_tail(&cd_sender->tx_free, &cd_sender->tx_buffer[i].list);
+    }
+
+#else
+  cd_sender->tx_head  = 0;
+  cd_sender->tx_queue = 0;
+  cd_sender->tx_tail  = 0;
+#endif
+  return;
+}
+
+/****************************************************************************
+ * Name: can_add_sendnode
+ *
+ * Description:
+ *   Add message to sender.
+ *
+ ****************************************************************************/
+
+void can_add_sendnode(FAR struct can_txcache_s *cd_sender,
+                      FAR struct can_msg_s *msg, int msglen)
+{
+#ifdef CONFIG_CAN_TXPRIORITY
+  DEBUGASSERT(FREE_COUNT(cd_sender) > 0);

Review Comment:
   Done!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org