summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorGrissiom <[email protected]>2013-10-09 20:27:00 +0800
committerGrissiom <[email protected]>2013-10-09 23:26:42 +0800
commit5674198759e899854498207353ae59c526929070 (patch)
treecc5778352d6f58ddb89c109313d74de5fa507405 /examples
parent83bb05419f7aba80f6a10a48f88a2838a356737a (diff)
components/utilities: add ymodem
Real-YModem implemented a flexible YModem support. It use callback-based structure to let the user application to deal with the data. It contains 3 examples: 1. echo.c: write the data recieved on YModem to an other device 2. null.c: discard the YModem data 3. tofile.c: write the data to the file system Currently, it does not support batch file transmission.
Diffstat (limited to 'examples')
-rw-r--r--examples/ymodem/echo.c59
-rw-r--r--examples/ymodem/null.c28
-rw-r--r--examples/ymodem/tofile.c113
3 files changed, 200 insertions, 0 deletions
diff --git a/examples/ymodem/echo.c b/examples/ymodem/echo.c
new file mode 100644
index 0000000000..5ffa5ff417
--- /dev/null
+++ b/examples/ymodem/echo.c
@@ -0,0 +1,59 @@
+#include <ymodem.h>
+
+static rt_device_t _odev;
+
+static enum rym_code _rym_echo_data(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ rt_device_write(_odev, 0, buf, len);
+ return RYM_CODE_ACK;
+}
+
+rt_err_t rym_cat_to_dev(rt_device_t idev, rt_device_t odev)
+{
+ struct rym_ctx rctx;
+ rt_err_t res;
+ _odev = odev;
+
+ rt_kprintf("entering RYM mode\n");
+ odev->flag &= ~RT_DEVICE_FLAG_STREAM;
+ res = rt_device_open(odev, 0);
+ if (res != RT_EOK)
+ {
+ rt_kprintf("open output device error: 0x%x", -res);
+ return res;
+ }
+ res = rym_recv_on_device(&rctx, idev,
+ RT_NULL, _rym_echo_data, RT_NULL, 1000);
+ rt_device_close(_odev);
+ rt_kprintf("leaving RYM mode with code %X\n", res);
+ return res;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void rym_cat_vcom(void)
+{
+ extern rt_err_t rym_cat_to_dev(rt_device_t idev, rt_device_t odev);
+ rt_device_t idev, odev;
+
+ rt_thread_delay(RT_TICK_PER_SECOND*10);
+
+ idev = rt_device_find("uart1");
+ if (!idev)
+ {
+ rt_kprintf("could not find idev\n");
+ }
+ odev = rt_device_find("vcom");
+ if (!odev)
+ {
+ rt_kprintf("could not find odev\n");
+ }
+
+ rym_cat_to_dev(idev, odev);
+}
+FINSH_FUNCTION_EXPORT(rym_cat_vcom, test the YModem);
+#endif
+
diff --git a/examples/ymodem/null.c b/examples/ymodem/null.c
new file mode 100644
index 0000000000..5e3baa9870
--- /dev/null
+++ b/examples/ymodem/null.c
@@ -0,0 +1,28 @@
+#include <ymodem.h>
+
+static enum rym_code _rym_dummy_write(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ return RYM_CODE_ACK;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+rt_err_t rym_null(char *devname)
+{
+ struct rym_ctx rctx;
+ rt_device_t dev = rt_device_find(devname);
+ if (!dev)
+ {
+ rt_kprintf("could not find device %s\n", devname);
+ return -1;
+ }
+
+ return rym_recv_on_device(&rctx, dev,
+ RT_NULL, _rym_dummy_write, RT_NULL, 1000);
+}
+FINSH_FUNCTION_EXPORT(rym_null, dump data to null);
+#endif
+
diff --git a/examples/ymodem/tofile.c b/examples/ymodem/tofile.c
new file mode 100644
index 0000000000..2deef73c2c
--- /dev/null
+++ b/examples/ymodem/tofile.c
@@ -0,0 +1,113 @@
+#include <rtthread.h>
+#include <ymodem.h>
+#include <dfs_posix.h>
+#include <stdlib.h>
+
+#include <board.h>
+
+struct custom_ctx
+{
+ struct rym_ctx parent;
+ int fd;
+ int flen;
+ char fpath[256];
+};
+
+static enum rym_code _rym_bg(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx*)ctx;
+ cctx->fpath[0] = '/';
+ /* the buf should be the file name */
+ strcpy(&(cctx->fpath[1]), buf);
+ cctx->fd = open(cctx->fpath, O_CREAT | O_WRONLY | O_TRUNC, 0);
+ if (cctx->fd < 0)
+ {
+ rt_err_t err = rt_get_errno();
+ rt_kprintf("error creating file: %d\n", err);
+ rt_kprintf("abort transmission\n");
+ return RYM_CODE_CAN;
+ }
+
+ cctx->flen = atoi(buf+strlen(buf)+1);
+ if (cctx->flen == 0)
+ cctx->flen = -1;
+ return RYM_CODE_ACK;
+}
+
+static enum rym_code _rym_tof(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx*)ctx;
+ RT_ASSERT(cctx->fd >= 0);
+ if (cctx->flen == -1)
+ {
+ write(cctx->fd, buf, len);
+ }
+ else
+ {
+ int wlen = len > cctx->flen ? cctx->flen : len;
+ write(cctx->fd, buf, wlen);
+ cctx->flen -= wlen;
+ }
+ return RYM_CODE_ACK;
+}
+
+static enum rym_code _rym_end(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx*)ctx;
+
+ RT_ASSERT(cctx->fd >= 0);
+ close(cctx->fd);
+ cctx->fd = -1;
+
+ return RYM_CODE_ACK;
+}
+
+rt_err_t rym_write_to_file(rt_device_t idev)
+{
+ rt_err_t res;
+ struct custom_ctx *ctx = rt_malloc(sizeof(*ctx));
+
+ RT_ASSERT(idev);
+
+ rt_kprintf("entering RYM mode\n");
+
+ res = rym_recv_on_device(&ctx->parent, idev,
+ _rym_bg, _rym_tof, _rym_end, 1000);
+
+ /* there is no Ymodem traffic on the line so print out info. */
+ rt_kprintf("leaving RYM mode with code %d\n", res);
+ rt_kprintf("file %s has been created.\n", ctx->fpath);
+
+ rt_free(ctx);
+
+ return res;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+rt_err_t ry(char *dname)
+{
+ rt_err_t res;
+
+ rt_device_t dev = rt_device_find(dname);
+ if (!dev)
+ {
+ rt_kprintf("could not find device:%s\n", dname);
+ return -RT_ERROR;
+ }
+
+ res = rym_write_to_file(dev);
+
+ return res;
+}
+FINSH_FUNCTION_EXPORT(ry, receive files by ymodem protocol);
+#endif