You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "anjiahao1 (via GitHub)" <gi...@apache.org> on 2023/03/06 12:24:24 UTC

[GitHub] [nuttx-apps] anjiahao1 opened a new pull request, #1627: support ymodem protocal and sb rb application

anjiahao1 opened a new pull request, #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627

   ## Summary
   support ymodem, can use `sb` `rb` to send file and receive file
   ## Impact
   Noting
   ## Testing
   
   i test sb and rb in armv8-m borad, that run ok.
   Compared with zmodem, ymodem is less prone to errors and has lower requirements on hardware.


-- 
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


[GitHub] [nuttx-apps] anjiahao1 commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anjiahao1 (via GitHub)" <gi...@apache.org>.
anjiahao1 commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127411207


##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ymodem_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)

Review Comment:
   There are not many logs, just print some key information and error information



-- 
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


[GitHub] [nuttx-apps] anjiahao1 commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anjiahao1 (via GitHub)" <gi...@apache.org>.
anjiahao1 commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127327544


##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ymodem_uart_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                            size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t i = 0;
+  ssize_t ret;
+  long base;
+
+  base = get_current_time();
+  while (get_current_time() - base < timeout && i < size)
+    {
+      ret = read(uart_fd, buf + i, size - i);
+      if (ret >= 0)
+        {
+          i += ret;
+        }
+    }
+
+  if (i == 0)
+    {
+      return -1;
+    }
+
+  return i;
+}
+
+ssize_t ymodem_uart_send(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                         size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t sendsize = 0;
+  size_t bufsize = 0;
+  size_t ret;
+  int count;
+  long base;
+
+  ioctl(uart_fd, FIONSPACE, &bufsize);
+  base = get_current_time();
+  while (get_current_time() - base < timeout)
+    {
+      if (size < bufsize)
+        {
+          bufsize = size;
+        }
+
+      ret = write(uart_fd, buf + sendsize, bufsize);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      sendsize += ret;
+      size -= ret;
+      if (size)
+        {
+wait_send:

Review Comment:
   don't use delay,just use ioctl get remaining writing byte



-- 
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


[GitHub] [nuttx-apps] anchao commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anchao (via GitHub)" <gi...@apache.org>.
anchao commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127324803


##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ymodem_uart_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                            size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t i = 0;
+  ssize_t ret;
+  long base;
+
+  base = get_current_time();
+  while (get_current_time() - base < timeout && i < size)
+    {
+      ret = read(uart_fd, buf + i, size - i);
+      if (ret >= 0)
+        {
+          i += ret;
+        }
+    }
+
+  if (i == 0)
+    {
+      return -1;
+    }
+
+  return i;
+}
+
+ssize_t ymodem_uart_send(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                         size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t sendsize = 0;
+  size_t bufsize = 0;
+  size_t ret;
+  int count;
+  long base;
+
+  ioctl(uart_fd, FIONSPACE, &bufsize);
+  base = get_current_time();
+  while (get_current_time() - base < timeout)
+    {
+      if (size < bufsize)
+        {
+          bufsize = size;
+        }
+
+      ret = write(uart_fd, buf + sendsize, bufsize);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      sendsize += ret;
+      size -= ret;
+      if (size)
+        {
+wait_send:

Review Comment:
   or maybe it is better to add some delay here?



-- 
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


[GitHub] [nuttx-apps] anjiahao1 commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anjiahao1 (via GitHub)" <gi...@apache.org>.
anjiahao1 commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127326967


##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(FAR struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + YMODEM_FILE_NAME_LENGTH];
+  FAR struct ym_fd *ym_fd = ctx->priv;
+  FAR char *filename;
+  size_t size;
+  size_t ret;
+
+  if (ctx->packet_type == YMODEM_FILE_RECV_NAME_PKT)
+    {
+      if (ym_fd->file_fd != 0)
+        {
+          close(ym_fd->file_fd);
+        }
+
+      if (strlen(ym_fd->pathname) != 0)
+        {
+          if (ym_fd->pathname[strlen(ym_fd->pathname) - 1] == '/')
+            {
+              sprintf(pathname, "%s%s", ym_fd->pathname, ctx->file_name);
+            }
+          else
+            {
+              sprintf(pathname, "%s/%s", ym_fd->pathname, ctx->file_name);
+            }
+
+          filename = pathname;
+        }
+      else
+        {
+          filename = ctx->file_name;
+        }
+
+      ym_fd->file_fd = open(filename, O_CREAT | O_RDWR);
+      if (ym_fd->file_fd < 0)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size = 0;
+    }
+  else if (ctx->packet_type == YMODEM_RECV_DATA_PKT)
+    {
+      if (ym_fd->file_saved_size + ctx->packet_size > ctx->file_length)
+        {
+          size = ctx->file_length - ym_fd->file_saved_size;
+        }
+      else
+        {
+          size = ctx->packet_size;
+        }
+
+      ret = write(ym_fd->file_fd, ctx->data, size);
+      if (ret != size)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size += ret;
+    }
+
+  return 0;
+}
+
+static void show_usage(FAR const char *progname, int errcode)
+{
+  fprintf(stderr, "USAGE: %s [OPTIONS]\n", progname);
+  fprintf(stderr, "\nWhere:\n");
+  fprintf(stderr, "\nand OPTIONS include the following:\n");
+  fprintf(stderr,
+          "\t-d <device>: Communication device to use.  Default: %s\n",
+          CONFIG_SYSTEM_YMODEM_DEVNAME);
+  fprintf(stderr,
+          "\t-p <path>: Save remote file path. Default: Current path\n");
+  exit(errcode);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  FAR const char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;
+  struct termios saveterm;
+  struct ymodem_ctx ctx;
+  struct termios term;
+  struct ym_fd ym_fd;
+  int option;
+
+  memset(&ym_fd, 0, sizeof(struct ym_fd));
+  while ((option = getopt(argc, argv, "d:p:h")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'd':
+            devname = optarg;
+            break;
+          case 'h':
+            show_usage(argv[0], EXIT_FAILURE);
+          case 'p':
+            strncpy(ym_fd.pathname, optarg, PATH_MAX);
+            break;
+          default:
+          case '?':
+            fprintf(stderr, "ERROR: Unrecognized option\n");
+            show_usage(argv[0], EXIT_FAILURE);
+            break;
+        }
+    }
+
+  memset(&ctx, 0, sizeof(struct ymodem_ctx));
+  ctx.send = ymodem_uart_send;
+  ctx.receive = ymodem_uart_receive;
+  ctx.packet_handler = handler;
+  ctx.timeout = 200;
+  ctx.priv = &ym_fd;
+
+  ym_fd.file_fd = 0;
+  ym_fd.uart_fd = open(devname, O_RDWR | O_NONBLOCK);
+  if (ym_fd.uart_fd < 0)
+    {
+      printf("open\n");
+      return 0;
+    }
+
+  tcgetattr(ym_fd.uart_fd, &saveterm);
+  tcgetattr(ym_fd.uart_fd, &term);
+  cfmakeraw(&term);
+  tcsetattr(ym_fd.uart_fd, TCSANOW, &term);
+
+  sched_lock();

Review Comment:
   Make sure that other applications will not use/dev/console



-- 
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


[GitHub] [nuttx-apps] anchao commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anchao (via GitHub)" <gi...@apache.org>.
anchao commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127358716


##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ymodem_uart_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                            size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t i = 0;
+  ssize_t ret;
+  long base;
+
+  base = get_current_time();
+  while (get_current_time() - base < timeout && i < size)
+    {
+      ret = read(uart_fd, buf + i, size - i);
+      if (ret >= 0)
+        {
+          i += ret;
+        }
+    }
+
+  if (i == 0)
+    {
+      return -1;
+    }
+
+  return i;
+}
+
+ssize_t ymodem_uart_send(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                         size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t sendsize = 0;
+  size_t bufsize = 0;
+  size_t ret;
+  int count;
+  long base;
+
+  ioctl(uart_fd, FIONSPACE, &bufsize);
+  base = get_current_time();
+  while (get_current_time() - base < timeout)
+    {
+      if (size < bufsize)
+        {
+          bufsize = size;
+        }
+
+      ret = write(uart_fd, buf + sendsize, bufsize);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      sendsize += ret;
+      size -= ret;
+      if (size)
+        {
+wait_send:

Review Comment:
   There will be a potential busyloop here



-- 
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


[GitHub] [nuttx-apps] xiaoxiang781216 commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1126908488


##########
system/ymodem/README.md:
##########
@@ -0,0 +1,28 @@
+# Introduce
+
+This is [ymodem protocal](http://pauillac.inria.fr/~doligez/zmodem/ymodem.txt). 
+According to it, the sb rb application is realized, which is used to send files and receive files respectively
+
+# Usage
+
+In the ubuntu system, lszrz needs to be installed, can use `sudo apt install lszrz`. 
+Use minicom to communicate with the board.
+
+## Sendfile to pc
+
+use sb cmd like this `nsh> sb /tmp/test.c ...`, this command support send multiple files together 
+then use `<Ctrl + a> , r` chose `ymodem` to receive borad file.

Review Comment:
   ```suggestion
   then use `<Ctrl + a> , r` chose `ymodem` to receive board file.
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
+#else
+#  define ym_debug(...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];

Review Comment:
   ```suggestion
     uint8_t data[PACKET_1K_SIZE];
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
+#else
+#  define ym_debug(...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  CODE ssize_t (*send)(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                       size_t size, uint32_t timeout);
+  CODE ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf,

Review Comment:
   ```suggestion
     CODE ssize_t (*receive)(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
+#else
+#  define ym_debug(...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];

Review Comment:
   char to uint8_t



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
+#else
+#  define ym_debug(...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  CODE ssize_t (*send)(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                       size_t size, uint32_t timeout);
+  CODE ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf,
+                          size_t size, uint32_t timeout);
+  CODE ssize_t (*packet_handler)(FAR struct ymodem_ctx *ctx);
+  FAR void *priv;
+  uint16_t need_sendfile_num;
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+  int debug_fd;
+#endif
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int ymodem_rcv(FAR struct ymodem_ctx *ctx);

Review Comment:
   ```suggestion
   int ymodem_recv(FAR struct ymodem_ctx *ctx);
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)

Review Comment:
   ym_->ymodem_



##########
system/ymodem/ym_utils.h:
##########
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YM_UTILS_H
+#define __APPS_SYSTEM_YMODEM_YM_UTILS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+ssize_t ym_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,

Review Comment:
   ym_ to ymodem_



##########
system/ymodem/sb_main.c:
##########
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * apps/system/ymodem/sb_main.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 <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+struct ym_fd

Review Comment:
   ym->ymodem



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
+#else
+#  define ym_debug(...)
+#endif
+
+#define PACKET_SIZE                  (128)

Review Comment:
   add prefix YMODE_



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
+#else
+#  define ym_debug(...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)

Review Comment:
   YM_ to YMODEM_



-- 
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


[GitHub] [nuttx-apps] anjiahao1 commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anjiahao1 (via GitHub)" <gi...@apache.org>.
anjiahao1 commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127454300


##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ymodem_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)

Review Comment:
   you can set CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH to "/dev/console"



-- 
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


[GitHub] [nuttx-apps] anjiahao1 commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anjiahao1 (via GitHub)" <gi...@apache.org>.
anjiahao1 commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127326708


##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ymodem_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)

Review Comment:
   However, it is usually transmitted by/dev/console. It is more convenient for using writing files



-- 
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


[GitHub] [nuttx-apps] anchao commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anchao (via GitHub)" <gi...@apache.org>.
anchao commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127316928


##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(FAR struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + YMODEM_FILE_NAME_LENGTH];
+  FAR struct ym_fd *ym_fd = ctx->priv;
+  FAR char *filename;
+  size_t size;
+  size_t ret;
+
+  if (ctx->packet_type == YMODEM_FILE_RECV_NAME_PKT)
+    {
+      if (ym_fd->file_fd != 0)
+        {
+          close(ym_fd->file_fd);
+        }
+
+      if (strlen(ym_fd->pathname) != 0)
+        {
+          if (ym_fd->pathname[strlen(ym_fd->pathname) - 1] == '/')
+            {
+              sprintf(pathname, "%s%s", ym_fd->pathname, ctx->file_name);
+            }
+          else
+            {
+              sprintf(pathname, "%s/%s", ym_fd->pathname, ctx->file_name);
+            }
+
+          filename = pathname;
+        }
+      else
+        {
+          filename = ctx->file_name;
+        }
+
+      ym_fd->file_fd = open(filename, O_CREAT | O_RDWR);
+      if (ym_fd->file_fd < 0)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size = 0;
+    }
+  else if (ctx->packet_type == YMODEM_RECV_DATA_PKT)
+    {
+      if (ym_fd->file_saved_size + ctx->packet_size > ctx->file_length)
+        {
+          size = ctx->file_length - ym_fd->file_saved_size;
+        }
+      else
+        {
+          size = ctx->packet_size;
+        }
+
+      ret = write(ym_fd->file_fd, ctx->data, size);
+      if (ret != size)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size += ret;
+    }
+
+  return 0;
+}
+
+static void show_usage(FAR const char *progname, int errcode)
+{
+  fprintf(stderr, "USAGE: %s [OPTIONS]\n", progname);
+  fprintf(stderr, "\nWhere:\n");
+  fprintf(stderr, "\nand OPTIONS include the following:\n");
+  fprintf(stderr,
+          "\t-d <device>: Communication device to use.  Default: %s\n",
+          CONFIG_SYSTEM_YMODEM_DEVNAME);
+  fprintf(stderr,
+          "\t-p <path>: Save remote file path. Default: Current path\n");
+  exit(errcode);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  FAR const char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;
+  struct termios saveterm;
+  struct ymodem_ctx ctx;
+  struct termios term;
+  struct ym_fd ym_fd;
+  int option;
+
+  memset(&ym_fd, 0, sizeof(struct ym_fd));
+  while ((option = getopt(argc, argv, "d:p:h")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'd':
+            devname = optarg;
+            break;
+          case 'h':
+            show_usage(argv[0], EXIT_FAILURE);
+          case 'p':
+            strncpy(ym_fd.pathname, optarg, PATH_MAX);
+            break;
+          default:
+          case '?':
+            fprintf(stderr, "ERROR: Unrecognized option\n");
+            show_usage(argv[0], EXIT_FAILURE);
+            break;
+        }
+    }
+
+  memset(&ctx, 0, sizeof(struct ymodem_ctx));
+  ctx.send = ymodem_uart_send;
+  ctx.receive = ymodem_uart_receive;
+  ctx.packet_handler = handler;
+  ctx.timeout = 200;
+  ctx.priv = &ym_fd;
+
+  ym_fd.file_fd = 0;
+  ym_fd.uart_fd = open(devname, O_RDWR | O_NONBLOCK);
+  if (ym_fd.uart_fd < 0)
+    {
+      printf("open\n");
+      return 0;
+    }
+
+  tcgetattr(ym_fd.uart_fd, &saveterm);
+  tcgetattr(ym_fd.uart_fd, &term);
+  cfmakeraw(&term);
+  tcsetattr(ym_fd.uart_fd, TCSANOW, &term);
+
+  sched_lock();

Review Comment:
   why need sched_lock()?



##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ymodem_uart_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                            size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t i = 0;
+  ssize_t ret;
+  long base;
+
+  base = get_current_time();
+  while (get_current_time() - base < timeout && i < size)
+    {
+      ret = read(uart_fd, buf + i, size - i);
+      if (ret >= 0)
+        {
+          i += ret;
+        }
+    }
+
+  if (i == 0)
+    {
+      return -1;
+    }
+
+  return i;
+}
+
+ssize_t ymodem_uart_send(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf,
+                         size_t size, uint32_t timeout)
+{
+  int uart_fd = *(FAR int *)ctx->priv;
+  size_t sendsize = 0;
+  size_t bufsize = 0;
+  size_t ret;
+  int count;
+  long base;
+
+  ioctl(uart_fd, FIONSPACE, &bufsize);
+  base = get_current_time();
+  while (get_current_time() - base < timeout)
+    {
+      if (size < bufsize)
+        {
+          bufsize = size;
+        }
+
+      ret = write(uart_fd, buf + sendsize, bufsize);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      sendsize += ret;
+      size -= ret;
+      if (size)
+        {
+wait_send:

Review Comment:
   ```
   do
     {
       ioctl(uart_fd, FIONWRITE, &count);
     }
   while (count != 0);
   
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ymodem_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)

Review Comment:
   Redirecte to stdout if CONFIG_SYSTEM_YMODEM_DEBUG is enabled && transport device is not /dev/console



-- 
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


[GitHub] [nuttx-apps] pkarashchenko commented on a diff in pull request #1627: support ymodem protocal and sb rb application

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


##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   static int handler(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/sb_main.c:
##########
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * apps/system/ymodem/sb_main.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 <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char **filelist;

Review Comment:
   ```suggestion
     FAR char **filelist;
   ```



##########
system/ymodem/sb_main.c:
##########
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * apps/system/ymodem/sb_main.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 <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char **filelist;
+  size_t filenum;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static ssize_t handler(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   static ssize_t handler(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                   uint32_t timeout)
+{
+  int uart_fd = *(int *)ctx->priv;
+  size_t i = 0;
+  ssize_t ret;
+  long base;
+
+  base = get_current_time();
+  while (get_current_time() - base < timeout && i < size)
+    {
+      ret = read(uart_fd, buf + i, size - i);
+      if (ret >= 0)
+        {
+          i += ret;
+        }
+    }
+
+  if (i == 0)
+    {
+      return -1;
+    }
+
+  return i;
+}
+
+ssize_t ym_send(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,

Review Comment:
   ```suggestion
   ssize_t ym_send(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,
   ```



##########
system/ymodem/sb_main.c:
##########
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * apps/system/ymodem/sb_main.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 <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char **filelist;
+  size_t filenum;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static ssize_t handler(struct ymodem_ctx *ctx)
+{
+  struct stat info;
+  struct ym_fd *ym_fd = ctx->priv;
+  char *filename;

Review Comment:
   ```suggestion
     FAR struct ym_fd *ym_fd = ctx->priv;
     FAR char *filename;
   ```



##########
system/ymodem/ym_utils.h:
##########
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+#define __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                   uint32_t timeout);
+
+ssize_t ym_send(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                uint32_t timeout);
+
+#endif /* __APPS_SYSTEM_YMODEM_YM_UTILS_H_ */

Review Comment:
   ```suggestion
   #endif /* __APPS_SYSTEM_YMODEM_YM_UTILS_H */
   ```



##########
system/ymodem/ym_utils.h:
##########
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+#define __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                   uint32_t timeout);
+
+ssize_t ym_send(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,

Review Comment:
   ```suggestion
   ssize_t ym_send(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,
   ```



##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + FILE_NAME_LENGTH];
+  struct ym_fd *ym_fd = ctx->priv;
+  char *filename;
+  size_t size;
+  size_t ret;
+
+  if (ctx->packet_type == YM_FILE_RECV_NAME_PKT)
+    {
+      if (ym_fd->file_fd != 0)
+        {
+          close(ym_fd->file_fd);
+        }
+
+      if (strlen(ym_fd->pathname) != 0)
+        {
+          if (ym_fd->pathname[strlen(ym_fd->pathname) - 1] == '/')
+            {
+              sprintf(pathname, "%s%s", ym_fd->pathname, ctx->file_name);
+            }
+          else
+            {
+              sprintf(pathname, "%s/%s", ym_fd->pathname, ctx->file_name);
+            }
+
+          filename = pathname;
+        }
+      else
+        {
+          filename = ctx->file_name;
+        }
+
+      ym_fd->file_fd = open(filename, O_CREAT | O_RDWR);
+      if (ym_fd->file_fd < 0)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size = 0;
+    }
+  else if (ctx->packet_type == YM_RECV_DATA_PKT)
+    {
+      if (ym_fd->file_saved_size + ctx->packet_size > ctx->file_length)
+        {
+          size = ctx->file_length - ym_fd->file_saved_size;
+        }
+      else
+        {
+          size = ctx->packet_size;
+        }
+
+      ret = write(ym_fd->file_fd, ctx->data, size);
+      if (ret != size)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size += ret;
+    }
+
+  return 0;
+}
+
+static void show_usage(FAR const char *progname, int errcode)
+{
+  fprintf(stderr, "USAGE: %s [OPTIONS]\n", progname);
+  fprintf(stderr, "\nWhere:\n");
+  fprintf(stderr, "\nand OPTIONS include the following:\n");
+  fprintf(stderr,
+          "\t-d <device>: Communication device to use.  Default: %s\n",
+          CONFIG_SYSTEM_YMODEM_DEVNAME);
+  fprintf(stderr,
+          "\t-p <path>: Save remote file path. Default: Current path\n");
+  exit(errcode);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv)

Review Comment:
   ```suggestion
   int main(int argc, FAR char *argv[])
   ```



##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + FILE_NAME_LENGTH];
+  struct ym_fd *ym_fd = ctx->priv;
+  char *filename;

Review Comment:
   ```suggestion
     FAR char *filename;
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)
+{
+  size_t size;
+  uint16_t crc;
+  uint8_t send_crc[2];
+
+  crc = crc16((const uint8_t *)ctx->data, ctx->packet_size);

Review Comment:
   ```suggestion
     crc = crc16((FAR const uint8_t *)ctx->data, ctx->packet_size);
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)
+{
+  size_t size;
+  uint16_t crc;
+  uint8_t send_crc[2];
+
+  crc = crc16((const uint8_t *)ctx->data, ctx->packet_size);
+  size = ctx->send(ctx, (uint8_t *)&ctx->header,

Review Comment:
   ```suggestion
     size = ctx->send(ctx, (FAR uint8_t *)&ctx->header,
   ```



##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + FILE_NAME_LENGTH];
+  struct ym_fd *ym_fd = ctx->priv;

Review Comment:
   ```suggestion
     FAR struct ym_fd *ym_fd = ctx->priv;
   ```



##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + FILE_NAME_LENGTH];
+  struct ym_fd *ym_fd = ctx->priv;
+  char *filename;
+  size_t size;
+  size_t ret;
+
+  if (ctx->packet_type == YM_FILE_RECV_NAME_PKT)
+    {
+      if (ym_fd->file_fd != 0)
+        {
+          close(ym_fd->file_fd);
+        }
+
+      if (strlen(ym_fd->pathname) != 0)
+        {
+          if (ym_fd->pathname[strlen(ym_fd->pathname) - 1] == '/')
+            {
+              sprintf(pathname, "%s%s", ym_fd->pathname, ctx->file_name);
+            }
+          else
+            {
+              sprintf(pathname, "%s/%s", ym_fd->pathname, ctx->file_name);
+            }
+
+          filename = pathname;
+        }
+      else
+        {
+          filename = ctx->file_name;
+        }
+
+      ym_fd->file_fd = open(filename, O_CREAT | O_RDWR);
+      if (ym_fd->file_fd < 0)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size = 0;
+    }
+  else if (ctx->packet_type == YM_RECV_DATA_PKT)
+    {
+      if (ym_fd->file_saved_size + ctx->packet_size > ctx->file_length)
+        {
+          size = ctx->file_length - ym_fd->file_saved_size;
+        }
+      else
+        {
+          size = ctx->packet_size;
+        }
+
+      ret = write(ym_fd->file_fd, ctx->data, size);
+      if (ret != size)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size += ret;
+    }
+
+  return 0;
+}
+
+static void show_usage(FAR const char *progname, int errcode)
+{
+  fprintf(stderr, "USAGE: %s [OPTIONS]\n", progname);
+  fprintf(stderr, "\nWhere:\n");
+  fprintf(stderr, "\nand OPTIONS include the following:\n");
+  fprintf(stderr,
+          "\t-d <device>: Communication device to use.  Default: %s\n",
+          CONFIG_SYSTEM_YMODEM_DEVNAME);
+  fprintf(stderr,
+          "\t-p <path>: Save remote file path. Default: Current path\n");
+  exit(errcode);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv)
+{
+  char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;

Review Comment:
   ```suggestion
     FAR const char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;
   ```



##########
system/ymodem/sb_main.c:
##########
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * apps/system/ymodem/sb_main.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 <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char **filelist;
+  size_t filenum;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static ssize_t handler(struct ymodem_ctx *ctx)
+{
+  struct stat info;
+  struct ym_fd *ym_fd = ctx->priv;
+  char *filename;
+  ssize_t ret = -EINVAL;
+
+  if (ctx->packet_type == YM_FILE_SEND_NAME_PKT)
+    {
+      if (ym_fd->file_fd != 0)
+        {
+          close(ym_fd->file_fd);
+        }
+
+      filename = ym_fd->filelist[ym_fd->filenum++];
+      ret = lstat(filename, &info);
+      if (ret < 0)
+        {
+          return -1;
+        }
+
+      ym_fd->file_fd = open(filename, O_RDWR);
+      if (ym_fd->file_fd < 0)
+        {
+          return -1;
+        }
+
+      filename = basename(filename);
+      strncpy(ctx->file_name, filename, FILE_NAME_LENGTH);
+      ctx->file_length = info.st_size;
+    }
+  else if (ctx->packet_type == YM_SEND_DATA_PKT)
+    {
+      ret = read(ym_fd->file_fd, ctx->data, ctx->packet_size);
+      if (ret < 0)
+        {
+          return ret;
+        }
+    }
+
+  return ret;
+}
+
+static void show_usage(FAR const char *progname, int errcode)
+{
+  fprintf(stderr, "USAGE: %s [OPTIONS] <lname> [<lname> [<lname> ...]]\n",
+                  progname);
+  fprintf(stderr, "\nWhere:\n");
+  fprintf(stderr, "\t<lname> is the local file name\n");
+  fprintf(stderr, "\nand OPTIONS include the following:\n");
+  fprintf(stderr,
+          "\t-d <device>: Communication device to use.  Default: %s\n",
+          CONFIG_SYSTEM_YMODEM_DEVNAME);
+
+  exit(errcode);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;

Review Comment:
   ```suggestion
     FAR const char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)

Review Comment:
   ```suggestion
   #  define ym_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)
   #else
   #  define ym_debug(...)
   ```



##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,

Review Comment:
   ```suggestion
   ssize_t ym_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)
+{
+  size_t size;
+  uint16_t crc;
+  uint8_t send_crc[2];
+
+  crc = crc16((const uint8_t *)ctx->data, ctx->packet_size);
+  size = ctx->send(ctx, (uint8_t *)&ctx->header,
+                   ctx->packet_size + 3, ctx->timeout);
+
+  if (size != ctx->packet_size + 3)
+    {
+      ym_debug("send pkt error\n");
+      return -1;
+    }
+
+  send_crc[0] = crc >> 8;
+  send_crc[1] = crc & 0x00ff;
+  size = ctx->send(ctx, send_crc, 2, ctx->timeout);
+  if (size != 2)
+    {
+      ym_debug("send crc16 error\n");
+      return -1;
+    }
+
+  return 0;
+}
+
+static int ymodem_rcv_cmd(struct ymodem_ctx *ctx, uint8_t cmd)
+{
+  size_t size;
+  uint8_t chunk[1];
+
+  size = ctx->receive(ctx, chunk, 1, ctx->timeout);
+  if (size != 1)
+    {
+      ym_debug("receive cmd error\n");
+      return -1;
+    }
+
+  if (chunk[0] == NAK)
+    {
+      return -EAGAIN;
+    }
+
+  if (chunk[0] != cmd)
+    {
+      ym_debug("receive cmd error, must 0x%x, but receive %d\n",
+               cmd, chunk[0]);
+      return -EINVAL;
+    }
+
+  return 0;
+}
+
+static int ymodem_send_file(struct ymodem_ctx *ctx)
+{
+  uint8_t chunk[1];
+  ssize_t readsize;
+  ssize_t size;
+  int err = 0;
+  int ret;
+
+  if (!ctx || !ctx->send || !ctx->receive || !ctx->packet_handler)
+    {
+      ym_debug("%s: invalid context config\n", __func__);
+      return -EINVAL;
+    }
+
+  if (ctx->need_sendfile_num <= 0)
+    {
+      ym_debug("need_sendfile_num is %d, no file to send!\n",
+               ctx->need_sendfile_num);
+      return -EINVAL;
+    }
+
+  chunk[0] = 0;
+  ym_debug("waiting handshake\n");
+  do
+    {
+      size = ctx->receive(ctx, chunk, 1, ctx->timeout);
+    }
+  while (err++ < MAX_ERRORS && chunk[0] != CRC16);
+
+  if (err >= MAX_ERRORS)
+    {
+      ym_debug("waiting handshake error\n");
+      return -ETIMEDOUT;
+    }
+
+  ym_debug("ymodem send file start\n");
+send_start:
+  ctx->packet_type = YM_FILE_SEND_NAME_PKT;
+  ctx->packet_handler(ctx);
+  if ((ctx->file_name[0] == 0 || ctx->file_length == 0))
+    {
+      ym_debug("get fileinfo error\n");
+      return -EINVAL;
+    }
+
+  ym_debug("sendfile filename:%s filelength:%d\n",
+           ctx->file_name, ctx->file_length);
+  memset(ctx->data, 0, PACKET_SIZE);
+  strncpy(ctx->data, ctx->file_name, FILE_NAME_LENGTH);
+  sprintf(ctx->data + strlen(ctx->file_name) + 1, "%d", ctx->file_length);
+  ctx->header = SOH;
+  ctx->packet_size = PACKET_SIZE;
+  ctx->seq[0] = 0x00;
+  ctx->seq[1] = 0xff;
+
+send_name:
+  ret = ymodem_send_pkt(ctx);
+  if (ret < 0)
+    {
+      ym_debug("send name pkt error\n");
+      return -EINVAL;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send name pkt receive NAK, need send again\n");
+      goto send_name;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send name pkt, receive error cmd\n");
+      return ret;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, CRC16);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send name pkt receive NAK, need send again\n");
+      goto send_name;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send name pkt, receive error cmd\n");
+      return ret;
+    }
+
+  ctx->packet_type = YM_SEND_DATA_PKT;
+send_pkt:
+  if (ctx->file_length <= PACKET_1K_SIZE)
+    {
+      ctx->header = SOH;
+      ctx->packet_size = PACKET_SIZE;
+    }
+  else
+    {
+      ctx->header = STX;
+      ctx->packet_size = PACKET_1K_SIZE;
+    }
+
+    ym_debug("packet_size is %d\n", ctx->packet_size);
+    ctx->seq[0]++;
+    ctx->seq[1]--;
+    readsize = ctx->packet_handler(ctx);
+    ym_debug("%s:%d: readsize is %d\n", __FILE__, __LINE__, readsize);
+
+  if (readsize < 0)
+    {
+      return readsize;
+    }
+
+  if (readsize == 0)
+    {
+      goto send_eot;
+    }
+
+  if (readsize < ctx->packet_size)
+    {
+      memset(ctx->data + readsize, 0x1a, ctx->packet_size - readsize);
+    }
+
+send_pkt_again:
+  ret = ymodem_send_pkt(ctx);
+  if (ret < 0)
+    {
+      ym_debug("send data pkt error\n");
+      return ret;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send data pkt receive NAK, need send again\n");
+      goto send_pkt_again;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send data pkt, receive error\n");
+      return ret;
+    }
+
+  ctx->file_length -= readsize;
+  if (ctx->file_length != 0)
+    {
+      ym_debug("The remain bytes sent are %d\n", ctx->file_length);
+      goto send_pkt;
+    }
+
+send_eot:
+  chunk[0] = EOT;
+  size = ctx->send(ctx, chunk, 1, ctx->timeout);
+  if (size < 0)
+    {
+      ym_debug("%s:%d: send EOT error\n", __FILE__, __LINE__, size);
+      return -1;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send EOT receive NAK, need send again\n");
+      goto send_eot;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send EOT, receive ACK error\n");
+      return ret;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, CRC16);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send EOT receive NAK, need send again\n");
+      goto send_eot;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send EOT, receive CRC16 error\n");
+      return ret;
+    }
+
+  if (--ctx->need_sendfile_num != 0)
+    {
+      ym_debug("need sendfile num is %d, so send file again\n",
+               ctx->need_sendfile_num);
+      goto send_start;
+    }
+
+send_last:
+  ctx->header = SOH;
+  ctx->packet_type = YM_SEND_DATA_PKT;
+  ctx->packet_size = PACKET_SIZE;
+  ctx->seq[0] = 0x00;
+  ctx->seq[1] = 0xff;
+  memset(ctx->data, 0, PACKET_SIZE);
+  ret = ymodem_send_pkt(ctx);
+  if (ret < 0)
+    {
+      ym_debug("send last pkt error\n");
+      return -1;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send last pkt, need send again\n");
+      goto send_last;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send last pkt, receive error\n");
+      return ret;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int ymodem_rcv(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   int ymodem_rcv(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  ssize_t (*send)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                  uint32_t timeout);
+  ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,

Review Comment:
   ```suggestion
     CODE ssize_t (*receive)(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,
   ```



##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                   uint32_t timeout)
+{
+  int uart_fd = *(int *)ctx->priv;

Review Comment:
   ```suggestion
     int uart_fd = *(FAR int *)ctx->priv;
   ```



##########
system/ymodem/ym_utils.c:
##########
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.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 <sys/time.h>
+#include <sys/ioctl.h>
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static long get_current_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                   uint32_t timeout)
+{
+  int uart_fd = *(int *)ctx->priv;
+  size_t i = 0;
+  ssize_t ret;
+  long base;
+
+  base = get_current_time();
+  while (get_current_time() - base < timeout && i < size)
+    {
+      ret = read(uart_fd, buf + i, size - i);
+      if (ret >= 0)
+        {
+          i += ret;
+        }
+    }
+
+  if (i == 0)
+    {
+      return -1;
+    }
+
+  return i;
+}
+
+ssize_t ym_send(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                uint32_t timeout)
+{
+  int uart_fd = *(int *)ctx->priv;

Review Comment:
   ```suggestion
     int uart_fd = *(FAR int *)ctx->priv;
   ```



##########
system/ymodem/ym_utils.h:
##########
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+#define __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+ssize_t ym_receive(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,

Review Comment:
   ```suggestion
   ssize_t ym_receive(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)
+{
+  size_t size;
+  uint16_t crc;
+  uint8_t send_crc[2];
+
+  crc = crc16((const uint8_t *)ctx->data, ctx->packet_size);
+  size = ctx->send(ctx, (uint8_t *)&ctx->header,
+                   ctx->packet_size + 3, ctx->timeout);
+
+  if (size != ctx->packet_size + 3)
+    {
+      ym_debug("send pkt error\n");
+      return -1;
+    }
+
+  send_crc[0] = crc >> 8;
+  send_crc[1] = crc & 0x00ff;
+  size = ctx->send(ctx, send_crc, 2, ctx->timeout);
+  if (size != 2)
+    {
+      ym_debug("send crc16 error\n");
+      return -1;
+    }
+
+  return 0;
+}
+
+static int ymodem_rcv_cmd(struct ymodem_ctx *ctx, uint8_t cmd)
+{
+  size_t size;
+  uint8_t chunk[1];
+
+  size = ctx->receive(ctx, chunk, 1, ctx->timeout);
+  if (size != 1)
+    {
+      ym_debug("receive cmd error\n");
+      return -1;
+    }
+
+  if (chunk[0] == NAK)
+    {
+      return -EAGAIN;
+    }
+
+  if (chunk[0] != cmd)
+    {
+      ym_debug("receive cmd error, must 0x%x, but receive %d\n",
+               cmd, chunk[0]);
+      return -EINVAL;
+    }
+
+  return 0;
+}
+
+static int ymodem_send_file(struct ymodem_ctx *ctx)
+{
+  uint8_t chunk[1];
+  ssize_t readsize;
+  ssize_t size;
+  int err = 0;
+  int ret;
+
+  if (!ctx || !ctx->send || !ctx->receive || !ctx->packet_handler)
+    {
+      ym_debug("%s: invalid context config\n", __func__);
+      return -EINVAL;
+    }
+
+  if (ctx->need_sendfile_num <= 0)
+    {
+      ym_debug("need_sendfile_num is %d, no file to send!\n",
+               ctx->need_sendfile_num);
+      return -EINVAL;
+    }
+
+  chunk[0] = 0;
+  ym_debug("waiting handshake\n");
+  do
+    {
+      size = ctx->receive(ctx, chunk, 1, ctx->timeout);
+    }
+  while (err++ < MAX_ERRORS && chunk[0] != CRC16);
+
+  if (err >= MAX_ERRORS)
+    {
+      ym_debug("waiting handshake error\n");
+      return -ETIMEDOUT;
+    }
+
+  ym_debug("ymodem send file start\n");
+send_start:
+  ctx->packet_type = YM_FILE_SEND_NAME_PKT;
+  ctx->packet_handler(ctx);
+  if ((ctx->file_name[0] == 0 || ctx->file_length == 0))
+    {
+      ym_debug("get fileinfo error\n");
+      return -EINVAL;
+    }
+
+  ym_debug("sendfile filename:%s filelength:%d\n",
+           ctx->file_name, ctx->file_length);
+  memset(ctx->data, 0, PACKET_SIZE);
+  strncpy(ctx->data, ctx->file_name, FILE_NAME_LENGTH);
+  sprintf(ctx->data + strlen(ctx->file_name) + 1, "%d", ctx->file_length);
+  ctx->header = SOH;
+  ctx->packet_size = PACKET_SIZE;
+  ctx->seq[0] = 0x00;
+  ctx->seq[1] = 0xff;
+
+send_name:
+  ret = ymodem_send_pkt(ctx);
+  if (ret < 0)
+    {
+      ym_debug("send name pkt error\n");
+      return -EINVAL;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send name pkt receive NAK, need send again\n");
+      goto send_name;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send name pkt, receive error cmd\n");
+      return ret;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, CRC16);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send name pkt receive NAK, need send again\n");
+      goto send_name;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send name pkt, receive error cmd\n");
+      return ret;
+    }
+
+  ctx->packet_type = YM_SEND_DATA_PKT;
+send_pkt:
+  if (ctx->file_length <= PACKET_1K_SIZE)
+    {
+      ctx->header = SOH;
+      ctx->packet_size = PACKET_SIZE;
+    }
+  else
+    {
+      ctx->header = STX;
+      ctx->packet_size = PACKET_1K_SIZE;
+    }
+
+    ym_debug("packet_size is %d\n", ctx->packet_size);
+    ctx->seq[0]++;
+    ctx->seq[1]--;
+    readsize = ctx->packet_handler(ctx);
+    ym_debug("%s:%d: readsize is %d\n", __FILE__, __LINE__, readsize);
+
+  if (readsize < 0)
+    {
+      return readsize;
+    }
+
+  if (readsize == 0)
+    {
+      goto send_eot;
+    }
+
+  if (readsize < ctx->packet_size)
+    {
+      memset(ctx->data + readsize, 0x1a, ctx->packet_size - readsize);
+    }
+
+send_pkt_again:
+  ret = ymodem_send_pkt(ctx);
+  if (ret < 0)
+    {
+      ym_debug("send data pkt error\n");
+      return ret;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send data pkt receive NAK, need send again\n");
+      goto send_pkt_again;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send data pkt, receive error\n");
+      return ret;
+    }
+
+  ctx->file_length -= readsize;
+  if (ctx->file_length != 0)
+    {
+      ym_debug("The remain bytes sent are %d\n", ctx->file_length);
+      goto send_pkt;
+    }
+
+send_eot:
+  chunk[0] = EOT;
+  size = ctx->send(ctx, chunk, 1, ctx->timeout);
+  if (size < 0)
+    {
+      ym_debug("%s:%d: send EOT error\n", __FILE__, __LINE__, size);
+      return -1;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send EOT receive NAK, need send again\n");
+      goto send_eot;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send EOT, receive ACK error\n");
+      return ret;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, CRC16);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send EOT receive NAK, need send again\n");
+      goto send_eot;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send EOT, receive CRC16 error\n");
+      return ret;
+    }
+
+  if (--ctx->need_sendfile_num != 0)
+    {
+      ym_debug("need sendfile num is %d, so send file again\n",
+               ctx->need_sendfile_num);
+      goto send_start;
+    }
+
+send_last:
+  ctx->header = SOH;
+  ctx->packet_type = YM_SEND_DATA_PKT;
+  ctx->packet_size = PACKET_SIZE;
+  ctx->seq[0] = 0x00;
+  ctx->seq[1] = 0xff;
+  memset(ctx->data, 0, PACKET_SIZE);
+  ret = ymodem_send_pkt(ctx);
+  if (ret < 0)
+    {
+      ym_debug("send last pkt error\n");
+      return -1;
+    }
+
+  ret = ymodem_rcv_cmd(ctx, ACK);
+  if (ret == -EAGAIN)
+    {
+      ym_debug("send last pkt, need send again\n");
+      goto send_last;
+    }
+
+  if (ret < 0)
+    {
+      ym_debug("send last pkt, receive error\n");
+      return ret;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int ymodem_rcv(struct ymodem_ctx *ctx)
+{
+  int ret;
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+  ctx->debug_fd = open(CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH,
+                       O_CREAT | O_RDWR);
+  if (ctx->debug_fd < 0)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  if (!ctx || !ctx->send || !ctx->receive || !ctx->packet_handler)
+    {
+      ym_debug("ymodem: invalid context config\n");
+      return -EINVAL;
+    }
+
+  while (1)
+    {
+      ret = ymodem_rcv_file(ctx);
+      if (ret == -EEOT)
+        {
+          continue;
+        }
+
+      break;
+    }
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+  close(ctx->debug_fd);
+#endif
+
+  return ret;
+}
+
+int ymodem_send(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   int ymodem_send(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  ssize_t (*send)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,

Review Comment:
   ```suggestion
     CODE ssize_t (*send)(FAR struct ymodem_ctx *ctx, FAR uint8_t *buf, size_t size,
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  ssize_t (*send)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                  uint32_t timeout);
+  ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                     uint32_t timeout);
+  ssize_t (*packet_handler)(struct ymodem_ctx *ctx);

Review Comment:
   ```suggestion
     CODE ssize_t (*packet_handler)(FAR struct ymodem_ctx *ctx);
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  ssize_t (*send)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                  uint32_t timeout);
+  ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                     uint32_t timeout);
+  ssize_t (*packet_handler)(struct ymodem_ctx *ctx);
+  void *priv;

Review Comment:
   ```suggestion
     FAR void *priv;
   ```



##########
system/ymodem/ym_utils.h:
##########
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * apps/system/ymodem/ym_utils.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YM_UTILS_H_
+#define __APPS_SYSTEM_YMODEM_YM_UTILS_H_

Review Comment:
   ```suggestion
   #ifndef __APPS_SYSTEM_YMODEM_YM_UTILS_H
   #define __APPS_SYSTEM_YMODEM_YM_UTILS_H
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  ssize_t (*send)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                  uint32_t timeout);
+  ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                     uint32_t timeout);
+  ssize_t (*packet_handler)(struct ymodem_ctx *ctx);
+  void *priv;
+  uint16_t need_sendfile_num;
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+  int debug_fd;
+#endif
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int ymodem_rcv(struct ymodem_ctx *ctx);
+int ymodem_send(struct ymodem_ctx *ctx);

Review Comment:
   ```suggestion
   int ymodem_rcv(FAR struct ymodem_ctx *ctx);
   int ymodem_send(FAR struct ymodem_ctx *ctx);
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;

Review Comment:
   ```suggestion
     FAR char *str;
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   static int ymodem_rcv_pkt(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);

Review Comment:
   ```suggestion
     cal_crc = crc16((FAR const uint8_t *)ctx->data, packet_size);
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   static int ymodem_rcv_file(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   static int ymodem_send_pkt(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)
+{
+  size_t size;
+  uint16_t crc;
+  uint8_t send_crc[2];
+
+  crc = crc16((const uint8_t *)ctx->data, ctx->packet_size);
+  size = ctx->send(ctx, (uint8_t *)&ctx->header,
+                   ctx->packet_size + 3, ctx->timeout);
+
+  if (size != ctx->packet_size + 3)
+    {
+      ym_debug("send pkt error\n");
+      return -1;
+    }
+
+  send_crc[0] = crc >> 8;
+  send_crc[1] = crc & 0x00ff;
+  size = ctx->send(ctx, send_crc, 2, ctx->timeout);
+  if (size != 2)
+    {
+      ym_debug("send crc16 error\n");
+      return -1;
+    }
+
+  return 0;
+}
+
+static int ymodem_rcv_cmd(struct ymodem_ctx *ctx, uint8_t cmd)

Review Comment:
   ```suggestion
   static int ymodem_rcv_cmd(FAR struct ymodem_ctx *ctx, uint8_t cmd)
   ```



##########
system/ymodem/ymodem.c:
##########
@@ -0,0 +1,624 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.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 <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <nuttx/crc16.h>
+#include "ymodem.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SOH           (0x01)  /* start of 128-byte data packet */
+#define STX           (0x02)  /* start of 1024-byte data packet */
+#define EOT           (0x04)  /* end of transmission */
+#define ACK           (0x06)  /* acknowledge */
+#define NAK           (0x15)  /* negative acknowledge */
+#define CA            (0x18)  /* two of these in succession aborts transfer */
+#define CRC16         (0x43)  /* 'C' == 0x43, request 16-bit CRC */
+
+#define MAX_ERRORS    (100)
+
+#define EEOT 200    /* End of transfer */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int ymodem_rcv_pkt(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  uint16_t packet_size;
+  uint16_t rcv_crc;
+  uint16_t cal_crc;
+  uint8_t crchl[2];
+  uint8_t chunk[1];
+  int ret;
+
+  ret = ctx->receive(ctx, chunk, 1, timeout);
+  if (ret != 1)
+    {
+      return ret;
+    }
+
+  switch (chunk[0])
+    {
+      case SOH:
+        packet_size = PACKET_SIZE;
+        break;
+      case STX:
+        packet_size = PACKET_1K_SIZE;
+        break;
+      case EOT:
+        return -EEOT;
+      case CA:
+        ret = ctx->receive(ctx, chunk, 1, timeout);
+        if (ret != 1 && chunk[0] == CA)
+          {
+            return -ECANCELED;
+          }
+        else
+          {
+            return -EBADMSG;
+          }
+
+      default:
+          ym_debug("rcv_pkt: EBADMSG: c=%d\n", c);
+          return -EBADMSG;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->seq, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, (uint8_t *)ctx->data, packet_size, timeout);
+  if (ret != packet_size)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  ret = ctx->receive(ctx, crchl, 2, timeout);
+  if (ret != 2)
+    {
+      ym_debug("rcv_pkt: err=%d\n", ret);
+      return ret;
+    }
+
+  if ((ctx->seq[0] + ctx->seq[1]) != 0xff)
+    {
+      ym_debug("rcv_pkt: EILSEQ seq[]=%d %d\n", ctx->seq[0], ctx->seq[1]);
+      return -EILSEQ;
+    }
+
+  rcv_crc = (uint16_t)((crchl[0] << 8) + crchl[1]);
+  cal_crc = crc16((const uint8_t *)ctx->data, packet_size);
+  if (rcv_crc != cal_crc)
+    {
+      ym_debug("rcv_pkt: EBADMSG rcv:cal=%x %x\n", rcv_crc, cal_crc);
+      return -EBADMSG;
+    }
+
+  ctx->packet_size = packet_size;
+  ym_debug("rcv_pkt:OK: size=%d, seq=%d\n", packet_size, ctx->seq[0]);
+  return 0;
+}
+
+static int ymodem_rcv_file(struct ymodem_ctx *ctx)
+{
+  uint32_t timeout = ctx->timeout;
+  bool file_start = false;
+  bool file_done = false;
+  uint32_t total_seq = 0;
+  bool canceled = false;
+  uint8_t chunk[1];
+  int ret = 0;
+  int err = 0;
+  char *str;
+
+  chunk[0] = CRC16;
+  ctx->send(ctx, chunk, 1, timeout);
+  while (!file_done)
+    {
+      ret = ymodem_rcv_pkt(ctx);
+      if (!ret)
+        {
+          if ((total_seq & 0xff) != ctx->seq[0])
+            {
+              ym_debug("rcv_file: total seq erro:%d %d\n", total_seq,
+                                                           ctx->seq[0]);
+              chunk[0] = CRC16;
+              ctx->send(ctx, chunk, 1, timeout);
+            }
+          else
+            {
+              /* update with the total sequence number */
+
+              ctx->seq[0] = total_seq;
+
+              /* file name packet */
+
+              if (total_seq == 0)
+                {
+                  /* Filename packet is empty, end session */
+
+                  if (ctx->data[0] == '\0')
+                    {
+                      ym_debug("rcv_file: session finished\n");
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+
+                      /* last file done, so the session also finished */
+
+                      file_done = true;
+                    }
+                  else
+                    {
+                      str = ctx->data;
+                      ctx->packet_type = YM_FILE_RECV_NAME_PKT;
+                      strncpy(ctx->file_name, str, FILE_NAME_LENGTH);
+                      ctx->file_name[FILE_NAME_LENGTH - 1] = '\0';
+                      str += strlen(str) + 1;
+                      ctx->file_length = atoi(str);
+                      ym_debug("rcv_file: new file %s(%d) start\n",
+                               ctx->file_name, ctx->file_length);
+                      ret = ctx->packet_handler(ctx);
+                      if (ret)
+                        {
+                          ym_debug("rcv_file: handler err for file \
+                                    name packet: ret=%d\n", ret);
+                          canceled = true;
+                          ret = -ENOEXEC;
+                          break;
+                        }
+
+                      file_start = true;
+                      chunk[0] = ACK;
+                      ctx->send(ctx, chunk, 1, timeout);
+                      chunk[0] = CRC16;
+                      ctx->send(ctx, chunk, 1, timeout);
+                    }
+                }
+              else
+                {
+                  /* data packet */
+
+                  ctx->packet_type = YM_RECV_DATA_PKT;
+                  ret = ctx->packet_handler(ctx);
+                  if (ret)
+                    {
+                      ym_debug("rcv_file: handler err for data \
+                                packet: ret=%d\n", ret);
+                      canceled = true;
+                      ret = -ENOEXEC;
+                      break;
+                    }
+
+                  chunk[0] = ACK;
+                  ctx->send(ctx, chunk, 1, timeout);
+                }
+
+              ym_debug("rcv_file: pkt %d %s\n",
+                        total_seq, ret ? "failed" : "success");
+
+              total_seq++;
+            }
+        }
+      else if (ret == -ECANCELED)
+        {
+          ym_debug("rcv_file: canceled by sender\n");
+          canceled = true;
+          break;
+        }
+      else if (ret == -EEOT)
+        {
+          chunk[0] = ACK;
+          ctx->send(ctx, chunk, 1, timeout);
+          file_done = true;
+          ym_debug("rcv_file: finished one file transfer\n");
+        }
+      else
+        {
+          /* other errors, like ETIME, EILSEQ, EBADMSG... */
+
+          if (file_start)
+            {
+             err++;
+            }
+
+          if (err > MAX_ERRORS)
+            {
+              ym_debug("rcv_file: too many errors, cancel!!\n");
+              canceled = true;
+              break;
+            }
+
+          chunk[0] = CRC16;
+          ctx->send(ctx, chunk, 1, timeout);
+        }
+    }
+
+  if (canceled)
+    {
+      chunk[0] = CA;
+      ctx->send(ctx, chunk, 1, timeout);
+      ctx->send(ctx, chunk, 1, timeout);
+      ym_debug("rcv_file: cancel command sent to sender\n");
+    }
+
+  return ret;
+}
+
+static int ymodem_send_pkt(struct ymodem_ctx *ctx)
+{
+  size_t size;
+  uint16_t crc;
+  uint8_t send_crc[2];
+
+  crc = crc16((const uint8_t *)ctx->data, ctx->packet_size);
+  size = ctx->send(ctx, (uint8_t *)&ctx->header,
+                   ctx->packet_size + 3, ctx->timeout);
+
+  if (size != ctx->packet_size + 3)
+    {
+      ym_debug("send pkt error\n");
+      return -1;
+    }
+
+  send_crc[0] = crc >> 8;
+  send_crc[1] = crc & 0x00ff;
+  size = ctx->send(ctx, send_crc, 2, ctx->timeout);
+  if (size != 2)
+    {
+      ym_debug("send crc16 error\n");
+      return -1;
+    }
+
+  return 0;
+}
+
+static int ymodem_rcv_cmd(struct ymodem_ctx *ctx, uint8_t cmd)
+{
+  size_t size;
+  uint8_t chunk[1];
+
+  size = ctx->receive(ctx, chunk, 1, ctx->timeout);
+  if (size != 1)
+    {
+      ym_debug("receive cmd error\n");
+      return -1;
+    }
+
+  if (chunk[0] == NAK)
+    {
+      return -EAGAIN;
+    }
+
+  if (chunk[0] != cmd)
+    {
+      ym_debug("receive cmd error, must 0x%x, but receive %d\n",
+               cmd, chunk[0]);
+      return -EINVAL;
+    }
+
+  return 0;
+}
+
+static int ymodem_send_file(struct ymodem_ctx *ctx)

Review Comment:
   ```suggestion
   static int ymodem_send_file(FAR struct ymodem_ctx *ctx)
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#define ym_debug(x...) dprintf(ctx->debug_fd, x)
+#else
+#define ym_debug(x...)
+#endif
+
+#define PACKET_SIZE                  (128)
+#define PACKET_1K_SIZE               (1024)
+#define FILE_NAME_LENGTH             (64)
+
+#define YM_FILE_RECV_NAME_PKT        (0)
+#define YM_RECV_DATA_PKT             (1)
+#define YM_FILE_SEND_NAME_PKT        (2)
+#define YM_SEND_DATA_PKT             (3)
+#define YM_SEND_LAST_PKT             (4)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ymodem_ctx
+{
+  char header;
+  char seq[2];
+  char data[PACKET_1K_SIZE];
+  char file_name[FILE_NAME_LENGTH];
+  uint16_t packet_size;
+  int32_t file_length;
+  uint32_t timeout;
+  uint32_t packet_type;
+  ssize_t (*send)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                  uint32_t timeout);
+  ssize_t (*receive)(struct ymodem_ctx *ctx, uint8_t *buf, size_t size,
+                     uint32_t timeout);
+  ssize_t (*packet_handler)(struct ymodem_ctx *ctx);
+  void *priv;
+  uint16_t need_sendfile_num;
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+  int debug_fd;
+#endif
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int ymodem_rcv(struct ymodem_ctx *ctx);
+int ymodem_send(struct ymodem_ctx *ctx);
+
+#endif /* __APPS_SYSTEM_YMODEM_YMODEM_H_ */

Review Comment:
   ```suggestion
   #endif /* __APPS_SYSTEM_YMODEM_YMODEM_H */
   ```



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H_
+#define __APPS_SYSTEM_YMODEM_YMODEM_H_

Review Comment:
   ```suggestion
   #ifndef __APPS_SYSTEM_YMODEM_YMODEM_H
   #define __APPS_SYSTEM_YMODEM_YMODEM_H
   ```



-- 
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


[GitHub] [nuttx-apps] anchao commented on a diff in pull request #1627: support ymodem protocal and sb rb application

Posted by "anchao (via GitHub)" <gi...@apache.org>.
anchao commented on code in PR #1627:
URL: https://github.com/apache/nuttx-apps/pull/1627#discussion_r1127334338


##########
system/ymodem/rb_main.c:
##########
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/system/ymodem/rb_main.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 <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <nuttx/fs/ioctl.h>
+#include "ymodem.h"
+#include "ym_utils.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ym_fd
+{
+  int uart_fd;
+  int file_fd;
+  char pathname[PATH_MAX];
+  size_t file_saved_size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int handler(FAR struct ymodem_ctx *ctx)
+{
+  char pathname[PATH_MAX + YMODEM_FILE_NAME_LENGTH];
+  FAR struct ym_fd *ym_fd = ctx->priv;
+  FAR char *filename;
+  size_t size;
+  size_t ret;
+
+  if (ctx->packet_type == YMODEM_FILE_RECV_NAME_PKT)
+    {
+      if (ym_fd->file_fd != 0)
+        {
+          close(ym_fd->file_fd);
+        }
+
+      if (strlen(ym_fd->pathname) != 0)
+        {
+          if (ym_fd->pathname[strlen(ym_fd->pathname) - 1] == '/')
+            {
+              sprintf(pathname, "%s%s", ym_fd->pathname, ctx->file_name);
+            }
+          else
+            {
+              sprintf(pathname, "%s/%s", ym_fd->pathname, ctx->file_name);
+            }
+
+          filename = pathname;
+        }
+      else
+        {
+          filename = ctx->file_name;
+        }
+
+      ym_fd->file_fd = open(filename, O_CREAT | O_RDWR);
+      if (ym_fd->file_fd < 0)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size = 0;
+    }
+  else if (ctx->packet_type == YMODEM_RECV_DATA_PKT)
+    {
+      if (ym_fd->file_saved_size + ctx->packet_size > ctx->file_length)
+        {
+          size = ctx->file_length - ym_fd->file_saved_size;
+        }
+      else
+        {
+          size = ctx->packet_size;
+        }
+
+      ret = write(ym_fd->file_fd, ctx->data, size);
+      if (ret != size)
+        {
+          return -1;
+        }
+
+      ym_fd->file_saved_size += ret;
+    }
+
+  return 0;
+}
+
+static void show_usage(FAR const char *progname, int errcode)
+{
+  fprintf(stderr, "USAGE: %s [OPTIONS]\n", progname);
+  fprintf(stderr, "\nWhere:\n");
+  fprintf(stderr, "\nand OPTIONS include the following:\n");
+  fprintf(stderr,
+          "\t-d <device>: Communication device to use.  Default: %s\n",
+          CONFIG_SYSTEM_YMODEM_DEVNAME);
+  fprintf(stderr,
+          "\t-p <path>: Save remote file path. Default: Current path\n");
+  exit(errcode);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  FAR const char *devname = CONFIG_SYSTEM_YMODEM_DEVNAME;
+  struct termios saveterm;
+  struct ymodem_ctx ctx;
+  struct termios term;
+  struct ym_fd ym_fd;
+  int option;
+
+  memset(&ym_fd, 0, sizeof(struct ym_fd));
+  while ((option = getopt(argc, argv, "d:p:h")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'd':
+            devname = optarg;
+            break;
+          case 'h':
+            show_usage(argv[0], EXIT_FAILURE);
+          case 'p':
+            strncpy(ym_fd.pathname, optarg, PATH_MAX);
+            break;
+          default:
+          case '?':
+            fprintf(stderr, "ERROR: Unrecognized option\n");
+            show_usage(argv[0], EXIT_FAILURE);
+            break;
+        }
+    }
+
+  memset(&ctx, 0, sizeof(struct ymodem_ctx));
+  ctx.send = ymodem_uart_send;
+  ctx.receive = ymodem_uart_receive;
+  ctx.packet_handler = handler;
+  ctx.timeout = 200;
+  ctx.priv = &ym_fd;
+
+  ym_fd.file_fd = 0;
+  ym_fd.uart_fd = open(devname, O_RDWR | O_NONBLOCK);
+  if (ym_fd.uart_fd < 0)
+    {
+      printf("open\n");
+      return 0;
+    }
+
+  tcgetattr(ym_fd.uart_fd, &saveterm);
+  tcgetattr(ym_fd.uart_fd, &term);
+  cfmakeraw(&term);
+  tcsetattr(ym_fd.uart_fd, TCSANOW, &term);
+
+  sched_lock();

Review Comment:
   It's better not to use the kernel API, the application is better to keep POSIX compatible



##########
system/ymodem/ymodem.h:
##########
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * apps/system/ymodem/ymodem.h
+ *
+ * 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 __APPS_SYSTEM_YMODEM_YMODEM_H
+#define __APPS_SYSTEM_YMODEM_YMODEM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_YMODEM_DEBUGFILE_PATH
+#  define ymodem_debug(...) dprintf(ctx->debug_fd, ##__VA_ARGS__)

Review Comment:
   too many logs will be generated during the transmission process. If you continue to write /tmp, it will  consume to much of memory, which is not friendly on devices with limited resources.



-- 
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


[GitHub] [nuttx-apps] acassis merged pull request #1627: support ymodem protocal and sb rb application

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


-- 
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