diff options
| author | Grissiom <[email protected]> | 2013-10-09 20:27:00 +0800 |
|---|---|---|
| committer | Grissiom <[email protected]> | 2013-10-09 23:26:42 +0800 |
| commit | 5674198759e899854498207353ae59c526929070 (patch) | |
| tree | cc5778352d6f58ddb89c109313d74de5fa507405 /examples | |
| parent | 83bb05419f7aba80f6a10a48f88a2838a356737a (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.c | 59 | ||||
| -rw-r--r-- | examples/ymodem/null.c | 28 | ||||
| -rw-r--r-- | examples/ymodem/tofile.c | 113 |
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 |
