eCos读UART数据实例

#include "oem_portmisc.h"

static cyg_io_handle_t ser_hndl;

static char stack[UART_READ_TASK_STACK_SZ];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;

static char pf_stack[PARSE_TASK_STACK_SZ];
static cyg_thread pf_thread_data;
static cyg_handle_t pf_thread_handle;

/* Mailbox的结构是一个FIFO类型的循环队列,存储的是指针 */
/* Search "cyg_mbox_create fifo" in baidu for more info */
static cyg_handle_t uart_mbox_h;
static cyg_mbox uart_mbox;

static cyg_mutex_t uart_mutex;

static u8 ring_buf[MSG_SZ * NR_MSG];
static u32 rb_write_seq = 0;
static u32 rb_read_seq = 0;

#define rb_lock() do {              \
    cyg_mutex_lock(&uart_mutex);    \
} while (0)

#define rb_unlock() do {            \
    cyg_mutex_unlock(&uart_mutex);  \
} while (0)

static bool snd_data(const u8 *data)
{
    if (uart_mbox_h && cyg_mbox_tryput(uart_mbox_h, (void *)data)) {
        return true;
    }
    return false;
}

void *uart_get_data(void)
{
    if (uart_mbox_h) {
        return cyg_mbox_get(uart_mbox_h);
    }

    return NULL;
}

static void push_msg(u8 *msg)
{
    u32 offset;

    if (!msg) {
        return;
    }

    rb_lock();
    offset = (rb_write_seq & (NR_MSG - 1)) * MSG_SZ;
    memcpy(&(ring_buf[offset]), msg, MSG_SZ);
    rb_write_seq++;
    if ((rb_write_seq - rb_read_seq) > NR_MSG) {
        rb_read_seq = rb_write_seq - NR_MSG;
    }
    rb_unlock();
}

static bool pull_msg(u8 *msg)
{
    u32 offset;

    if (!msg) {
        return false;
    }

    rb_lock();
    if (rb_read_seq == rb_write_seq) {
        rb_unlock();
        return false;
    }
    offset = (rb_read_seq & (NR_MSG - 1)) * MSG_SZ;
    memcpy(msg, &(ring_buf[offset]), MSG_SZ);
    rb_read_seq++;
    rb_unlock();
    return true;
}

static void uart_read_task(cyg_addrword_t data)
{
    u8 frame[MSG_SZ];
    u8 i;
    u32 nread;
    u32 ret = 0;

    diag_printf("[OEM][%s] enter uart_read_task\n", __func__);
    while (1) {
rx_2bytes_hdr:
        i = 0;
        while (i < 1) {
            nread = 1;
            ret = cyg_io_read(ser_hndl, &frame[i], &nread);
            if (ENOERR != ret) {
                continue;
            }
            if (frame[i] != 0x55) {
                continue;
            }
            i++;
            break;
        }
        while (i < 2) {
            nread = 1;
            ret = cyg_io_read(ser_hndl, &frame[i], &nread);
            if (ENOERR != ret) {
                continue;
            }
            if (frame[i] != 0x5A) {
                goto rx_2bytes_hdr;
            }
            i++;
            break;
        }

        while (i < MSG_SZ) {
            nread = MSG_SZ - i;
            ret = cyg_io_read(ser_hndl, &frame[i], &nread);
            if (ENOERR != ret) {
                continue;
            }
            i += nread;
        }

        push_msg(frame);
    }
    diag_printf("[OEM][%s] finished\n", __func__);
}

static void parse_frame_task(cyg_addrword_t data)
{
    u8 frame[MSG_SZ];
    u8 i;

    while (1) {
        if (pull_msg(frame)) {
#if defined(DEBUG)
            for (i = 0; i < MSG_SZ; i++) {
                diag_printf("%02x ", frame[i]);
            }
            diag_printf("\n");
#endif
            cyg_thread_delay(100);
        }
    }
}

void uart_init(void)
{
    int ret;
    // fuelgauge uart config
    cyg_serial_info_t serial_info =
        CYG_SERIAL_INFO_INIT(CYGNUM_SERIAL_BAUD_4800,
                CYGNUM_SERIAL_STOP_1,
                CYGNUM_SERIAL_PARITY_EVEN,
                CYGNUM_SERIAL_WORD_LENGTH_8,
                0 );
    cyg_uint32 size = sizeof(serial_info);

    cyg_mbox_create(&uart_mbox_h, &uart_mbox);
    cyg_mutex_init(&uart_mutex);

    ret = cyg_io_lookup(FG_UART, &ser_hndl);
    if (ret != ENOERR) {
        diag_printf("[OEM] failed to opening \"%s\"\n", FG_UART);
        return 0;
    }

    ret = cyg_io_set_config(ser_hndl, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &size);
    if (ret != ENOERR)
        diag_printf("[OEM] set_config flow_control returned an error\n");

    diag_printf("[OEM] succeeded in opening \"%s\"\n", FG_UART);

    cyg_thread_create(UART_READ_TASK_PRIORITY,  // Priority - just a number
            uart_read_task,             // entry
            0,                          // entry parameter
            "uart_read_task",           // Name
            &stack[0],                  // Stack
            UART_READ_TASK_STACK_SZ,    // Size
            &thread_handle,             // Handle
            &thread_data                // Thread data structure
            );
    cyg_thread_resume(thread_handle);   // Start it
#if 1
    // Decode frame thread
    cyg_thread_create(PARSE_TASK_PRIORITY,  // Priority - just a number
            parse_frame_task,               // entry
            0,                              // entry parameter
            "parse_frame_task",             // Name
            &pf_stack[0],                   // Stack
            PARSE_TASK_STACK_SZ,            // Size
            &pf_thread_handle,              // Handle
            &pf_thread_data                 // Thread data structure
            );
    cyg_thread_resume(pf_thread_handle);    // Start it
#endif
}
module_init(uart_init);

你可能感兴趣的:(MCU,uart,eCos)